"""EUR/USD signal producer config. Ported from feature/eurusd-support. All tuned values here are a pre-realism baseline (tuned before spread charging and next-open fills) and are re-tuned against the realistic backtester at 1-pip round-trip cost — see EurUsdStrategyConfig in config.py. """ from typing import Optional, List from config import PlatformConfig, Timeframe, EURUSD _CONFIRMATIONS = { Timeframe.M5: [Timeframe.M15, Timeframe.H1], Timeframe.M15: [Timeframe.M5, Timeframe.H1], Timeframe.H1: [Timeframe.M15, Timeframe.H4], Timeframe.H4: [Timeframe.H1, Timeframe.D1], } _TRENDING = { "ema_trend": 2.0, "rsi": 1.0, "macd": 2.0, "bollinger": 0.5, "keltner": 1.0, "roc": 1.5, "candlestick": 0.5, "divergence": 2.0, "adx": 1.0, } EUR_REGIME_WEIGHTS = { "trending_up": _TRENDING, "trending_down": _TRENDING, "trending": _TRENDING, "ranging": { "ema_trend": 0.3, "rsi": 2.0, "macd": 1.0, "bollinger": 2.0, "keltner": 1.5, "roc": 0.5, "candlestick": 0.8, "divergence": 2.5, "adx": 0.5, }, "transitioning": { "ema_trend": 1.5, "rsi": 1.5, "macd": 2.0, "bollinger": 1.0, "keltner": 1.5, "roc": 2.0, "candlestick": 0.8, "divergence": 2.0, "adx": 1.0, }, } _M5_TRENDING = { "ema_trend": 1.5, "rsi": 1.0, "macd": 2.5, "bollinger": 0.5, "keltner": 2.0, "roc": 2.0, "candlestick": 0.3, "divergence": 1.0, "adx": 1.0, } M5_REGIME_WEIGHTS = { "trending_up": _M5_TRENDING, "trending_down": _M5_TRENDING, "trending": _M5_TRENDING, "ranging": { "ema_trend": 0.3, "rsi": 1.5, "macd": 1.5, "bollinger": 1.5, "keltner": 2.0, "roc": 1.0, "candlestick": 0.3, "divergence": 1.5, "adx": 0.5, }, "transitioning": { "ema_trend": 1.0, "rsi": 1.0, "macd": 2.5, "bollinger": 0.5, "keltner": 2.5, "roc": 2.0, "candlestick": 0.3, "divergence": 1.0, "adx": 1.0, }, } def make_config( primary_tf: Timeframe, confirmation_tfs: Optional[List[Timeframe]] = None, ) -> PlatformConfig: config = PlatformConfig() config.symbol = EURUSD config.display_name = "EUR/USD" config.pip_value = 0.0001 config.primary_timeframe = primary_tf config.confirmation_timeframes = ( confirmation_tfs or _CONFIRMATIONS.get(primary_tf, [Timeframe.M15, Timeframe.H4]) ) # XAU gates are display-gated in the aggregator; disabling here is # belt-and-braces so no gold logic can ever fire on an EUR config. config.xau_strategy.enabled = False config.backtest.session_start_hour = 7 config.backtest.session_end_hour = 20 config.backtest.blocked_hours_utc = [22, 23, 0, 1, 2, 3] config.backtest.allowed_weekdays = [0, 1, 2, 3, 4] if primary_tf == Timeframe.M5: config.technical.regime_weights_override = M5_REGIME_WEIGHTS 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.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 return config