|
@@ -130,6 +130,11 @@ class InfoCommands:
|
|
|
position_side = 'long' if contracts > 0 else 'short'
|
|
|
order_side = 'buy' if contracts > 0 else 'sell'
|
|
|
|
|
|
+ # 🔧 FIX: If entry price is 0, try to estimate it
|
|
|
+ if entry_price <= 0:
|
|
|
+ entry_price = await self._estimate_entry_price_for_orphaned_position(symbol, contracts)
|
|
|
+ logger.info(f"🔄 Estimated entry price for orphaned {symbol}: ${entry_price:.4f}")
|
|
|
+
|
|
|
logger.info(f"🔄 Auto-syncing orphaned position: {symbol} {position_side} {abs(contracts)} @ ${entry_price}")
|
|
|
|
|
|
# Create trade lifecycle for external position
|
|
@@ -1333,4 +1338,49 @@ Tap any button below for instant access to bot functions:
|
|
|
]
|
|
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
|
|
|
|
|
- await context.bot.send_message(chat_id=chat_id, text=commands_text, parse_mode='HTML', reply_markup=reply_markup)
|
|
|
+ await context.bot.send_message(chat_id=chat_id, text=commands_text, parse_mode='HTML', reply_markup=reply_markup)
|
|
|
+
|
|
|
+ async def _estimate_entry_price_for_orphaned_position(self, symbol: str, contracts: float) -> float:
|
|
|
+ """Estimate entry price for an orphaned position by checking recent fills and market data."""
|
|
|
+ try:
|
|
|
+ # Method 1: Check recent fills from the exchange
|
|
|
+ recent_fills = self.trading_engine.get_recent_fills()
|
|
|
+ if recent_fills:
|
|
|
+ # Look for recent fills for this symbol
|
|
|
+ symbol_fills = [fill for fill in recent_fills if fill.get('symbol') == symbol]
|
|
|
+
|
|
|
+ if symbol_fills:
|
|
|
+ # Get the most recent fill as entry price estimate
|
|
|
+ latest_fill = symbol_fills[0] # Assuming sorted by newest first
|
|
|
+ fill_price = float(latest_fill.get('price', 0))
|
|
|
+
|
|
|
+ if fill_price > 0:
|
|
|
+ logger.info(f"💡 Found recent fill price for {symbol}: ${fill_price:.4f}")
|
|
|
+ return fill_price
|
|
|
+
|
|
|
+ # Method 2: Use current market price as fallback
|
|
|
+ market_data = self.trading_engine.get_market_data(symbol)
|
|
|
+ if market_data and market_data.get('ticker'):
|
|
|
+ current_price = float(market_data['ticker'].get('last', 0))
|
|
|
+
|
|
|
+ if current_price > 0:
|
|
|
+ logger.warning(f"⚠️ Using current market price as entry estimate for {symbol}: ${current_price:.4f}")
|
|
|
+ return current_price
|
|
|
+
|
|
|
+ # Method 3: Last resort - try bid/ask average
|
|
|
+ if market_data and market_data.get('ticker'):
|
|
|
+ bid = float(market_data['ticker'].get('bid', 0))
|
|
|
+ ask = float(market_data['ticker'].get('ask', 0))
|
|
|
+
|
|
|
+ if bid > 0 and ask > 0:
|
|
|
+ avg_price = (bid + ask) / 2
|
|
|
+ logger.warning(f"⚠️ Using bid/ask average as entry estimate for {symbol}: ${avg_price:.4f}")
|
|
|
+ return avg_price
|
|
|
+
|
|
|
+ # Method 4: Absolute fallback - return a small positive value to avoid 0
|
|
|
+ logger.error(f"❌ Could not estimate entry price for {symbol}, using fallback value of $1.00")
|
|
|
+ return 1.0
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"❌ Error estimating entry price for {symbol}: {e}")
|
|
|
+ return 1.0 # Safe fallback
|