Browse Source

Increment BOT_VERSION to 2.2.143 and enhance order display logic in InfoCommands.

- Updated BOT_VERSION for the upcoming release.
- Improved order grouping and display for open exchange orders, including better handling of pending stop loss activations.
- Added functionality to display orphaned pending stop loss activations when no open orders are present, enhancing user visibility into order status.
Carles Sentis 2 days ago
parent
commit
4ef3784360
2 changed files with 99 additions and 28 deletions
  1. 98 27
      src/commands/info_commands.py
  2. 1 1
      trading_bot.py

+ 98 - 27
src/commands/info_commands.py

@@ -421,59 +421,130 @@ class InfoCommands:
                     
                     # Group orders by symbol
                     orders_by_symbol = {}
-                    for order in orders:
-                        symbol = order.get('symbol', '').replace('/USDC:USDC', '')
-                        if symbol not in orders_by_symbol:
-                            orders_by_symbol[symbol] = []
-                        orders_by_symbol[symbol].append(order)
+                    # Keep track of parent_bot_order_ref_ids for pending SLs already displayed with an open parent order
+                    displayed_sl_parent_refs = set()
                     
-                    for symbol, symbol_orders in orders_by_symbol.items():
+                    for order in orders: # Iterate through orders from self.trading_engine.get_orders()
+                        symbol_display_key = order.get('symbol', '').replace('/USDC:USDC', '')
+                        if symbol_display_key not in orders_by_symbol:
+                            orders_by_symbol[symbol_display_key] = []
+                        orders_by_symbol[symbol_display_key].append(order) # Group by display key
+                    
+                    formatter = get_formatter() # Get formatter once
+
+                    for symbol, symbol_orders_list in orders_by_symbol.items():
                         orders_text += f"📊 <b>{symbol}</b>\n"
                         
-                        formatter = get_formatter()
-                        for order in symbol_orders:
-                            side = order.get('side', '').upper()
-                            amount = float(order.get('amount', 0))
-                            price = float(order.get('price', 0))
-                            order_type = order.get('type', 'unknown').title()
-                            order_id = order.get('id', 'N/A')
+                        for order_data in symbol_orders_list: # This is an individual exchange order
+                            side = order_data.get('side', '').upper()
+                            amount = float(order_data.get('amount', 0))
+                            price = float(order_data.get('price', 0))
+                            order_type = order_data.get('type', 'unknown').title()
+                            exchange_order_id = order_data.get('id', 'N/A') # Renamed for clarity
                             
-                            # Order emoji
                             side_emoji = "🟢" if side == "BUY" else "🔴"
                             
-                            orders_text += f"   {side_emoji} {side} {amount:.6f} @ {formatter.format_price_with_symbol(price, symbol)}\n"
-                            orders_text += f"   📋 Type: {order_type} | ID: {order_id}\n"
+                            orders_text += f"   {side_emoji} {side} {formatter.format_amount(amount, symbol)} @ {formatter.format_price_with_symbol(price, symbol)}\n"
+                            orders_text += f"   📋 Type: {order_type} | ID: {exchange_order_id}\n"
                             
-                            # Check for pending stop losses linked to this order
                             stats = self.trading_engine.get_stats()
                             if stats:
-                                # Try to find this order in our database to get its bot_order_ref_id
-                                order_in_db = stats.get_order_by_exchange_id(order_id)
+                                order_in_db = stats.get_order_by_exchange_id(exchange_order_id)
                                 if order_in_db:
                                     bot_ref_id = order_in_db.get('bot_order_ref_id')
                                     if bot_ref_id:
-                                        # Look for pending stop losses with this order as parent
                                         pending_sls = stats.get_orders_by_status(
-                                            status='pending_trigger', 
-                                            order_type_filter='stop_limit_trigger',
+                                            status='pending_activation', 
+                                            order_type_filter='pending_sl_activation',
                                             parent_bot_order_ref_id=bot_ref_id
                                         )
                                         
                                         if pending_sls:
-                                            sl_order = pending_sls[0]  # Should only be one
+                                            sl_order = pending_sls[0]
                                             sl_price = sl_order.get('price', 0)
-                                            sl_side = sl_order.get('side', '').upper()
-                                            orders_text += f"   🛑 Pending SL: {sl_side} @ {formatter.format_price_with_symbol(sl_price, symbol)} (activates when filled)\n"
+                                            sl_conceptual_side = sl_order.get('side', '').upper()
+                                            
+                                            orders_text += f"   ⏳ Pending SL Activation: {sl_conceptual_side} at {formatter.format_price_with_symbol(sl_price, symbol)}\n"
+                                            orders_text += f"      (Activates after main order fills)\n"
+                                            displayed_sl_parent_refs.add(bot_ref_id)
                             
                             orders_text += "\n"
                     
