Fix M5 signal quality: ATR ordering bug, noise gates, blocked-hour leak (+41R)
ATR was computed after EMAs so ribbon compression detection was dead code on all timeframes — moved ATR first. Extended M5 swing S/R lookback from 50 to 120 bars. Added four M5-specific filters: min score, MTF agreement, confirmation TF conviction, and SELL quality cap (A-grade M5 shorts enter at dip extremes and lose). Fixed backtester blocked-hour check to use bar close time matching the live bot. Added trade geometry config (spread gate, SL floor, TP floor RR) and primary_tf mismatch guard in backtester. Backtest: 1133 trades/+11.5R → 419 trades/+41.0R, PF 1.03→1.37, DD 21→11R. Train/val split positive in both halves (+19.8R/+21.3R). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -124,6 +124,20 @@ class SignalConfig:
|
||||
# — smaller wins make the fixed spread a larger share of every TP.
|
||||
tp_tightening_factor: float = 1.0
|
||||
|
||||
# ── Trade geometry ────────────────────────────────────────────
|
||||
# Round-trip transaction cost estimate in price units (XAU ~$0.30).
|
||||
round_trip_cost: float = 0.30
|
||||
# Spread gate: reject setups whose TP1 distance is below
|
||||
# round_trip_cost × this multiple (caps cost at ~3% of target).
|
||||
# Validated 2026-07: small-target trades lose in both data halves
|
||||
# on M5 while TP≥$10 trades earn ~+0.08R/trade.
|
||||
min_tp_cost_multiple: float = 30.0
|
||||
# Fixed SL floor in pips (80 pips = $8 on XAU). 0 disables — SL then
|
||||
# floors at ATR × v2_sl_atr_multiplier only.
|
||||
min_sl_pips: float = 80.0
|
||||
# TP1 floor as a fraction of SL distance (0.5 = historical RR 0.5).
|
||||
tp_floor_rr: float = 0.5
|
||||
|
||||
|
||||
@dataclass
|
||||
class NewsConfig:
|
||||
@@ -166,6 +180,20 @@ class XauStrategyConfig:
|
||||
# shorts lose consistently against gold's macro uptrend).
|
||||
sell_vol_regimes: List[str] = field(default_factory=lambda: ["high", "extreme"])
|
||||
|
||||
# ── M5-specific filters ──────────────────────────────────────
|
||||
# M5 signals are noisy; require stronger confirmation before
|
||||
# generating trade setups. Without these, M5 is breakeven
|
||||
# (+0.01R/trade) with 21% drawdown.
|
||||
m5_require_mtf: bool = True
|
||||
m5_min_abs_score: float = 30.0
|
||||
m5_min_confirmation_score: float = 10.0
|
||||
# A-grade M5 SELLs enter at the extreme of temporary dips and
|
||||
# lose (-0.017R/trade on 163 trades) — maximum conviction at
|
||||
# the worst entry. Cap SELL quality so A-grade can't trigger
|
||||
# the ATR-based setup generator; B-grade swing setups survive
|
||||
# because they catch moderate drops, not extremes.
|
||||
m5_sell_max_quality: List[str] = field(default_factory=lambda: ["B", "C"])
|
||||
|
||||
|
||||
@dataclass
|
||||
class FilterConfig:
|
||||
|
||||
Reference in New Issue
Block a user