fixes
This commit is contained in:
@ -170,6 +170,9 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
|||||||
self.williams_features = {} # Symbol -> Williams features
|
self.williams_features = {} # Symbol -> Williams features
|
||||||
self.symbol_correlation_matrix = {} # Pre-computed correlations
|
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
|
# Initialize COB Integration for real-time market microstructure
|
||||||
# PROPERLY INITIALIZED: Create the COB integration instance synchronously
|
# PROPERLY INITIALIZED: Create the COB integration instance synchronously
|
||||||
try:
|
try:
|
||||||
@ -2478,7 +2481,7 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
|||||||
threshold_type = "ENTRY"
|
threshold_type = "ENTRY"
|
||||||
|
|
||||||
# For entries, check if CNN predicts favorable pivot
|
# 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:
|
try:
|
||||||
# Get market data for CNN analysis
|
# Get market data for CNN analysis
|
||||||
current_price = market_state.prices.get(self.timeframes[0], 0)
|
current_price = market_state.prices.get(self.timeframes[0], 0)
|
||||||
@ -2524,7 +2527,7 @@ class EnhancedTradingOrchestrator(TradingOrchestrator):
|
|||||||
'action_type': threshold_type,
|
'action_type': threshold_type,
|
||||||
'threshold_used': threshold,
|
'threshold_used': threshold,
|
||||||
'pivot_enhanced': True,
|
'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)
|
'timeframe_breakdown': [(tf.timeframe, tf.action, tf.confidence)
|
||||||
for tf in best_pred.timeframe_predictions],
|
for tf in best_pred.timeframe_predictions],
|
||||||
'market_regime': market_state.market_regime
|
'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"}),
|
], className="card bg-light", style={"height": "60px"}),
|
||||||
], style={"display": "grid", "gridTemplateColumns": "repeat(4, 1fr)", "gap": "8px", "width": "60%"}),
|
], 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([
|
html.Div([
|
||||||
|
# Recent Trading Signals Column (50%)
|
||||||
html.Div([
|
html.Div([
|
||||||
html.H6([
|
html.Div([
|
||||||
html.I(className="fas fa-robot me-2"),
|
html.H6([
|
||||||
"Recent Trading Signals & Executions"
|
html.I(className="fas fa-robot me-2"),
|
||||||
], className="card-title mb-2"),
|
"Recent Trading Signals"
|
||||||
html.Div(id="recent-decisions", style={"height": "160px", "overflowY": "auto"})
|
], className="card-title mb-2"),
|
||||||
], className="card-body p-2")
|
html.Div(id="recent-decisions", style={"height": "160px", "overflowY": "auto"})
|
||||||
], className="card", style={"width": "48%", "marginLeft": "2%"})
|
], 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"),
|
], className="d-flex mb-3"),
|
||||||
|
|
||||||
# Charts row - More compact
|
# Charts row - Now full width since training moved up
|
||||||
html.Div([
|
html.Div([
|
||||||
# Price chart - 70% width
|
# Price chart - Full width
|
||||||
html.Div([
|
html.Div([
|
||||||
html.Div([
|
html.Div([
|
||||||
html.H6([
|
html.H6([
|
||||||
@ -864,18 +878,7 @@ class TradingDashboard:
|
|||||||
], className="card-title mb-2"),
|
], className="card-title mb-2"),
|
||||||
dcc.Graph(id="price-chart", style={"height": "400px"})
|
dcc.Graph(id="price-chart", style={"height": "400px"})
|
||||||
], className="card-body p-2")
|
], className="card-body p-2")
|
||||||
], className="card", style={"width": "70%"}),
|
], className="card", style={"width": "100%"}),
|
||||||
|
|
||||||
# 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="row g-2 mb-3"),
|
], className="row g-2 mb-3"),
|
||||||
|
|
||||||
# CNN Model Monitoring & COB Integration - MERGED into 1 row with 4 columns
|
# 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")
|
return self._create_empty_chart("Chart Error", "Chart temporarily unavailable")
|
||||||
|
|
||||||
def _create_training_metrics_cached(self):
|
def _create_training_metrics_cached(self):
|
||||||
"""Cached training metrics with reduced computation"""
|
"""Enhanced training metrics with COB $1 buckets"""
|
||||||
try:
|
try:
|
||||||
return [
|
content = []
|
||||||
html.H6("Training Status", className="text-success"),
|
|
||||||
html.P(f"Models Active: {len(getattr(self.model_registry, 'models', {})) if self.model_registry else 0}",
|
# Training Status Section
|
||||||
className="text-muted small"),
|
content.append(html.H6("Training Status", className="text-success mb-2"))
|
||||||
html.P(f"Last Update: {datetime.now().strftime('%H:%M:%S')}",
|
content.append(html.P(f"Models Active: {len(getattr(self.model_registry, 'models', {})) if self.model_registry else 0}",
|
||||||
className="text-muted small")
|
className="text-muted small"))
|
||||||
]
|
content.append(html.P(f"Last Update: {datetime.now().strftime('%H:%M:%S')}",
|
||||||
except:
|
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")]
|
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):
|
def _create_decisions_list_cached(self):
|
||||||
"""Cached decisions list with limited entries"""
|
"""Cached decisions list with limited entries"""
|
||||||
|
Reference in New Issue
Block a user