diff --git a/config.py b/config.py index 65607d7..c0c30ba 100755 --- a/config.py +++ b/config.py @@ -142,7 +142,7 @@ class XauStrategyConfig: Legacy gates (H4 RSI, H1 MACD, M15 score) removed in favor of new momentum indicators (ROC, Keltner squeeze, ADX slope). """ - enabled: bool = True + enabled: bool = False rsi_entry_threshold: float = 45.0 tp_atr_multiplier: float = 1.0 sl_atr_multiplier: float = 2.0 @@ -172,10 +172,10 @@ class EurUsdStrategyConfig: allowed_weekdays: List[int] = field(default_factory=lambda: [0, 1, 2, 3, 4]) min_atr_threshold: float = 0.0003 sl_atr_multiplier: float = 1.5 - tp_atr_multiplier: float = 1.0 + tp_atr_multiplier: float = 1.2 sl_atr_floor: float = 1.2 - min_rr_ratio: float = 0.5 + min_rr_ratio: float = 1.0 mature_move_threshold: float = 35.0 tp_quality_scale: Dict[str, float] = field(default_factory=lambda: { "A+": 1.0, "A": 1.0, "B": 1.0, "C": 1.0, @@ -188,8 +188,10 @@ class EurUsdStrategyConfig: min_entry_score: float = 38.0 min_entry_confidence: float = 60.0 block_rsi_extended: bool = True - be_trigger_r: float = 0.2 - be_buffer_r: float = 0.05 + blocked_vol_regimes: List[str] = field(default_factory=list) + min_indicator_agreement: int = 0 + be_trigger_r: float = 0.3 + be_buffer_r: float = 0.15 @dataclass diff --git a/pair_signals/eurusd.py b/pair_signals/eurusd.py index eae0f60..995bc84 100644 --- a/pair_signals/eurusd.py +++ b/pair_signals/eurusd.py @@ -77,12 +77,15 @@ def make_config( if primary_tf == Timeframe.M5: config.technical.regime_weights_override = M5_REGIME_WEIGHTS - config.eur_strategy.sl_atr_floor = 0.8 + config.technical.swing_sr_lookback = 20 + config.eur_strategy.sl_atr_floor = 0.7 config.eur_strategy.sl_atr_multiplier = 0.3 config.eur_strategy.min_quality_grades = ["A+", "A", "B"] config.eur_strategy.min_entry_score = 35.0 config.eur_strategy.min_entry_confidence = 50.0 - config.backtest.blocked_hours_utc = [22, 23, 0, 1, 2, 3, 4, 19, 21] + config.eur_strategy.blocked_vol_regimes = ["high"] + config.eur_strategy.min_indicator_agreement = 6 + config.backtest.blocked_hours_utc = [22, 23, 0, 1, 2, 3, 4, 6, 9, 11, 19, 21] else: config.technical.regime_weights_override = EUR_REGIME_WEIGHTS diff --git a/pair_signals/xauusd.py b/pair_signals/xauusd.py index 5236bd8..94ffbce 100644 --- a/pair_signals/xauusd.py +++ b/pair_signals/xauusd.py @@ -16,6 +16,7 @@ def make_config( confirmation_tfs: Optional[List[Timeframe]] = None, ) -> PlatformConfig: config = PlatformConfig() + config.xau_strategy.enabled = True config.primary_timeframe = primary_tf config.confirmation_timeframes = ( confirmation_tfs or _CONFIRMATIONS.get(primary_tf, [Timeframe.M15, Timeframe.H4]) diff --git a/signal_aggregator.py b/signal_aggregator.py index 1e126df..db25ed7 100755 --- a/signal_aggregator.py +++ b/signal_aggregator.py @@ -474,6 +474,27 @@ class SignalAggregator: f"EUR CONF FILTER: {report.final_confidence} < {eur.min_entry_confidence}" ) report.signal_quality = "F" + if (report.signal_quality != "F" + and eur.blocked_vol_regimes + and report.volatility_regime): + if report.volatility_regime in eur.blocked_vol_regimes: + report.warnings.append( + f"EUR VOL FILTER: {report.volatility_regime} volatility blocked" + ) + report.signal_quality = "F" + if (report.signal_quality != "F" + and eur.min_indicator_agreement > 0 + and report.primary_analysis): + agree_count = sum( + 1 for ind in report.primary_analysis.indicators.values() + if ind.signal.value != 0 + and (ind.signal.value > 0) == (report.final_score > 0) + ) + if agree_count < eur.min_indicator_agreement: + report.warnings.append( + f"EUR AGREE FILTER: {agree_count} < {eur.min_indicator_agreement}" + ) + report.signal_quality = "F" if (report.signal_quality != "F" and eur.block_rsi_extended and report.primary_analysis): diff --git a/test_all.py b/test_all.py index ed6137c..28f62c3 100644 --- a/test_all.py +++ b/test_all.py @@ -190,7 +190,7 @@ def _(): @test("XauStrategyConfig defaults") def _(): xc = XauStrategyConfig() - assert xc.enabled is True + assert xc.enabled is False assert xc.rsi_entry_threshold == 45.0 assert xc.min_ema200_tfs == 2 assert xc.allow_generic_trades is True @@ -1656,7 +1656,7 @@ def _(): assert 6 not in cfg.allowed_weekdays # No Sunday assert cfg.min_atr_threshold == 0.0003 assert cfg.sl_atr_floor == 1.2 - assert cfg.min_rr_ratio == 0.5 + assert cfg.min_rr_ratio == 1.0 assert cfg.mature_move_threshold == 35.0 assert cfg.tp_quality_scale["A+"] == 1.0 assert cfg.tp_quality_scale["A"] == 1.0 @@ -1755,13 +1755,13 @@ def _(): config.eur_strategy.blocked_regimes = [] config.eur_strategy.min_quality_grades = [] assert config.eur_strategy.sl_atr_floor == 1.2 - assert config.eur_strategy.min_rr_ratio == 0.5 + assert config.eur_strategy.min_rr_ratio == 1.0 agg = SignalAggregator(config) df = make_ohlcv(n=300, start_price=1.0800, trend=0.0003, seed=77) dfs = {Timeframe.H1: df, Timeframe.M15: df, Timeframe.H4: df} report = agg.analyze_from_dataframes(symbol=EURUSD, dfs=dfs, use_news=False) if report.trade_setup: - assert report.trade_setup.risk_reward >= 0.5 - 0.01 + assert report.trade_setup.risk_reward >= 1.0 - 0.01 # ══════════════════════════════════════════════════════════════════════