-                    orders_text += f"💼 <b>Total Orders:</b> {len(orders)}\n"
+                    orders_text += f"💼 <b>Total Open Exchange Orders:</b> {len(orders)}\n"
+                    
+                    # Now, check for any other pending_sl_activation orders whose parents are not in the open list
+                    stats_for_orphan_check = self.trading_engine.get_stats() # Get stats again if not already available
+                    if stats_for_orphan_check:
+                        all_pending_sl_activations = stats_for_orphan_check.get_orders_by_status(
+                            status='pending_activation',
+                            order_type_filter='pending_sl_activation'
+                        )
+                        
+                        orphaned_pending_sls_to_display = []
+                        for sl_order_data in all_pending_sl_activations:
+                            parent_ref = sl_order_data.get('parent_bot_order_ref_id')
+                            if parent_ref not in displayed_sl_parent_refs:
+                                orphaned_pending_sls_to_display.append(sl_order_data)
+                        
+                        if orphaned_pending_sls_to_display:
+                            orders_text += "\n" 
+                            orders_text += "⏳ <b>Pending SL Activations (Entry Order Assumed Filled/Closed)</b>\n\n"
+                            
+                            orphaned_sls_by_symbol_group = {}
+                            for sl_data in orphaned_pending_sls_to_display:
+                                sl_symbol_raw = sl_data.get('symbol', '')
+                                sl_symbol_display_key = sl_symbol_raw.replace('/USDC:USDC', '')
+                                if sl_symbol_display_key not in orphaned_sls_by_symbol_group:
+                                    orphaned_sls_by_symbol_group[sl_symbol_display_key] = []
+                                orphaned_sls_by_symbol_group[sl_symbol_display_key].append(sl_data)
+                            
+                            for sl_sym_key, sl_list_items in orphaned_sls_by_symbol_group.items():
+                                orders_text += f"📊 <b>{sl_sym_key}</b>\n"
+                                for sl_item in sl_list_items:
+                                    sl_price_val = sl_item.get('price', 0)
+                                    sl_side_val = sl_item.get('side', '').upper()
+                                    orders_text += f"   ⏳ Pending SL: {sl_side_val} at {formatter.format_price_with_symbol(sl_price_val, sl_sym_key)}\n"
+                                    orders_text += f"      (Awaiting activation by bot)\n\n"
+                                    
+                            orders_text += f"📦 <b>Total Pending Activations (Entry Filled):</b> {len(orphaned_pending_sls_to_display)}\n"
+
                     orders_text += f"💡 Use /coo [token] to cancel orders"
                     
                 else:
                     orders_text = "📋 <b>Open Orders</b>\n\n"
                     orders_text += "📭 No open orders\n\n"
-                    orders_text += "💡 Use /long, /short, /sl, or /tp to create orders"
+                    # Check for purely conceptual pending SLs even if no exchange orders are open
+                    stats_for_empty_check = self.trading_engine.get_stats()
+                    if stats_for_empty_check:
+                        all_pending_sl_activations_empty = stats_for_empty_check.get_orders_by_status(
+                            status='pending_activation',
+                            order_type_filter='pending_sl_activation'
+                        )
+                        if all_pending_sl_activations_empty:
+                            orders_text += "\n" 
+                            orders_text += "⏳ <b>Pending SL Activations (Entry Order Assumed Filled/Closed)</b>\n\n"
+                            formatter_for_empty = get_formatter() # Ensure formatter is available
+
+                            orphaned_sls_by_symbol_group_empty = {}
+                            for sl_data_empty in all_pending_sl_activations_empty:
+                                sl_symbol_raw_empty = sl_data_empty.get('symbol', '')
+                                sl_symbol_display_key_empty = sl_symbol_raw_empty.replace('/USDC:USDC', '')
+                                if sl_symbol_display_key_empty not in orphaned_sls_by_symbol_group_empty:
+                                    orphaned_sls_by_symbol_group_empty[sl_symbol_display_key_empty] = []
+                                orphaned_sls_by_symbol_group_empty[sl_symbol_display_key_empty].append(sl_data_empty)
+                            
+                            for sl_sym_key_empty, sl_list_items_empty in orphaned_sls_by_symbol_group_empty.items():
+                                orders_text += f"📊 <b>{sl_sym_key_empty}</b>\n"
+                                for sl_item_empty in sl_list_items_empty:
+                                    sl_price_val_empty = sl_item_empty.get('price', 0)
+                                    sl_side_val_empty = sl_item_empty.get('side', '').upper()
+                                    orders_text += f"   ⏳ Pending SL: {sl_side_val_empty} at {formatter_for_empty.format_price_with_symbol(sl_price_val_empty, sl_sym_key_empty)}\n"
+                                    orders_text += f"      (Awaiting activation by bot)\n\n"
+                            orders_text += f"📦 <b>Total Pending Activations (Entry Filled):</b> {len(all_pending_sl_activations_empty)}\n"
+                        else:
+                             orders_text += "💡 Use /long, /short, /sl, or /tp to create orders" # Original message if no pending SLs either
+                    else:
+                        orders_text += "💡 Use /long, /short, /sl, or /tp to create orders"
                 
                 await reply_method(text=orders_text, parse_mode='HTML')
             else:

+ 1 - 1
trading_bot.py

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