#!/usr/bin/env python3 """ Configuration module for enhanced velocity calculations in CLP Scalper Hedger Provides configurable parameters for multi-timeframe velocity detection """ from dataclasses import dataclass, field from typing import Dict, List, Optional import json import os @dataclass class VelocityTimeframe: """Configuration for a single velocity timeframe""" name: str periods: int # Number of periods to average over weight: float # Weight in decision making (0.0 to 1.0) threshold: float # Velocity threshold for this timeframe description: str @dataclass class VelocityConfig: """Enhanced velocity configuration with multiple timeframes and market conditions""" # Basic settings max_velocity_cap: float = 0.5 # Cap at 50% change per interval history_length: int = 60 # Keep last 60 price points for calculations # Timeframe configurations timeframes: Optional[List[VelocityTimeframe]] = None # Market condition thresholds normal_threshold: float = 0.0005 # 0.05% for normal markets volatile_threshold: float = 0.001 # 0.1% for volatile markets extreme_threshold: float = 0.002 # 0.2% for extreme markets # Emergency detection settings extreme_move_threshold: float = 0.002 # 0.2% for immediate response sustained_move_periods: int = 5 # Periods for sustained move detection # Smoothing settings use_ema_smoothing: bool = True ema_alpha: float = 0.2 # EMA smoothing factor # Edge proximity for velocity triggers edge_proximity_factor: float = 0.05 # 5% from range edge def __post_init__(self): """Initialize default timeframes if not provided""" if self.timeframes is None: self.timeframes = [ VelocityTimeframe( name="1s", periods=1, weight=0.4, threshold=self.extreme_threshold, description="Instantaneous velocity for emergency detection" ), VelocityTimeframe( name="5s", periods=5, weight=0.3, threshold=self.normal_threshold, description="Short-term smoothed velocity" ), VelocityTimeframe( name="10s", periods=10, weight=0.2, threshold=self.normal_threshold * 0.8, description="Medium-term trend detection" ), VelocityTimeframe( name="30s", periods=30, weight=0.1, threshold=self.normal_threshold * 0.6, description="Long-term sustained moves" ) ] @classmethod def conservative(cls) -> 'VelocityConfig': """Conservative configuration for low-risk trading""" config = cls() config.normal_threshold = 0.0003 # 0.03% config.volatile_threshold = 0.0006 # 0.06% config.extreme_threshold = 0.001 # 0.1% config.extreme_move_threshold = 0.001 # 0.1% return config @classmethod def aggressive(cls) -> 'VelocityConfig': """Aggressive configuration for high-frequency trading""" config = cls() config.normal_threshold = 0.001 # 0.1% config.volatile_threshold = 0.002 # 0.2% config.extreme_threshold = 0.003 # 0.3% config.extreme_move_threshold = 0.003 # 0.3% return config @classmethod def from_file(cls, config_path: str) -> 'VelocityConfig': """Load configuration from JSON file""" if not os.path.exists(config_path): raise FileNotFoundError(f"Configuration file not found: {config_path}") with open(config_path, 'r') as f: data = json.load(f) # Reconstruct VelocityTimeframe objects if 'timeframes' in data and data['timeframes'] is not None: data['timeframes'] = [VelocityTimeframe(**tf) for tf in data['timeframes']] return cls(**data) def to_file(self, config_path: str) -> None: """Save configuration to JSON file""" data = { 'max_velocity_cap': self.max_velocity_cap, 'history_length': self.history_length, 'timeframes': [ { 'name': tf.name, 'periods': tf.periods, 'weight': tf.weight, 'threshold': tf.threshold, 'description': tf.description } for tf in self.timeframes or [] ], 'normal_threshold': self.normal_threshold, 'volatile_threshold': self.volatile_threshold, 'extreme_threshold': self.extreme_threshold, 'extreme_move_threshold': self.extreme_move_threshold, 'sustained_move_periods': self.sustained_move_periods, 'use_ema_smoothing': self.use_ema_smoothing, 'ema_alpha': self.ema_alpha, 'edge_proximity_factor': self.edge_proximity_factor } # Only create directory if path contains directory config_dir = os.path.dirname(config_path) if config_dir: os.makedirs(config_dir, exist_ok=True) with open(config_path, 'w') as f: json.dump(data, f, indent=2) def get_active_threshold(self, market_volatility: float) -> float: """Get appropriate threshold based on market volatility""" if market_volatility < 0.001: # Very low volatility return self.normal_threshold elif market_volatility < 0.003: # Normal volatility return self.volatile_threshold else: # High volatility return self.extreme_threshold def create_default_config() -> VelocityConfig: """Create default velocity configuration""" return VelocityConfig() def create_config_files() -> None: """Create example configuration files""" configs = { 'velocity_config_conservative.json': create_default_config().conservative(), 'velocity_config_normal.json': create_default_config(), 'velocity_config_aggressive.json': create_default_config().aggressive() } for filename, config in configs.items(): config.to_file(filename) if __name__ == "__main__": # Example usage and config file creation print("Creating velocity configuration files...") create_config_files() print("Configuration files created successfully!") # Display default configuration default_config = create_default_config() print(f"\nDefault configuration:") print(f"Normal threshold: {default_config.normal_threshold*100:.3f}%") if default_config.timeframes: print(f"Timeframes: {len(default_config.timeframes)}") for tf in default_config.timeframes: print(f" - {tf.name}: {tf.periods} periods, {tf.threshold*100:.3f}% threshold, {tf.weight:.1f} weight")