public virtual IBacktestResult GetResult() { var tradeEngine = Robot.Trade; var trades = tradeEngine.Trades.ToList(); var result = new BacktestResult { TotalTradesNumber = trades.Count, LongTradesNumber = trades.Where(iTrade => iTrade.Order.TradeType == TradeType.Buy).Count(), ShortTradesNumber = trades.Where(iTrade => iTrade.Order.TradeType == TradeType.Sell).Count(), NetProfit = trades.Select(iTrade => iTrade.Order.NetProfit).Sum(), WinningRate = trades.Count > 0 ? trades.Where(iTrade => iTrade.Order.NetProfit > 0).Count() / (double)trades.Count * 100 : 0, }; var grossProfit = trades.Where(iTrade => iTrade.Order.GrossProfit > 0).Sum(iTrade => iTrade.Order.GrossProfit); var grossLoss = trades.Where(iTrade => iTrade.Order.GrossProfit < 0).Sum(iTrade => Math.Abs(iTrade.Order.GrossProfit)); result.ProfitFactor = grossLoss > 0 ? grossProfit / grossLoss : grossProfit; result.MaxEquityDrawdown = MaxDrawdownCalculator.GetMaxDrawdown(Robot.Account.EquityChanges); result.MaxBalanceDrawdown = MaxDrawdownCalculator.GetMaxDrawdown(Robot.Account.BalanceChanges); result.Commission = trades.Sum(iTrade => iTrade.Order.Commission); if (Robot.Account.CurrentBalance > 0) { var depositTransaction = Robot.Account.Transactions.FirstOrDefault(iTransaction => iTransaction.Amount > 0); if (depositTransaction != null && trades.Any()) { var initialDeposit = depositTransaction.Amount; var tradeData = trades.Select(iTrade => iTrade.Order.NetProfit); result.SharpeRatio = SharpeRatioCalculator.GetSharpeRatio(tradeData); result.SortinoRatio = SortinoRatioCalculator.GetSortinoRatio(tradeData); } } var winningTrades = trades.Where(iTrade => iTrade.Order.NetProfit > 0); var losingTrades = trades.Where(iTrade => iTrade.Order.NetProfit < 0); result.AverageProfit = winningTrades.Count() > 0 ? winningTrades.Average(iTrade => iTrade.Order.NetProfit) : 0; result.AverageLoss = losingTrades.Count() > 0 ? losingTrades.Average(iTrade => iTrade.Order.NetProfit) : 0; result.AverageReturn = trades.Count > 0 ? trades.Average(iTrade => iTrade.Order.NetProfit) : 0; if (trades.Any()) { var durationAverageInHours = trades.Select(iTrade => iTrade.Duration.TotalHours).Average(); result.AverageTradeDuration = TimeSpan.FromHours(durationAverageInHours); result.AverageBarsPeriod = trades.Select(iTrade => iTrade.BarsPeriod).Average(); } return(result); }
public override void CloseMarketOrder(MarketOrder order, CloseReason closeReason) { if (_orders.Contains(order)) { _orders.Remove(order); } var exitPrice = order.TradeType == TradeType.Buy ? order.Symbol.GetPrice(TradeType.Sell) : order.Symbol.GetPrice(TradeType.Buy); var barsPeriod = order.Symbol.Bars.Time.Where(iBarTime => iBarTime >= order.OpenTime).Count(); var tradingEvent = new TradingEvent(Server.CurrentTime, TradingEventType.MarketOrderClosed, order, string.Empty); _journal.Add(tradingEvent); Account.ChangeMargin(-order.MarginUsed, Server.CurrentTime, string.Empty, AccountChangeType.Trading); Account.ChangeBalance(order.NetProfit, Server.CurrentTime, string.Empty, AccountChangeType.Trading); var tradeData = Trades.Select(iTrade => iTrade.Order.NetProfit); var sharpeRatio = SharpeRatioCalculator.GetSharpeRatio(tradeData); var sortinoRatio = SortinoRatioCalculator.GetSortinoRatio(tradeData); var equityMaxDrawDown = MaxDrawdownCalculator.GetMaxDrawdown(Account.EquityChanges); var balanceMaxDrawDown = MaxDrawdownCalculator.GetMaxDrawdown(Account.BalanceChanges); var id = _trades.Count + 1; var tradeParameters = new TradeParameters { Id = id, Order = order, ExitTime = Server.CurrentTime, ExitPrice = exitPrice, Balance = Account.CurrentBalance, Equity = Account.Equity, BalanceMaxDrawDown = balanceMaxDrawDown, EquityMaxDrawDown = equityMaxDrawDown, BarsPeriod = barsPeriod, CloseReason = closeReason, SharpeRatio = sharpeRatio, SortinoRatio = sortinoRatio }; var trade = new Trade(tradeParameters); _trades.Add(trade); }
public void GetMaxDrawdownZeroTest() { var changes = new List <IAccountChange> { new AccountChange(1000, 100, DateTimeOffset.Now.AddDays(-10), string.Empty, AccountChangeType.Deposit), new AccountChange(1100, 100, DateTimeOffset.Now.AddDays(-9), string.Empty, AccountChangeType.Trading), new AccountChange(1200, 100, DateTimeOffset.Now.AddDays(-8), string.Empty, AccountChangeType.Trading), }; var actualDrawdown = MaxDrawdownCalculator.GetMaxDrawdown(changes); var expectedDrawdown = 0; Assert.AreEqual(expectedDrawdown, actualDrawdown); }