feat: Multi-Pair Divergence Selection Strategy
- Extend regime detection to top 10 cryptocurrencies (45 pairs) - Dynamic pair selection based on divergence score (|z_score| * probability) - Universal ML model trained on all pairs - Correlation-based filtering to avoid redundant positions - Funding rate integration from OKX for all 10 assets - ATR-based dynamic stop-loss and take-profit - Walk-forward training with 70/30 split Performance: +35.69% return (vs +28.66% baseline), 63.6% win rate
This commit is contained in:
88
strategies/multi_pair/config.py
Normal file
88
strategies/multi_pair/config.py
Normal file
@@ -0,0 +1,88 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user