Improve perf for backtests

This commit is contained in:
2025-11-10 02:15:43 +07:00
parent 7e52b7a734
commit 51a227e27e
24 changed files with 1327 additions and 443 deletions

View File

@@ -32,18 +32,13 @@ public class RsiDivergenceIndicatorBase : IndicatorBase
return null;
}
var ticker = candles.First().Ticker;
try
{
var rsiResult = candles.TakeLast(10 * Period.Value).GetRsi(Period.Value).ToList();
var candlesRsi = MapRsiToCandle(rsiResult, candles.TakeLast(10 * Period.Value));
if (candlesRsi.Count(c => c.Rsi > 0) == 0)
if (rsiResult.Count == 0)
return null;
GetLongSignals(candlesRsi, candles);
GetShortSignals(candlesRsi, candles);
ProcessRsiDivergenceSignals(rsiResult, candles);
return Signals;
}
@@ -53,6 +48,63 @@ public class RsiDivergenceIndicatorBase : IndicatorBase
}
}
/// <summary>
/// Runs the indicator using pre-calculated RSI values for performance optimization.
/// </summary>
public override List<LightSignal> Run(HashSet<Candle> candles, IndicatorsResultBase preCalculatedValues)
{
if (!Period.HasValue || candles.Count <= Period)
{
return null;
}
try
{
// Use pre-calculated RSI values if available
List<RsiResult> rsiResult = null;
if (preCalculatedValues?.Rsi != null && preCalculatedValues.Rsi.Any())
{
// Filter pre-calculated RSI values to match the candles we're processing
var relevantCandles = candles.TakeLast(10 * Period.Value);
rsiResult = preCalculatedValues.Rsi
.Where(r => relevantCandles.Any(c => c.Date == r.Date))
.OrderBy(r => r.Date)
.ToList();
}
// If no pre-calculated values or they don't match, fall back to regular calculation
if (rsiResult == null || !rsiResult.Any())
{
return Run(candles);
}
ProcessRsiDivergenceSignals(rsiResult, candles);
return Signals;
}
catch (RuleException)
{
return null;
}
}
/// <summary>
/// Processes RSI divergence signals based on price and RSI divergence patterns.
/// This method is shared between the regular Run() and optimized Run() methods.
/// </summary>
/// <param name="rsiResult">List of RSI calculation results</param>
/// <param name="candles">Candles to process</param>
private void ProcessRsiDivergenceSignals(List<RsiResult> rsiResult, HashSet<Candle> candles)
{
var candlesRsi = MapRsiToCandle(rsiResult, candles.TakeLast(10 * Period.Value));
if (candlesRsi.Count(c => c.Rsi > 0) == 0)
return;
GetLongSignals(candlesRsi, candles);
GetShortSignals(candlesRsi, candles);
}
public override IndicatorsResultBase GetIndicatorValues(HashSet<Candle> candles)
{
return new IndicatorsResultBase()