From 6d661f459e559f980bc3c29d88681e92266abdf3 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Fri, 14 Nov 2025 20:49:02 +0700 Subject: [PATCH] Remove candle from backtest return + fix message when good backtest --- .../Backtests/BacktestExecutor.cs | 7 ++- .../Backtests/Backtester.cs | 61 ++++++------------- .../Bots/Grains/BacktestTradingBotGrain.cs | 5 +- .../Shared/MessengerService.cs | 6 +- src/Managing.Domain/Backtests/Backtest.cs | 18 +----- .../src/generated/ManagingApi.ts | 1 - .../src/generated/ManagingApiTypes.ts | 1 - 7 files changed, 30 insertions(+), 69 deletions(-) diff --git a/src/Managing.Application/Backtests/BacktestExecutor.cs b/src/Managing.Application/Backtests/BacktestExecutor.cs index 2be56973..7cdb8a3d 100644 --- a/src/Managing.Application/Backtests/BacktestExecutor.cs +++ b/src/Managing.Application/Backtests/BacktestExecutor.cs @@ -383,8 +383,7 @@ public class BacktestExecutor var finalRequestId = requestId != null ? Guid.Parse(requestId) : Guid.NewGuid(); // Create backtest result with conditional candles and indicators values - var result = new Backtest(config, tradingBot.Positions, tradingBot.Signals, - withCandles ? candles : new HashSet()) + var result = new Backtest(config, tradingBot.Positions, tradingBot.Signals) { FinalPnl = realizedPnl, // Realized PnL before fees WinRate = winRate, @@ -485,7 +484,9 @@ public class BacktestExecutor string.Join(", ", bottlenecks)); } - _logger.LogInformation("🎯 Backtest completed successfully - RequestId: {RequestId} - Score: {Score} - Realized PnL: {RealizedPnl} - Net PnL: {NetPnl} - Fees: {Fees}", finalRequestId, result.Score, result.FinalPnl, result.NetPnl, result.Fees); + _logger.LogInformation( + "🎯 Backtest completed successfully - RequestId: {RequestId} - Score: {Score} - Realized PnL: {RealizedPnl} - Net PnL: {NetPnl} - Fees: {Fees}", + finalRequestId, result.Score, result.FinalPnl, result.NetPnl, result.Fees); // Convert Backtest to LightBacktest return ConvertToLightBacktest(result); diff --git a/src/Managing.Application/Backtests/Backtester.cs b/src/Managing.Application/Backtests/Backtester.cs index 28884704..13b97050 100644 --- a/src/Managing.Application/Backtests/Backtester.cs +++ b/src/Managing.Application/Backtests/Backtester.cs @@ -4,7 +4,6 @@ using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Shared; using Managing.Application.Hubs; -using Managing.Domain.Accounts; using Managing.Domain.Backtests; using Managing.Domain.Bots; using Managing.Domain.Candles; @@ -136,7 +135,8 @@ namespace Managing.Application.Backtests var startDate = candles.Min(c => c.Date); var endDate = candles.Max(c => c.Date); - return await RunTradingBotBacktest(config, startDate, endDate, user, false, withCandles, requestId, metadata); + return await RunTradingBotBacktest(config, startDate, endDate, user, false, withCandles, requestId, + metadata); } public async Task DeleteBacktestAsync(string id) @@ -215,31 +215,6 @@ namespace Managing.Application.Backtests if (backtest == null) return null; - if (backtest.Candles == null || backtest.Candles.Count == 0 || backtest.Candles.Count < 10) - { - try - { - var account = new Account - { Name = backtest.Config.AccountName, Exchange = TradingExchanges.Evm }; - - var candles = await _exchangeService.GetCandlesInflux( - account.Exchange, - backtest.Config.Ticker, - backtest.StartDate, - backtest.Config.Timeframe, - backtest.EndDate); - - if (candles != null && candles.Count > 0) - { - backtest.Candles = candles; - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to retrieve candles for backtest {Id}", id); - } - } - return backtest; } @@ -348,12 +323,12 @@ namespace Managing.Application.Backtests { // Generate backtest requests from variants (same logic as BundleBacktestGrain) var backtestRequests = await GenerateBacktestRequestsFromVariants(bundleRequest); - + if (backtestRequests != null && backtestRequests.Any()) { // Create jobs for all variants await _jobService.CreateBundleJobsAsync(bundleRequest, backtestRequests); - + _logger.LogInformation( "Created {JobCount} backtest jobs for bundle request {BundleRequestId}", backtestRequests.Count, bundleRequest.RequestId); @@ -380,12 +355,12 @@ namespace Managing.Application.Backtests { // Generate backtest requests from variants var backtestRequests = await GenerateBacktestRequestsFromVariants(bundleRequest); - + if (backtestRequests != null && backtestRequests.Any()) { // Create jobs for all variants await _jobService.CreateBundleJobsAsync(bundleRequest, backtestRequests); - + _logger.LogInformation( "Created {JobCount} backtest jobs for bundle request {BundleRequestId}", backtestRequests.Count, bundleRequest.RequestId); @@ -399,8 +374,8 @@ namespace Managing.Application.Backtests } catch (Exception ex) { - _logger.LogError(ex, - "Error creating jobs for bundle request {BundleRequestId}", + _logger.LogError(ex, + "Error creating jobs for bundle request {BundleRequestId}", bundleRequest.RequestId); throw; } @@ -431,7 +406,9 @@ namespace Managing.Application.Backtests } // Get the first account for the user - var accounts = await _accountService.GetAccountsByUserAsync(bundleRequest.User, hideSecrets: true, getBalance: false); + var accounts = + await _accountService.GetAccountsByUserAsync(bundleRequest.User, hideSecrets: true, + getBalance: false); var firstAccount = accounts.FirstOrDefault(); if (firstAccount == null) @@ -573,15 +550,17 @@ namespace Managing.Application.Backtests return (bundleRequests, totalCount); } - public async Task<(IEnumerable BundleRequests, int TotalCount)> GetBundleBacktestRequestsPaginatedAsync( - int page, - int pageSize, - BundleBacktestRequestSortableColumn sortBy = BundleBacktestRequestSortableColumn.CreatedAt, - string sortOrder = "desc", - BundleBacktestRequestsFilter? filter = null) + public async Task<(IEnumerable BundleRequests, int TotalCount)> + GetBundleBacktestRequestsPaginatedAsync( + int page, + int pageSize, + BundleBacktestRequestSortableColumn sortBy = BundleBacktestRequestSortableColumn.CreatedAt, + string sortOrder = "desc", + BundleBacktestRequestsFilter? filter = null) { var (bundleRequests, totalCount) = - await _backtestRepository.GetBundleBacktestRequestsPaginatedAsync(page, pageSize, sortBy, sortOrder, filter); + await _backtestRepository.GetBundleBacktestRequestsPaginatedAsync(page, pageSize, sortBy, sortOrder, + filter); return (bundleRequests, totalCount); } diff --git a/src/Managing.Application/Bots/Grains/BacktestTradingBotGrain.cs b/src/Managing.Application/Bots/Grains/BacktestTradingBotGrain.cs index 9dd7c2fe..4efacf74 100644 --- a/src/Managing.Application/Bots/Grains/BacktestTradingBotGrain.cs +++ b/src/Managing.Application/Bots/Grains/BacktestTradingBotGrain.cs @@ -85,7 +85,7 @@ public class BacktestTradingBotGrain : Grain, IBacktestTradingBotGrain var lastYieldTime = DateTime.UtcNow; const int yieldIntervalMs = 5000; // Yield control every 5 seconds to prevent timeout const int candlesPerBatch = 100; // Process in batches to allow Orleans to check for cancellation - + // Process all candles following the exact pattern from GetBacktestingResult foreach (var candle in candles) { @@ -164,8 +164,7 @@ public class BacktestTradingBotGrain : Grain, IBacktestTradingBotGrain var finalRequestId = requestId != null ? Guid.Parse(requestId) : Guid.NewGuid(); // Create backtest result with conditional candles and indicators values - var result = new Backtest(config, tradingBot.Positions, tradingBot.Signals, - withCandles ? candles : new HashSet()) + var result = new Backtest(config, tradingBot.Positions, tradingBot.Signals) { FinalPnl = finalPnl, WinRate = winRate, diff --git a/src/Managing.Application/Shared/MessengerService.cs b/src/Managing.Application/Shared/MessengerService.cs index 0bb3e334..a58d3cb1 100644 --- a/src/Managing.Application/Shared/MessengerService.cs +++ b/src/Managing.Application/Shared/MessengerService.cs @@ -257,7 +257,7 @@ public class MessengerService : IMessengerService var score = backtest.Score; var winRate = backtest.WinRate; var tradeCount = backtest.Positions?.Count ?? 0; - var finalPnl = backtest.FinalPnl; + var netPnl = backtest.NetPnl; var growthPercentage = backtest.GrowthPercentage; var maxDrawdown = backtest.Statistics?.MaxDrawdown ?? 0; var sharpeRatio = (backtest.Statistics?.SharpeRatio * 100) ?? 0; @@ -288,8 +288,8 @@ public class MessengerService : IMessengerService $"🔍 Score Analysis: {backtest.ScoreMessage}\n" + $"🏆 Win Rate: {winRate:F1}%\n" + $"📊 Total Trades: {tradeCount}\n" + - $"💰 Final PnL: ${finalPnl:F2}\n" + - $"📈 Growth: {growthPercentage:F1}%\n" + + $"💰 Net PnL: ${netPnl:F2}\n" + + $"📈 ROI: {growthPercentage:F1}%\n" + $"📉 Max Drawdown: ${maxDrawdown:N}\n" + $"📊 Sharpe Ratio: {sharpeRatio:F2}\n\n" + $"🆔 Backtest ID: {backtest.Id}"; diff --git a/src/Managing.Domain/Backtests/Backtest.cs b/src/Managing.Domain/Backtests/Backtest.cs index dcd6b094..60b7e990 100644 --- a/src/Managing.Domain/Backtests/Backtest.cs +++ b/src/Managing.Domain/Backtests/Backtest.cs @@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations; using Exilion.TradingAtomics; using Managing.Domain.Bots; -using Managing.Domain.Candles; using Managing.Domain.Indicators; using Managing.Domain.Trades; using Managing.Domain.Users; @@ -14,26 +13,12 @@ public class Backtest public Backtest( TradingBotConfig config, Dictionary positions, - Dictionary signals, - HashSet candles = null) + Dictionary signals) { Config = config; Positions = positions; Signals = signals; - Candles = candles != null ? candles : new HashSet(); WalletBalances = new List>(); - - // Initialize start and end dates if candles are provided - if (candles != null && candles.Count > 0) - { - StartDate = candles.Min(c => c.Date); - EndDate = candles.Max(c => c.Date); - } - else - { - StartDate = DateTime.UtcNow.AddDays(-30); - EndDate = DateTime.UtcNow; - } } [Required] public string Id { get; set; } @@ -44,7 +29,6 @@ public class Backtest [Required] public TradingBotConfig Config { get; } [Required] public Dictionary Positions { get; } [Required] public Dictionary Signals { get; } - [Required] public HashSet Candles { get; set; } [Required] public DateTime StartDate { get; set; } [Required] public DateTime EndDate { get; set; } [Required] public PerformanceMetrics Statistics { get; set; } diff --git a/src/Managing.WebApp/src/generated/ManagingApi.ts b/src/Managing.WebApp/src/generated/ManagingApi.ts index 6145bec0..5047454c 100644 --- a/src/Managing.WebApp/src/generated/ManagingApi.ts +++ b/src/Managing.WebApp/src/generated/ManagingApi.ts @@ -4736,7 +4736,6 @@ export interface Backtest { config: TradingBotConfig; positions: { [key: string]: Position; }; signals: { [key: string]: LightSignal; }; - candles: Candle[]; startDate: Date; endDate: Date; statistics: PerformanceMetrics; diff --git a/src/Managing.WebApp/src/generated/ManagingApiTypes.ts b/src/Managing.WebApp/src/generated/ManagingApiTypes.ts index f6c2d3ae..ba4cb765 100644 --- a/src/Managing.WebApp/src/generated/ManagingApiTypes.ts +++ b/src/Managing.WebApp/src/generated/ManagingApiTypes.ts @@ -298,7 +298,6 @@ export interface Backtest { config: TradingBotConfig; positions: { [key: string]: Position; }; signals: { [key: string]: LightSignal; }; - candles: Candle[]; startDate: Date; endDate: Date; statistics: PerformanceMetrics;