Add bundle backtest refact + fix whitelist

This commit is contained in:
2025-10-12 14:40:20 +07:00
parent 4543246871
commit 5acc77650f
21 changed files with 2961 additions and 628 deletions

View File

@@ -12,6 +12,7 @@ using Managing.Domain.Strategies;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Orleans.Concurrency;
using static Managing.Common.Enums;
namespace Managing.Application.Grains;
@@ -103,12 +104,11 @@ public class BundleBacktestGrain : Grain, IBundleBacktestGrain, IRemindable
bundleRequest.Status = BundleBacktestRequestStatus.Running;
await backtester.UpdateBundleBacktestRequestAsync(bundleRequest);
// Deserialize the backtest requests as strongly-typed objects
var backtestRequests =
JsonSerializer.Deserialize<List<RunBacktestRequest>>(bundleRequest.BacktestRequestsJson);
if (backtestRequests == null)
// Generate backtest requests from variant configuration
var backtestRequests = GenerateBacktestRequestsFromVariants(bundleRequest);
if (backtestRequests == null || !backtestRequests.Any())
{
throw new InvalidOperationException("Failed to deserialize backtest requests");
throw new InvalidOperationException("Failed to generate backtest requests from variants");
}
// Process each backtest request sequentially
@@ -130,6 +130,90 @@ public class BundleBacktestGrain : Grain, IBundleBacktestGrain, IRemindable
}
}
/// <summary>
/// Generates individual backtest requests from variant configuration
/// </summary>
private List<RunBacktestRequest> GenerateBacktestRequestsFromVariants(BundleBacktestRequest bundleRequest)
{
try
{
// Deserialize the variant configurations
var universalConfig = JsonSerializer.Deserialize<BundleBacktestUniversalConfig>(bundleRequest.UniversalConfigJson);
var dateTimeRanges = JsonSerializer.Deserialize<List<DateTimeRange>>(bundleRequest.DateTimeRangesJson);
var moneyManagementVariants = JsonSerializer.Deserialize<List<MoneyManagementVariant>>(bundleRequest.MoneyManagementVariantsJson);
var tickerVariants = JsonSerializer.Deserialize<List<Ticker>>(bundleRequest.TickerVariantsJson);
if (universalConfig == null || dateTimeRanges == null || moneyManagementVariants == null || tickerVariants == null)
{
_logger.LogError("Failed to deserialize variant configurations for bundle request {RequestId}", bundleRequest.RequestId);
return new List<RunBacktestRequest>();
}
var backtestRequests = new List<RunBacktestRequest>();
foreach (var dateRange in dateTimeRanges)
{
foreach (var mmVariant in moneyManagementVariants)
{
foreach (var ticker in tickerVariants)
{
var config = new TradingBotConfigRequest
{
AccountName = universalConfig.AccountName,
Ticker = ticker,
Timeframe = universalConfig.Timeframe,
IsForWatchingOnly = universalConfig.IsForWatchingOnly,
BotTradingBalance = universalConfig.BotTradingBalance,
Name = $"{universalConfig.BotName}_{ticker}_{dateRange.StartDate:yyyyMMdd}_{dateRange.EndDate:yyyyMMdd}",
FlipPosition = universalConfig.FlipPosition,
CooldownPeriod = universalConfig.CooldownPeriod,
MaxLossStreak = universalConfig.MaxLossStreak,
Scenario = universalConfig.Scenario,
ScenarioName = universalConfig.ScenarioName,
MoneyManagement = mmVariant.MoneyManagement,
MaxPositionTimeHours = universalConfig.MaxPositionTimeHours,
CloseEarlyWhenProfitable = universalConfig.CloseEarlyWhenProfitable,
FlipOnlyWhenInProfit = universalConfig.FlipOnlyWhenInProfit,
UseSynthApi = universalConfig.UseSynthApi,
UseForPositionSizing = universalConfig.UseForPositionSizing,
UseForSignalFiltering = universalConfig.UseForSignalFiltering,
UseForDynamicStopLoss = universalConfig.UseForDynamicStopLoss
};
var backtestRequest = new RunBacktestRequest
{
Config = config,
StartDate = dateRange.StartDate,
EndDate = dateRange.EndDate,
Balance = universalConfig.BotTradingBalance,
WatchOnly = universalConfig.WatchOnly,
Save = universalConfig.Save,
WithCandles = false, // Bundle backtests never return candles
MoneyManagement = mmVariant.MoneyManagement != null ?
new MoneyManagement
{
Name = mmVariant.MoneyManagement.Name,
Timeframe = mmVariant.MoneyManagement.Timeframe,
StopLoss = mmVariant.MoneyManagement.StopLoss,
TakeProfit = mmVariant.MoneyManagement.TakeProfit,
Leverage = mmVariant.MoneyManagement.Leverage
} : null
};
backtestRequests.Add(backtestRequest);
}
}
}
return backtestRequests;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error generating backtest requests from variants for bundle request {RequestId}", bundleRequest.RequestId);
return new List<RunBacktestRequest>();
}
}
private async Task ProcessSingleBacktest(
IBacktester backtester,
RunBacktestRequest runBacktestRequest,
@@ -138,10 +222,8 @@ public class BundleBacktestGrain : Grain, IBundleBacktestGrain, IRemindable
{
try
{
// Get total count from deserialized requests instead of string splitting
var backtestRequests =
JsonSerializer.Deserialize<List<RunBacktestRequest>>(bundleRequest.BacktestRequestsJson);
var totalCount = backtestRequests?.Count ?? 0;
// Calculate total count from the variant configuration
var totalCount = bundleRequest.TotalBacktests;
// Update current backtest being processed
bundleRequest.CurrentBacktest = $"Backtest {index + 1} of {totalCount}";