This commit is contained in:
Dobromir Popov
2025-07-29 19:02:44 +03:00
parent ac4068c168
commit 0b5fa07498
4 changed files with 143 additions and 56 deletions

View File

@ -327,7 +327,8 @@ 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_callback_exceptions=True)
# Suppress Dash development mode logging
self.app.enable_dev_tools(debug=False, dev_tools_silence_routes_logging=True)
@ -1363,43 +1364,72 @@ class CleanTradingDashboard:
error_msg = html.P(f"COB Error: {str(e)}", className="text-danger small")
return error_msg, error_msg
# Original training metrics callback - temporarily disabled for testing
# @self.app.callback(
# Output('training-metrics', 'children'),
# [Input('slow-interval-component', 'n_intervals'),
# Input('fast-interval-component', 'n_intervals'), # Add fast interval for testing
# Input('refresh-training-metrics-btn', 'n_clicks')] # Add manual refresh button
# )
# def update_training_metrics(slow_intervals, fast_intervals, n_clicks):
# """Update training metrics"""
# logger.info(f"update_training_metrics callback triggered with slow_intervals={slow_intervals}, fast_intervals={fast_intervals}, n_clicks={n_clicks}")
# try:
# # Get toggle states from orchestrator
# toggle_states = {}
# if self.orchestrator:
# # Get all available models dynamically
# available_models = self._get_available_models()
# logger.info(f"Available models: {list(available_models.keys())}")
# for model_name in available_models.keys():
# toggle_states[model_name] = self.orchestrator.get_model_toggle_state(model_name)
# else:
# # Fallback to dashboard dynamic state
# toggle_states = {}
# for model_name, state in self.model_toggle_states.items():
# toggle_states[model_name] = state
# # Now using slow-interval-component (10s) - no batching needed
#
# logger.info(f"Getting training metrics with toggle_states: {toggle_states}")
# metrics_data = self._get_training_metrics(toggle_states)
# logger.info(f"update_training_metrics callback: got metrics_data type={type(metrics_data)}")
# if metrics_data and isinstance(metrics_data, dict):
# logger.info(f"Metrics data keys: {list(metrics_data.keys())}")
# if 'loaded_models' in metrics_data:
# logger.info(f"Loaded models count: {len(metrics_data['loaded_models'])}")
# logger.info(f"Loaded model names: {list(metrics_data['loaded_models'].keys())}")
# else:
# logger.warning("No 'loaded_models' key in metrics_data!")
# else:
# logger.warning(f"Invalid metrics_data: {metrics_data}")
#
# logger.info("Formatting training metrics...")
# formatted_metrics = self.component_manager.format_training_metrics(metrics_data)
# logger.info(f"Formatted metrics type: {type(formatted_metrics)}, length: {len(formatted_metrics) if isinstance(formatted_metrics, list) else 'N/A'}")
# return formatted_metrics
# except PreventUpdate:
# logger.info("PreventUpdate raised in training metrics callback")
# raise
# except Exception as e:
# logger.error(f"Error updating training metrics: {e}")
# import traceback
# logger.error(f"Traceback: {traceback.format_exc()}")
# return [html.P(f"Error: {str(e)}", className="text-danger")]
# Test callback for training metrics
@self.app.callback(
Output('training-metrics', 'children'),
[Input('slow-interval-component', 'n_intervals')] # OPTIMIZED: Move to 10s interval
[Input('refresh-training-metrics-btn', 'n_clicks')],
prevent_initial_call=False
)
def update_training_metrics(n):
"""Update training metrics"""
def test_training_metrics_callback(n_clicks):
"""Test callback for training metrics"""
logger.info(f"test_training_metrics_callback triggered with n_clicks={n_clicks}")
try:
# Get toggle states from orchestrator
toggle_states = {}
if self.orchestrator:
# Get all available models dynamically
available_models = self._get_available_models()
for model_name in available_models.keys():
toggle_states[model_name] = self.orchestrator.get_model_toggle_state(model_name)
else:
# Fallback to dashboard dynamic state
toggle_states = {}
for model_name, state in self.model_toggle_states.items():
toggle_states[model_name] = state
# Now using slow-interval-component (10s) - no batching needed
metrics_data = self._get_training_metrics(toggle_states)
logger.debug(f"update_training_metrics callback: got metrics_data type={type(metrics_data)}")
if metrics_data and isinstance(metrics_data, dict):
logger.debug(f"Metrics data keys: {list(metrics_data.keys())}")
if 'loaded_models' in metrics_data:
logger.debug(f"Loaded models count: {len(metrics_data['loaded_models'])}")
logger.debug(f"Loaded model names: {list(metrics_data['loaded_models'].keys())}")
else:
logger.warning("No 'loaded_models' key in metrics_data!")
else:
logger.warning(f"Invalid metrics_data: {metrics_data}")
return self.component_manager.format_training_metrics(metrics_data)
except PreventUpdate:
raise
# Return a simple test message
return [html.P("Training metrics test - callback is working!", className="text-success")]
except Exception as e:
logger.error(f"Error updating training metrics: {e}")
logger.error(f"Error in test callback: {e}")
return [html.P(f"Error: {str(e)}", className="text-danger")]
# Manual trading buttons