private static void Visualize(BacktestConfig backtest, ProfitComputer computer, IStrategy strategy, int maxInv, ProfitInfo report, ProfitInfo[] days, ProfitInfo[] months) { if (computer == null || backtest.Visualize == null || !backtest.Visualize.Value) { return; } PrepareWebVisualization(backtest, computer, strategy, maxInv, report, report, days, months); var chart = new ChartVisualizer(); var filename = Path.GetFileName(backtest.DirectoryPath); var strategyName = strategy.GetType().Name.ToLower(); var pnl = report.Pnl; var name = $"{pnl:#.00} {backtest.QuoteSymbol} (max inv: {maxInv}) "; var nameWithFee = $"{report.PnlWithFee:#.00} {backtest.QuoteSymbol} (max inv: {maxInv}) "; var dir = GetPathToReportDir(backtest); var pattern = ExtractFromPattern(backtest); var targetFile = Path.Combine(dir, $"{pattern}__{strategyName}__{maxInv}__{pnl:0}"); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var bars = computer.Bars; var totalBars = bars.Length; if (backtest.VisualizeSkipBars.HasValue) { bars = bars.Skip(backtest.VisualizeSkipBars.Value).ToArray(); } if (backtest.VisualizeLimitBars.HasValue) { bars = bars.Take(backtest.VisualizeLimitBars.Value).ToArray(); } var minIndex = bars.Min(x => x.Index); var maxIndex = bars.Max(x => x.Index); var trades = computer.Trades .Where(x => x.BarIndex >= minIndex && x.BarIndex <= maxIndex) .ToArray(); chart.Plot(name, nameWithFee, targetFile, totalBars, bars, trades, days, months); }
private static void PrepareWebVisualization(BacktestConfig backtest, ProfitComputer computer, IStrategy strategy, in int maxInv,
private static void RunBacktest(BacktestConfig backtest, Func <IStrategy> strategyFactory) { var files = LoadAllFiles(backtest.DirectoryPath, backtest.FilePattern); if (backtest.SkipFiles.HasValue) { files = files.Skip(backtest.SkipFiles.Value).ToArray(); } if (backtest.LimitFiles.HasValue) { files = files.Take(backtest.LimitFiles.Value).ToArray(); } if (!files.Any()) { return; } Console.WriteLine(); Console.WriteLine("====================================================================="); Console.WriteLine($" Running for {files.Length} files from dir '{backtest.DirectoryPath}' and pattern: '{backtest.FilePattern}'"); var builderTop = new StringBuilder(); var builder = new StringBuilder(); foreach (var maxInventory in backtest.MaxInventory) { RangeBarModel lastBar = null; var strategy = strategyFactory(); var computer = new ProfitComputer(strategy, backtest, maxInventory); foreach (var file in files) { var bars = LoadBars(backtest, file); computer.ProcessBars(bars); lastBar = bars.LastOrDefault(); } if (lastBar != null) { computer.ProcessLastBar(lastBar); } var report = computer.GetReport(); builderTop.AppendLine(report.ToString()); builder.AppendLine( $"==== MAX INV: {maxInventory} {new string('=', 133)}"); builder.AppendLine(); builder.AppendLine(report.ToString()); Console.WriteLine($" {report}"); var reportDays = new List <ProfitInfo>(); var perMonth = computer.GetReportByMonth(); foreach (var month in perMonth) { builder.AppendLine($" {month.Report}"); if (month.Month == null) { builderTop.AppendLine($"{month.Report}"); continue; } var perDay = computer.GetReportPerDays(month.Year.Value, month.Month.Value); reportDays.AddRange(perDay.Where(x => x.Day != null)); foreach (var day in perDay) { builder.AppendLine($" {day.Report}"); } } //var totalReportAllDays = computer.GetTotalReport(reportDays.ToArray()); //builderTop.AppendLine($"{totalReportAllDays.Report}"); //builderTop.AppendLine(); builder.AppendLine(); builder.AppendLine(); Visualize(backtest, computer, strategy, maxInventory, report, reportDays.ToArray(), perMonth.Where(x => x.Month.HasValue).ToArray()); } var mergedReport = $"{builderTop}{Environment.NewLine}{builder}"; SaveTextReport(mergedReport, backtest, strategyFactory()); Console.WriteLine(); }
private static void RunBacktest(BacktestConfig backtest, Func <IStrategy> strategyFactory) { var files = LoadAllFiles(backtest.DirectoryPath, backtest.FilePattern); if (backtest.SkipFiles.HasValue) { files = files.Skip(backtest.SkipFiles.Value).ToArray(); } if (backtest.LimitFiles.HasValue) { files = files.Take(backtest.LimitFiles.Value).ToArray(); } if (!files.Any()) { return; } Console.WriteLine(); Console.WriteLine("====================================================================="); Console.WriteLine($" Running for {files.Length} files from dir '{backtest.DirectoryPath}' and pattern: '{backtest.FilePattern}'"); var builderTop = new StringBuilder(); var builder = new StringBuilder(); foreach (var maxInventory in backtest.MaxInventory) { RangeBarModel lastBar = null; var strategy = strategyFactory(); var computer = new ProfitComputer(strategy, backtest, maxInventory); foreach (var file in files) { var bars = LoadBars(backtest, file); computer.ProcessBars(bars); lastBar = bars.LastOrDefault(); } if (lastBar != null) { computer.ProcessLastBar(lastBar); } var primaryReport = computer.GetReport(); var perMonth = computer.GetReportByMonth(); var reportDays = new List <ProfitInfo>(); var maxTotalPnl = maxInventory * computer.InitialPrice; var minTotalPnl = maxTotalPnl; var totalPnl = maxTotalPnl; foreach (var month in perMonth) { if (month.Month == null) { continue; } var perDay = computer.GetReportPerDays(month.Year.Value, month.Month.Value, ref maxTotalPnl, ref minTotalPnl, ref totalPnl); reportDays.AddRange(perDay.Where(x => x.Day != null)); month.MaxDrawdownPercentage = perDay.Min(x => x.MaxDrawdownPercentage); month.SubProfits = perDay; } primaryReport.MaxDrawdownPercentage = perMonth.Min(x => x.MaxDrawdownPercentage); builderTop.AppendLine(primaryReport.ToString()); builder.AppendLine( $"==== MAX INV: {maxInventory} {new string('=', 133)}"); builder.AppendLine(); builder.AppendLine(primaryReport.ToString()); var consoleDefaultColor = Console.ForegroundColor; var reportColor = Console.ForegroundColor; var pnl = backtest.DisplayFee != null && backtest.DisplayFee.Value ? primaryReport.PnlWithFee : primaryReport.Pnl; if (pnl < 0) { reportColor = ConsoleColor.DarkRed; } else if (pnl > 0 && primaryReport.MaxDrawdownPercentage >= -0.03) { reportColor = ConsoleColor.Green; } else if (pnl > 0) { reportColor = ConsoleColor.DarkGreen; } Console.ForegroundColor = reportColor; Console.WriteLine($" {primaryReport}"); Console.ForegroundColor = consoleDefaultColor; foreach (var month in perMonth) { if (month.Month == null) { builder.AppendLine($" {month.Report}"); builderTop.AppendLine($"{month.Report}"); continue; } builder.AppendLine($" {month.Report}"); foreach (var day in month.SubProfits) { builder.AppendLine($" {day.Report}"); } } //var totalReportAllDays = computer.GetTotalReport(reportDays.ToArray()); //builderTop.AppendLine($"{totalReportAllDays.Report}"); //builderTop.AppendLine(); builder.AppendLine(); builder.AppendLine(); Visualize(backtest, computer, strategy, maxInventory, primaryReport, reportDays.ToArray(), perMonth.Where(x => x.Month.HasValue).ToArray()); } var mergedReport = $"{builderTop}{Environment.NewLine}{builder}"; SaveTextReport(mergedReport, backtest, strategyFactory()); Console.WriteLine(); }