From 271e7d59b5196321179557e1549309cfe37523c6 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 7 Jul 2025 01:44:16 +0300 Subject: [PATCH] fixed cob --- web/clean_dashboard.py | 56 ++++++++++++++++++++++++++++++++++++++-- web/component_manager.py | 19 +++++++++++--- web/layout_manager.py | 44 +++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/web/clean_dashboard.py b/web/clean_dashboard.py index aa4b94a..bb10a20 100644 --- a/web/clean_dashboard.py +++ b/web/clean_dashboard.py @@ -514,8 +514,11 @@ class CleanTradingDashboard: eth_imbalance_stats = self._calculate_cumulative_imbalance('ETH/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) - btc_components = self.component_manager.format_cob_data(btc_snapshot, 'BTC/USDT', btc_imbalance_stats) + # Determine COB data source mode + 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 @@ -580,6 +583,34 @@ class CleanTradingDashboard: return f"x{leverage_value}" 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 @self.app.callback( Output('clear-session-btn', 'children'), @@ -1953,6 +1984,27 @@ class CleanTradingDashboard: except Exception as e: logger.warning(f"Error getting COB snapshot for {symbol}: {e}") 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]: """Get enhanced training statistics from the training system and orchestrator""" diff --git a/web/component_manager.py b/web/component_manager.py index 069fab3..4d4ae6a 100644 --- a/web/component_manager.py +++ b/web/component_manager.py @@ -272,13 +272,14 @@ class DashboardComponentManager: logger.error(f"Error formatting system status: {e}") 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.""" try: if not cob_snapshot: return html.Div([ 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) @@ -316,7 +317,7 @@ class DashboardComponentManager: } # --- 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 --- 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}") 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.""" mid_price = stats.get('mid_price', 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_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 = [] if cumulative_imbalance_stats: 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([ 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([ 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") diff --git a/web/layout_manager.py b/web/layout_manager.py index 5102fa6..dcd0bf0 100644 --- a/web/layout_manager.py +++ b/web/layout_manager.py @@ -145,6 +145,50 @@ class DashboardLayoutManager: ) ], 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.I(className="fas fa-trash me-1"), "Clear Session"