Преглед на файлове

Implement external stop loss detection in info_commands for enhanced risk management.

- Added functionality to retrieve exchange orders and identify unlinked external stop losses for open positions.
- Updated position display to include external stop loss prices, improving risk visibility for users.
- Enhanced comments for clarity on stop loss and take profit display logic.
Carles Sentis преди 1 седмица
родител
ревизия
62c84ac847
променени са 2 файла, в които са добавени 58 реда и са изтрити 5 реда
  1. 57 4
      src/commands/info_commands.py
  2. 1 1
      trading_bot.py

+ 57 - 4
src/commands/info_commands.py

@@ -167,6 +167,9 @@ class InfoCommands:
                 total_position_value = 0
                 total_margin_used = 0 
                 
+                # Get exchange orders to detect external stop losses
+                exchange_orders = self.trading_engine.get_orders() or []
+                
                 for position_trade in open_positions:
                     symbol = position_trade['symbol']
                     # base_asset is the asset being traded, quote_asset is the settlement currency (usually USDC)
@@ -304,17 +307,67 @@ class InfoCommands:
                         liq_price_str = formatter.format_price_with_symbol(position_trade.get('liquidation_price'), base_asset)
                         positions_text += f"   ⚠️ Liquidation: {liq_price_str}\n"
                     
-                    # Show stop loss if linked
+                    # Show stop loss if linked in database
                     if position_trade.get('stop_loss_price'):
                         sl_price = position_trade['stop_loss_price']
                         positions_text += f"   🛑 Stop Loss: {formatter.format_price_with_symbol(sl_price, base_asset)}\n"
                     
-                    # Show take profit if linked
+                    # Show take profit if linked in database
                     if position_trade.get('take_profit_price'):
                         tp_price = position_trade['take_profit_price']
                         positions_text += f"   🎯 Take Profit: {formatter.format_price_with_symbol(tp_price, base_asset)}\n"
                     
-
+                    # Detect external/unlinked stop losses for this position
+                    external_sls = []
+                    for order in exchange_orders:
+                        try:
+                            order_symbol = order.get('symbol')
+                            order_side = order.get('side', '').lower()
+                            order_type = order.get('type', '').lower()
+                            order_price = float(order.get('price', 0))
+                            trigger_price = order.get('info', {}).get('triggerPrice')
+                            is_reduce_only = order.get('reduceOnly', False) or order.get('info', {}).get('reduceOnly', False)
+                            order_amount = float(order.get('amount', 0))
+                            
+                            # Check if this order could be a stop loss for this position
+                            if (order_symbol == symbol and is_reduce_only and 
+                                abs(order_amount - abs_current_amount) < 0.01 * abs_current_amount):
+                                
+                                # Get trigger price (prefer triggerPrice over regular price)
+                                sl_trigger_price = 0
+                                if trigger_price:
+                                    try:
+                                        sl_trigger_price = float(trigger_price)
+                                    except (ValueError, TypeError):
+                                        pass
+                                if not sl_trigger_price and order_price > 0:
+                                    sl_trigger_price = order_price
+                                
+                                # Check if it's positioned correctly relative to entry price
+                                is_valid_sl = False
+                                if position_side == 'long' and order_side == 'sell':
+                                    # Long position: SL should be sell order below entry price
+                                    if sl_trigger_price > 0 and sl_trigger_price < entry_price:
+                                        is_valid_sl = True
+                                elif position_side == 'short' and order_side == 'buy':
+                                    # Short position: SL should be buy order above entry price
+                                    if sl_trigger_price > 0 and sl_trigger_price > entry_price:
+                                        is_valid_sl = True
+                                
+                                # Check if it's already linked in database
+                                linked_sl_order_id = position_trade.get('stop_loss_order_id')
+                                is_already_linked = (linked_sl_order_id and linked_sl_order_id == order.get('id'))
+                                
+                                if is_valid_sl and not is_already_linked:
+                                    external_sls.append(sl_trigger_price)
+                                    
+                        except Exception as order_err:
+                            # Skip problematic orders
+                            continue
+                    
+                    # Show external stop losses (unlinked)
+                    for ext_sl_price in external_sls:
+                        positions_text += f"   🛡️ External SL: {formatter.format_price_with_symbol(ext_sl_price, base_asset)}\n"
 
                     positions_text += f"   🆔 Lifecycle ID: {position_trade['trade_lifecycle_id'][:8]}\n\n"
                 
@@ -331,7 +384,7 @@ class InfoCommands:
                     margin_pnl_percentage = (total_unrealized / total_margin_used) * 100
                     positions_text += f"   📊 Portfolio Return: {margin_pnl_percentage:+.2f}% (on margin)\n"
                 positions_text += "\n"
-                positions_text += f"🤖 <b>Legend:</b> 🤖 Bot-created • 🔄 External/synced\n"
+                positions_text += f"🤖 <b>Legend:</b> 🤖 Bot-created • 🔄 External/synced • 🛡️ External SL\n"
                 positions_text += f"💡 Use /sl [token] [price] or /tp [token] [price] to set risk management"
                 
             else:

+ 1 - 1
trading_bot.py

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