Forráskód Böngészése

Refactor position closure notifications and market data handling in PositionMonitor

- Simplified position closure notification by removing "External" from the message for clarity.
- Enhanced immediate notification logic for bot exits to ensure accurate PnL reporting.
- Improved market data retrieval for exit price estimation, including better error handling and logging for invalid data scenarios.
- Added checks to prevent duplicate processing of lifecycle closures, enhancing reliability in position management.
Carles Sentis 1 napja
szülő
commit
09814235d5
2 módosított fájl, 23 hozzáadás és 9 törlés
  1. 22 8
      src/monitoring/position_monitor.py
  2. 1 1
      trading_bot.py

+ 22 - 8
src/monitoring/position_monitor.py

@@ -222,7 +222,7 @@ class PositionMonitor:
                     roe_text = ""
                 
                 message = f"""
-🎯 <b>Position Closed (External)</b>
+🎯 <b>Position Closed</b>
 
 📊 <b>Trade Details:</b>
 • Token: {token}
@@ -621,9 +621,11 @@ class PositionMonitor:
                                 logger.info(f"{pnl_emoji} Lifecycle CLOSED: {lc_id} ({closure_reason_action_type}). PNL for fill: {await formatter.format_price_with_symbol(realized_pnl)}")
                                 symbols_with_fills.add(token)
                                 
-                                # For bot exits, don't send "External" notification here - let reconciliation handle it
-                                # to avoid duplicate notifications
-                                logger.info(f"ℹ️ Bot exit processed for {full_symbol}. Reconciliation will handle position closed notification.")
+                                # Send notification immediately with correct PnL from actual fill
+                                await self._send_position_change_notification(
+                                    full_symbol, side_from_fill, amount_from_fill, price_from_fill,
+                                    'position_closed', timestamp_dt, active_lc, realized_pnl
+                                )
                                 
                                 stats.migrate_trade_to_aggregated_stats(lc_id)
                                 if bot_order_db_id_to_update:
@@ -1018,14 +1020,26 @@ class PositionMonitor:
                 logger.info(f"ℹ️ Position for {symbol} already marked as closed in lifecycle {lifecycle_id[:8]}. Skipping duplicate close processing.")
                 return
             
+            # Check if this was already migrated to aggregated stats (bot exit already processed it)
+            try:
+                if not stats.get_trade_by_lifecycle_id(lifecycle_id):
+                    logger.info(f"ℹ️ Lifecycle {lifecycle_id[:8]} for {symbol} already migrated to aggregated stats. Bot exit already handled this closure.")
+                    return
+            except Exception:
+                # If we can't check, proceed with caution
+                pass
+            
             # Estimate exit price from market data
             exit_price = 0
             try:
-                market_data = await self.trading_engine.get_symbol_data(symbol)
-                if market_data and 'markPrice' in market_data:
-                    exit_price = float(market_data['markPrice'])
+                market_data = self.trading_engine.get_market_data(symbol)
+                if market_data and market_data.get('ticker'):
+                    exit_price = float(market_data['ticker'].get('last', 0))
+                    if exit_price <= 0:
+                        logger.warning(f"⚠️ Invalid market price for {symbol} - using entry price")
+                        exit_price = entry_price
                 else:
-                    logger.warning(f"⚠️ Could not get exit price for {symbol} - using entry price")
+                    logger.warning(f"⚠️ Could not get market data for {symbol} - using entry price")
                     exit_price = entry_price
             except Exception as e:
                 logger.warning(f"⚠️ Error fetching market data for {symbol}: {e} - using entry price")

+ 1 - 1
trading_bot.py

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