浏览代码

Re-enable and enhance copy trading commands in TelegramTradingBot

- Restored initialization of CopyTradingCommands, allowing users to access copy trading functionalities.
- Updated command handlers to include subcommands for copy trading: status, start, and stop.
- Improved regex filter to recognize "COPY" command in keyboard inputs.
- Added detailed help message for copy trading commands to guide users on usage and features.
Carles Sentis 5 天之前
父节点
当前提交
6c7e0cc64b
共有 3 个文件被更改,包括 85 次插入12 次删除
  1. 19 11
      src/bot/core.py
  2. 65 0
      src/commands/copy_trading_commands.py
  3. 1 1
      trading_bot.py

+ 19 - 11
src/bot/core.py

@@ -31,8 +31,7 @@ from src.commands.info.risk import RiskCommands
 from src.commands.info.price import PriceCommands
 from src.commands.info.balance_adjustments import BalanceAdjustmentsCommands
 from src.commands.info.commands import CommandsInfo
-# TEMPORARY: Disable copy trading commands to prevent blocking I/O
-# from src.commands.copy_trading_commands import CopyTradingCommands
+from src.commands.copy_trading_commands import CopyTradingCommands
 
 logger = logging.getLogger(__name__)
 
@@ -72,8 +71,7 @@ class TelegramTradingBot:
         self.price_cmds = PriceCommands(self.trading_engine, self.notification_manager)
         self.balance_adjustments_cmds = BalanceAdjustmentsCommands(self.trading_engine, self.notification_manager)
         self.commands_cmds = CommandsInfo(self.trading_engine, self.notification_manager)
-        # TEMPORARY: Disable copy trading commands to prevent blocking I/O
-        # self.copy_trading_cmds = CopyTradingCommands(self.monitoring_coordinator)
+        self.copy_trading_cmds = CopyTradingCommands(self.monitoring_coordinator)
 
         # Create a class to hold all info commands
         class InfoCommandsHandler:
@@ -156,6 +154,9 @@ class TelegramTradingBot:
         self.application.add_handler(CommandHandler("commands", self.commands_cmds.commands_command))
         self.application.add_handler(CommandHandler("c", self.commands_cmds.commands_command))  # Alias
         
+        # Copy trading commands (single command with subcommands)
+        self.application.add_handler(CommandHandler("copy", self.copy_trading_cmds.copy_command))
+        
         # Management commands
         self.application.add_handler(CommandHandler("monitoring", self.management_commands.monitoring_command))
         self.application.add_handler(CommandHandler("alarm", self.management_commands.alarm_command))
@@ -171,7 +172,7 @@ class TelegramTradingBot:
         # Callback and message handlers
         self.application.add_handler(CallbackQueryHandler(self.trading_commands.button_callback))
         self.application.add_handler(MessageHandler(
-            filters.Regex(r'^(LONG|SHORT|EXIT|SL|TP|LEVERAGE|BALANCE|POSITIONS|ORDERS|STATS|MARKET|PERFORMANCE|DAILY|WEEKLY|MONTHLY|RISK|ALARM|MONITORING|LOGS|DEBUG|VERSION|COMMANDS|KEYBOARD|COO)'),
+            filters.Regex(r'^(LONG|SHORT|EXIT|SL|TP|LEVERAGE|BALANCE|POSITIONS|ORDERS|STATS|MARKET|PERFORMANCE|DAILY|WEEKLY|MONTHLY|RISK|ALARM|MONITORING|LOGS|DEBUG|VERSION|COMMANDS|KEYBOARD|COO|COPY)'),
             self.handle_keyboard_command
         ))
         
@@ -206,6 +207,7 @@ class TelegramTradingBot:
             "DEBUG": self.management_commands.debug_command,
             "VERSION": self.management_commands.version_command,
             "KEYBOARD": self.management_commands.keyboard_command,
+            "COPY": self._handle_copy_status_keyboard,
         }
 
         command_func = command_map.get(command_text)
@@ -221,6 +223,12 @@ class TelegramTradingBot:
                 f"Unknown command: {command_text}", chat_id=update.effective_chat.id
             )
 
