Add M5 gates 5-6 and trailing-stop exits (+48R → +105R on 12mo)
Gates 5-6 in the M5 filter: block 'high' vol regime entries (chop transition — 61% WR, negative total while low/normal/extreme all positive) and block SELLs with RSI<25 (dip already extended, mean- reverts before target). 365d: 419→311 trades, +41→+48.4R, DD 11.2→8.0R. Replace the fixed RR-0.5 take-profit with a trailing stop: arm at +0.6R favorable excursion, trail 0.75R behind best price, stop levels update at bar close (conservative). The RR-0.5 target was the binding constraint — winners kept running after TP. Whole trail parameter grid (arm 0.4-1.2 × dist 0.5-1.25) lands +90-103R, a plateau not a spike; also +91.7R on the pre-gate 419-trade population. TP1 stays advisory; Telegram alerts include the arm price and trail distance. max_hold 200→300 bars (trailing exits need room; +10R). 12mo M5, same 311 trades: +105.0R total, PF 2.27, DD 7.9R, 61% WR, train/val +54.6/+50.4, every quarter positive.
This commit is contained in:
@@ -350,6 +350,33 @@ class SignalAggregator:
|
||||
report.trade_setup = None
|
||||
return
|
||||
|
||||
# Gate 5: block chop-transition volatility. 'high' vol on M5 is
|
||||
# elevated noise without the directional expansion of 'extreme'
|
||||
# — stops get swept before targets (61% WR, negative total in
|
||||
# every backtest window; low/normal/extreme all positive).
|
||||
if report.volatility_regime in xau_cfg.m5_blocked_vol_regimes:
|
||||
report.warnings.append(
|
||||
f"M5 FILTER: '{report.volatility_regime}' volatility — "
|
||||
f"chop-transition regime, stops get swept"
|
||||
)
|
||||
report.signal_quality = "D"
|
||||
report.trade_setup = None
|
||||
return
|
||||
|
||||
# Gate 6: SELL RSI floor — shorting with RSI already < 25 means
|
||||
# entering at the extreme of the dip (same pathology as Gate 4,
|
||||
# visible through RSI instead of quality grade).
|
||||
if is_sell:
|
||||
rsi_ind = report.primary_analysis.indicators.get("rsi")
|
||||
if rsi_ind is not None and rsi_ind.value < xau_cfg.m5_sell_min_rsi:
|
||||
report.warnings.append(
|
||||
f"M5 FILTER: SELL blocked — RSI {rsi_ind.value:.0f} < "
|
||||
f"{xau_cfg.m5_sell_min_rsi:.0f}, dip already extended"
|
||||
)
|
||||
report.signal_quality = "D"
|
||||
report.trade_setup = None
|
||||
return
|
||||
|
||||
# ── Public: bar-replayable entry point ─────────────────────────
|
||||
|
||||
def analyze_from_dataframes(
|
||||
|
||||
Reference in New Issue
Block a user