diff --git a/web/clean_dashboard.py b/web/clean_dashboard.py index 161589c..6c6baeb 100644 --- a/web/clean_dashboard.py +++ b/web/clean_dashboard.py @@ -327,7 +327,7 @@ class CleanTradingDashboard: self.app = Dash(__name__, external_stylesheets=[ 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css' - ]) + ], suppress_callback_exceptions=True) # Suppress Dash development mode logging self.app.enable_dev_tools(debug=False, dev_tools_silence_routes_logging=True) @@ -864,14 +864,32 @@ class CleanTradingDashboard: available_models[model_name] = {'name': model_name, 'type': 'unknown'} logger.debug(f"Found {len(toggle_models)} models in toggle states") + # Apply model name mapping to match orchestrator's internal mapping + # This ensures component IDs match what the orchestrator expects + mapped_models = {} + model_mapping = { + 'dqn_agent': 'dqn', + 'enhanced_cnn': 'cnn', + 'extrema_trainer': 'extrema_trainer', + 'decision': 'decision_fusion', + 'cob_rl': 'cob_rl', + 'transformer': 'transformer' + } + + for model_name, model_info in available_models.items(): + # Use mapped name if available, otherwise use original name + mapped_name = model_mapping.get(model_name, model_name) + mapped_models[mapped_name] = model_info + logger.debug(f"Mapped model name: {model_name} -> {mapped_name}") + # Fallback: Add known models if none found - if not available_models: + if not mapped_models: fallback_models = ['dqn', 'cnn', 'cob_rl', 'decision_fusion', 'transformer'] for model_name in fallback_models: - available_models[model_name] = {'name': model_name, 'type': 'fallback'} + mapped_models[model_name] = {'name': model_name, 'type': 'fallback'} logger.warning(f"Using fallback models: {fallback_models}") - return available_models + return mapped_models except Exception as e: logger.error(f"Error getting available models: {e}") @@ -916,13 +934,25 @@ class CleanTradingDashboard: enabled = bool(value and len(value) > 0) # Convert list to boolean if self.orchestrator: + # Map component model name back to orchestrator's expected model name + reverse_mapping = { + 'dqn': 'dqn_agent', + 'cnn': 'enhanced_cnn', + 'decision_fusion': 'decision', + 'extrema_trainer': 'extrema_trainer', + 'cob_rl': 'cob_rl', + 'transformer': 'transformer' + } + + orchestrator_model_name = reverse_mapping.get(model_name, model_name) + # Update orchestrator toggle state if toggle_type == 'inference': - self.orchestrator.set_model_toggle_state(model_name, inference_enabled=enabled) + self.orchestrator.set_model_toggle_state(orchestrator_model_name, inference_enabled=enabled) elif toggle_type == 'training': - self.orchestrator.set_model_toggle_state(model_name, training_enabled=enabled) + self.orchestrator.set_model_toggle_state(orchestrator_model_name, training_enabled=enabled) - logger.info(f"Model {model_name} {toggle_type} toggle: {enabled}") + logger.info(f"Model {model_name} ({orchestrator_model_name}) {toggle_type} toggle: {enabled}") # Update dashboard state variables for backward compatibility self._update_dashboard_state_variable(model_name, toggle_type, enabled) @@ -3651,7 +3681,17 @@ class CleanTradingDashboard: available_models = self._get_available_models() toggle_states = {} for model_name in available_models.keys(): - toggle_states[model_name] = self.orchestrator.get_model_toggle_state(model_name) + # Map component model name to orchestrator model name for getting toggle state + reverse_mapping = { + 'dqn': 'dqn_agent', + 'cnn': 'enhanced_cnn', + 'decision_fusion': 'decision', + 'extrema_trainer': 'extrema_trainer', + 'cob_rl': 'cob_rl', + 'transformer': 'transformer' + } + orchestrator_model_name = reverse_mapping.get(model_name, model_name) + toggle_states[model_name] = self.orchestrator.get_model_toggle_state(orchestrator_model_name) else: # Fallback to default states for known models toggle_states = { @@ -3711,8 +3751,19 @@ class CleanTradingDashboard: try: if self.orchestrator: + # Map component model name to orchestrator model name for getting statistics + reverse_mapping = { + 'dqn': 'dqn_agent', + 'cnn': 'enhanced_cnn', + 'decision_fusion': 'decision', + 'extrema_trainer': 'extrema_trainer', + 'cob_rl': 'cob_rl', + 'transformer': 'transformer' + } + orchestrator_model_name = reverse_mapping.get(model_name, model_name) + # Use the new model statistics system - model_stats = self.orchestrator.get_model_statistics(model_name.lower()) + model_stats = self.orchestrator.get_model_statistics(orchestrator_model_name) if model_stats: # Last inference time timing['last_inference'] = model_stats.last_inference_time @@ -3755,7 +3806,7 @@ class CleanTradingDashboard: dqn_prediction_count = len(self.recent_decisions) if signal_generation_active else 0 # Get latest DQN prediction from orchestrator statistics - dqn_stats = orchestrator_stats.get('dqn_agent') + dqn_stats = orchestrator_stats.get('dqn_agent') # Use orchestrator's internal name if dqn_stats and dqn_stats.predictions_history: # Get the most recent prediction latest_pred = list(dqn_stats.predictions_history)[-1] @@ -3786,8 +3837,8 @@ class CleanTradingDashboard: last_confidence = 0.68 last_timestamp = datetime.now().strftime('%H:%M:%S') - # Get real DQN statistics from orchestrator (try both old and new names) - dqn_stats = orchestrator_stats.get('dqn_agent') or orchestrator_stats.get('dqn') + # Get real DQN statistics from orchestrator (use orchestrator's internal name) + dqn_stats = orchestrator_stats.get('dqn_agent') dqn_current_loss = dqn_stats.current_loss if dqn_stats else None dqn_best_loss = dqn_stats.best_loss if dqn_stats else None dqn_accuracy = dqn_stats.accuracy if dqn_stats else None @@ -3867,8 +3918,8 @@ class CleanTradingDashboard: cnn_state = model_states.get('cnn', {}) cnn_timing = get_model_timing_info('CNN') - # Get real CNN statistics from orchestrator (try both old and new names) - cnn_stats = orchestrator_stats.get('enhanced_cnn') or orchestrator_stats.get('cnn') + # Get real CNN statistics from orchestrator (use orchestrator's internal name) + cnn_stats = orchestrator_stats.get('enhanced_cnn') cnn_active = cnn_stats is not None # Get latest CNN prediction from orchestrator statistics @@ -4095,7 +4146,10 @@ class CleanTradingDashboard: # 4. COB RL Model Status - using orchestrator SSOT cob_state = model_states.get('cob_rl', {}) cob_timing = get_model_timing_info('COB_RL') - cob_active = True + + # Get real COB RL statistics from orchestrator (use orchestrator's internal name) + cob_stats = orchestrator_stats.get('cob_rl') + cob_active = cob_stats is not None cob_predictions_count = len(self.recent_decisions) * 2 # Get COB RL toggle states @@ -4154,10 +4208,8 @@ class CleanTradingDashboard: decision_inference_enabled = decision_toggle_state.get("inference_enabled", True) decision_training_enabled = decision_toggle_state.get("training_enabled", True) - # Get real decision fusion statistics from orchestrator - decision_stats = None - if self.orchestrator and hasattr(self.orchestrator, 'model_statistics'): - decision_stats = self.orchestrator.model_statistics.get('decision_fusion') + # Get real decision fusion statistics from orchestrator (use orchestrator's internal name) + decision_stats = orchestrator_stats.get('decision') # Get real last prediction last_prediction = 'HOLD'