From 5dbc177016c7d0f8b921d970111d3ace692bbeba Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Wed, 25 Jun 2025 22:29:08 +0300 Subject: [PATCH] fixes --- web/clean_dashboard.py | 220 +++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 107 deletions(-) diff --git a/web/clean_dashboard.py b/web/clean_dashboard.py index 567b6f0..d5c4716 100644 --- a/web/clean_dashboard.py +++ b/web/clean_dashboard.py @@ -237,6 +237,10 @@ class CleanTradingDashboard: def update_metrics(n): """Update key metrics""" try: + # Sync position from trading executor first + symbol = 'ETH/USDT' + self._sync_position_from_executor(symbol) + # Get current price current_price = self._get_current_price('ETH/USDT') price_str = f"${current_price:.2f}" if current_price else "Loading..." @@ -1290,6 +1294,30 @@ class CleanTradingDashboard: logger.debug(f"Error checking signal generation status: {e}") return False + def _sync_position_from_executor(self, symbol: str): + """Sync current position from trading executor""" + try: + if self.trading_executor and hasattr(self.trading_executor, 'get_current_position'): + executor_position = self.trading_executor.get_current_position(symbol) + if executor_position: + # Update dashboard position to match executor + self.current_position = { + 'side': executor_position.get('side', 'UNKNOWN'), + 'size': executor_position.get('size', 0), + 'price': executor_position.get('price', 0), + 'symbol': executor_position.get('symbol', symbol), + 'entry_time': executor_position.get('entry_time', datetime.now()), + 'leverage': 50, + 'unrealized_pnl': executor_position.get('unrealized_pnl', 0) + } + logger.debug(f"Synced position from executor: {self.current_position['side']} {self.current_position['size']:.3f}") + else: + # No position in executor + self.current_position = None + logger.debug("No position in trading executor") + except Exception as e: + logger.debug(f"Error syncing position from executor: {e}") + def _get_cnn_pivot_prediction(self) -> Optional[Dict]: """Get CNN pivot point prediction from orchestrator""" try: @@ -1539,67 +1567,45 @@ class CleanTradingDashboard: logger.info(f"EXECUTED {action} signal: {symbol} @ ${signal.get('price', 0):.2f} " f"(conf: {signal['confidence']:.2f}, size: {size}) - {execution_reason}") - # Create trade record for tracking - trade_record = { - 'symbol': symbol, - 'side': action, - 'quantity': size, - 'entry_price': signal.get('price', 0), - 'entry_time': datetime.now(), - 'pnl': 0.0, - 'fees': 0.001, # Small demo fee - 'confidence': signal.get('confidence', 0), - 'trade_type': 'auto_signal' - } + # Sync position from trading executor after execution + self._sync_position_from_executor(symbol) - # Create/update current position for unrealized P&L tracking - current_price = signal.get('price', 0) - if action == 'BUY': - # Create or add to LONG position - self.current_position = { - 'side': 'LONG', - 'size': size, - 'price': current_price, - 'symbol': symbol, - 'entry_time': datetime.now(), - 'leverage': 50 - } - logger.info(f"Auto-signal created LONG position: {size:.3f} @ ${current_price:.2f}") - else: # SELL - # Create SHORT position or close LONG - if self.current_position and self.current_position.get('side') == 'LONG': - # Close LONG position and calculate realized P&L - entry_price = self.current_position.get('price', 0) - position_size = self.current_position.get('size', 0) - if entry_price and position_size: - # Calculate leveraged P&L for position close - raw_pnl = (current_price - entry_price) * position_size - leveraged_pnl = raw_pnl * 50 # x50 leverage - self.session_pnl += leveraged_pnl - trade_record['pnl'] = leveraged_pnl - logger.info(f"Closed LONG position: P&L ${leveraged_pnl:.2f} (x50 leverage)") - self.current_position = None - else: - # Create SHORT position - self.current_position = { - 'side': 'SHORT', - 'size': size, - 'price': current_price, - 'symbol': symbol, - 'entry_time': datetime.now(), - 'leverage': 50 + # Get trade history from executor for completed trades + executor_trades = self.trading_executor.get_trade_history() if hasattr(self.trading_executor, 'get_trade_history') else [] + + # Only add completed trades to closed_trades (not position opens) + if executor_trades: + latest_trade = executor_trades[-1] + # Check if this is a completed trade (has exit price/time) + if hasattr(latest_trade, 'exit_time') and latest_trade.exit_time: + trade_record = { + 'symbol': latest_trade.symbol, + 'side': latest_trade.side, + 'quantity': latest_trade.quantity, + 'entry_price': latest_trade.entry_price, + 'exit_price': latest_trade.exit_price, + 'entry_time': latest_trade.entry_time, + 'exit_time': latest_trade.exit_time, + 'pnl': latest_trade.pnl, + 'fees': latest_trade.fees, + 'confidence': latest_trade.confidence, + 'trade_type': 'auto_signal' } - logger.info(f"Auto-signal created SHORT position: {size:.3f} @ ${current_price:.2f}") + + # Only add if not already in closed_trades + if not any(t.get('entry_time') == trade_record['entry_time'] for t in self.closed_trades): + self.closed_trades.append(trade_record) + self.session_pnl += latest_trade.pnl + logger.info(f"Auto-signal completed trade: {action} P&L ${latest_trade.pnl:.2f}") - self.closed_trades.append(trade_record) - - # Update session metrics immediately - if action == 'SELL': - demo_pnl = 0.05 # Demo profit for SELL - self.session_pnl += demo_pnl - trade_record['pnl'] = demo_pnl - trade_record['exit_price'] = signal.get('price', 0) - trade_record['exit_time'] = datetime.now() + # Position status will be shown from sync with executor + if self.current_position: + side = self.current_position.get('side', 'UNKNOWN') + size = self.current_position.get('size', 0) + price = self.current_position.get('price', 0) + logger.info(f"Auto-signal position: {side} {size:.3f} @ ${price:.2f}") + else: + logger.info(f"Auto-signal: No open position after {action}") else: signal['blocked'] = True @@ -1689,6 +1695,9 @@ class CleanTradingDashboard: logger.warning("No current price available for manual trade") return + # Sync current position from trading executor first + self._sync_position_from_executor(symbol) + # CAPTURE ALL MODEL INPUTS FOR COLD START TRAINING using core TradeDataManager try: from core.trade_data_manager import TradeDataManager @@ -1729,58 +1738,55 @@ class CleanTradingDashboard: decision['executed'] = True logger.info(f"Manual {action} executed at ${current_price:.2f}") - # Create a trade record for tracking WITH model inputs - trade_record = { - 'symbol': symbol, - 'side': action, - 'quantity': 0.01, - 'entry_price': current_price, - 'exit_price': current_price, - 'entry_time': datetime.now(), - 'exit_time': datetime.now(), - 'pnl': 0.0, # Manual test trades have 0 P&L initially - 'fees': 0.0, - 'confidence': 1.0, - 'trade_type': 'manual', - 'model_inputs_at_entry': model_inputs, # CRITICAL: Store model inputs for training - 'entry_market_state': model_inputs.get('market_state', {}), - 'entry_features': model_inputs.get('features', {}), - 'entry_predictions': model_inputs.get('predictions', {}), - 'training_ready': True # Mark as ready for cold start training - } + # Sync position from trading executor after execution + self._sync_position_from_executor(symbol) - # Create/update current position for unrealized P&L tracking - if action == 'BUY': - # Create or add to LONG position - self.current_position = { - 'side': 'LONG', - 'size': 0.004, # Example position size as mentioned by user - 'price': current_price, - 'symbol': symbol, - 'entry_time': datetime.now(), - 'leverage': 50 - } - logger.info(f"Created LONG position: {self.current_position['size']:.3f} @ ${current_price:.2f}") - else: # SELL - # Create SHORT position or close LONG - if self.current_position and self.current_position.get('side') == 'LONG': - # Close LONG position - self.current_position = None - logger.info("Closed LONG position") - else: - # Create SHORT position - self.current_position = { - 'side': 'SHORT', - 'size': 0.004, - 'price': current_price, - 'symbol': symbol, - 'entry_time': datetime.now(), - 'leverage': 50 + # Get trade history from executor for completed trades + executor_trades = self.trading_executor.get_trade_history() if hasattr(self.trading_executor, 'get_trade_history') else [] + + # Only add completed trades to closed_trades (not position opens) + if executor_trades: + latest_trade = executor_trades[-1] + # Check if this is a completed trade (has exit price/time) + if hasattr(latest_trade, 'exit_time') and latest_trade.exit_time: + trade_record = { + 'symbol': latest_trade.symbol, + 'side': latest_trade.side, + 'quantity': latest_trade.quantity, + 'entry_price': latest_trade.entry_price, + 'exit_price': latest_trade.exit_price, + 'entry_time': latest_trade.entry_time, + 'exit_time': latest_trade.exit_time, + 'pnl': latest_trade.pnl, + 'fees': latest_trade.fees, + 'confidence': latest_trade.confidence, + 'trade_type': 'manual', + 'model_inputs_at_entry': model_inputs, + 'training_ready': True } - logger.info(f"Created SHORT position: {self.current_position['size']:.3f} @ ${current_price:.2f}") + + # Only add if not already in closed_trades + if not any(t.get('entry_time') == trade_record['entry_time'] for t in self.closed_trades): + self.closed_trades.append(trade_record) + logger.info(f"Added completed trade to closed_trades: {action} P&L ${latest_trade.pnl:.2f}") - # Add to closed trades for display - self.closed_trades.append(trade_record) + # Store for cold start training when trade closes using core TradeDataManager + try: + case_id = trade_data_manager.store_trade_for_training({ + 'symbol': symbol, + 'side': action, + 'quantity': 0.01, + 'entry_price': current_price, + 'pnl': 0.0, # Will be updated when position closes + 'confidence': 1.0, + 'trade_type': 'manual', + 'model_inputs_at_entry': model_inputs, + 'training_ready': True + }) + if case_id: + logger.info(f"Trade stored for training with case ID: {case_id}") + except Exception as e: + logger.warning(f"Failed to store trade for training: {e}") # Store for cold start training when trade closes using core TradeDataManager try: