Improve perf for backtests
This commit is contained in:
@@ -31,34 +31,10 @@ public class MacdCrossIndicatorBase : IndicatorBase
|
||||
try
|
||||
{
|
||||
var macd = candles.GetMacd(FastPeriods.Value, SlowPeriods.Value, SignalPeriods.Value).ToList();
|
||||
var macdCandle = MapMacdToCandle(macd, candles.TakeLast(SignalPeriods.Value));
|
||||
|
||||
if (macd.Count == 0)
|
||||
return null;
|
||||
|
||||
var previousCandle = macdCandle[0];
|
||||
foreach (var currentCandle in macdCandle.Skip(1))
|
||||
{
|
||||
// // Only trigger signals when Signal line is outside -100 to 100 range (extreme conditions)
|
||||
// if (currentCandle.Signal < -200 || currentCandle.Signal > 200)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
// Check for MACD line crossing below Signal line (bearish cross)
|
||||
if (previousCandle.Macd > previousCandle.Signal && currentCandle.Macd < currentCandle.Signal)
|
||||
{
|
||||
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
|
||||
}
|
||||
|
||||
// Check for MACD line crossing above Signal line (bullish cross)
|
||||
if (previousCandle.Macd < previousCandle.Signal && currentCandle.Macd > currentCandle.Signal)
|
||||
{
|
||||
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
|
||||
}
|
||||
|
||||
previousCandle = currentCandle;
|
||||
}
|
||||
ProcessMacdSignals(macd, candles);
|
||||
|
||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
||||
}
|
||||
@@ -68,6 +44,77 @@ public class MacdCrossIndicatorBase : IndicatorBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the indicator using pre-calculated MACD values for performance optimization.
|
||||
/// </summary>
|
||||
public override List<LightSignal> Run(HashSet<Candle> candles, IndicatorsResultBase preCalculatedValues)
|
||||
{
|
||||
if (candles.Count <= 2 * (SlowPeriods + SignalPeriods))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Use pre-calculated MACD values if available
|
||||
List<MacdResult> macd = null;
|
||||
if (preCalculatedValues?.Macd != null && preCalculatedValues.Macd.Any())
|
||||
{
|
||||
// Filter pre-calculated MACD values to match the candles we're processing
|
||||
macd = preCalculatedValues.Macd
|
||||
.Where(m => candles.Any(c => c.Date == m.Date))
|
||||
.OrderBy(m => m.Date)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// If no pre-calculated values or they don't match, fall back to regular calculation
|
||||
if (macd == null || !macd.Any())
|
||||
{
|
||||
return Run(candles);
|
||||
}
|
||||
|
||||
ProcessMacdSignals(macd, candles);
|
||||
|
||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
||||
}
|
||||
catch (RuleException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes MACD signals based on MACD line crossing the Signal line.
|
||||
/// This method is shared between the regular Run() and optimized Run() methods.
|
||||
/// </summary>
|
||||
/// <param name="macd">List of MACD calculation results</param>
|
||||
/// <param name="candles">Candles to process</param>
|
||||
private void ProcessMacdSignals(List<MacdResult> macd, HashSet<Candle> candles)
|
||||
{
|
||||
var macdCandle = MapMacdToCandle(macd, candles.TakeLast(SignalPeriods.Value));
|
||||
|
||||
if (macdCandle.Count == 0)
|
||||
return;
|
||||
|
||||
var previousCandle = macdCandle[0];
|
||||
foreach (var currentCandle in macdCandle.Skip(1))
|
||||
{
|
||||
// Check for MACD line crossing below Signal line (bearish cross)
|
||||
if (previousCandle.Macd > previousCandle.Signal && currentCandle.Macd < currentCandle.Signal)
|
||||
{
|
||||
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
|
||||
}
|
||||
|
||||
// Check for MACD line crossing above Signal line (bullish cross)
|
||||
if (previousCandle.Macd < previousCandle.Signal && currentCandle.Macd > currentCandle.Signal)
|
||||
{
|
||||
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
|
||||
}
|
||||
|
||||
previousCandle = currentCandle;
|
||||
}
|
||||
}
|
||||
|
||||
public override IndicatorsResultBase GetIndicatorValues(HashSet<Candle> candles)
|
||||
{
|
||||
return new IndicatorsResultBase()
|
||||
|
||||
Reference in New Issue
Block a user