Exemplo n.º 1
0
        public AccountDayStatistic CalculateStatistic(MT4AccountInfo accountInfo, DateTime date, mt4_trades[] orders, AccountDayStatistic lastStatisticModel)
        {
            var statistic = CalculateStatisticForClosedOrders(date, date.AddDays(1), accountInfo, orders, lastStatisticModel);

            CalculateProfitPercent(statistic, accountInfo.ServerName, date, date.AddDays(1).AddSeconds(-1), orders, lastStatisticModel);

            return(statistic);
        }
Exemplo n.º 2
0
        private AccountDayStatistic CalculateStatisticForClosedOrders(DateTime date, DateTime endOfDay, MT4AccountInfo accountInfo, IEnumerable <mt4_trades> allOrders, AccountDayStatistic previousStatistic)
        {
            var orders = allOrders
                         .Where(order => order.LOGIN == accountInfo.Login &&
                                ((order.CLOSE_TIME >= date && order.CLOSE_TIME < endOfDay) ||
                                 (order.CLOSE_TIME == Constants.BeginEpoch && order.OPEN_TIME < endOfDay) ||
                                 (order.CLOSE_TIME >= endOfDay && order.OPEN_TIME < endOfDay)))
                         .ToArray();

            var res = new AccountDayStatistic();

            res.Date            = date;
            res.AccountId       = accountInfo.AccountId;
            res.ClientAccountId = accountInfo.ClientId;

            res.CurrentBalance = previousStatistic.CurrentBalance +
                                 (decimal)orders
                                 .Where(trades => trades.CMD == (int)OrderType.BALANCE || trades.CMD == (int)OrderType.CREDIT || trades.CMD == (int)OrderType.BUY || trades.CMD == (int)OrderType.SELL)
                                 .Sum(trade => trade.PROFIT + trade.COMMISSION + trade.SWAPS + trade.TAXES);

            res.BalancePerDay = orders.Where(trades => trades.CMD == (int)OrderType.BALANCE || trades.CMD == (int)OrderType.CREDIT).Sum(trades => trades.PROFIT);

            var tradingOrders = orders
                                .Where(trades => trades.CMD == (int)OrderType.BUY || trades.CMD == (int)OrderType.SELL)
                                .Select(trades => trades)
                                .ToArray();
            var closedOrders = tradingOrders
                               .Where(trades => trades.CLOSE_TIME != Constants.BeginEpoch && trades.CLOSE_TIME < endOfDay)
                               .Select(trades => trades)
                               .ToArray();

            var openedOrders = tradingOrders
                               .Where(trades => trades.OPEN_TIME >= date && trades.OPEN_TIME < endOfDay)
                               .Select(trades => trades)
                               .ToArray();

            var performance = (double)previousStatistic.RiskTotal;

            foreach (var openOrder in openedOrders)
            {
                var currentBalance = closedOrders.Where(x => x.CLOSE_TIME < openOrder.OPEN_TIME).Sum(x => x.PROFIT + x.TAXES + x.SWAPS + x.COMMISSION) +
                                     orders.Where(x => (x.CMD == 5 || x.CMD == 6) && x.CLOSE_TIME < openOrder.OPEN_TIME).Sum(x => x.PROFIT);

                var orderPerformance = (openOrder.PROFIT + openOrder.SWAPS + openOrder.TAXES + openOrder.COMMISSION) / ((double)previousStatistic.CurrentBalance + currentBalance) + 1;

                if (Math.Abs(orderPerformance) > 0.01)
                {
                    performance = (performance + 1) * orderPerformance - 1;
                }
            }
            res.RiskTotal = (decimal)performance;

            // Closed per day
            res.ClosedProfitInPointsPerDay =
                closedOrders
                .Where(order => order.CMD == (int)OrderType.BUY || order.CMD == (int)OrderType.SELL)
                .Sum(trade => trade.CMD == (int)OrderType.BUY
                                                ? (int)((trade.CLOSE_PRICE - trade.OPEN_PRICE) / cacheService.GetSymbolCoefficient(trade.SYMBOL, trade.DIGITS))
                                                : (int)((trade.OPEN_PRICE - trade.CLOSE_PRICE) / cacheService.GetSymbolCoefficient(trade.SYMBOL, trade.DIGITS)));
            res.ProfitTradesCountPerDay     = closedOrders.Count(order => order.PROFIT + order.COMMISSION + order.SWAPS + order.TAXES > 0.0);
            res.ClosedLoseTradesCountPerDay = closedOrders.Count(order => order.PROFIT + order.COMMISSION + order.SWAPS + order.TAXES <= 0.0);
            res.ClosedProfitPerDay          = closedOrders.Sum(order => order.PROFIT + order.COMMISSION + order.SWAPS + order.TAXES);

            //res.ClosedProfitInPercentsPerDay = Math.Abs(previousStatistic.CurrentBalance) < Constants.Tolerance
            //	? 0.0
            //	: ((res.ClosedProfitPerDay / (double)previousStatistic.CurrentBalance) * 100.0);

            // Closed total
            res.ClosedLoseTradesTotal = previousStatistic.ClosedLoseTradesTotal + res.ClosedLoseTradesCountPerDay;
            //res.ClosedProfitInPercentsTotal = previousStatistic.ClosedProfitInPercentsTotal + res.ClosedProfitInPercentsPerDay;
            res.ClosedProfitInPointsTotal = previousStatistic.ClosedProfitInPointsTotal + res.ClosedProfitInPointsPerDay;
            res.ClosedProfitTotal         = previousStatistic.ClosedProfitTotal + res.ClosedProfitPerDay;
            res.ClosedProfitTradesTotal   = previousStatistic.ClosedProfitTradesTotal + res.ProfitTradesCountPerDay;

            res.OpenedTradesCountPerDay  = tradingOrders.Count(trades => trades.OPEN_TIME >= date);
            res.OpenedTradesCountCurrent = tradingOrders.Count(order => order.CLOSE_TIME == Constants.BeginEpoch);
            res.OpenedTradesCountTotal   = previousStatistic.OpenedTradesCountTotal + res.OpenedTradesCountPerDay;

            var tradeTimePerDay   = closedOrders.Sum(trades => (trades.CLOSE_TIME - trades.OPEN_TIME).TotalMinutes);
            var closedTradesTotal = previousStatistic.ClosedProfitTradesTotal + previousStatistic.ClosedLoseTradesTotal;

            res.AvarageTradeTimeInMinutes = Math.Abs(tradeTimePerDay) <= 0.001
                                ? 0
                                : tradeTimePerDay / (res.ProfitTradesCountPerDay + res.ClosedLoseTradesCountPerDay);
            var totalTradeTime = previousStatistic.AvarageTradeTimeInMinutesTotal * (closedTradesTotal) + tradeTimePerDay;

            res.AvarageTradeTimeInMinutesTotal = Math.Abs(totalTradeTime) <= 0.001
                                ? 0
                                : totalTradeTime / (res.ClosedLoseTradesTotal + res.ClosedProfitTradesTotal);

            res.VolumePerDay           = closedOrders.Sum(trades => trades.VOLUME);
            res.VolumeEfficiencyPerDay = Math.Abs(res.VolumePerDay) < 0.0001 ? 0.0 : res.ClosedProfitPerDay / res.VolumePerDay;

            res.MaxOpenOrders = res.OpenedTradesCountPerDay > previousStatistic.MaxOpenOrders
                                ? res.OpenedTradesCountPerDay
                                : previousStatistic.MaxOpenOrders;

            res.TradeAmountTotal = previousStatistic.TradeAmountTotal +
                                   orders
                                   .Where(trades => (trades.CMD == (int)OrderType.BUY || trades.CMD == (int)OrderType.SELL) && trades.CLOSE_TIME != Constants.BeginEpoch)
                                   .Sum(trades => (decimal)trades.VOLUME);

            return(res);
        }