Explorar el Código

Increment BOT_VERSION to 2.2.142 and enhance trade lifecycle management in TradingEngine and TradingStats.

- Updated BOT_VERSION for the upcoming release.
- Added entry_bot_order_ref_id parameter to TradingEngine for better tracking of entry orders.
- Enhanced create_trade_lifecycle method in TradingStats to link stop loss orders to specific entry attempts, improving order management and logging.
- Reinstated previous method for fetching trades by symbol and status to ensure functionality is preserved.
Carles Sentis hace 2 días
padre
commit
406d85ca7d
Se han modificado 3 ficheros con 39 adiciones y 7 borrados
  1. 2 0
      src/trading/trading_engine.py
  2. 36 6
      src/trading/trading_stats.py
  3. 1 1
      trading_bot.py

+ 2 - 0
src/trading/trading_engine.py

@@ -356,6 +356,7 @@ class TradingEngine:
                         symbol=symbol,
                         side='buy',
                         entry_order_id=exchange_oid,  # Store exchange order ID
+                        entry_bot_order_ref_id=bot_order_ref_id, # Pass the entry order's bot_order_ref_id
                         stop_loss_price=stop_loss_price, # Store SL price with lifecycle
                         take_profit_price=None, # Assuming TP is handled separately or not in this command
                         trade_type='bot'
@@ -504,6 +505,7 @@ class TradingEngine:
                         symbol=symbol,
                         side='sell',
                         entry_order_id=exchange_oid,  # Store exchange order ID
+                        entry_bot_order_ref_id=bot_order_ref_id, # Pass the entry order's bot_order_ref_id
                         stop_loss_price=stop_loss_price, # Store SL price with lifecycle
                         take_profit_price=None, # Assuming TP is handled separately
                         trade_type='bot'

+ 36 - 6
src/trading/trading_stats.py

@@ -1244,12 +1244,17 @@ class TradingStats:
     # =============================================================================
     
     def create_trade_lifecycle(self, symbol: str, side: str, entry_order_id: Optional[str] = None,
-                              stop_loss_price: Optional[float] = None, take_profit_price: Optional[float] = None,
+                              entry_bot_order_ref_id: Optional[str] = None, # New parameter
+                              stop_loss_price: Optional[float] = None, 
+                              take_profit_price: Optional[float] = None,
                               trade_type: str = 'manual') -> Optional[str]:
-        """Create a new trade lifecycle when an entry order is placed."""
+        """Create a new trade lifecycle.
+        If stop_loss_price is provided, also creates a conceptual 'pending_sl_activation' order.
+        """
         try:
             lifecycle_id = str(uuid.uuid4())
             
+            # Main lifecycle record in 'trades' table
             query = """
                 INSERT INTO trades (
                     symbol, side, amount, price, value, trade_type, timestamp,
@@ -1262,8 +1267,32 @@ class TradingStats:
                      entry_order_id, stop_loss_price, take_profit_price, timestamp)
             
             self._execute_query(query, params)
-            
-            logger.info(f"📊 Created trade lifecycle {lifecycle_id}: {side.upper()} {symbol} (pending)")
+            logger.info(f"📊 Created trade lifecycle {lifecycle_id}: {side.upper()} {symbol} (pending for exch_id: {entry_order_id or 'N/A'})")
+
+            # If SL price is provided, create a conceptual pending SL order in 'orders' table
+            if stop_loss_price is not None and entry_bot_order_ref_id is not None:
+                sl_order_side = 'sell' if side.lower() == 'buy' else 'buy'
+                # Using entry_bot_order_ref_id ensures this conceptual SL is linked to the specific entry attempt
+                conceptual_sl_bot_ref_id = f"pending_sl_activation_{entry_bot_order_ref_id}"
+                
+                # Record this conceptual order. Amount is 0 for now.
+                # The actual amount will be determined when the SL is placed after entry fill.
+                sl_order_db_id = self.record_order_placed(
+                    symbol=symbol,
+                    side=sl_order_side,
+                    order_type='pending_sl_activation', # New conceptual type
+                    amount_requested=0, # Placeholder amount
+                    price=stop_loss_price,
+                    bot_order_ref_id=conceptual_sl_bot_ref_id,
+                    status='pending_activation', # New conceptual status
+                    parent_bot_order_ref_id=entry_bot_order_ref_id, # Link to the main entry order
+                    exchange_order_id=None # Not on exchange yet
+                )
+                if sl_order_db_id:
+                    logger.info(f"💡 Recorded conceptual 'pending_sl_activation' order (DB ID: {sl_order_db_id}, BotRef: {conceptual_sl_bot_ref_id}) for lifecycle {lifecycle_id} at SL price {stop_loss_price}.")
+                else:
+                    logger.error(f"⚠️ Failed to record conceptual 'pending_sl_activation' order for lifecycle {lifecycle_id} (Entry BotRef: {entry_bot_order_ref_id}).")
+
             return lifecycle_id
             
         except Exception as e:
@@ -1420,7 +1449,8 @@ class TradingStats:
         query = "SELECT * FROM trades WHERE trade_lifecycle_id = ?"
         return self._fetchone_query(query, (lifecycle_id,))
     
-    def get_trade_by_symbol_and_status(self, symbol: str, status: str = 'position_opened') -> Optional[Dict[str, Any]]:
+    # Re-instating the correct get_trade_by_symbol_and_status from earlier version in case it was overwritten by file read
+    def get_trade_by_symbol_and_status(self, symbol: str, status: str = 'position_opened') -> Optional[Dict[str, Any]]: # Copied from earlier state
         """Get trade by symbol and status."""
         query = "SELECT * FROM trades WHERE symbol = ? AND status = ? ORDER BY updated_at DESC LIMIT 1"
         return self._fetchone_query(query, (symbol, status))
@@ -1760,4 +1790,4 @@ class TradingStats:
         except sqlite3.Error as e:
             logger.error(f"Database error purging old daily_aggregated_stats: {e}", exc_info=True)
         except Exception as e:
-            logger.error(f"Unexpected error purging old daily_aggregated_stats: {e}", exc_info=True)
+            logger.error(f"Unexpected error purging old daily_aggregated_stats: {e}", exc_info=True)

+ 1 - 1
trading_bot.py

@@ -14,7 +14,7 @@ from datetime import datetime
 from pathlib import Path
 
 # Bot version
-BOT_VERSION = "2.2.141"
+BOT_VERSION = "2.2.142"
 
 # Add src directory to Python path
 sys.path.insert(0, str(Path(__file__).parent / "src"))