PnL in reward, show leveraged power in dash (broken)
This commit is contained in:
@ -964,6 +964,7 @@ class CleanTradingDashboard:
|
||||
)
|
||||
def update_metrics(n):
|
||||
"""Update key metrics - ENHANCED with position sync monitoring"""
|
||||
logger.debug(f"update_metrics callback triggered (n={n})")
|
||||
try:
|
||||
# PERIODIC POSITION SYNC: Every 30 seconds, verify position sync
|
||||
if n % 30 == 0 and n > 0: # Skip initial load (n=0)
|
||||
@ -1102,7 +1103,14 @@ class CleanTradingDashboard:
|
||||
# For simulation, show starting balance + session P&L
|
||||
current_balance = self._cached_live_balance if hasattr(self, '_cached_live_balance') else self._get_initial_balance()
|
||||
portfolio_value = current_balance + total_session_pnl # Live balance + unrealized P&L
|
||||
portfolio_str = f"${portfolio_value:.2f}"
|
||||
|
||||
# Add max position info to portfolio display
|
||||
try:
|
||||
max_position_info = self._calculate_max_position_display()
|
||||
portfolio_str = f"${portfolio_value:.2f} | {max_position_info}"
|
||||
except Exception as e:
|
||||
logger.error(f"Error calculating max position display: {e}")
|
||||
portfolio_str = f"${portfolio_value:.2f}"
|
||||
|
||||
# Profitability multiplier - get from trading executor
|
||||
profitability_multiplier = 0.0
|
||||
@ -1352,6 +1360,11 @@ class CleanTradingDashboard:
|
||||
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
|
||||
@ -1646,6 +1659,38 @@ class CleanTradingDashboard:
|
||||
logger.debug(f"Error calculating opening fee: {e}")
|
||||
return position_size_usd * 0.0006 # Fallback to 0.06%
|
||||
|
||||
def _calculate_max_position_display(self) -> str:
|
||||
"""Calculate and display maximum position size based on current balance and leverage"""
|
||||
try:
|
||||
# Get current balance
|
||||
current_balance = self._get_live_account_balance()
|
||||
if current_balance <= 0:
|
||||
return "No Balance"
|
||||
|
||||
# Get current leverage
|
||||
leverage = getattr(self, 'current_leverage', 50) # Default to 50x
|
||||
|
||||
# Get current price for ETH/USDT
|
||||
current_price = self._get_current_price('ETH/USDT')
|
||||
if not current_price or current_price <= 0:
|
||||
return "Price N/A"
|
||||
|
||||
# Calculate maximum position value (balance * leverage)
|
||||
max_position_value = current_balance * leverage
|
||||
|
||||
# Calculate maximum ETH quantity
|
||||
max_eth_quantity = max_position_value / current_price
|
||||
|
||||
# Format display
|
||||
if max_eth_quantity >= 0.01: # Show in ETH if >= 0.01
|
||||
return f"${max_position_value:.1f} ({max_eth_quantity:.2f} ETH)"
|
||||
else:
|
||||
return f"${max_position_value:.1f} ({max_eth_quantity:.4f} ETH)"
|
||||
|
||||
except Exception as e:
|
||||
logger.debug(f"Error calculating max position display: {e}")
|
||||
return "Calc Error"
|
||||
|
||||
def _calculate_closing_fee(self, current_price: float, quantity: float) -> float:
|
||||
"""Calculate closing fee for a position at current price"""
|
||||
try:
|
||||
@ -3532,11 +3577,22 @@ class CleanTradingDashboard:
|
||||
if self.orchestrator and hasattr(self.orchestrator, 'get_model_states'):
|
||||
try:
|
||||
model_states = self.orchestrator.get_model_states()
|
||||
logger.debug(f"Retrieved model states from orchestrator: {model_states}")
|
||||
logger.debug(f"Retrieved model states from orchestrator: {list(model_states.keys()) if model_states else 'None'}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting model states from orchestrator: {e}")
|
||||
model_states = None
|
||||
|
||||
# Also try to get orchestrator statistics for debugging
|
||||
if self.orchestrator:
|
||||
try:
|
||||
all_stats = self.orchestrator.get_model_statistics()
|
||||
if all_stats:
|
||||
logger.debug(f"Available orchestrator statistics: {list(all_stats.keys())}")
|
||||
else:
|
||||
logger.debug("No orchestrator statistics available")
|
||||
except Exception as e:
|
||||
logger.debug(f"Error getting orchestrator statistics: {e}")
|
||||
|
||||
# Fallback if orchestrator not available or returns None
|
||||
if model_states is None:
|
||||
logger.warning("No model states available from orchestrator, using fallback")
|
||||
@ -3549,6 +3605,26 @@ class CleanTradingDashboard:
|
||||
'decision': {'initial_loss': None, 'current_loss': None, 'best_loss': None, 'checkpoint_loaded': False}
|
||||
}
|
||||
|
||||
# Create mapping for model states to handle both old and new model names
|
||||
if model_states and self.orchestrator:
|
||||
# Map new registry names to old dashboard names for compatibility
|
||||
registry_to_dashboard_mapping = {
|
||||
'dqn_agent': 'dqn',
|
||||
'enhanced_cnn': 'cnn',
|
||||
'cob_rl_model': 'cob_rl',
|
||||
'decision_fusion': 'decision_fusion',
|
||||
'transformer': 'transformer'
|
||||
}
|
||||
|
||||
# Copy states from new names to old names if they exist
|
||||
for registry_name, dashboard_name in registry_to_dashboard_mapping.items():
|
||||
if registry_name in model_states and dashboard_name not in model_states:
|
||||
model_states[dashboard_name] = model_states[registry_name]
|
||||
logger.debug(f"Mapped model state {registry_name} -> {dashboard_name}")
|
||||
elif dashboard_name not in model_states:
|
||||
# Ensure we have a state for the dashboard name
|
||||
model_states[dashboard_name] = {'initial_loss': None, 'current_loss': None, 'best_loss': None, 'checkpoint_loaded': False}
|
||||
|
||||
# Get latest predictions from all models
|
||||
latest_predictions = self._get_latest_model_predictions()
|
||||
cnn_prediction = self._get_cnn_pivot_prediction()
|
||||
@ -3598,6 +3674,23 @@ class CleanTradingDashboard:
|
||||
"transformer": {"inference_enabled": True, "training_enabled": True}
|
||||
}
|
||||
|
||||
# Create mapping for backward compatibility between old dashboard names and new registry names
|
||||
model_name_mapping = {
|
||||
'dqn': 'dqn_agent',
|
||||
'cnn': 'enhanced_cnn',
|
||||
'cob_rl': 'cob_rl_model',
|
||||
'decision_fusion': 'decision_fusion',
|
||||
'transformer': 'transformer'
|
||||
}
|
||||
|
||||
# Ensure we have toggle states for the old names used by the dashboard
|
||||
for old_name, new_name in model_name_mapping.items():
|
||||
if old_name not in toggle_states and new_name in toggle_states:
|
||||
toggle_states[old_name] = toggle_states[new_name]
|
||||
elif old_name not in toggle_states:
|
||||
# Default state if neither old nor new name exists
|
||||
toggle_states[old_name] = {"inference_enabled": True, "training_enabled": True}
|
||||
|
||||
# Helper function to safely calculate improvement percentage
|
||||
def safe_improvement_calc(initial, current, default_improvement=0.0):
|
||||
try:
|
||||
@ -3705,8 +3798,8 @@ class CleanTradingDashboard:
|
||||
last_confidence = 0.68
|
||||
last_timestamp = datetime.now().strftime('%H:%M:%S')
|
||||
|
||||
# Get real DQN statistics from orchestrator
|
||||
dqn_stats = orchestrator_stats.get('dqn_agent')
|
||||
# Get real DQN statistics from orchestrator (try both old and new names)
|
||||
dqn_stats = orchestrator_stats.get('dqn_agent') or orchestrator_stats.get('dqn')
|
||||
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
|
||||
@ -3786,8 +3879,8 @@ class CleanTradingDashboard:
|
||||
cnn_state = model_states.get('cnn', {})
|
||||
cnn_timing = get_model_timing_info('CNN')
|
||||
|
||||
# Get real CNN statistics from orchestrator
|
||||
cnn_stats = orchestrator_stats.get('enhanced_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')
|
||||
cnn_active = cnn_stats is not None
|
||||
|
||||
# Get latest CNN prediction from orchestrator statistics
|
||||
@ -4153,12 +4246,15 @@ class CleanTradingDashboard:
|
||||
|
||||
# DEBUG: Log what we're returning
|
||||
models_count = len(metrics.get('loaded_models', {}))
|
||||
logger.info(f"Training metrics being returned: {models_count} models loaded")
|
||||
logger.debug(f"Training metrics being returned: {models_count} models loaded")
|
||||
if models_count == 0:
|
||||
logger.warning("No models in loaded_models!")
|
||||
logger.warning(f"Metrics keys: {list(metrics.keys())}")
|
||||
for model_name, model_info in metrics.get('loaded_models', {}).items():
|
||||
logger.info(f"Model {model_name}: active={model_info.get('active', False)}, checkpoint_loaded={model_info.get('checkpoint_loaded', False)}")
|
||||
logger.warning(f"Model states available: {list(model_states.keys()) if model_states else 'None'}")
|
||||
logger.warning(f"Toggle states available: {list(toggle_states.keys()) if toggle_states else 'None'}")
|
||||
else:
|
||||
for model_name, model_info in metrics.get('loaded_models', {}).items():
|
||||
logger.debug(f"Model {model_name}: active={model_info.get('active', False)}, checkpoint_loaded={model_info.get('checkpoint_loaded', False)}")
|
||||
|
||||
return metrics
|
||||
|
||||
|
Reference in New Issue
Block a user