Переглянути джерело

Increment BOT_VERSION to 2.2.128 and enhance MarketMonitor with improved fill fetching logic.

- Updated BOT_VERSION for the upcoming release.
- Modified MarketMonitor to fetch all recent fills for the account and filter by symbol, improving accuracy in determining exit prices.
- Enhanced startup synchronization logic to increase the likelihood of retrieving relevant fills, ensuring better performance during initialization.
- Improved logging for exit price determination to provide clearer insights into the trading process.
Carles Sentis 3 днів тому
батько
коміт
239b1e9bca
3 змінених файлів з 35 додано та 32 видалено
  1. 33 30
      src/monitoring/market_monitor.py
  2. 1 1
      src/trading/trading_stats.py
  3. 1 1
      trading_bot.py

+ 33 - 30
src/monitoring/market_monitor.py

@@ -1773,19 +1773,22 @@ class MarketMonitor:
 
                     # Attempt to find a recent closing fill from the exchange
                     try:
-                        recent_fills = self.trading_engine.get_recent_fills(symbol=symbol, limit=10) # Fetch last 10 fills for the symbol
-                        if recent_fills:
-                            closing_side = 'sell' if position_side == 'long' else 'buy'
-                            relevant_fills = sorted(
-                                [f for f in recent_fills if f.get('side') == closing_side and f.get('symbol') == symbol],
-                                key=lambda f: f.get('timestamp'), reverse=True # Most recent first
-                            )
-                            if relevant_fills:
-                                last_closing_fill = relevant_fills[0]
-                                exit_price_for_calc = float(last_closing_fill.get('price', 0))
-                                fill_timestamp = datetime.fromtimestamp(last_closing_fill.get('timestamp')/1000, tz=timezone.utc).isoformat() if last_closing_fill.get('timestamp') else "N/A"
-                                price_source_info = f"last exchange fill ({formatter.format_price(exit_price_for_calc, symbol)} @ {fill_timestamp})"
-                                logger.info(f"AUTO-SYNC: Using exit price {price_source_info} for {symbol} lifecycle {lc_id}.")
+                        # Fetch all recent fills for the account, then filter by symbol
+                        all_recent_fills = self.trading_engine.get_recent_fills(limit=20) # Increased limit slightly
+                        if all_recent_fills:
+                            symbol_specific_fills = [f for f in all_recent_fills if f.get('symbol') == symbol]
+                            if symbol_specific_fills:
+                                closing_side = 'sell' if position_side == 'long' else 'buy'
+                                relevant_fills = sorted(
+                                    [f for f in symbol_specific_fills if f.get('side') == closing_side], # Already filtered by symbol
+                                    key=lambda f: f.get('timestamp'), reverse=True # Most recent first
+                                )
+                                if relevant_fills:
+                                    last_closing_fill = relevant_fills[0]
+                                    exit_price_for_calc = float(last_closing_fill.get('price', 0))
+                                    fill_timestamp = datetime.fromtimestamp(last_closing_fill.get('timestamp')/1000, tz=timezone.utc).isoformat() if last_closing_fill.get('timestamp') else "N/A"
+                                    price_source_info = f"last exchange fill ({formatter.format_price(exit_price_for_calc, symbol)} @ {fill_timestamp})"
+                                    logger.info(f"AUTO-SYNC: Using exit price {price_source_info} for {symbol} lifecycle {lc_id}.")
                     except Exception as e:
                         logger.warning(f"AUTO-SYNC: Error fetching recent fills for {symbol} to determine exit price: {e}")
 
@@ -1999,23 +2002,23 @@ class MarketMonitor:
                         price_source_info = "unknown"
 
                         try:
-                            # recent_fills for startup sync might be empty if called too early
-                            # self.trading_engine.get_recent_fills might not be fully populated yet or too broad.
-                            # Using a limited fetch here, but it might be better to rely on mark/entry price at startup for simplicity if fills are problematic.
-                            recent_fills_for_startup_sync = self.trading_engine.get_recent_fills(symbol=symbol, limit=10)
-                            if recent_fills_for_startup_sync:
-                                closing_side = 'sell' if position_side == 'long' else 'buy'
-                                relevant_fills = sorted(
-                                    [f for f in recent_fills_for_startup_sync if f.get('side') == closing_side and f.get('symbol') == symbol],
-                                    key=lambda f: f.get('timestamp'), reverse=True
-                                )
-                                if relevant_fills:
-                                    last_closing_fill = relevant_fills[0]
-                                    exit_price_for_calc = float(last_closing_fill.get('price', 0))
-                                    fill_ts_val = last_closing_fill.get('timestamp')
-                                    fill_timestamp_str = datetime.fromtimestamp(fill_ts_val/1000, tz=timezone.utc).isoformat() if fill_ts_val else "N/A"
-                                    price_source_info = f"last exchange fill ({formatter.format_price(exit_price_for_calc, symbol)} @ {fill_timestamp_str})"
-                                    logger.info(f"STARTUP SYNC: Using exit price {price_source_info} for {symbol} lifecycle {lc_id}.")
+                            # Fetch all recent fills, then filter by symbol
+                            all_recent_fills_for_startup_sync = self.trading_engine.get_recent_fills(limit=20) # Fetch more to increase chance
+                            if all_recent_fills_for_startup_sync:
+                                symbol_specific_fills_startup = [f for f in all_recent_fills_for_startup_sync if f.get('symbol') == symbol]
+                                if symbol_specific_fills_startup:
+                                    closing_side = 'sell' if position_side == 'long' else 'buy'
+                                    relevant_fills = sorted(
+                                        [f for f in symbol_specific_fills_startup if f.get('side') == closing_side], # Already filtered by symbol
+                                        key=lambda f: f.get('timestamp'), reverse=True
+                                    )
+                                    if relevant_fills:
+                                        last_closing_fill = relevant_fills[0]
+                                        exit_price_for_calc = float(last_closing_fill.get('price', 0))
+                                        fill_ts_val = last_closing_fill.get('timestamp')
+                                        fill_timestamp_str = datetime.fromtimestamp(fill_ts_val/1000, tz=timezone.utc).isoformat() if fill_ts_val else "N/A"
+                                        price_source_info = f"last exchange fill ({formatter.format_price(exit_price_for_calc, symbol)} @ {fill_timestamp_str})"
+                                        logger.info(f"STARTUP SYNC: Using exit price {price_source_info} for {symbol} lifecycle {lc_id}.")
                         except Exception as e:
                             logger.warning(f"STARTUP SYNC: Error fetching recent fills for {symbol} to determine exit price: {e}")
 

+ 1 - 1
src/trading/trading_stats.py

@@ -1334,7 +1334,7 @@ class TradingStats:
             trade_info = self.get_trade_by_lifecycle_id(lifecycle_id) # Fetch to get symbol for P&L formatting context
             symbol_for_formatting = trade_info.get('symbol', 'USD') # Default to USD for PNL if symbol unknown
             pnl_emoji = "🟢" if realized_pnl >= 0 else "🔴"
-            logger.info(f"{pnl_emoji} Trade lifecycle {lifecycle_id} position closed: P&L {formatter.format_price_with_symbol(realized_pnl, quote_asset=symbol_for_formatting.split('/')[-1] if '/' in symbol_for_formatting else 'USD')}")
+            logger.info(f"{pnl_emoji} Trade lifecycle {lifecycle_id} position closed: P&L {formatter.format_price_with_symbol(realized_pnl)}")
             return True
             
         except Exception as e:

+ 1 - 1
trading_bot.py

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