Log exception when backtest failed for no candles

This commit is contained in:
2025-11-05 17:27:48 +07:00
parent 5afddb895e
commit c183a71bd0
2 changed files with 29 additions and 15 deletions

View File

@@ -222,7 +222,8 @@ namespace Managing.Application.Backtests
startDate, timeframe, endDate); startDate, timeframe, endDate);
if (candles == null || candles.Count == 0) if (candles == null || candles.Count == 0)
throw new Exception($"No candles for {ticker} on {timeframe} timeframe"); throw new Exception(
$"No candles for {ticker} on {timeframe} timeframe for start {startDate} to end {endDate}");
return candles; return candles;
} }
@@ -451,11 +452,13 @@ namespace Managing.Application.Backtests
BacktestsFilter? filter = null) BacktestsFilter? filter = null)
{ {
var (backtests, totalCount) = var (backtests, totalCount) =
await _backtestRepository.GetBacktestsByUserPaginatedAsync(user, page, pageSize, sortBy, sortOrder, filter); await _backtestRepository.GetBacktestsByUserPaginatedAsync(user, page, pageSize, sortBy, sortOrder,
filter);
return (backtests, totalCount); return (backtests, totalCount);
} }
public async Task InsertBundleBacktestRequestForUserAsync(User user, BundleBacktestRequest bundleRequest, bool saveAsTemplate = false) public async Task InsertBundleBacktestRequestForUserAsync(User user, BundleBacktestRequest bundleRequest,
bool saveAsTemplate = false)
{ {
await _backtestRepository.InsertBundleBacktestRequestForUserAsync(user, bundleRequest); await _backtestRepository.InsertBundleBacktestRequestForUserAsync(user, bundleRequest);

View File

@@ -133,6 +133,7 @@ public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
_logger.LogError(ex, "Error processing backtest {Index} for bundle request {RequestId}", _logger.LogError(ex, "Error processing backtest {Index} for bundle request {RequestId}",
i + 1, bundleRequest.RequestId); i + 1, bundleRequest.RequestId);
bundleRequest.FailedBacktests++; bundleRequest.FailedBacktests++;
SentrySdk.CaptureException(ex);
await backtester.UpdateBundleBacktestRequestAsync(bundleRequest); await backtester.UpdateBundleBacktestRequestAsync(bundleRequest);
} }
} }
@@ -339,31 +340,38 @@ public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
/// <summary> /// <summary>
/// Generates individual backtest requests from variant configuration /// Generates individual backtest requests from variant configuration
/// </summary> /// </summary>
private async Task<List<RunBacktestRequest>> GenerateBacktestRequestsFromVariants(BundleBacktestRequest bundleRequest) private async Task<List<RunBacktestRequest>> GenerateBacktestRequestsFromVariants(
BundleBacktestRequest bundleRequest)
{ {
try try
{ {
// Deserialize the variant configurations // Deserialize the variant configurations
var universalConfig = JsonSerializer.Deserialize<BundleBacktestUniversalConfig>(bundleRequest.UniversalConfigJson); var universalConfig =
JsonSerializer.Deserialize<BundleBacktestUniversalConfig>(bundleRequest.UniversalConfigJson);
var dateTimeRanges = JsonSerializer.Deserialize<List<DateTimeRange>>(bundleRequest.DateTimeRangesJson); var dateTimeRanges = JsonSerializer.Deserialize<List<DateTimeRange>>(bundleRequest.DateTimeRangesJson);
var moneyManagementVariants = JsonSerializer.Deserialize<List<MoneyManagementVariant>>(bundleRequest.MoneyManagementVariantsJson); var moneyManagementVariants =
JsonSerializer.Deserialize<List<MoneyManagementVariant>>(bundleRequest.MoneyManagementVariantsJson);
var tickerVariants = JsonSerializer.Deserialize<List<Ticker>>(bundleRequest.TickerVariantsJson); var tickerVariants = JsonSerializer.Deserialize<List<Ticker>>(bundleRequest.TickerVariantsJson);
if (universalConfig == null || dateTimeRanges == null || moneyManagementVariants == null || tickerVariants == null) if (universalConfig == null || dateTimeRanges == null || moneyManagementVariants == null ||
tickerVariants == null)
{ {
_logger.LogError("Failed to deserialize variant configurations for bundle request {RequestId}", bundleRequest.RequestId); _logger.LogError("Failed to deserialize variant configurations for bundle request {RequestId}",
bundleRequest.RequestId);
return new List<RunBacktestRequest>(); return new List<RunBacktestRequest>();
} }
// Get the first account for the user using AccountService // Get the first account for the user using AccountService
using var scope = _serviceProvider.CreateScope(); using var scope = _serviceProvider.CreateScope();
var accountService = scope.ServiceProvider.GetRequiredService<IAccountService>(); var accountService = scope.ServiceProvider.GetRequiredService<IAccountService>();
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(); var firstAccount = accounts.FirstOrDefault();
if (firstAccount == null) if (firstAccount == null)
{ {
_logger.LogError("No accounts found for user {UserId} in bundle request {RequestId}", bundleRequest.User.Id, bundleRequest.RequestId); _logger.LogError("No accounts found for user {UserId} in bundle request {RequestId}",
bundleRequest.User.Id, bundleRequest.RequestId);
return new List<RunBacktestRequest>(); return new List<RunBacktestRequest>();
} }
@@ -382,7 +390,8 @@ public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
Timeframe = universalConfig.Timeframe, Timeframe = universalConfig.Timeframe,
IsForWatchingOnly = universalConfig.IsForWatchingOnly, IsForWatchingOnly = universalConfig.IsForWatchingOnly,
BotTradingBalance = universalConfig.BotTradingBalance, BotTradingBalance = universalConfig.BotTradingBalance,
Name = $"{universalConfig.BotName}_{ticker}_{dateRange.StartDate:yyyyMMdd}_{dateRange.EndDate:yyyyMMdd}", Name =
$"{universalConfig.BotName}_{ticker}_{dateRange.StartDate:yyyyMMdd}_{dateRange.EndDate:yyyyMMdd}",
FlipPosition = universalConfig.FlipPosition, FlipPosition = universalConfig.FlipPosition,
CooldownPeriod = universalConfig.CooldownPeriod, CooldownPeriod = universalConfig.CooldownPeriod,
MaxLossStreak = universalConfig.MaxLossStreak, MaxLossStreak = universalConfig.MaxLossStreak,
@@ -407,15 +416,16 @@ public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
WatchOnly = universalConfig.WatchOnly, WatchOnly = universalConfig.WatchOnly,
Save = universalConfig.Save, Save = universalConfig.Save,
WithCandles = false, // Bundle backtests never return candles WithCandles = false, // Bundle backtests never return candles
MoneyManagement = mmVariant.MoneyManagement != null ? MoneyManagement = mmVariant.MoneyManagement != null
new MoneyManagement ? new MoneyManagement
{ {
Name = mmVariant.MoneyManagement.Name, Name = mmVariant.MoneyManagement.Name,
Timeframe = mmVariant.MoneyManagement.Timeframe, Timeframe = mmVariant.MoneyManagement.Timeframe,
StopLoss = mmVariant.MoneyManagement.StopLoss, StopLoss = mmVariant.MoneyManagement.StopLoss,
TakeProfit = mmVariant.MoneyManagement.TakeProfit, TakeProfit = mmVariant.MoneyManagement.TakeProfit,
Leverage = mmVariant.MoneyManagement.Leverage Leverage = mmVariant.MoneyManagement.Leverage
} : null }
: null
}; };
backtestRequests.Add(backtestRequest); backtestRequests.Add(backtestRequest);
@@ -427,7 +437,8 @@ public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error generating backtest requests from variants for bundle request {RequestId}", bundleRequest.RequestId); _logger.LogError(ex, "Error generating backtest requests from variants for bundle request {RequestId}",
bundleRequest.RequestId);
return new List<RunBacktestRequest>(); return new List<RunBacktestRequest>();
} }
} }