diff --git a/_dev/notes.md b/_dev/notes.md index f969db5..f7f66ac 100644 --- a/_dev/notes.md +++ b/_dev/notes.md @@ -31,3 +31,41 @@ how effective is our training? show current loss and accuracy on the chart. also >> Training what are our rewards and penalties in the RL training pipeline? reprt them so we can evaluate them and make sure they are working as expected and do improvements + + + + +>> clean dashboard + + + + + +initial dash loads 180 historical candles, but then we drop them when we get the live ones. all od them instead of just the last. so in one minute we have a 2 candles chart :) +use existing checkpoint manager if it;s not too bloated as well. otherwise re-implement clean one where we keep rotate up to 5 checkpoints - best if we can reliably measure performance, otherwise latest 5 + + +### **✅ Trading Integration** +- [ ] Recent signals show with confidence levels +- [ ] Manual BUY/SELL buttons work +- [ ] Executed vs blocked signals displayed +- [ ] Current position shows correctly +- [ ] Session P&L updates in real-time + +### **✅ COB Integration** +- [ ] System status shows "COB: Active" +- [ ] ETH/USDT COB data displays +- [ ] BTC/USDT COB data displays +- [ ] Order book metrics update + +### **✅ Training Pipeline** +- [ ] CNN model status shows "Active" +- [ ] RL model status shows "Training" +- [ ] Training metrics update +- [ ] Model performance data available + +### **✅ Performance** +- [ ] Chart updates every second +- [ ] No flickering or data loss +- [ ] WebSocket connection stable +- [ ] Memory usage reasonable \ No newline at end of file diff --git a/web/clean_dashboard.py b/web/clean_dashboard.py index 58f43aa..4abc773 100644 --- a/web/clean_dashboard.py +++ b/web/clean_dashboard.py @@ -319,23 +319,47 @@ class CleanTradingDashboard: def _create_price_chart(self, symbol: str) -> go.Figure: """Create 1-minute main chart with 1-second mini chart - Updated every second""" try: - # Get 1-minute data (main chart) - FIXED for real-time updates - # First try to create 1m bars from WebSocket 1s data + # FIXED: Merge historical + live data instead of replacing + # 1. Get historical 1-minute data as base (180 candles = 3 hours) + df_historical = self.data_provider.get_historical_data(symbol, '1m', limit=180) + + # 2. Get WebSocket 1s data and convert to 1m bars ws_data_raw = self._get_websocket_chart_data(symbol, 'raw') + df_live = None if ws_data_raw is not None and len(ws_data_raw) > 60: - # Resample 1s data to 1m bars for real-time updating 1m chart - df_main = ws_data_raw.resample('1min').agg({ + # Resample 1s data to 1m bars + df_live = ws_data_raw.resample('1min').agg({ 'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last', 'volume': 'sum' - }).dropna().tail(180) # Last 3 hours - main_source = "WebSocket 1m (Real-time)" + }).dropna() + + # 3. Merge historical + live data intelligently + if df_historical is not None and not df_historical.empty: + if df_live is not None and not df_live.empty: + # Find overlap point - where live data starts + live_start = df_live.index[0] + + # Keep historical data up to live data start + df_historical_clean = df_historical[df_historical.index < live_start] + + # Combine: historical (older) + live (newer) + df_main = pd.concat([df_historical_clean, df_live]).tail(180) + main_source = f"Historical + Live ({len(df_historical_clean)} + {len(df_live)} bars)" + else: + # No live data, use historical only + df_main = df_historical + main_source = "Historical 1m" + elif df_live is not None and not df_live.empty: + # No historical data, use live only + df_main = df_live.tail(180) + main_source = "Live 1m (WebSocket)" else: - # Fallback to historical 1-minute data (3 hours) - df_main = self.data_provider.get_historical_data(symbol, '1m', limit=180) - main_source = "Historical 1m" + # No data at all + df_main = None + main_source = "No data" # Get 1-second data (mini chart) ws_data_1s = self._get_websocket_chart_data(symbol, '1s')