COB integration - finally

This commit is contained in:
Dobromir Popov
2025-06-26 01:42:48 +03:00
parent 616f019855
commit 3a5a1056c4
5 changed files with 1013 additions and 336 deletions

View File

@ -140,7 +140,7 @@ class TradingOrchestrator:
from NN.models.dqn_agent import DQNAgent from NN.models.dqn_agent import DQNAgent
state_size = self.config.rl.get('state_size', 13800) # Enhanced with COB features state_size = self.config.rl.get('state_size', 13800) # Enhanced with COB features
action_size = self.config.rl.get('action_space', 3) action_size = self.config.rl.get('action_space', 3)
self.rl_agent = DQNAgent(state_size=state_size, action_size=action_size) self.rl_agent = DQNAgent(state_shape=state_size, n_actions=action_size)
# Load best checkpoint and capture initial state # Load best checkpoint and capture initial state
if hasattr(self.rl_agent, 'load_best_checkpoint'): if hasattr(self.rl_agent, 'load_best_checkpoint'):

View File

@ -117,7 +117,7 @@ class TradeDataManager:
model_inputs['price_history'] = [] model_inputs['price_history'] = []
total_features = sum(len(v) if isinstance(v, (dict, list)) else 1 for v in model_inputs.values()) total_features = sum(len(v) if isinstance(v, (dict, list)) else 1 for v in model_inputs.values())
logger.info(f" Captured {total_features} total features for cold start training") logger.info(f" Captured {total_features} total features for cold start training")
return model_inputs return model_inputs

View File

@ -180,7 +180,7 @@ def start_clean_dashboard_with_training():
time.sleep(3) time.sleep(3)
# Start dashboard server (this blocks) # Start dashboard server (this blocks)
logger.info("🚀 Starting Clean Dashboard Server...") logger.info(" Starting Clean Dashboard Server...")
dashboard.run_server(host='127.0.0.1', port=dashboard_port, debug=False) dashboard.run_server(host='127.0.0.1', port=dashboard_port, debug=False)
except KeyboardInterrupt: except KeyboardInterrupt:

File diff suppressed because it is too large Load Diff

View File

@ -336,6 +336,146 @@ class DashboardComponentManager:
logger.error(f"Error formatting COB data: {e}") logger.error(f"Error formatting COB data: {e}")
return [html.P(f"Error: {str(e)}", className="text-danger small")] return [html.P(f"Error: {str(e)}", className="text-danger small")]
def format_cob_data_with_buckets(self, cob_snapshot, symbol, price_buckets, memory_stats, bucket_size=1.0):
"""Format COB data with price buckets for high-frequency display"""
try:
components = []
# Symbol header with memory stats
buffer_count = memory_stats.get('buffer_updates', 0)
memory_count = memory_stats.get('memory_snapshots', 0)
total_updates = memory_stats.get('total_updates', 0)
components.append(html.Div([
html.Strong(f"{symbol}", className="text-info"),
html.Span(f" - High-Freq COB", className="small text-muted"),
html.Br(),
html.Span(f"Buffer: {buffer_count} | Memory: {memory_count} | Total: {total_updates}",
className="small text-success")
], className="mb-2"))
# COB snapshot data (if available)
if cob_snapshot:
if hasattr(cob_snapshot, 'volume_weighted_mid'):
# Real COB snapshot
mid_price = getattr(cob_snapshot, 'volume_weighted_mid', 0)
spread_bps = getattr(cob_snapshot, 'spread_bps', 0)
imbalance = getattr(cob_snapshot, 'liquidity_imbalance', 0)
components.append(html.Div([
html.Div([
html.I(className="fas fa-dollar-sign text-success me-2"),
html.Span(f"Mid: ${mid_price:.2f}", className="small fw-bold")
], className="mb-1"),
html.Div([
html.I(className="fas fa-arrows-alt-h text-warning me-2"),
html.Span(f"Spread: {spread_bps:.1f} bps", className="small")
], className="mb-1")
]))
# Imbalance
imbalance_color = "text-success" if imbalance > 0.1 else "text-danger" if imbalance < -0.1 else "text-muted"
imbalance_text = "Bid Heavy" if imbalance > 0.1 else "Ask Heavy" if imbalance < -0.1 else "Balanced"
components.append(html.Div([
html.I(className="fas fa-balance-scale me-2"),
html.Span(f"{imbalance_text} ({imbalance:.3f})", className=f"small {imbalance_color}")
], className="mb-2"))
else:
# Fallback for other data formats
components.append(html.Div([
html.I(className="fas fa-chart-bar text-info me-2"),
html.Span("COB: Active", className="small")
], className="mb-2"))
# Price Buckets Section
components.append(html.H6([
html.I(className="fas fa-layer-group me-2 text-primary"),
f"${bucket_size:.0f} Price Buckets (±5 levels)"
], className="mb-2"))
if price_buckets:
# Sort buckets by price
sorted_buckets = sorted(price_buckets, key=lambda x: x['price'])
bucket_rows = []
for bucket in sorted_buckets:
price = bucket['price']
total_vol = bucket['total_volume']
bid_pct = bucket['bid_pct']
ask_pct = bucket['ask_pct']
# Format volume
if total_vol > 1000000:
vol_str = f"${total_vol/1000000:.1f}M"
elif total_vol > 1000:
vol_str = f"${total_vol/1000:.0f}K"
else:
vol_str = f"${total_vol:.0f}"
# Color based on bid/ask dominance
if bid_pct > 60:
row_class = "border-success"
dominance = "BID"
dominance_class = "text-success"
elif ask_pct > 60:
row_class = "border-danger"
dominance = "ASK"
dominance_class = "text-danger"
else:
row_class = "border-secondary"
dominance = "BAL"
dominance_class = "text-muted"
bucket_row = html.Div([
html.Div([
html.Span(f"${price:.0f}", className="fw-bold me-2"),
html.Span(vol_str, className="text-info me-2"),
html.Span(f"{dominance}", className=f"small {dominance_class}")
], className="d-flex justify-content-between"),
html.Div([
# Bid bar
html.Div(
style={
"width": f"{bid_pct}%",
"height": "4px",
"backgroundColor": "#28a745",
"display": "inline-block"
}
),
# Ask bar
html.Div(
style={
"width": f"{ask_pct}%",
"height": "4px",
"backgroundColor": "#dc3545",
"display": "inline-block"
}
)
], className="mt-1")
], className=f"border {row_class} rounded p-2 mb-1 small")
bucket_rows.append(bucket_row)
components.extend(bucket_rows)
else:
components.append(html.P("No price bucket data", className="text-muted small"))
# High-frequency update rate info
components.append(html.Div([
html.Hr(),
html.Div([
html.I(className="fas fa-tachometer-alt text-info me-2"),
html.Span("High-Freq: 50-100 Hz | UI: 10 Hz", className="small text-muted")
])
]))
return components
except Exception as e:
logger.error(f"Error formatting COB data with buckets: {e}")
return [html.P(f"Error: {str(e)}", className="text-danger small")]
def format_training_metrics(self, metrics_data): def format_training_metrics(self, metrics_data):
"""Format training metrics for display - Enhanced with loaded models""" """Format training metrics for display - Enhanced with loaded models"""
try: try: