""" Configuration for Multi-Pair Divergence Strategy. """ from dataclasses import dataclass, field @dataclass class MultiPairConfig: """ Configuration parameters for multi-pair divergence strategy. Attributes: assets: List of asset symbols to analyze (top 10 by market cap) z_window: Rolling window for Z-Score calculation (hours) z_entry_threshold: Minimum |Z-Score| to consider for entry prob_threshold: Minimum ML probability to consider for entry correlation_threshold: Max correlation to allow between pairs correlation_window: Rolling window for correlation (hours) atr_period: ATR lookback period for dynamic stops sl_atr_multiplier: Stop-loss as multiple of ATR tp_atr_multiplier: Take-profit as multiple of ATR train_ratio: Walk-forward train/test split ratio horizon: Look-ahead horizon for target calculation (hours) profit_target: Minimum profit threshold for target labels funding_threshold: Funding rate threshold for filtering """ # Asset Universe assets: list[str] = field(default_factory=lambda: [ "BTC-USDT", "ETH-USDT", "SOL-USDT", "XRP-USDT", "BNB-USDT", "DOGE-USDT", "ADA-USDT", "AVAX-USDT", "LINK-USDT", "DOT-USDT" ]) # Z-Score Thresholds z_window: int = 24 z_entry_threshold: float = 1.0 # ML Thresholds prob_threshold: float = 0.5 train_ratio: float = 0.7 horizon: int = 102 profit_target: float = 0.005 # Correlation Filtering correlation_threshold: float = 0.85 correlation_window: int = 168 # 7 days in hours # Risk Management - ATR-Based Stops # SL/TP are calculated as multiples of ATR # Mean ATR for crypto is ~0.6% per hour, so: # - 10x ATR = ~6% SL (matches previous fixed 6%) # - 8x ATR = ~5% TP (matches previous fixed 5%) atr_period: int = 14 # ATR lookback period (hours for 1h timeframe) sl_atr_multiplier: float = 10.0 # Stop-loss = entry +/- (ATR * multiplier) tp_atr_multiplier: float = 8.0 # Take-profit = entry +/- (ATR * multiplier) # Fallback fixed percentages (used if ATR is unavailable) base_sl_pct: float = 0.06 base_tp_pct: float = 0.05 # ATR bounds to prevent extreme stops min_sl_pct: float = 0.02 # Minimum 2% stop-loss max_sl_pct: float = 0.10 # Maximum 10% stop-loss min_tp_pct: float = 0.02 # Minimum 2% take-profit max_tp_pct: float = 0.15 # Maximum 15% take-profit volatility_window: int = 24 # Funding Rate Filter # OKX funding rates are typically 0.0001 (0.01%) per 8h # Extreme funding is > 0.0005 (0.05%) which indicates crowded trade funding_threshold: float = 0.0005 # 0.05% - filter extreme funding # Trade Management # Note: Setting min_hold_bars=0 and z_exit_threshold=0 gives best results # The mean-reversion exit at Z=0 is the primary profit driver min_hold_bars: int = 0 # Disabled - let mean reversion drive exits switch_threshold: float = 999.0 # Disabled - don't switch mid-trade cooldown_bars: int = 0 # Disabled - enter when signal appears z_exit_threshold: float = 0.0 # Exit at Z=0 (mean reversion complete) # Exchange exchange_id: str = "okx" timeframe: str = "1h" def get_pair_count(self) -> int: """Calculate number of unique pairs from asset list.""" n = len(self.assets) return n * (n - 1) // 2