fixed cob

This commit is contained in:
Dobromir Popov
2025-07-07 01:44:16 +03:00
parent c2c0e12a4b
commit 271e7d59b5
3 changed files with 113 additions and 6 deletions

View File

@ -514,8 +514,11 @@ class CleanTradingDashboard:
eth_imbalance_stats = self._calculate_cumulative_imbalance('ETH/USDT') eth_imbalance_stats = self._calculate_cumulative_imbalance('ETH/USDT')
btc_imbalance_stats = self._calculate_cumulative_imbalance('BTC/USDT') btc_imbalance_stats = self._calculate_cumulative_imbalance('BTC/USDT')
eth_components = self.component_manager.format_cob_data(eth_snapshot, 'ETH/USDT', eth_imbalance_stats) # Determine COB data source mode
btc_components = self.component_manager.format_cob_data(btc_snapshot, 'BTC/USDT', btc_imbalance_stats) cob_mode = self._get_cob_mode()
eth_components = self.component_manager.format_cob_data(eth_snapshot, 'ETH/USDT', eth_imbalance_stats, cob_mode)
btc_components = self.component_manager.format_cob_data(btc_snapshot, 'BTC/USDT', btc_imbalance_stats, cob_mode)
return eth_components, btc_components return eth_components, btc_components
@ -580,6 +583,34 @@ class CleanTradingDashboard:
return f"x{leverage_value}" return f"x{leverage_value}"
return "x50" return "x50"
# Entry Aggressiveness slider callback
@self.app.callback(
Output('entry-agg-display', 'children'),
[Input('entry-aggressiveness-slider', 'value')]
)
def update_entry_aggressiveness_display(agg_value):
"""Update entry aggressiveness display and orchestrator setting"""
if agg_value is not None:
# Update orchestrator's entry aggressiveness
if self.orchestrator:
self.orchestrator.entry_aggressiveness = agg_value
return f"{agg_value:.1f}"
return "0.5"
# Exit Aggressiveness slider callback
@self.app.callback(
Output('exit-agg-display', 'children'),
[Input('exit-aggressiveness-slider', 'value')]
)
def update_exit_aggressiveness_display(agg_value):
"""Update exit aggressiveness display and orchestrator setting"""
if agg_value is not None:
# Update orchestrator's exit aggressiveness
if self.orchestrator:
self.orchestrator.exit_aggressiveness = agg_value
return f"{agg_value:.1f}"
return "0.5"
# Clear session button # Clear session button
@self.app.callback( @self.app.callback(
Output('clear-session-btn', 'children'), Output('clear-session-btn', 'children'),
@ -1953,6 +1984,27 @@ class CleanTradingDashboard:
except Exception as e: except Exception as e:
logger.warning(f"Error getting COB snapshot for {symbol}: {e}") logger.warning(f"Error getting COB snapshot for {symbol}: {e}")
return None return None
def _get_cob_mode(self) -> str:
"""Get current COB data collection mode"""
try:
# Check if orchestrator COB integration is working
if hasattr(self.orchestrator, 'cob_integration') and self.orchestrator.cob_integration:
# Try to get a snapshot from orchestrator
snapshot = self.orchestrator.cob_integration.get_cob_snapshot('ETH/USDT')
if snapshot and hasattr(snapshot, 'consolidated_bids') and snapshot.consolidated_bids:
return "WS" # WebSocket/Advanced mode
# Check if fallback data is available
if hasattr(self, 'latest_cob_data') and 'ETH/USDT' in self.latest_cob_data:
if self.latest_cob_data['ETH/USDT']:
return "REST" # REST API fallback mode
return "None" # No data available
except Exception as e:
logger.debug(f"Error determining COB mode: {e}")
return "Error"
def _get_enhanced_training_stats(self) -> Dict[str, Any]: def _get_enhanced_training_stats(self) -> Dict[str, Any]:
"""Get enhanced training statistics from the training system and orchestrator""" """Get enhanced training statistics from the training system and orchestrator"""

View File

@ -272,13 +272,14 @@ class DashboardComponentManager:
logger.error(f"Error formatting system status: {e}") logger.error(f"Error formatting system status: {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(self, cob_snapshot, symbol, cumulative_imbalance_stats=None): def format_cob_data(self, cob_snapshot, symbol, cumulative_imbalance_stats=None, cob_mode="Unknown"):
"""Format COB data into a split view with summary, imbalance stats, and a compact ladder.""" """Format COB data into a split view with summary, imbalance stats, and a compact ladder."""
try: try:
if not cob_snapshot: if not cob_snapshot:
return html.Div([ return html.Div([
html.H6(f"{symbol} COB", className="mb-2"), html.H6(f"{symbol} COB", className="mb-2"),
html.P("No COB data available", className="text-muted small") html.P("No COB data available", className="text-muted small"),
html.P(f"Mode: {cob_mode}", className="text-muted small")
]) ])
# Handle both old format (with stats attribute) and new format (direct attributes) # Handle both old format (with stats attribute) and new format (direct attributes)
@ -316,7 +317,7 @@ class DashboardComponentManager:
} }
# --- Left Panel: Overview and Stats --- # --- Left Panel: Overview and Stats ---
overview_panel = self._create_cob_overview_panel(symbol, stats, cumulative_imbalance_stats) overview_panel = self._create_cob_overview_panel(symbol, stats, cumulative_imbalance_stats, cob_mode)
# --- Right Panel: Compact Ladder --- # --- Right Panel: Compact Ladder ---
ladder_panel = self._create_cob_ladder_panel(bids, asks, mid_price, symbol) ladder_panel = self._create_cob_ladder_panel(bids, asks, mid_price, symbol)
@ -330,7 +331,7 @@ class DashboardComponentManager:
logger.error(f"Error formatting split COB data: {e}") logger.error(f"Error formatting split 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 _create_cob_overview_panel(self, symbol, stats, cumulative_imbalance_stats): def _create_cob_overview_panel(self, symbol, stats, cumulative_imbalance_stats, cob_mode="Unknown"):
"""Creates the left panel with summary and imbalance stats.""" """Creates the left panel with summary and imbalance stats."""
mid_price = stats.get('mid_price', 0) mid_price = stats.get('mid_price', 0)
spread_bps = stats.get('spread_bps', 0) spread_bps = stats.get('spread_bps', 0)
@ -342,6 +343,10 @@ class DashboardComponentManager:
imbalance_text = f"Bid Heavy ({imbalance:.3f})" if imbalance > 0 else f"Ask Heavy ({imbalance:.3f})" imbalance_text = f"Bid Heavy ({imbalance:.3f})" if imbalance > 0 else f"Ask Heavy ({imbalance:.3f})"
imbalance_color = "text-success" if imbalance > 0 else "text-danger" imbalance_color = "text-success" if imbalance > 0 else "text-danger"
# COB mode indicator
mode_color = "text-success" if cob_mode == "WS" else "text-warning" if cob_mode == "REST" else "text-muted"
mode_icon = "fas fa-wifi" if cob_mode == "WS" else "fas fa-globe" if cob_mode == "REST" else "fas fa-question"
imbalance_stats_display = [] imbalance_stats_display = []
if cumulative_imbalance_stats: if cumulative_imbalance_stats:
imbalance_stats_display.append(html.H6("Cumulative Imbalance", className="mt-3 mb-2 small text-muted text-uppercase")) imbalance_stats_display.append(html.H6("Cumulative Imbalance", className="mt-3 mb-2 small text-muted text-uppercase"))
@ -350,6 +355,12 @@ class DashboardComponentManager:
return html.Div([ return html.Div([
html.H6(f"{symbol} - COB Overview", className="mb-2"), html.H6(f"{symbol} - COB Overview", className="mb-2"),
html.Div([
html.Span([
html.I(className=f"{mode_icon} me-1 {mode_color}"),
html.Span(f"Mode: {cob_mode}", className=f"small {mode_color}")
], className="mb-2")
]),
html.Div([ html.Div([
self._create_stat_card("Mid Price", f"${mid_price:,.2f}", "fas fa-dollar-sign"), self._create_stat_card("Mid Price", f"${mid_price:,.2f}", "fas fa-dollar-sign"),
self._create_stat_card("Spread", f"{spread_bps:.1f} bps", "fas fa-arrows-alt-h") self._create_stat_card("Spread", f"{spread_bps:.1f} bps", "fas fa-arrows-alt-h")

View File

@ -145,6 +145,50 @@ class DashboardLayoutManager:
) )
], className="mb-2"), ], className="mb-2"),
# Entry Aggressiveness Control
html.Div([
html.Label([
html.I(className="fas fa-bullseye me-1"),
"Entry Aggressiveness: ",
html.Span(id="entry-agg-display", children="0.5", className="fw-bold text-success")
], className="form-label small mb-1"),
dcc.Slider(
id='entry-aggressiveness-slider',
min=0.0,
max=1.0,
step=0.1,
value=0.5,
marks={
0.0: {'label': 'Conservative', 'style': {'fontSize': '7px'}},
0.5: {'label': 'Balanced', 'style': {'fontSize': '7px'}},
1.0: {'label': 'Aggressive', 'style': {'fontSize': '7px'}}
},
tooltip={"placement": "bottom", "always_visible": False}
)
], className="mb-2"),
# Exit Aggressiveness Control
html.Div([
html.Label([
html.I(className="fas fa-sign-out-alt me-1"),
"Exit Aggressiveness: ",
html.Span(id="exit-agg-display", children="0.5", className="fw-bold text-danger")
], className="form-label small mb-1"),
dcc.Slider(
id='exit-aggressiveness-slider',
min=0.0,
max=1.0,
step=0.1,
value=0.5,
marks={
0.0: {'label': 'Conservative', 'style': {'fontSize': '7px'}},
0.5: {'label': 'Balanced', 'style': {'fontSize': '7px'}},
1.0: {'label': 'Aggressive', 'style': {'fontSize': '7px'}}
},
tooltip={"placement": "bottom", "always_visible": False}
)
], className="mb-2"),
html.Button([ html.Button([
html.I(className="fas fa-trash me-1"), html.I(className="fas fa-trash me-1"),
"Clear Session" "Clear Session"