fixes
This commit is contained in:
@ -170,6 +170,9 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
||||
self.williams_features = {} # Symbol -> Williams features
|
||||
self.symbol_correlation_matrix = {} # Pre-computed correlations
|
||||
|
||||
# Initialize pivot RL trainer (if available)
|
||||
self.pivot_rl_trainer = None # Will be initialized if enhanced pivot training is needed
|
||||
|
||||
# Initialize COB Integration for real-time market microstructure
|
||||
# PROPERLY INITIALIZED: Create the COB integration instance synchronously
|
||||
try:
|
||||
@ -2478,7 +2481,7 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
||||
threshold_type = "ENTRY"
|
||||
|
||||
# For entries, check if CNN predicts favorable pivot
|
||||
if hasattr(self.pivot_rl_trainer, 'williams') and self.pivot_rl_trainer.williams.cnn_model:
|
||||
if hasattr(self, 'pivot_rl_trainer') and self.pivot_rl_trainer and hasattr(self.pivot_rl_trainer, 'williams') and self.pivot_rl_trainer.williams.cnn_model:
|
||||
try:
|
||||
# Get market data for CNN analysis
|
||||
current_price = market_state.prices.get(self.timeframes[0], 0)
|
||||
@ -2524,7 +2527,7 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
||||
'action_type': threshold_type,
|
||||
'threshold_used': threshold,
|
||||
'pivot_enhanced': True,
|
||||
'cnn_integrated': hasattr(self.pivot_rl_trainer, 'williams') and self.pivot_rl_trainer.williams.cnn_model is not None,
|
||||
'cnn_integrated': hasattr(self, 'pivot_rl_trainer') and self.pivot_rl_trainer and hasattr(self.pivot_rl_trainer, 'williams') and self.pivot_rl_trainer.williams.cnn_model is not None,
|
||||
'timeframe_breakdown': [(tf.timeframe, tf.action, tf.confidence)
|
||||
for tf in best_pred.timeframe_predictions],
|
||||
'market_regime': market_state.market_regime
|
||||
|
156
web/dashboard.py
156
web/dashboard.py
@ -841,21 +841,35 @@ class TradingDashboard:
|
||||
], className="card bg-light", style={"height": "60px"}),
|
||||
], style={"display": "grid", "gridTemplateColumns": "repeat(4, 1fr)", "gap": "8px", "width": "60%"}),
|
||||
|
||||
# Right side - Recent Signals & Executions
|
||||
# Right side - Merged: Recent Signals & Model Training - 2 columns
|
||||
html.Div([
|
||||
# Recent Trading Signals Column (50%)
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-robot me-2"),
|
||||
"Recent Trading Signals & Executions"
|
||||
], className="card-title mb-2"),
|
||||
html.Div(id="recent-decisions", style={"height": "160px", "overflowY": "auto"})
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "48%", "marginLeft": "2%"})
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-robot me-2"),
|
||||
"Recent Trading Signals"
|
||||
], className="card-title mb-2"),
|
||||
html.Div(id="recent-decisions", style={"height": "160px", "overflowY": "auto"})
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "48%"}),
|
||||
|
||||
# Model Training + COB Buckets Column (50%)
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-brain me-2"),
|
||||
"Training Progress & COB $1 Buckets"
|
||||
], className="card-title mb-2"),
|
||||
html.Div(id="training-metrics", style={"height": "160px", "overflowY": "auto"})
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "48%", "marginLeft": "4%"}),
|
||||
], style={"width": "48%", "marginLeft": "2%", "display": "flex"})
|
||||
], className="d-flex mb-3"),
|
||||
|
||||
# Charts row - More compact
|
||||
# Charts row - Now full width since training moved up
|
||||
html.Div([
|
||||
# Price chart - 70% width
|
||||
# Price chart - Full width
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
@ -864,18 +878,7 @@ class TradingDashboard:
|
||||
], className="card-title mb-2"),
|
||||
dcc.Graph(id="price-chart", style={"height": "400px"})
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "70%"}),
|
||||
|
||||
# Model Training Metrics - 30% width
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-brain me-2"),
|
||||
"Model Training Progress"
|
||||
], className="card-title mb-2"),
|
||||
html.Div(id="training-metrics", style={"height": "400px", "overflowY": "auto"})
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "28%", "marginLeft": "2%"}),
|
||||
], className="card", style={"width": "100%"}),
|
||||
], className="row g-2 mb-3"),
|
||||
|
||||
# CNN Model Monitoring & COB Integration - MERGED into 1 row with 4 columns
|
||||
@ -6070,17 +6073,108 @@ class TradingDashboard:
|
||||
return self._create_empty_chart("Chart Error", "Chart temporarily unavailable")
|
||||
|
||||
def _create_training_metrics_cached(self):
|
||||
"""Cached training metrics with reduced computation"""
|
||||
"""Enhanced training metrics with COB $1 buckets"""
|
||||
try:
|
||||
return [
|
||||
html.H6("Training Status", className="text-success"),
|
||||
html.P(f"Models Active: {len(getattr(self.model_registry, 'models', {})) if self.model_registry else 0}",
|
||||
className="text-muted small"),
|
||||
html.P(f"Last Update: {datetime.now().strftime('%H:%M:%S')}",
|
||||
className="text-muted small")
|
||||
]
|
||||
except:
|
||||
content = []
|
||||
|
||||
# Training Status Section
|
||||
content.append(html.H6("Training Status", className="text-success mb-2"))
|
||||
content.append(html.P(f"Models Active: {len(getattr(self.model_registry, 'models', {})) if self.model_registry else 0}",
|
||||
className="text-muted small"))
|
||||
content.append(html.P(f"Last Update: {datetime.now().strftime('%H:%M:%S')}",
|
||||
className="text-muted small"))
|
||||
|
||||
# COB $1 Buckets Section
|
||||
content.append(html.Hr())
|
||||
content.append(html.H6("COB $1 Buckets", className="text-info mb-2"))
|
||||
|
||||
# Get COB bucket data if available
|
||||
try:
|
||||
if hasattr(self.orchestrator, 'cob_integration') and self.orchestrator.cob_integration:
|
||||
cob_buckets = self._get_cob_dollar_buckets()
|
||||
if cob_buckets:
|
||||
# Show top 5 buckets by volume
|
||||
for i, bucket in enumerate(cob_buckets[:5]):
|
||||
price_range = f"${bucket['price']:.0f}-${bucket['price']+1:.0f}"
|
||||
volume = bucket['total_volume']
|
||||
bid_pct = (bucket['bid_volume'] / volume * 100) if volume > 0 else 0
|
||||
ask_pct = (bucket['ask_volume'] / volume * 100) if volume > 0 else 0
|
||||
|
||||
content.append(html.P([
|
||||
html.Span(price_range, className="text-warning small fw-bold"),
|
||||
html.Br(),
|
||||
html.Span(f"Vol: ${volume:,.0f} ", className="text-muted small"),
|
||||
html.Span(f"B:{bid_pct:.0f}% ", className="text-success small"),
|
||||
html.Span(f"A:{ask_pct:.0f}%", className="text-danger small")
|
||||
], className="mb-1"))
|
||||
else:
|
||||
content.append(html.P("COB buckets loading...", className="text-muted small"))
|
||||
else:
|
||||
content.append(html.P("COB integration inactive", className="text-warning small"))
|
||||
except Exception as e:
|
||||
content.append(html.P(f"COB error: {str(e)[:30]}...", className="text-danger small"))
|
||||
|
||||
return content
|
||||
|
||||
except Exception as e:
|
||||
return [html.P("Training metrics unavailable", className="text-muted")]
|
||||
|
||||
def _get_cob_dollar_buckets(self) -> List[Dict]:
|
||||
"""Get COB data grouped into $1 buckets"""
|
||||
try:
|
||||
buckets = []
|
||||
|
||||
# Get COB data for primary symbols
|
||||
for symbol in ['ETH/USDT', 'BTC/USDT']:
|
||||
if hasattr(self.orchestrator, 'cob_integration') and self.orchestrator.cob_integration:
|
||||
try:
|
||||
cob_snapshot = self.orchestrator.cob_integration.get_cob_snapshot(symbol)
|
||||
if cob_snapshot:
|
||||
mid_price = cob_snapshot.volume_weighted_mid
|
||||
|
||||
# Create $1 buckets around mid price (±$50 range)
|
||||
price_buckets = {}
|
||||
for i in range(-50, 51):
|
||||
bucket_price = int(mid_price) + i
|
||||
price_buckets[bucket_price] = {
|
||||
'price': bucket_price,
|
||||
'bid_volume': 0,
|
||||
'ask_volume': 0,
|
||||
'total_volume': 0
|
||||
}
|
||||
|
||||
# Aggregate bid data into buckets
|
||||
for level in cob_snapshot.consolidated_bids:
|
||||
bucket_price = int(level.price)
|
||||
if bucket_price in price_buckets:
|
||||
price_buckets[bucket_price]['bid_volume'] += level.total_volume_usd
|
||||
price_buckets[bucket_price]['total_volume'] += level.total_volume_usd
|
||||
|
||||
# Aggregate ask data into buckets
|
||||
for level in cob_snapshot.consolidated_asks:
|
||||
bucket_price = int(level.price)
|
||||
if bucket_price in price_buckets:
|
||||
price_buckets[bucket_price]['ask_volume'] += level.total_volume_usd
|
||||
price_buckets[bucket_price]['total_volume'] += level.total_volume_usd
|
||||
|
||||
# Convert to list and sort by volume
|
||||
symbol_buckets = [bucket for bucket in price_buckets.values() if bucket['total_volume'] > 0]
|
||||
symbol_buckets.sort(key=lambda x: x['total_volume'], reverse=True)
|
||||
|
||||
# Add symbol info and take top buckets
|
||||
for bucket in symbol_buckets[:10]:
|
||||
bucket['symbol'] = symbol
|
||||
buckets.append(bucket)
|
||||
except Exception as e:
|
||||
logger.debug(f"Error getting COB buckets for {symbol}: {e}")
|
||||
|
||||
# Sort all buckets by total volume and return top 10
|
||||
buckets.sort(key=lambda x: x['total_volume'], reverse=True)
|
||||
return buckets[:10]
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating COB dollar buckets: {e}")
|
||||
return []
|
||||
|
||||
def _create_decisions_list_cached(self):
|
||||
"""Cached decisions list with limited entries"""
|
||||
|
Reference in New Issue
Block a user