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); }
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); }