+    async def _handle_copy_status_keyboard(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
+        """Handle COPY keyboard command by showing copy trading status."""
+        # Set context.args to simulate /copy status
+        context.args = ["status"]
+        await self.copy_trading_cmds.copy_command(update, context)
+
     async def start_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
         """Handle the /start command."""
         logger.info(f"/start command triggered by chat_id: {update.effective_chat.id}")
@@ -294,9 +302,9 @@ class TelegramTradingBot:
 • /alarm 3 - Remove alarm ID 3
 
 <b>🔄 Copy Trading:</b>
-• /copy_status - View copy trading status & session info
-• /copy_start [address] - Start copying a target trader
-• /copy_stop - Stop copy trading (preserves session)
+• /copy status - View copy trading status & session info
+• /copy start [address] - Start copying a target trader
+• /copy stop - Stop copy trading (preserves session)
 
 <b>🔄 Automatic Monitoring:</b>
 • Real-time order fill alerts
@@ -394,9 +402,9 @@ For support, contact your bot administrator.
 • /sync force - Clear local data and resync with exchange
 
 🔄 <b>Copy Trading:</b>
-• /copy_status - View copy trading status & configuration
-• /copy_start [address] - Start copying a target trader's positions
-• /copy_stop - Stop copy trading (session data preserved)
+• /copy status - View copy trading status & configuration
+• /copy start [address] - Start copying a target trader's positions
+• /copy stop - Stop copy trading (session data preserved)
 
 For support or issues, check the logs or contact the administrator.
         """

+ 65 - 0
src/commands/copy_trading_commands.py

@@ -24,6 +24,71 @@ class CopyTradingCommands:
         """Check if the chat ID is authorized."""
         return str(chat_id) == str(Config.TELEGRAM_CHAT_ID)
     
+    async def copy_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
+        """Handle the /copy command with subcommands: status, start, stop."""
+        chat_id = update.effective_chat.id
+        if not self._is_authorized(chat_id):
+            await context.bot.send_message(chat_id=chat_id, text="❌ Unauthorized access.")
+            return
+        
+        # Parse subcommand
+        if not context.args or len(context.args) == 0:
+            # No subcommand provided, show help
+            await self._copy_help(update, context)
+            return
+        
+        subcommand = context.args[0].lower()
+        
+        if subcommand == "status":
+            await self.copy_status_command(update, context)
+        elif subcommand == "start":
+            # Pass remaining args (target address) to start command
+            context.args = context.args[1:]  # Remove 'start' from args
+            await self.copy_start_command(update, context)
+        elif subcommand == "stop":
+            await self.copy_stop_command(update, context)
+        else:
+            # Invalid subcommand
+            await context.bot.send_message(
+                chat_id=chat_id,
+                text=f"❌ Unknown copy trading command: '{subcommand}'\n\nUse /copy without arguments to see available commands.",
+                parse_mode='HTML'
+            )
+    
+    async def _copy_help(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
+        """Show copy trading help."""
+        chat_id = update.effective_chat.id
+        
+        help_text = """
+🔄 <b>Copy Trading Commands</b>
+
+<b>Available Commands:</b>
+• <code>/copy status</code> - View copy trading status & session info
+• <code>/copy start [address]</code> - Start copying a target trader
+• <code>/copy stop</code> - Stop copy trading (preserves session)
+
+<b>Examples:</b>
+• <code>/copy status</code>
+• <code>/copy start 0x1234567890abcdef1234567890abcdef12345678</code>
+• <code>/copy stop</code>
+
+<b>Features:</b>
+• 📊 Real-time position monitoring
+• 🔄 Automatic trade copying
+• 💰 Configurable portfolio allocation
+• 📱 Full notification support
+• 💾 Session persistence (can resume after stop)
+• ⚠️ Only copies NEW trades (skips existing positions)
+
+Use <code>/copy status</code> to check current status and configuration.
+        """
+        
+        await context.bot.send_message(
+            chat_id=chat_id,
+            text=help_text,
+            parse_mode='HTML'
+        )
+    
     async def copy_status_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
         """Handle the /copy_status command."""
         chat_id = update.effective_chat.id

+ 1 - 1
trading_bot.py

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