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

@ -140,7 +140,8 @@ class DashboardComponentManager:
# Create table headers
headers = html.Thead([
html.Tr([
html.Th("Time", className="small"),
html.Th("Entry Time", className="small"),
html.Th("Exit Time", className="small"),
html.Th("Side", className="small"),
html.Th("Size", className="small"),
html.Th("Entry", className="small"),
@ -158,6 +159,7 @@ class DashboardComponentManager:
if hasattr(trade, 'entry_time'):
# This is a trade object
entry_time = getattr(trade, 'entry_time', 'Unknown')
exit_time = getattr(trade, 'exit_time', 'Unknown')
side = getattr(trade, 'side', 'UNKNOWN')
size = getattr(trade, 'size', 0)
entry_price = getattr(trade, 'entry_price', 0)
@ -168,6 +170,7 @@ class DashboardComponentManager:
else:
# This is a dictionary format
entry_time = trade.get('entry_time', 'Unknown')
exit_time = trade.get('exit_time', 'Unknown')
side = trade.get('side', 'UNKNOWN')
size = trade.get('quantity', trade.get('size', 0)) # Try 'quantity' first, then 'size'
entry_price = trade.get('entry_price', 0)
@ -176,11 +179,17 @@ class DashboardComponentManager:
fees = trade.get('fees', 0)
hold_time_seconds = trade.get('hold_time_seconds', 0.0)
# Format time
# Format entry time
if isinstance(entry_time, datetime):
time_str = entry_time.strftime('%H:%M:%S')
entry_time_str = entry_time.strftime('%H:%M:%S')
else:
time_str = str(entry_time)
entry_time_str = str(entry_time)
# Format exit time
if isinstance(exit_time, datetime):
exit_time_str = exit_time.strftime('%H:%M:%S')
else:
exit_time_str = str(exit_time)
# Determine P&L color
pnl_class = "text-success" if pnl >= 0 else "text-danger"
@ -197,7 +206,8 @@ class DashboardComponentManager:
net_pnl = pnl - fees
row = html.Tr([
html.Td(time_str, className="small"),
html.Td(entry_time_str, className="small"),
html.Td(exit_time_str, className="small"),
html.Td(side, className=f"small {side_class}"),
html.Td(f"${position_size_usd:.2f}", className="small"), # Show size in USD
html.Td(f"${entry_price:.2f}", className="small"),
@ -714,11 +724,11 @@ class DashboardComponentManager:
"""Format training metrics for display - Enhanced with loaded models"""
try:
# DEBUG: Log what we're receiving
logger.debug(f"format_training_metrics received: {type(metrics_data)}")
logger.info(f"format_training_metrics received: {type(metrics_data)}")
if metrics_data:
logger.debug(f"Metrics keys: {list(metrics_data.keys()) if isinstance(metrics_data, dict) else 'Not a dict'}")
logger.info(f"Metrics keys: {list(metrics_data.keys()) if isinstance(metrics_data, dict) else 'Not a dict'}")
if isinstance(metrics_data, dict) and 'loaded_models' in metrics_data:
logger.debug(f"Loaded models: {list(metrics_data['loaded_models'].keys())}")
logger.info(f"Loaded models: {list(metrics_data['loaded_models'].keys())}")
if not metrics_data or 'error' in metrics_data:
logger.warning(f"No training data or error in metrics_data: {metrics_data}")
@ -772,6 +782,7 @@ class DashboardComponentManager:
checkpoint_status = "LOADED" if model_info.get('checkpoint_loaded', False) else "FRESH"
# Model card
logger.info(f"Creating model card for {model_name} with toggles: inference={model_info.get('inference_enabled', True)}, training={model_info.get('training_enabled', True)}")
model_card = html.Div([
# Header with model name and toggle
html.Div([
@ -1043,10 +1054,15 @@ class DashboardComponentManager:
html.Span(f"{enhanced_stats['recent_validation_score']:.3f}", className="text-primary small fw-bold")
], className="mb-1"))
logger.info(f"format_training_metrics returning {len(content)} components")
for i, component in enumerate(content[:3]): # Log first 3 components
logger.info(f" Component {i}: {type(component)}")
return content
except Exception as e:
logger.error(f"Error formatting training metrics: {e}")
import traceback
logger.error(f"Traceback: {traceback.format_exc()}")
return [html.P(f"Error: {str(e)}", className="text-danger small")]
def _format_cnn_pivot_prediction(self, model_info):