|
@@ -16,62 +16,85 @@ class OrdersCommands(InfoCommandsBase):
|
|
|
await self._reply(update, "❌ Unauthorized access.")
|
|
|
return
|
|
|
|
|
|
- # Get open orders
|
|
|
- open_orders = self.trading_engine.get_orders()
|
|
|
- if not open_orders:
|
|
|
- await self._reply(update, "📭 No open orders")
|
|
|
+ # Get open orders from the exchange
|
|
|
+ open_orders = self.trading_engine.get_orders() or []
|
|
|
+
|
|
|
+ # Get pending stop loss orders from the database
|
|
|
+ stats = self.trading_engine.get_stats()
|
|
|
+ pending_sl_orders = []
|
|
|
+ if stats:
|
|
|
+ pending_sl_orders = stats.get_orders_by_status('pending_trigger')
|
|
|
+
|
|
|
+ # Combine both lists
|
|
|
+ all_orders = open_orders + pending_sl_orders
|
|
|
+
|
|
|
+ if not all_orders:
|
|
|
+ await self._reply(update, "📭 No open or pending orders")
|
|
|
return
|
|
|
|
|
|
# Format orders text
|
|
|
- orders_text = "📋 <b>Open Orders</b>\n\n"
|
|
|
+ orders_text = "📋 <b>Open & Pending Orders</b>\n\n"
|
|
|
|
|
|
- for order in open_orders:
|
|
|
+ for order in all_orders:
|
|
|
try:
|
|
|
+ is_pending_sl = order.get('status') == 'pending_trigger'
|
|
|
+
|
|
|
symbol = order.get('symbol', 'unknown')
|
|
|
base_asset = symbol.split('/')[0] if '/' in symbol else symbol.split(':')[0]
|
|
|
- order_type = order.get('type', 'unknown').upper()
|
|
|
- side = order.get('side', 'unknown').upper()
|
|
|
- price = float(order.get('price', 0))
|
|
|
- amount = float(order.get('amount', 0))
|
|
|
- filled = float(order.get('filled', 0))
|
|
|
- remaining = amount - filled
|
|
|
- status = order.get('status', 'unknown').upper()
|
|
|
+
|
|
|
+ if is_pending_sl:
|
|
|
+ order_type = "STOP (PENDING)"
|
|
|
+ side = order.get('side', 'unknown').upper()
|
|
|
+ price = float(order.get('price', 0)) # This is the trigger price for pending SL
|
|
|
+ amount = float(order.get('amount_requested', 0))
|
|
|
+ status = "PENDING TRIGGER"
|
|
|
+ order_id = order.get('bot_order_ref_id', 'unknown')
|
|
|
+ else:
|
|
|
+ order_type = order.get('type', 'unknown').upper()
|
|
|
+ side = order.get('side', 'unknown').upper()
|
|
|
+ price = float(order.get('price', 0))
|
|
|
+ amount = float(order.get('amount', 0))
|
|
|
+ filled = float(order.get('filled', 0))
|
|
|
+ amount = amount - filled # Show remaining amount
|
|
|
+ status = order.get('status', 'unknown').upper()
|
|
|
+ order_id = order.get('id', 'unknown')
|
|
|
|
|
|
# Skip fully filled orders
|
|
|
- if remaining <= 0:
|
|
|
+ if amount <= 0:
|
|
|
continue
|
|
|
-
|
|
|
+
|
|
|
# Format order details
|
|
|
formatter = self._get_formatter()
|
|
|
price_str = await formatter.format_price_with_symbol(price, base_asset)
|
|
|
- amount_str = await formatter.format_amount(remaining, base_asset)
|
|
|
+ amount_str = await formatter.format_amount(amount, base_asset)
|
|
|
|
|
|
# Order header
|
|
|
side_emoji = "🟢" if side == "BUY" else "🔴"
|
|
|
orders_text += f"{side_emoji} <b>{base_asset} {side} {order_type}</b>\n"
|
|
|
+ orders_text += f" Status: {status}\n"
|
|
|
orders_text += f" 📏 Amount: {amount_str} {base_asset}\n"
|
|
|
- orders_text += f" 💰 Price: {price_str}\n"
|
|
|
+ orders_text += f" 💰 {'Trigger Price' if is_pending_sl else 'Price'}: {price_str}\n"
|
|
|
|
|
|
- # Add order type specific info
|
|
|
- if order_type == "STOP_LOSS" or order_type == "TAKE_PROFIT":
|
|
|
+ # Add order type specific info for exchange orders
|
|
|
+ if not is_pending_sl and (order_type == "STOP_LOSS" or order_type == "TAKE_PROFIT"):
|
|
|
trigger_price = order.get('info', {}).get('triggerPrice')
|
|
|
if trigger_price:
|
|
|
trigger_price_str = await formatter.format_price_with_symbol(float(trigger_price), base_asset)
|
|
|
orders_text += f" 🎯 Trigger: {trigger_price_str}\n"
|
|
|
-
|
|
|
+
|
|
|
# Add order ID
|
|
|
- order_id = order.get('id', 'unknown')
|
|
|
- orders_text += f" 🆔 Order ID: {order_id[:8]}\n\n"
|
|
|
+ id_label = "Bot Ref ID" if is_pending_sl else "Order ID"
|
|
|
+ orders_text += f" 🆔 {id_label}: {order_id[:12]}\n\n"
|
|
|
|
|
|
except Exception as e:
|
|
|
- logger.error(f"Error processing order {order.get('symbol', 'unknown')}: {e}")
|
|
|
+ logger.error(f"Error processing order {order.get('symbol', 'unknown')}: {e}", exc_info=True)
|
|
|
continue
|
|
|
-
|
|
|
+
|
|
|
# Add footer
|
|
|
- orders_text += "💡 Use /long, /short, /sl, or /tp to create orders"
|
|
|
+ orders_text += "💡 Pending SL orders are activated when the entry order fills."
|
|
|
|
|
|
await self._reply(update, orders_text.strip())
|
|
|
|
|
|
except Exception as e:
|
|
|
- logger.error(f"Error in orders command: {e}")
|
|
|
+ logger.error(f"Error in orders command: {e}", exc_info=True)
|
|
|
await self._reply(update, "❌ Error retrieving order information.")
|