Add benchmark for backtest on the test

This commit is contained in:
2025-11-11 11:23:30 +07:00
parent 2ca77bc2f9
commit 14d101b63e
8 changed files with 360 additions and 43 deletions

View File

@@ -1,4 +1,5 @@
using Managing.Application.Abstractions.Repositories;
using System.Collections.Concurrent;
using Managing.Application.Abstractions.Repositories;
using Managing.Application.Abstractions.Services;
using Managing.Domain.Accounts;
using Managing.Domain.Bots;
@@ -431,6 +432,7 @@ public class TradingService : ITradingService
/// <summary>
/// Calculates indicators values for a given scenario and candles.
/// Uses parallel processing for independent indicator calculations to improve performance.
/// </summary>
/// <param name="scenario">The scenario containing indicators.</param>
/// <param name="candles">The candles to calculate indicators for.</param>
@@ -439,7 +441,7 @@ public class TradingService : ITradingService
Scenario scenario,
HashSet<Candle> candles)
{
// Offload CPU-bound indicator calculations to thread pool
// Offload CPU-bound indicator calculations to thread pool with parallel processing
return await Task.Run(() =>
{
var indicatorsValues = new Dictionary<IndicatorType, IndicatorsResultBase>();
@@ -449,19 +451,39 @@ public class TradingService : ITradingService
return indicatorsValues;
}
// Build indicators from scenario
foreach (var indicator in scenario.Indicators)
// Use parallel processing for independent indicator calculations
// Configure parallelism based on indicator count and system capabilities
var maxDegreeOfParallelism = Math.Min(scenario.Indicators.Count, Environment.ProcessorCount);
var options = new ParallelOptions
{
MaxDegreeOfParallelism = maxDegreeOfParallelism,
CancellationToken = CancellationToken.None
};
// Use thread-safe concurrent dictionary for parallel writes
var concurrentResults = new ConcurrentDictionary<IndicatorType, IndicatorsResultBase>();
// Parallel calculation of indicators
Parallel.ForEach(scenario.Indicators, options, indicator =>
{
try
{
var buildedIndicator = ScenarioHelpers.BuildIndicator(ScenarioHelpers.BaseToLight(indicator));
indicatorsValues[indicator.Type] = buildedIndicator.GetIndicatorValues(candles);
var result = buildedIndicator.GetIndicatorValues(candles);
concurrentResults[indicator.Type] = result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error calculating indicator {IndicatorName}: {ErrorMessage}",
indicator.Name, ex.Message);
}
});
// Convert to regular dictionary for return
foreach (var kvp in concurrentResults)
{
indicatorsValues[kvp.Key] = kvp.Value;
}
return indicatorsValues;