Setup bundle for backtest
This commit is contained in:
156
src/Managing.Application.Workers/BundleBacktestWorker.cs
Normal file
156
src/Managing.Application.Workers/BundleBacktestWorker.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Text.Json;
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Workers.Abstractions;
|
||||
using Managing.Domain.Backtests;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.Workers;
|
||||
|
||||
/// <summary>
|
||||
/// Worker for processing bundle backtest requests
|
||||
/// </summary>
|
||||
public class BundleBacktestWorker : BaseWorker<BundleBacktestWorker>
|
||||
{
|
||||
private readonly IBacktestRepository _backtestRepository;
|
||||
private readonly IBacktester _backtester;
|
||||
private static readonly WorkerType _workerType = WorkerType.BundleBacktest;
|
||||
|
||||
public BundleBacktestWorker(
|
||||
IBacktestRepository backtestRepository,
|
||||
IBacktester backtester,
|
||||
ILogger<BundleBacktestWorker> logger,
|
||||
IWorkerService workerService) : base(
|
||||
_workerType,
|
||||
logger,
|
||||
TimeSpan.FromMinutes(1),
|
||||
workerService)
|
||||
{
|
||||
_backtestRepository = backtestRepository;
|
||||
_backtester = backtester;
|
||||
}
|
||||
|
||||
protected override async Task Run(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get pending bundle backtest requests
|
||||
var pendingRequests = _backtestRepository.GetPendingBundleBacktestRequests();
|
||||
|
||||
foreach (var bundleRequest in pendingRequests)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
await ProcessBundleRequest(bundleRequest, cancellationToken);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error in BundleBacktestWorker");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessBundleRequest(BundleBacktestRequest bundleRequest, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Starting to process bundle backtest request {RequestId}", bundleRequest.RequestId);
|
||||
|
||||
// Update status to running
|
||||
bundleRequest.Status = BundleBacktestRequestStatus.Running;
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
|
||||
// Deserialize the backtest requests as dynamic objects
|
||||
var backtestRequests = JsonSerializer.Deserialize<List<JsonElement>>(bundleRequest.BacktestRequestsJson);
|
||||
if (backtestRequests == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to deserialize backtest requests");
|
||||
}
|
||||
|
||||
// Process each backtest request
|
||||
for (int i = 0; i < backtestRequests.Count; i++)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
var requestElement = backtestRequests[i];
|
||||
|
||||
// Update current backtest being processed
|
||||
bundleRequest.CurrentBacktest = $"Backtest {i + 1} of {backtestRequests.Count}";
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
|
||||
// Convert JSON element to domain model and run backtest
|
||||
await RunSingleBacktest(requestElement, bundleRequest.RequestId, cancellationToken);
|
||||
|
||||
// Update progress
|
||||
bundleRequest.CompletedBacktests++;
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
|
||||
_logger.LogInformation("Completed backtest {Index} for bundle request {RequestId}",
|
||||
i + 1, bundleRequest.RequestId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing backtest {Index} for bundle request {RequestId}",
|
||||
i + 1, bundleRequest.RequestId);
|
||||
bundleRequest.FailedBacktests++;
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
}
|
||||
}
|
||||
|
||||
// Update final status
|
||||
if (bundleRequest.FailedBacktests == 0)
|
||||
{
|
||||
bundleRequest.Status = BundleBacktestRequestStatus.Completed;
|
||||
}
|
||||
else if (bundleRequest.CompletedBacktests == 0)
|
||||
{
|
||||
bundleRequest.Status = BundleBacktestRequestStatus.Failed;
|
||||
bundleRequest.ErrorMessage = "All backtests failed";
|
||||
}
|
||||
else
|
||||
{
|
||||
bundleRequest.Status = BundleBacktestRequestStatus.Completed;
|
||||
bundleRequest.ErrorMessage = $"{bundleRequest.FailedBacktests} backtests failed";
|
||||
}
|
||||
|
||||
bundleRequest.CompletedAt = DateTime.UtcNow;
|
||||
bundleRequest.CurrentBacktest = null;
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
|
||||
_logger.LogInformation("Completed processing bundle backtest request {RequestId} with status {Status}",
|
||||
bundleRequest.RequestId, bundleRequest.Status);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing bundle backtest request {RequestId}", bundleRequest.RequestId);
|
||||
|
||||
bundleRequest.Status = BundleBacktestRequestStatus.Failed;
|
||||
bundleRequest.ErrorMessage = ex.Message;
|
||||
bundleRequest.CompletedAt = DateTime.UtcNow;
|
||||
_backtestRepository.UpdateBundleBacktestRequest(bundleRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunSingleBacktest(JsonElement requestElement, string bundleRequestId, CancellationToken cancellationToken)
|
||||
{
|
||||
// For now, we'll use a simplified approach that simulates backtest execution
|
||||
// In a real implementation, you would parse the JSON and convert to domain models
|
||||
|
||||
// Simulate backtest processing time
|
||||
await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken);
|
||||
|
||||
_logger.LogInformation("Processed backtest for bundle request {RequestId}", bundleRequestId);
|
||||
|
||||
// TODO: Implement actual backtest execution by:
|
||||
// 1. Parsing the JSON request element
|
||||
// 2. Converting to TradingBotConfig domain model
|
||||
// 3. Calling _backtester.RunTradingBotBacktest with proper parameters
|
||||
// 4. Handling the results and saving to database if needed
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user