Add EUR/USD pair constants and EurUsdStrategyConfig

- EURUSD in PAIR_INFO; new per-pair price_precision and default_spread
  fields on both pairs (backtester consumes default_spread when --spread
  is omitted)
- EurUsdStrategyConfig ported from feature/eurusd-support plus EUR-local
  cost knobs (round_trip_cost=1 pip, min_tp_cost_multiple=10,
  min_sl_pips=8) so SignalConfig's gold-dollar values never apply to EUR;
  donor-tuned values are a pre-realism baseline pending re-tune
- PlatformConfig.eur_strategy field; track EUR in news currencies
This commit is contained in:
Harwinder Sekhon
2026-07-10 20:50:08 -04:00
parent f3b90d3862
commit 9d3729ea73
+58 -2
View File
@@ -37,9 +37,16 @@ class MarketSession(Enum):
# ── Supported pairs ────────────────────────────────────────────── # ── Supported pairs ──────────────────────────────────────────────
XAUUSD = "XAU/USD" XAUUSD = "XAU/USD"
EURUSD = "EUR/USD"
# price_precision: decimals for SL/TP rounding and display.
# default_spread: round-trip cost per trade in price units, charged by
# the backtester when --spread is not given.
PAIR_INFO = { PAIR_INFO = {
XAUUSD: {"display": "XAU/USD", "pip_value": 0.10, "is_jpy_pair": False}, XAUUSD: {"display": "XAU/USD", "pip_value": 0.10, "is_jpy_pair": False,
"price_precision": 2, "default_spread": 0.30},
EURUSD: {"display": "EUR/USD", "pip_value": 0.0001, "is_jpy_pair": False,
"price_precision": 5, "default_spread": 0.0001},
} }
@@ -158,7 +165,7 @@ class SignalConfig:
@dataclass @dataclass
class NewsConfig: class NewsConfig:
"""Economic calendar & sentiment.""" """Economic calendar & sentiment."""
tracked_currencies: List[str] = field(default_factory=lambda: ["USD", "XAU"]) tracked_currencies: List[str] = field(default_factory=lambda: ["USD", "XAU", "EUR"])
pre_event_buffer_minutes: int = 30 pre_event_buffer_minutes: int = 30
post_event_buffer_minutes: int = 15 post_event_buffer_minutes: int = 15
# Wider stay-out window after a high-impact release that surprised # Wider stay-out window after a high-impact release that surprised
@@ -252,6 +259,54 @@ class XauStrategyConfig:
m5_pullback_touch_bars: int = 3 m5_pullback_touch_bars: int = 3
@dataclass
class EurUsdStrategyConfig:
"""EUR/USD strategy config — separate from XAU for independent tuning.
Values ported from feature/eurusd-support are a pre-realism baseline
(tuned before spread charging and next-open fills) and are re-tuned
against the realistic backtester. Cost knobs (round_trip_cost,
min_tp_cost_multiple, min_sl_pips) are EUR-local so nothing
gold-calibrated from SignalConfig leaks into the EUR path.
"""
enabled: bool = True
blocked_hours_utc: List[int] = field(default_factory=lambda: [22, 23, 0, 1, 2, 3])
weekend_filter: bool = True
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 # swing-buffer ATR multiple for SL placement
tp_atr_multiplier: float = 1.2
sl_atr_floor: float = 1.2
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,
})
blocked_regimes: List[str] = field(default_factory=lambda: ["ranging", "transitioning"])
min_quality_grades: List[str] = field(default_factory=lambda: ["A+", "A", "B"])
max_exhaustion_tags: int = 99
block_near_ema200: bool = False
session_hours: List[int] = field(default_factory=list)
min_entry_score: float = 38.0
min_entry_confidence: float = 60.0
block_rsi_extended: bool = True
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
# ── EUR-local trade-cost knobs (replace SignalConfig's gold-dollar
# values in the EUR path) ─────────────────────────────────────────
# Round-trip cost per trade in price units (1.0 pip).
round_trip_cost: float = 0.0001
# Reject setups whose TP1 distance < round_trip_cost × this multiple
# (10 → 10-pip minimum target; EUR M5 ATR runs ~5-8 pips).
min_tp_cost_multiple: float = 10.0
# Minimum SL distance in pips.
min_sl_pips: float = 8.0
@dataclass @dataclass
class FilterConfig: class FilterConfig:
"""Regime and session filters for live signals.""" """Regime and session filters for live signals."""
@@ -275,6 +330,7 @@ class PlatformConfig:
news: NewsConfig = field(default_factory=NewsConfig) news: NewsConfig = field(default_factory=NewsConfig)
backtest: FilterConfig = field(default_factory=FilterConfig) backtest: FilterConfig = field(default_factory=FilterConfig)
xau_strategy: XauStrategyConfig = field(default_factory=XauStrategyConfig) xau_strategy: XauStrategyConfig = field(default_factory=XauStrategyConfig)
eur_strategy: EurUsdStrategyConfig = field(default_factory=EurUsdStrategyConfig)
symbol: str = XAUUSD symbol: str = XAUUSD
display_name: str = "XAU/USD" display_name: str = "XAU/USD"