Jelajahi Sumber

Refactor SimplePositionTracker and TradeLifecycleManager to enhance position update handling. Added ROE percentage retrieval and improved notification details for position size changes. Updated database query construction for better clarity and efficiency in trade lifecycle updates.

Carles Sentis 1 Minggu lalu
induk
melakukan
88be3dc67f

+ 15 - 6
src/monitoring/simple_position_tracker.py

@@ -242,26 +242,35 @@ class SimplePositionTracker:
             lifecycle_id = db_pos['trade_lifecycle_id']
             entry_price = db_pos.get('entry_price', 0)
             
+            # Get ROE from exchange position
+            roe = exchange_pos.get('returnOnEquity', 0.0) * 100  # Convert to percentage
+            
             # Update position size using existing manager
             success = stats.trade_manager.update_trade_market_data(
                 lifecycle_id, 
                 current_position_size=exchange_size,
                 unrealized_pnl=exchange_pos.get('unrealizedPnl'),
-                unrealized_pnl_percentage=exchange_pos.get('returnOnEquity', 0.0) * 100  # Convert to percentage
+                unrealized_pnl_percentage=roe,  # Store ROE as percentage
+                mark_price=exchange_pos.get('markPrice'),
+                position_value=exchange_pos.get('positionValue'),
+                margin_used=exchange_pos.get('marginUsed'),
+                leverage=exchange_pos.get('leverage'),
+                liquidation_price=exchange_pos.get('liquidationPrice')
             )
             
             if success:
                 change_type = 'increased' if exchange_size > db_size else 'decreased'
                 size_diff = abs(exchange_size - db_size)
+                logger.info(f"📊 Position size {change_type}: {symbol} by {size_diff} (ROE: {roe:+.2f}%)")
                 
-                logger.info(f"📊 POSITION {change_type.upper()}: {symbol} {db_size} → {exchange_size}")
-                
-                # Send notification  
-                await self._send_position_notification(change_type, symbol, {
-                    'side': db_position_side,
+                # Send notification
+                await self._send_position_notification('size_changed', symbol, {
+                    'side': exchange_position_side,
                     'old_size': db_size,
                     'new_size': exchange_size,
+                    'change_type': change_type,
                     'size_diff': size_diff,
+                    'roe': roe,
                     'timestamp': timestamp
                 })
                 

+ 35 - 36
src/stats/trade_lifecycle_manager.py

@@ -332,70 +332,69 @@ class TradeLifecycleManager:
                                  leverage: Optional[float] = None,
                                  position_value: Optional[float] = None,
                                  unrealized_pnl_percentage: Optional[float] = None) -> bool:
-        """Update market-related data for an open trade lifecycle."""
+        """Update market data for a trade lifecycle."""
         try:
-            updates = []
+            # Build dynamic update query based on provided fields
+            update_fields = []
             params = []
             
             if unrealized_pnl is not None:
-                updates.append("unrealized_pnl = ?")
+                update_fields.append("unrealized_pnl = ?")
                 params.append(unrealized_pnl)
+            
             if mark_price is not None:
-                updates.append("mark_price = ?")
+                update_fields.append("mark_price = ?")
                 params.append(mark_price)
+            
             if current_position_size is not None:
-                updates.append("current_position_size = ?")
+                update_fields.append("current_position_size = ?")
                 params.append(current_position_size)
+            
             if entry_price is not None:
-                updates.append("entry_price = ?")
+                update_fields.append("entry_price = ?")
                 params.append(entry_price)
+            
             if liquidation_price is not None:
-                updates.append("liquidation_price = ?")
+                update_fields.append("liquidation_price = ?")
                 params.append(liquidation_price)
+            
             if margin_used is not None:
-                updates.append("margin_used = ?")
+                update_fields.append("margin_used = ?")
                 params.append(margin_used)
+            
             if leverage is not None:
-                updates.append("leverage = ?")
+                update_fields.append("leverage = ?")
                 params.append(leverage)
+            
             if position_value is not None:
-                updates.append("position_value = ?")
+                update_fields.append("position_value = ?")
                 params.append(position_value)
+            
             if unrealized_pnl_percentage is not None:
-                # Store ROE as a decimal (e.g., -0.326 for -32.6%)
-                # We'll handle the conversion to percentage when displaying
-                updates.append("unrealized_pnl_percentage = ?")
+                update_fields.append("unrealized_pnl_percentage = ?")
                 params.append(unrealized_pnl_percentage)
-
-            if not updates:
-                logger.debug(f"No market data fields provided to update for lifecycle {trade_lifecycle_id}.")
-                return True
-
+            
+            if not update_fields:
+                logger.warning(f"No fields to update for trade {trade_lifecycle_id}")
+                return False
+            
+            # Add timestamp and lifecycle_id
             timestamp = datetime.now(timezone.utc).isoformat()
-            updates.append("updated_at = ?")
+            update_fields.append("updated_at = ?")
             params.append(timestamp)
-
-            set_clause = ", ".join(updates)
+            params.append(trade_lifecycle_id)
+            
             query = f"""
-                UPDATE trades
-                SET {set_clause}
+                UPDATE trades 
+                SET {', '.join(update_fields)}
                 WHERE trade_lifecycle_id = ? AND status = 'position_opened'
             """
-            params.append(trade_lifecycle_id)
             
-            cursor = self.db.conn.cursor()
-            cursor.execute(query, tuple(params))
-            self.db.conn.commit()
-            updated_rows = cursor.rowcount
-
-            if updated_rows > 0:
-                logger.debug(f"💹 Updated market data for lifecycle {trade_lifecycle_id}")
-                return True
-            else:
-                return False
-
+            self.db._execute_query(query, params)
+            return True
+            
         except Exception as e:
-            logger.error(f"❌ Error updating market data for trade lifecycle {trade_lifecycle_id}: {e}")
+            logger.error(f"❌ Error updating trade market data: {e}")
             return False
 
     def get_recent_trades(self, limit: int = 10) -> List[Dict[str, Any]]:

+ 1 - 1
trading_bot.py

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