Merge commit 'd49a473ed6f4aef55bfdd47d6370e53582be6b7b' into cleanup
This commit is contained in:
@@ -10,11 +10,13 @@ from datetime import datetime
|
||||
class DashboardLayoutManager:
|
||||
"""Manages dashboard layout and structure"""
|
||||
|
||||
def __init__(self, starting_balance: float = 100.0, trading_executor=None):
|
||||
def __init__(self, starting_balance: float = 100.0, trading_executor=None, dashboard=None):
|
||||
self.starting_balance = starting_balance
|
||||
self.trading_executor = trading_executor
|
||||
self.dashboard = dashboard
|
||||
|
||||
def create_main_layout(self):
|
||||
<<<<<<< HEAD
|
||||
"""Create the main dashboard layout with dark theme"""
|
||||
return html.Div([
|
||||
self._create_header(),
|
||||
@@ -27,6 +29,35 @@ class DashboardLayoutManager:
|
||||
"minHeight": "100vh",
|
||||
"color": "#f8f9fa"
|
||||
})
|
||||
=======
|
||||
"""Create the main dashboard layout"""
|
||||
try:
|
||||
print("Creating main layout...")
|
||||
header = self._create_header()
|
||||
print("Header created")
|
||||
interval_component = self._create_interval_component()
|
||||
print("Interval component created")
|
||||
main_content = self._create_main_content()
|
||||
print("Main content created")
|
||||
|
||||
layout = html.Div([
|
||||
header,
|
||||
interval_component,
|
||||
main_content
|
||||
], className="container-fluid")
|
||||
|
||||
print("Main layout created successfully")
|
||||
return layout
|
||||
except Exception as e:
|
||||
print(f"Error creating main layout: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
# Return a simple error layout
|
||||
return html.Div([
|
||||
html.H1("Dashboard Error", className="text-danger"),
|
||||
html.P(f"Error creating layout: {str(e)}", className="text-danger")
|
||||
])
|
||||
>>>>>>> d49a473ed6f4aef55bfdd47d6370e53582be6b7b
|
||||
|
||||
def _create_prediction_tracking_section(self):
|
||||
"""Create prediction tracking and model performance section"""
|
||||
@@ -248,7 +279,7 @@ class DashboardLayoutManager:
|
||||
"Clean Trading Dashboard"
|
||||
], className="text-light mb-0"),
|
||||
html.P(
|
||||
f"Ultra-Fast Updates • Portfolio: ${self.starting_balance:,.0f} • {trading_mode}",
|
||||
f"Ultra-Fast Updates • Live Account Balance Sync • {trading_mode}",
|
||||
className="text-light mb-0 opacity-75 small"
|
||||
)
|
||||
], className="bg-dark p-2 mb-2")
|
||||
@@ -261,6 +292,7 @@ class DashboardLayoutManager:
|
||||
], className="bg-dark p-2 mb-2")
|
||||
|
||||
def _create_interval_component(self):
|
||||
<<<<<<< HEAD
|
||||
"""Create the auto-refresh interval component"""
|
||||
return html.Div([
|
||||
dcc.Interval(
|
||||
@@ -273,6 +305,32 @@ class DashboardLayoutManager:
|
||||
interval=60000, # Update every 60 seconds for chained inference
|
||||
n_intervals=0
|
||||
)
|
||||
=======
|
||||
"""Create the auto-refresh interval components with different frequencies"""
|
||||
return html.Div([
|
||||
# Fast interval for critical updates (2 seconds - reduced from 1s)
|
||||
dcc.Interval(
|
||||
id='interval-component',
|
||||
interval=2000, # Update every 2000 ms (0.5 Hz) - OPTIMIZED
|
||||
n_intervals=0
|
||||
),
|
||||
# Slow interval for non-critical updates (10 seconds - increased from 5s)
|
||||
dcc.Interval(
|
||||
id='slow-interval-component',
|
||||
interval=10000, # Update every 10 seconds (0.1 Hz) - OPTIMIZED
|
||||
n_intervals=0,
|
||||
disabled=False
|
||||
),
|
||||
# Fast interval for testing (5 seconds)
|
||||
dcc.Interval(
|
||||
id='fast-interval-component',
|
||||
interval=5000, # Update every 5 seconds for testing
|
||||
n_intervals=0,
|
||||
disabled=False
|
||||
),
|
||||
# WebSocket-based updates for high-frequency data (no interval needed)
|
||||
html.Div(id='websocket-updates-container', style={'display': 'none'})
|
||||
>>>>>>> d49a473ed6f4aef55bfdd47d6370e53582be6b7b
|
||||
])
|
||||
|
||||
def _create_main_content(self):
|
||||
@@ -297,6 +355,25 @@ class DashboardLayoutManager:
|
||||
|
||||
def _create_metrics_grid(self):
|
||||
"""Create the metrics grid with compact cards"""
|
||||
# Get exchange name dynamically
|
||||
exchange_name = "Exchange"
|
||||
if self.trading_executor:
|
||||
if hasattr(self.trading_executor, 'primary_name'):
|
||||
exchange_name = self.trading_executor.primary_name.upper()
|
||||
elif hasattr(self.trading_executor, 'exchange') and self.trading_executor.exchange:
|
||||
# Try to get exchange name from exchange interface
|
||||
exchange_class_name = self.trading_executor.exchange.__class__.__name__
|
||||
if 'Bybit' in exchange_class_name:
|
||||
exchange_name = "BYBIT"
|
||||
elif 'Mexc' in exchange_class_name or 'MEXC' in exchange_class_name:
|
||||
exchange_name = "MEXC"
|
||||
elif 'Binance' in exchange_class_name:
|
||||
exchange_name = "BINANCE"
|
||||
elif 'Deribit' in exchange_class_name:
|
||||
exchange_name = "DERIBIT"
|
||||
else:
|
||||
exchange_name = "EXCHANGE"
|
||||
|
||||
metrics_cards = [
|
||||
("current-price", "Live Price", "text-success"),
|
||||
("session-pnl", "Session P&L", ""),
|
||||
@@ -304,7 +381,9 @@ class DashboardLayoutManager:
|
||||
# ("leverage-info", "Leverage", "text-primary"),
|
||||
("trade-count", "Trades", "text-warning"),
|
||||
("portfolio-value", "Portfolio", "text-secondary"),
|
||||
("mexc-status", "MEXC API", "text-info")
|
||||
("profitability-multiplier", "Profit Boost", "text-primary"),
|
||||
("cob-websocket-status", "COB WebSocket", "text-warning"),
|
||||
("mexc-status", f"{exchange_name} API", "text-info")
|
||||
]
|
||||
|
||||
cards = []
|
||||
@@ -356,7 +435,64 @@ class DashboardLayoutManager:
|
||||
"Session Controls"
|
||||
], className="card-title mb-2"),
|
||||
|
||||
# Trading Agent Mode Toggle
|
||||
html.Div([
|
||||
html.Label([
|
||||
html.I(className="fas fa-robot me-1"),
|
||||
"Trading Agent: ",
|
||||
html.Span(
|
||||
id="trading-mode-display",
|
||||
children="LIVE" if getattr(self.dashboard, 'trading_mode_live', False) else "SIM",
|
||||
className="fw-bold text-danger" if getattr(self.dashboard, 'trading_mode_live', False) else "fw-bold text-warning"
|
||||
)
|
||||
], className="form-label small mb-1"),
|
||||
dcc.Checklist(
|
||||
id='trading-mode-switch',
|
||||
options=[{'label': '', 'value': 'live'}],
|
||||
value=['live'] if getattr(self.dashboard, 'trading_mode_live', False) else [],
|
||||
className="form-check-input"
|
||||
),
|
||||
html.Small("SIM = Simulation Mode, LIVE = Real Trading", className="text-muted d-block")
|
||||
], className="mb-2"),
|
||||
|
||||
# Cold Start Training Toggle
|
||||
html.Div([
|
||||
html.Label([
|
||||
html.I(className="fas fa-fire me-1"),
|
||||
"Cold Start Training: ",
|
||||
html.Span(
|
||||
id="cold-start-display",
|
||||
children="ON" if getattr(self.dashboard, 'cold_start_enabled', True) else "OFF",
|
||||
className="fw-bold text-success" if getattr(self.dashboard, 'cold_start_enabled', True) else "fw-bold text-secondary"
|
||||
)
|
||||
], className="form-label small mb-1"),
|
||||
dcc.Checklist(
|
||||
id='cold-start-switch',
|
||||
options=[{'label': '', 'value': 'enabled'}],
|
||||
value=['enabled'] if getattr(self.dashboard, 'cold_start_enabled', True) else [],
|
||||
className="form-check-input"
|
||||
),
|
||||
html.Small("Excessive training during cold start", className="text-muted d-block")
|
||||
], className="mb-2"),
|
||||
|
||||
html.Hr(className="my-2"),
|
||||
|
||||
# Leverage Control
|
||||
html.Div([
|
||||
html.Label([
|
||||
html.I(className="fas fa-compass me-1"),
|
||||
"Show Pivot Points: ",
|
||||
html.Span(id="pivots-display", children="ON", className="fw-bold text-success")
|
||||
], className="form-label small mb-1"),
|
||||
dcc.Checklist(
|
||||
id='show-pivots-switch',
|
||||
options=[{'label': '', 'value': 'enabled'}],
|
||||
value=['enabled'],
|
||||
className="form-check-input"
|
||||
),
|
||||
html.Small("Toggle pivot overlays on the chart", className="text-muted d-block")
|
||||
], className="mb-2"),
|
||||
|
||||
html.Div([
|
||||
html.Label([
|
||||
html.I(className="fas fa-sliders-h me-1"),
|
||||
@@ -455,6 +591,37 @@ class DashboardLayoutManager:
|
||||
html.I(className="fas fa-save me-1"),
|
||||
"Store All Models"
|
||||
], id="store-models-btn", className="btn btn-info btn-sm w-100 mt-2"),
|
||||
html.Button([
|
||||
html.I(className="fas fa-arrows-rotate me-1"),
|
||||
"Sync Positions/Orders"
|
||||
], id="manual-sync-btn", className="btn btn-primary btn-sm w-100 mt-2"),
|
||||
|
||||
# Text Export Controls
|
||||
html.Hr(className="my-2"),
|
||||
html.Small("Text Export & LLM", className="text-muted d-block mb-1"),
|
||||
html.Div([
|
||||
html.Button([
|
||||
html.I(className="fas fa-file-export me-1"),
|
||||
"Start Text Export"
|
||||
], id="start-text-export-btn", className="btn btn-success btn-sm me-1", style={"fontSize": "10px"}),
|
||||
html.Button([
|
||||
html.I(className="fas fa-stop me-1"),
|
||||
"Stop"
|
||||
], id="stop-text-export-btn", className="btn btn-danger btn-sm", style={"fontSize": "10px"})
|
||||
], className="d-flex mb-2"),
|
||||
html.Div([
|
||||
html.Button([
|
||||
html.I(className="fas fa-robot me-1"),
|
||||
"Start LLM"
|
||||
], id="start-llm-btn", className="btn btn-info btn-sm me-1", style={"fontSize": "10px"}),
|
||||
html.Button([
|
||||
html.I(className="fas fa-stop me-1"),
|
||||
"Stop"
|
||||
], id="stop-llm-btn", className="btn btn-warning btn-sm", style={"fontSize": "10px"})
|
||||
], className="d-flex mb-2"),
|
||||
html.Small(id="text-export-status", children="Export: Stopped", className="text-muted d-block"),
|
||||
html.Small(id="llm-status", children="LLM: Stopped", className="text-muted d-block"),
|
||||
|
||||
html.Hr(className="my-2"),
|
||||
html.Small("System Status", className="text-muted d-block mb-1"),
|
||||
html.Div([
|
||||
@@ -478,11 +645,12 @@ class DashboardLayoutManager:
|
||||
return html.Div([
|
||||
html.Div([
|
||||
html.Div([
|
||||
# Chart header with manual trading buttons
|
||||
# Chart header with manual trading buttons and live price
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-chart-candlestick me-2"),
|
||||
"Live 1m Price Chart (3h) + 1s Mini Chart (5min) - Updated Every Second"
|
||||
"Live Price (WebSocket): ",
|
||||
html.Span(id="chart-current-price", className="ms-2 text-primary", style={"fontWeight": "bold", "fontSize": "1.2em"})
|
||||
], className="card-title mb-0"),
|
||||
html.Div([
|
||||
html.Button([
|
||||
@@ -493,20 +661,33 @@ class DashboardLayoutManager:
|
||||
html.Button([
|
||||
html.I(className="fas fa-arrow-down me-1"),
|
||||
"SELL"
|
||||
], id="manual-sell-btn", className="btn btn-danger btn-sm",
|
||||
], id="manual-sell-btn", className="btn btn-danger btn-sm me-2",
|
||||
style={"fontSize": "10px", "padding": "2px 8px"}),
|
||||
html.Button([
|
||||
html.I(className="fas fa-times me-1"),
|
||||
"CLOSE"
|
||||
], id="manual-close-btn", className="btn btn-secondary btn-sm",
|
||||
style={"fontSize": "10px", "padding": "2px 8px"})
|
||||
], className="d-flex")
|
||||
], className="d-flex justify-content-between align-items-center mb-2"),
|
||||
|
||||
html.Div([
|
||||
dcc.Graph(id="price-chart", style={"height": "500px"})
|
||||
]),
|
||||
html.Hr(className="my-2"),
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-chart-line me-2"),
|
||||
"Polymarket vs CoinGecko (BTC/ETH, next 5 days)"
|
||||
], className="card-title mb-2"),
|
||||
dcc.Graph(id="polymarket-eth-btc-chart", style={"height": "350px"})
|
||||
])
|
||||
], className="card-body p-2")
|
||||
], className="card")
|
||||
])
|
||||
|
||||
def _create_cob_and_trades_row(self):
|
||||
"""Creates the row for COB ladders, closed trades, and model status - REORGANIZED LAYOUT"""
|
||||
"""Creates the row for COB ladders, closed trades, pending orders, and model status"""
|
||||
return html.Div([
|
||||
# Top row: COB Ladders (left) and Models/Training (right)
|
||||
html.Div([
|
||||
@@ -531,38 +712,77 @@ class DashboardLayoutManager:
|
||||
], className="d-flex")
|
||||
], style={"width": "60%"}),
|
||||
|
||||
# Right side: Models & Training Progress (40% width) - MOVED UP
|
||||
# Right side: Models & Training Progress (40% width)
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-brain me-2"),
|
||||
"Models & Training Progress",
|
||||
], className="card-title mb-2"),
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-brain me-2"),
|
||||
"Models & Training Progress",
|
||||
], className="card-title mb-2"),
|
||||
html.Button([
|
||||
html.I(className="fas fa-sync-alt me-1"),
|
||||
"Refresh"
|
||||
], id="refresh-training-metrics-btn", className="btn btn-sm btn-outline-primary")
|
||||
], className="d-flex justify-content-between align-items-center mb-2"),
|
||||
html.Div(
|
||||
id="training-metrics",
|
||||
style={"height": "300px", "overflowY": "auto"}, # Increased height
|
||||
style={"height": "300px", "overflowY": "auto"},
|
||||
),
|
||||
], className="card-body p-2")
|
||||
], className="card")
|
||||
], style={"width": "38%", "marginLeft": "2%"}),
|
||||
], className="d-flex mb-3"),
|
||||
|
||||
# Bottom row: Closed Trades (full width) - MOVED BELOW COB
|
||||
|
||||
# Mini COB Heatmaps (ETH and BTC)
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-history me-2"),
|
||||
"Recent Closed Trades",
|
||||
], className="card-title mb-2"),
|
||||
html.Div(
|
||||
id="closed-trades-table",
|
||||
style={"height": "200px", "overflowY": "auto"}, # Reduced height
|
||||
),
|
||||
], className="card-body p-2")
|
||||
], className="card")
|
||||
])
|
||||
html.H6([html.I(className="fas fa-fire me-2"), "ETH Heatmap"], className="card-title mb-2"),
|
||||
dcc.Graph(id='cob-heatmap-eth', config={'displayModeBar': False}, style={"height": "220px"})
|
||||
], className="card-body p-2", style={"flex": "1"}),
|
||||
html.Div([
|
||||
html.H6([html.I(className="fas fa-fire me-2"), "BTC Heatmap"], className="card-title mb-2"),
|
||||
dcc.Graph(id='cob-heatmap-btc', config={'displayModeBar': False}, style={"height": "220px"})
|
||||
], className="card-body p-2", style={"flex": "1", "marginLeft": "1rem"})
|
||||
], className="d-flex")
|
||||
], className="card"),
|
||||
|
||||
# Second row: Pending Orders (left) and Closed Trades (right)
|
||||
html.Div([
|
||||
# Left side: Pending Orders (40% width)
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-clock me-2"),
|
||||
"Pending Orders & Position Sync",
|
||||
], className="card-title mb-2"),
|
||||
html.Div(
|
||||
id="pending-orders-content",
|
||||
style={"height": "200px", "overflowY": "auto"},
|
||||
),
|
||||
], className="card-body p-2")
|
||||
], className="card")
|
||||
], style={"width": "40%"}),
|
||||
|
||||
# Right side: Closed Trades (58% width)
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.H6([
|
||||
html.I(className="fas fa-history me-2"),
|
||||
"Recent Closed Trades",
|
||||
], className="card-title mb-2"),
|
||||
html.Div(
|
||||
id="closed-trades-table",
|
||||
style={"height": "200px", "overflowY": "auto"},
|
||||
),
|
||||
], className="card-body p-2")
|
||||
], className="card")
|
||||
], style={"width": "58%", "marginLeft": "2%"}),
|
||||
], className="d-flex")
|
||||
])
|
||||
|
||||
def _create_analytics_and_performance_row(self):
|
||||
@@ -618,6 +838,9 @@ class DashboardLayoutManager:
|
||||
], className="card-body p-2")
|
||||
], className="card", style={"width": "30%", "marginLeft": "2%"})
|
||||
], className="d-flex")
|
||||
<<<<<<< HEAD
|
||||
|
||||
|
||||
|
||||
|
||||
=======
|
||||
>>>>>>> d49a473ed6f4aef55bfdd47d6370e53582be6b7b
|
||||
|
||||
Reference in New Issue
Block a user