This commit is contained in:
Dobromir Popov
2025-07-17 02:15:24 +03:00
parent b4e592b406
commit 6b9482d2be
6 changed files with 874 additions and 21 deletions

View File

@ -136,6 +136,11 @@ class TradingOrchestrator:
self.recent_decisions: Dict[str, List[TradingDecision]] = {} # {symbol: List[TradingDecision]}
self.model_performance: Dict[str, Dict[str, Any]] = {} # {model_name: {'correct': int, 'total': int, 'accuracy': float}}
# Signal rate limiting to prevent spam
self.last_signal_time: Dict[str, Dict[str, datetime]] = {} # {symbol: {action: datetime}}
self.min_signal_interval = timedelta(seconds=30) # Minimum 30 seconds between same signals
self.last_confirmed_signal: Dict[str, Dict[str, Any]] = {} # {symbol: {action, timestamp, confidence}}
# Signal accumulation for trend confirmation
self.signal_accumulator: Dict[str, List[Dict]] = {} # {symbol: List[signal_data]}
self.required_confirmations = 3 # Number of consistent signals needed
@ -871,6 +876,22 @@ class TradingOrchestrator:
'CNN': self.config.orchestrator.get('cnn_weight', 0.7),
'RL': self.config.orchestrator.get('rl_weight', 0.3)
}
# Add weights for specific models if they exist
if hasattr(self, 'cnn_model') and self.cnn_model:
self.model_weights["enhanced_cnn"] = 0.4
# Only add DQN agent weight if it exists
if hasattr(self, 'rl_agent') and self.rl_agent:
self.model_weights["dqn_agent"] = 0.3
# Add COB RL model weight if it exists
if hasattr(self, 'cob_rl_agent') and self.cob_rl_agent:
self.model_weights["cob_rl_model"] = 0.2
# Add extrema trainer weight if it exists
if hasattr(self, 'extrema_trainer') and self.extrema_trainer:
self.model_weights["extrema_trainer"] = 0.15
def register_model(self, model: ModelInterface, weight: Optional[float] = None) -> bool:
"""Register a new model with the orchestrator"""
@ -1960,10 +1981,27 @@ class TradingOrchestrator:
logger.info("Trading executor set for position tracking and P&L feedback")
def _check_signal_confirmation(self, symbol: str, signal_data: Dict) -> Optional[str]:
"""Check if we have enough signal confirmations for trend confirmation"""
"""Check if we have enough signal confirmations for trend confirmation with rate limiting"""
try:
# Clean up expired signals
current_time = signal_data['timestamp']
action = signal_data['action']
# Initialize signal tracking for this symbol if needed
if symbol not in self.last_signal_time:
self.last_signal_time[symbol] = {}
if symbol not in self.last_confirmed_signal:
self.last_confirmed_signal[symbol] = {}
# RATE LIMITING: Check if we recently confirmed the same signal
if action in self.last_confirmed_signal[symbol]:
last_confirmed = self.last_confirmed_signal[symbol][action]
time_since_last = current_time - last_confirmed['timestamp']
if time_since_last < self.min_signal_interval:
logger.debug(f"Rate limiting: {action} signal for {symbol} too recent "
f"({time_since_last.total_seconds():.1f}s < {self.min_signal_interval.total_seconds()}s)")
return None
# Clean up expired signals
self.signal_accumulator[symbol] = [
s for s in self.signal_accumulator[symbol]
if (current_time - s['timestamp']).total_seconds() < self.signal_timeout_seconds
@ -1982,8 +2020,8 @@ class TradingOrchestrator:
# Count action consensus
action_counts = {}
for action in actions:
action_counts[action] = action_counts.get(action, 0) + 1
for action_item in actions:
action_counts[action_item] = action_counts.get(action_item, 0) + 1
# Find dominant action
dominant_action = max(action_counts, key=action_counts.get)
@ -1991,8 +2029,24 @@ class TradingOrchestrator:
# Require at least 2/3 consensus
if consensus_count >= max(2, self.required_confirmations * 0.67):
# ADDITIONAL RATE LIMITING: Don't confirm if we just confirmed the same action
if dominant_action in self.last_confirmed_signal[symbol]:
last_confirmed = self.last_confirmed_signal[symbol][dominant_action]
time_since_last = current_time - last_confirmed['timestamp']
if time_since_last < self.min_signal_interval:
logger.debug(f"Rate limiting: Preventing duplicate {dominant_action} confirmation for {symbol}")
return None
# Record this confirmation
self.last_confirmed_signal[symbol][dominant_action] = {
'timestamp': current_time,
'confidence': signal_data['confidence']
}
# Clear accumulator after confirmation
self.signal_accumulator[symbol] = []
logger.info(f"Signal confirmed after rate limiting: {dominant_action} for {symbol}")
return dominant_action
return None