better decision details
This commit is contained in:
@ -256,6 +256,7 @@ class TradingDecision:
|
|||||||
timestamp: datetime
|
timestamp: datetime
|
||||||
reasoning: Dict[str, Any] # Why this decision was made
|
reasoning: Dict[str, Any] # Why this decision was made
|
||||||
memory_usage: Dict[str, int] # Memory usage of models
|
memory_usage: Dict[str, int] # Memory usage of models
|
||||||
|
source: str = "orchestrator" # Source of the decision (model name or system)
|
||||||
# NEW: Aggressiveness parameters
|
# NEW: Aggressiveness parameters
|
||||||
entry_aggressiveness: float = 0.5 # 0.0 = conservative, 1.0 = very aggressive
|
entry_aggressiveness: float = 0.5 # 0.0 = conservative, 1.0 = very aggressive
|
||||||
exit_aggressiveness: float = 0.5 # 0.0 = conservative, 1.0 = very aggressive
|
exit_aggressiveness: float = 0.5 # 0.0 = conservative, 1.0 = very aggressive
|
||||||
@ -4637,6 +4638,56 @@ class TradingOrchestrator:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error creating RL state for {symbol}: {e}")
|
logger.error(f"Error creating RL state for {symbol}: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _determine_decision_source(self, models_used: List[str], confidence: float) -> str:
|
||||||
|
"""Determine the source of a trading decision based on contributing models"""
|
||||||
|
try:
|
||||||
|
if not models_used:
|
||||||
|
return "no_models"
|
||||||
|
|
||||||
|
# If only one model contributed, use that as source
|
||||||
|
if len(models_used) == 1:
|
||||||
|
model_name = models_used[0]
|
||||||
|
# Map internal model names to user-friendly names
|
||||||
|
model_mapping = {
|
||||||
|
"dqn_agent": "DQN",
|
||||||
|
"cnn_model": "CNN",
|
||||||
|
"cob_rl": "COB-RL",
|
||||||
|
"decision_fusion": "Fusion",
|
||||||
|
"extrema_trainer": "Extrema",
|
||||||
|
"transformer": "Transformer"
|
||||||
|
}
|
||||||
|
return model_mapping.get(model_name, model_name)
|
||||||
|
|
||||||
|
# Multiple models - determine primary contributor
|
||||||
|
# Priority order: COB-RL > DQN > CNN > Others
|
||||||
|
priority_order = ["cob_rl", "dqn_agent", "cnn_model", "decision_fusion", "transformer", "extrema_trainer"]
|
||||||
|
|
||||||
|
for priority_model in priority_order:
|
||||||
|
if priority_model in models_used:
|
||||||
|
model_mapping = {
|
||||||
|
"cob_rl": "COB-RL",
|
||||||
|
"dqn_agent": "DQN",
|
||||||
|
"cnn_model": "CNN",
|
||||||
|
"decision_fusion": "Fusion",
|
||||||
|
"transformer": "Transformer",
|
||||||
|
"extrema_trainer": "Extrema"
|
||||||
|
}
|
||||||
|
primary_model = model_mapping.get(priority_model, priority_model)
|
||||||
|
|
||||||
|
# If high confidence, show primary model
|
||||||
|
if confidence > 0.7:
|
||||||
|
return primary_model
|
||||||
|
else:
|
||||||
|
# Lower confidence, show it's a combination
|
||||||
|
return f"{primary_model}+{len(models_used)-1}"
|
||||||
|
|
||||||
|
# Fallback: show number of models
|
||||||
|
return f"Ensemble({len(models_used)})"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error determining decision source: {e}")
|
||||||
|
return "orchestrator"
|
||||||
|
|
||||||
def _combine_predictions(
|
def _combine_predictions(
|
||||||
self,
|
self,
|
||||||
@ -4798,6 +4849,9 @@ class TradingOrchestrator:
|
|||||||
symbol, current_position_pnl
|
symbol, current_position_pnl
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Determine decision source based on contributing models
|
||||||
|
source = self._determine_decision_source(reasoning.get("models_used", []), best_confidence)
|
||||||
|
|
||||||
# Create final decision
|
# Create final decision
|
||||||
decision = TradingDecision(
|
decision = TradingDecision(
|
||||||
action=best_action,
|
action=best_action,
|
||||||
@ -4807,6 +4861,7 @@ class TradingOrchestrator:
|
|||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
reasoning=reasoning,
|
reasoning=reasoning,
|
||||||
memory_usage=memory_usage.get("models", {}) if memory_usage else {},
|
memory_usage=memory_usage.get("models", {}) if memory_usage else {},
|
||||||
|
source=source,
|
||||||
entry_aggressiveness=entry_aggressiveness,
|
entry_aggressiveness=entry_aggressiveness,
|
||||||
exit_aggressiveness=exit_aggressiveness,
|
exit_aggressiveness=exit_aggressiveness,
|
||||||
current_position_pnl=current_position_pnl,
|
current_position_pnl=current_position_pnl,
|
||||||
@ -4828,6 +4883,7 @@ class TradingOrchestrator:
|
|||||||
action="HOLD",
|
action="HOLD",
|
||||||
confidence=0.0,
|
confidence=0.0,
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
|
source="error_fallback",
|
||||||
price=price,
|
price=price,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
reasoning={"error": str(e)},
|
reasoning={"error": str(e)},
|
||||||
@ -5465,6 +5521,9 @@ class TradingOrchestrator:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Determine decision source
|
||||||
|
source = self._determine_decision_source(reasoning.get("models_used", []), best_confidence)
|
||||||
|
|
||||||
# Create final decision
|
# Create final decision
|
||||||
decision = TradingDecision(
|
decision = TradingDecision(
|
||||||
action=best_action,
|
action=best_action,
|
||||||
@ -5474,6 +5533,7 @@ class TradingOrchestrator:
|
|||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
reasoning=reasoning,
|
reasoning=reasoning,
|
||||||
memory_usage=memory_usage.get("models", {}) if memory_usage else {},
|
memory_usage=memory_usage.get("models", {}) if memory_usage else {},
|
||||||
|
source=source,
|
||||||
entry_aggressiveness=self.entry_aggressiveness,
|
entry_aggressiveness=self.entry_aggressiveness,
|
||||||
exit_aggressiveness=self.exit_aggressiveness,
|
exit_aggressiveness=self.exit_aggressiveness,
|
||||||
current_position_pnl=current_position_pnl,
|
current_position_pnl=current_position_pnl,
|
||||||
@ -6643,10 +6703,25 @@ class TradingOrchestrator:
|
|||||||
}
|
}
|
||||||
target = target_mapping.get(action, [0, 0, 1])
|
target = target_mapping.get(action, [0, 0, 1])
|
||||||
|
|
||||||
# Add training sample
|
# Decision fusion network doesn't have add_training_sample method
|
||||||
self.decision_fusion_network.add_training_sample(
|
# Instead, we'll store the training data for later batch training
|
||||||
fusion_input, target, weight=confidence
|
if not hasattr(self, 'decision_fusion_training_data'):
|
||||||
)
|
self.decision_fusion_training_data = []
|
||||||
|
|
||||||
|
# Convert target list to action string for compatibility
|
||||||
|
target_action = "BUY" if target[0] == 1 else "SELL" if target[1] == 1 else "HOLD"
|
||||||
|
|
||||||
|
self.decision_fusion_training_data.append({
|
||||||
|
'input_features': fusion_input,
|
||||||
|
'target_action': target_action,
|
||||||
|
'weight': confidence,
|
||||||
|
'timestamp': datetime.now()
|
||||||
|
})
|
||||||
|
|
||||||
|
# Train the network if we have enough samples
|
||||||
|
if len(self.decision_fusion_training_data) >= 5: # Train every 5 samples
|
||||||
|
self._train_decision_fusion_network()
|
||||||
|
self.decision_fusion_training_data = [] # Clear after training
|
||||||
|
|
||||||
models_trained.append("decision_fusion")
|
models_trained.append("decision_fusion")
|
||||||
logger.debug(f"🤝 Added decision fusion training sample: {action} {symbol}")
|
logger.debug(f"🤝 Added decision fusion training sample: {action} {symbol}")
|
||||||
|
@ -21,5 +21,5 @@
|
|||||||
"training_enabled": true
|
"training_enabled": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"timestamp": "2025-07-29T09:07:36.747677"
|
"timestamp": "2025-07-29T09:18:36.627596"
|
||||||
}
|
}
|
@ -2491,7 +2491,14 @@ class CleanTradingDashboard:
|
|||||||
|
|
||||||
# Extract source information from signal
|
# Extract source information from signal
|
||||||
signal_source = 'Unknown'
|
signal_source = 'Unknown'
|
||||||
if hasattr(signal, 'reasoning') and signal.reasoning:
|
|
||||||
|
# First try to get source directly from the signal (new method)
|
||||||
|
if hasattr(signal, 'source') and signal.source:
|
||||||
|
signal_source = signal.source
|
||||||
|
elif isinstance(signal, dict) and 'source' in signal and signal['source']:
|
||||||
|
signal_source = signal['source']
|
||||||
|
# Fallback to old method using reasoning.models_used
|
||||||
|
elif hasattr(signal, 'reasoning') and signal.reasoning:
|
||||||
models_used = signal.reasoning.get('models_used', [])
|
models_used = signal.reasoning.get('models_used', [])
|
||||||
if models_used:
|
if models_used:
|
||||||
signal_source = ', '.join(models_used)
|
signal_source = ', '.join(models_used)
|
||||||
@ -5107,6 +5114,7 @@ class CleanTradingDashboard:
|
|||||||
'blocked': False,
|
'blocked': False,
|
||||||
'manual': True, # CRITICAL: Mark as manual for special handling
|
'manual': True, # CRITICAL: Mark as manual for special handling
|
||||||
'reason': f'Manual {action} button',
|
'reason': f'Manual {action} button',
|
||||||
|
'source': 'Manual', # Clear source for manual trades
|
||||||
'model_inputs': model_inputs, # Store for training
|
'model_inputs': model_inputs, # Store for training
|
||||||
'persistent': True, # MARK for persistent display
|
'persistent': True, # MARK for persistent display
|
||||||
'chart_priority': 'HIGH' # High priority for chart display
|
'chart_priority': 'HIGH' # High priority for chart display
|
||||||
@ -8169,7 +8177,9 @@ class CleanTradingDashboard:
|
|||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'confidence': confidence,
|
'confidence': confidence,
|
||||||
'timestamp': datetime.now(),
|
'timestamp': datetime.now(),
|
||||||
'executed': False
|
'executed': False,
|
||||||
|
'source': getattr(decision, 'source', 'Unknown'),
|
||||||
|
'reasoning': getattr(decision, 'reasoning', {})
|
||||||
}
|
}
|
||||||
# Add any other attributes from the decision object
|
# Add any other attributes from the decision object
|
||||||
for attr in ['price', 'quantity', 'reasoning', 'model_source']:
|
for attr in ['price', 'quantity', 'reasoning', 'model_source']:
|
||||||
@ -8179,6 +8189,9 @@ class CleanTradingDashboard:
|
|||||||
dashboard_decision = decision.copy()
|
dashboard_decision = decision.copy()
|
||||||
dashboard_decision['timestamp'] = datetime.now()
|
dashboard_decision['timestamp'] = datetime.now()
|
||||||
dashboard_decision['executed'] = False
|
dashboard_decision['executed'] = False
|
||||||
|
# Ensure source is preserved
|
||||||
|
if 'source' not in dashboard_decision:
|
||||||
|
dashboard_decision['source'] = 'Unknown'
|
||||||
|
|
||||||
logger.info(f"[ORCHESTRATOR SIGNAL] Received: {action} for {symbol} (confidence: {confidence:.3f})")
|
logger.info(f"[ORCHESTRATOR SIGNAL] Received: {action} for {symbol} (confidence: {confidence:.3f})")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user