""" Forex Signal Intelligence Platform - Configuration =================================================== Central configuration for all signal analysis parameters. Tuned by market regime and validated against historical performance. """ from dataclasses import dataclass, field from enum import Enum from typing import Dict, List class Timeframe(Enum): M1 = "1min" M5 = "5min" M15 = "15min" M30 = "30min" H1 = "1h" H4 = "4h" D1 = "1d" W1 = "1wk" class SignalStrength(Enum): STRONG_BUY = 2 BUY = 1 NEUTRAL = 0 SELL = -1 STRONG_SELL = -2 class MarketSession(Enum): SYDNEY = "sydney" TOKYO = "tokyo" LONDON = "london" NEW_YORK = "new_york" OVERLAP_LONDON_NY = "london_ny_overlap" # ── Major Forex Pairs ────────────────────────────────────────────── MAJOR_PAIRS = [ "EURUSD=X", "GBPUSD=X", "USDJPY=X", "USDCHF=X", "AUDUSD=X", "USDCAD=X", "NZDUSD=X", ] CROSS_PAIRS = [ "EURGBP=X", "EURJPY=X", "GBPJPY=X", "AUDJPY=X", "EURCHF=X", "CADJPY=X", ] # Symbol display names SYMBOL_DISPLAY = { "EURUSD=X": "EUR/USD", "GBPUSD=X": "GBP/USD", "USDJPY=X": "USD/JPY", "USDCHF=X": "USD/CHF", "AUDUSD=X": "AUD/USD", "USDCAD=X": "USD/CAD", "NZDUSD=X": "NZD/USD", "EURGBP=X": "EUR/GBP", "EURJPY=X": "EUR/JPY", "GBPJPY=X": "GBP/JPY", "AUDJPY=X": "AUD/JPY", "EURCHF=X": "EUR/CHF", "CADJPY=X": "CAD/JPY", } # Pip values per symbol (used for trade setup risk/reward in pips) # Forex defaults: 0.01 for JPY pairs, 0.0001 for everything else. # Override here for any pair that doesn't follow that rule. PIP_VALUES: Dict[str, float] = {} @dataclass class TechnicalConfig: """Technical indicator parameters - carefully tuned for Forex.""" # EMA periods (fast/medium/slow for trend detection) ema_fast: int = 9 ema_medium: int = 21 ema_slow: int = 50 ema_trend: int = 200 # RSI rsi_period: int = 14 rsi_overbought: float = 70.0 rsi_oversold: float = 30.0 rsi_neutral_upper: float = 60.0 rsi_neutral_lower: float = 40.0 # MACD (12, 26, 9 is standard) macd_fast: int = 12 macd_slow: int = 26 macd_signal: int = 9 # Bollinger Bands bb_period: int = 20 bb_std: float = 2.0 # ATR for volatility measurement atr_period: int = 14 # Stochastic stoch_k: int = 14 stoch_d: int = 3 stoch_overbought: float = 80.0 stoch_oversold: float = 20.0 # ADX for trend strength adx_period: int = 14 adx_strong_trend: float = 25.0 adx_very_strong: float = 50.0 # Ichimoku ichimoku_tenkan: int = 9 ichimoku_kijun: int = 26 ichimoku_senkou_b: int = 52 # Volume profile volume_ma_period: int = 20 # Pivot points lookback pivot_lookback: int = 1 # Divergence detection — how many bars back to scan for swing points divergence_lookback: int = 14 @dataclass class SignalConfig: """Signal scoring and filtering parameters.""" # Minimum confidence to emit a signal (0-100) min_confidence: float = 55.0 # Weight allocation for composite score weights: Dict[str, float] = field(default_factory=lambda: { "trend": 0.25, # EMA alignment, ADX "momentum": 0.20, # RSI, Stochastic, MACD "volatility": 0.15, # BB position, ATR regime "price_action": 0.15, # Candlestick patterns, S/R "multi_timeframe": 0.15,# Higher TF confirmation "sentiment": 0.10, # News/calendar events }) # Multi-timeframe confirmation requirements mtf_agreement_threshold: int = 2 # out of 3 timeframes must agree # Signal cooldown (prevent over-signalling same direction) cooldown_bars: int = 5 # Risk management defaults default_risk_pct: float = 1.0 # risk 1% per trade default_rr_ratio: float = 2.0 # 1:2 risk-reward minimum @dataclass class NewsConfig: """Economic calendar and sentiment configuration.""" # High-impact event currencies tracked_currencies: List[str] = field(default_factory=lambda: [ "USD", "EUR", "GBP", "JPY", "CHF", "AUD", "CAD", "NZD" ]) # Event impact levels to monitor min_impact: str = "medium" # "low", "medium", "high" # Pre-event buffer (minutes before high-impact event = no new signals) pre_event_buffer_minutes: int = 30 # Post-event volatility window (minutes after event = cautious signals) post_event_buffer_minutes: int = 15 # News sentiment sources rss_feeds: List[str] = field(default_factory=lambda: [ "https://www.forexlive.com/feed/", "https://www.fxstreet.com/rss", ]) @dataclass class PlatformConfig: """Overall platform configuration.""" technical: TechnicalConfig = field(default_factory=TechnicalConfig) signals: SignalConfig = field(default_factory=SignalConfig) news: NewsConfig = field(default_factory=NewsConfig) # Default pairs to monitor watch_pairs: List[str] = field(default_factory=lambda: MAJOR_PAIRS) # Analysis timeframes (primary + confirmation) primary_timeframe: Timeframe = Timeframe.H1 confirmation_timeframes: List[Timeframe] = field( default_factory=lambda: [Timeframe.M15, Timeframe.D1] ) # Data source data_lookback_days: int = 60 # enough for 200 EMA on H1 # Twelve Data API key (overridden by TWELVE_DATA_API_KEY env var) twelve_data_api_key: str = "f563b22ffdfd4924955decbe1a8c8701" # Dashboard refresh interval (seconds) — used as a fallback when a # timeframe isn't covered by cache_ttl_per_tf below. refresh_interval: int = 300 # 5 minutes # Per-timeframe cache TTL (seconds). A 1-week candle changes less # often than a 15-minute candle, so caching them all for the same # 5 minutes wastes API credits. Tuned to roughly match each TF's # bar interval so we re-fetch about once per new bar. cache_ttl_per_tf: Dict[Timeframe, int] = field(default_factory=lambda: { Timeframe.M1: 60, # 1 minute Timeframe.M5: 150, # 2.5 minutes Timeframe.M15: 300, # 5 minutes Timeframe.M30: 600, # 10 minutes Timeframe.H1: 1800, # 30 minutes Timeframe.H4: 7200, # 2 hours Timeframe.D1: 14400, # 4 hours Timeframe.W1: 86400, # 24 hours }) # Logging log_level: str = "INFO" log_signals_to_file: bool = True signal_log_path: str = "signals.log"