fix(simulation,technicals): fix EMA 200 warmup distortion, intrabar execution path, and zero slippage
This commit is contained in:
@@ -62,8 +62,7 @@ public static class TechnicalIndicatorsEngine
|
||||
|
||||
public static decimal CalculateEma(IReadOnlyList<CandleDto> candles, int period)
|
||||
{
|
||||
if (candles == null || candles.Count == 0 || period <= 0) return 0m;
|
||||
if (candles.Count < period) return CalculateSma(candles, candles.Count);
|
||||
if (candles == null || candles.Count < period || period <= 0) return 0m;
|
||||
|
||||
decimal k = 2m / (period + 1);
|
||||
// Seed with SMA
|
||||
|
||||
@@ -246,14 +246,14 @@ public class TechnicalScoringEngine : ITechnicalScoringEngine
|
||||
decimal score = 50m;
|
||||
if (dir == SignalDirection.Buy)
|
||||
{
|
||||
if (ind.TryGetValue("EMA_20", out var e20) && ind.TryGetValue("EMA_50", out var e50) && e20 > e50) score += 15m;
|
||||
if (ind.TryGetValue("EMA_20", out var e20) && ind.TryGetValue("EMA_50", out var e50) && e20 > 0m && e50 > 0m && e20 > e50) score += 15m;
|
||||
if (ind.TryGetValue("RSI_14", out var rsi) && rsi is >= 45m and <= 65m) score += 15m;
|
||||
if (ind.TryGetValue("ADX_14", out var adx) && adx >= 25m) score += 10m;
|
||||
if (ind.TryGetValue("VWAP", out var vwap) && ind.TryGetValue("EMA_20", out var e20b) && e20b > vwap) score += 10m;
|
||||
if (ind.TryGetValue("VWAP", out var vwap) && vwap > 0m && ind.TryGetValue("EMA_20", out var e20b) && e20b > vwap) score += 10m;
|
||||
}
|
||||
else if (dir == SignalDirection.Sell)
|
||||
{
|
||||
if (ind.TryGetValue("EMA_20", out var e20) && ind.TryGetValue("EMA_50", out var e50) && e20 < e50) score += 15m;
|
||||
if (ind.TryGetValue("EMA_20", out var e20) && ind.TryGetValue("EMA_50", out var e50) && e20 > 0m && e50 > 0m && e20 < e50) score += 15m;
|
||||
if (ind.TryGetValue("RSI_14", out var rsi) && rsi is >= 35m and <= 55m) score += 15m;
|
||||
if (ind.TryGetValue("ADX_14", out var adx) && adx >= 25m) score += 10m;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ public class TrendPullbackFvgStrategy : ITechnicalStrategy
|
||||
public StrategyResultDto? Evaluate(TechnicalContext context, IReadOnlyList<PatternResultDto> activePatterns)
|
||||
{
|
||||
var candles = context.PrimaryCandles;
|
||||
if (candles.Count < 30) return null;
|
||||
|
||||
// Tunable for backtesting only (see TechnicalContext.ParameterOverrides doc comment) - defaults match
|
||||
// this strategy's original hardcoded values, so live scanning behavior is unchanged.
|
||||
@@ -30,13 +29,15 @@ public class TrendPullbackFvgStrategy : ITechnicalStrategy
|
||||
int emaSlowPeriod = (int)context.GetParameter(StrategyKey, "EmaSlow", 200m);
|
||||
decimal stopAtrMultiplier = context.GetParameter(StrategyKey, "StopAtrMultiplier", 1.2m);
|
||||
|
||||
if (candles.Count < emaSlowPeriod + 5) return null;
|
||||
|
||||
var current = candles.Last();
|
||||
decimal ema20 = TechnicalIndicatorsEngine.CalculateEma(candles, emaFastPeriod);
|
||||
decimal ema50 = TechnicalIndicatorsEngine.CalculateEma(candles, emaMidPeriod);
|
||||
decimal ema200 = TechnicalIndicatorsEngine.CalculateEma(candles, emaSlowPeriod);
|
||||
decimal atr = context.CurrentAtr > 0 ? context.CurrentAtr : TechnicalIndicatorsEngine.CalculateAtr(candles, 14);
|
||||
|
||||
if (atr <= 0) return null;
|
||||
if (ema20 <= 0m || ema50 <= 0m || ema200 <= 0m || atr <= 0) return null;
|
||||
|
||||
// Long Setup: Bullish Trend (EMA20 > EMA50 > EMA200) + Bullish FVG retracement.
|
||||
bool isBullishTrend = ema20 > ema50 && ema50 > ema200 && current.Close > ema50;
|
||||
|
||||
Reference in New Issue
Block a user