|
@@ -15,10 +15,12 @@ logger = logging.getLogger(__name__)
|
|
|
class TradingCommands:
|
|
|
"""Handles all trading-related Telegram commands."""
|
|
|
|
|
|
- def __init__(self, trading_engine, notification_manager):
|
|
|
- """Initialize with trading engine and notification manager."""
|
|
|
+ def __init__(self, trading_engine, notification_manager, info_commands_handler=None, management_commands_handler=None):
|
|
|
+ """Initialize with trading engine, notification manager, and other command handlers."""
|
|
|
self.trading_engine = trading_engine
|
|
|
self.notification_manager = notification_manager
|
|
|
+ self.info_commands_handler = info_commands_handler
|
|
|
+ self.management_commands_handler = management_commands_handler
|
|
|
|
|
|
def _is_authorized(self, chat_id: str) -> bool:
|
|
|
"""Check if the chat ID is authorized."""
|
|
@@ -472,7 +474,7 @@ This will place a limit {exit_side} order at ${stop_price:,.2f} to protect your
|
|
|
elif position_type == "SHORT" and tp_price >= entry_price:
|
|
|
await context.bot.send_message(chat_id=chat_id, text=(
|
|
|
f"⚠️ Take profit price should be BELOW entry price for short positions\n\n"
|
|
|
- f"�� Your {token} SHORT position:\n"
|
|
|
+ f"📊 Your {token} SHORT position:\n"
|
|
|
f"• Entry Price: ${entry_price:,.2f}\n"
|
|
|
f"• Take Profit: ${tp_price:,.2f} ❌\n\n"
|
|
|
f"💡 Try a lower price like: /tp {token} {entry_price * 0.95:.0f}"
|
|
@@ -588,31 +590,86 @@ This action cannot be undone.
|
|
|
return
|
|
|
|
|
|
callback_data = query.data
|
|
|
+ logger.info(f"Button callback triggered with data: {callback_data}")
|
|
|
+
|
|
|
+ # Define a map for informational and management command callbacks
|
|
|
+ # These commands expect `update` and `context` as if called by a CommandHandler
|
|
|
+ command_action_map = {}
|
|
|
+ if self.info_commands_handler:
|
|
|
+ command_action_map.update({
|
|
|
+ "balance": self.info_commands_handler.balance_command,
|
|
|
+ "positions": self.info_commands_handler.positions_command,
|
|
|
+ "orders": self.info_commands_handler.orders_command,
|
|
|
+ "stats": self.info_commands_handler.stats_command,
|
|
|
+ "price": self.info_commands_handler.price_command,
|
|
|
+ "market": self.info_commands_handler.market_command,
|
|
|
+ "performance": self.info_commands_handler.performance_command,
|
|
|
+ "daily": self.info_commands_handler.daily_command,
|
|
|
+ "weekly": self.info_commands_handler.weekly_command,
|
|
|
+ "monthly": self.info_commands_handler.monthly_command,
|
|
|
+ "trades": self.info_commands_handler.trades_command,
|
|
|
+ # Note: 'help' is handled separately below as its main handler is in TelegramTradingBot core
|
|
|
+ })
|
|
|
|
|
|
- try:
|
|
|
- if callback_data.startswith('confirm_long_'):
|
|
|
- await self._execute_long_callback(query, callback_data)
|
|
|
- elif callback_data.startswith('confirm_short_'):
|
|
|
- await self._execute_short_callback(query, callback_data)
|
|
|
- elif callback_data.startswith('confirm_exit_'):
|
|
|
- await self._execute_exit_callback(query, callback_data)
|
|
|
- elif callback_data.startswith('confirm_sl_'):
|
|
|
- await self._execute_sl_callback(query, callback_data)
|
|
|
- elif callback_data.startswith('confirm_tp_'):
|
|
|
- await self._execute_tp_callback(query, callback_data)
|
|
|
- elif callback_data.startswith('confirm_coo_'):
|
|
|
- await self._execute_coo_callback(query, callback_data)
|
|
|
- elif callback_data == 'cancel_order':
|
|
|
- await query.edit_message_text("❌ Order cancelled.")
|
|
|
-
|
|
|
- # Handle info command button callbacks
|
|
|
- elif callback_data in ['balance', 'positions', 'orders', 'stats', 'trades', 'market', 'price',
|
|
|
- 'performance', 'daily', 'weekly', 'monthly', 'alarm', 'monitoring', 'logs', 'help']:
|
|
|
- await query.edit_message_text(f"✅ Please use /{callback_data} command to get the latest data.")
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- await query.edit_message_text(f"❌ Error processing order: {e}")
|
|
|
- logger.error(f"Error in button callback: {e}")
|
|
|
+ if self.management_commands_handler:
|
|
|
+ command_action_map.update({
|
|
|
+ "alarm": self.management_commands_handler.alarm_command,
|
|
|
+ "monitoring": self.management_commands_handler.monitoring_command,
|
|
|
+ "logs": self.management_commands_handler.logs_command,
|
|
|
+ # Add other management commands here if they have quick action buttons
|
|
|
+ })
|
|
|
+
|
|
|
+ # Check if the callback_data matches a mapped informational/management command
|
|
|
+ if callback_data in command_action_map:
|
|
|
+ command_method = command_action_map[callback_data]
|
|
|
+ try:
|
|
|
+ logger.info(f"Executing {callback_data} command via button callback.")
|
|
|
+ # Edit the original message to indicate the action is being processed
|
|
|
+ # await query.edit_message_text(text=f"🔄 Processing {callback_data.capitalize()}...", parse_mode='HTML') # Optional
|
|
|
+ await command_method(update, context) # Call the actual command method
|
|
|
+ # After the command sends its own message(s), we might want to remove or clean up the original message with buttons.
|
|
|
+ # For now, let the command method handle all responses.
|
|
|
+ # Optionally, delete the message that had the buttons:
|
|
|
+ # await query.message.delete()
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Error executing command '{callback_data}' from button: {e}", exc_info=True)
|
|
|
+ try:
|
|
|
+ await query.message.reply_text(f"❌ Error processing {callback_data.capitalize()}: {e}")
|
|
|
+ except Exception as reply_e:
|
|
|
+ logger.error(f"Failed to send error reply for {callback_data} button: {reply_e}")
|
|
|
+ return # Handled
|
|
|
+
|
|
|
+ # Special handling for 'help' callback from InfoCommands quick menu
|
|
|
+ if callback_data == "help":
|
|
|
+ logger.info("Handling 'help' button callback. Guiding user to /help command.")
|
|
|
+ try:
|
|
|
+ # Remove the inline keyboard from the original message and provide guidance.
|
|
|
+ await query.edit_message_text(
|
|
|
+ text="📖 To view all commands and their descriptions, please type the /help command.",
|
|
|
+ reply_markup=None, # Remove buttons
|
|
|
+ parse_mode='HTML'
|
|
|
+ )
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"Error editing message for 'help' callback: {e}")
|
|
|
+ # Fallback if edit fails (e.g., message too old)
|
|
|
+ await query.message.reply_text("📖 Please type /help for command details.", parse_mode='HTML')
|
|
|
+ return # Handled
|
|
|
+
|
|
|
+ # Existing trading confirmation logic
|
|
|
+ if callback_data.startswith("confirm_long_"):
|
|
|
+ await self._execute_long_callback(query, callback_data)
|
|
|
+ elif callback_data.startswith("confirm_short_"):
|
|
|
+ await self._execute_short_callback(query, callback_data)
|
|
|
+ elif callback_data.startswith("confirm_exit_"):
|
|
|
+ await self._execute_exit_callback(query, callback_data)
|
|
|
+ elif callback_data.startswith("confirm_sl_"):
|
|
|
+ await self._execute_sl_callback(query, callback_data)
|
|
|
+ elif callback_data.startswith("confirm_tp_"):
|
|
|
+ await self._execute_tp_callback(query, callback_data)
|
|
|
+ elif callback_data.startswith("confirm_coo_"):
|
|
|
+ await self._execute_coo_callback(query, callback_data)
|
|
|
+ elif callback_data == 'cancel_order':
|
|
|
+ await query.edit_message_text("❌ Order cancelled.")
|
|
|
|
|
|
async def _execute_long_callback(self, query, callback_data):
|
|
|
"""Execute long order from callback."""
|