190 lines
7.0 KiB
Python
190 lines
7.0 KiB
Python
#!/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") |