123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- #!/usr/bin/env python3
- """
- Hyperliquid Manual Trading Bot - Main Launcher
- A simple launcher for systemd deployment.
- This is the ONLY file you need to run - it handles everything.
- """
- import sys
- import os
- import asyncio
- import logging
- import signal
- from datetime import datetime
- from pathlib import Path
- # Bot version
- BOT_VERSION = "2.2.0"
- # Add src directory to Python path
- sys.path.insert(0, str(Path(__file__).parent / "src"))
- try:
- from src.config.config import Config
- from src.bot.core import TelegramTradingBot
- from src.trading.trading_stats import TradingStats
- except ImportError as e:
- print(f"โ Import error: {e}")
- print("๐ก Make sure you're in the correct directory and dependencies are installed")
- sys.exit(1)
- # Global variables for graceful shutdown
- bot_instance = None
- is_shutting_down = False
- class BotManager:
- """Manages the trading bot with simple startup and shutdown."""
-
- def __init__(self):
- self.bot = None
- self.setup_logging()
-
- # Ensure logs directory exists
- os.makedirs("logs", exist_ok=True)
-
- def setup_logging(self):
- """Set up comprehensive logging."""
- # Create logs directory
- os.makedirs("logs", exist_ok=True)
-
- # Set up file logging
- log_file = f"logs/trading_bot_{datetime.now().strftime('%Y%m%d')}.log"
-
- try:
- from src.config.logging_config import setup_logging
- setup_logging()
- self.logger = logging.getLogger(__name__)
- self.logger.info(f"Logging initialized - Log file: {log_file}")
- except Exception as e:
- # Fallback logging setup
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
- handlers=[
- logging.FileHandler(log_file),
- logging.StreamHandler()
- ]
- )
- self.logger = logging.getLogger(__name__)
- self.logger.warning(f"Failed to setup advanced logging, using basic setup: {e}")
-
- def print_banner(self):
- """Print startup banner."""
- banner = f"""
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ ๐ฑ HYPERLIQUID TRADING BOT โ
- โ Version {BOT_VERSION} โ
- โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
- โ โ
- โ ๐ค Manual phone control via Telegram โ
- โ ๐ Comprehensive trading statistics โ
- โ ๐ก๏ธ Systemd managed service โ
- โ ๐พ Persistent data between restarts โ
- โ ๐ฑ Professional mobile interface โ
- โ โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- ๐ Starting at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
- ๐ Working directory: {os.getcwd()}
- ๐ Network: {'Testnet' if Config.HYPERLIQUID_TESTNET else '๐จ MAINNET ๐จ'}
- """
- print(banner)
-
- def validate_configuration(self):
- """Validate bot configuration."""
- self.logger.info("๐ Validating configuration...")
-
- missing_config = []
-
- if not hasattr(Config, 'HYPERLIQUID_WALLET_ADDRESS') or not Config.HYPERLIQUID_WALLET_ADDRESS:
- missing_config.append("HYPERLIQUID_WALLET_ADDRESS")
-
- if not hasattr(Config, 'TELEGRAM_BOT_TOKEN') or not Config.TELEGRAM_BOT_TOKEN:
- missing_config.append("TELEGRAM_BOT_TOKEN")
-
- if not hasattr(Config, 'TELEGRAM_CHAT_ID') or not Config.TELEGRAM_CHAT_ID:
- missing_config.append("TELEGRAM_CHAT_ID")
-
- if not hasattr(Config, 'TELEGRAM_ENABLED') or not Config.TELEGRAM_ENABLED:
- missing_config.append("TELEGRAM_ENABLED (must be true)")
-
- if missing_config:
- error_msg = f"โ Missing configuration: {', '.join(missing_config)}"
- self.logger.error(error_msg)
- print(f"\n{error_msg}")
- print("\n๐ก Setup steps:")
- print("1. Copy config: cp config/env.example .env")
- print("2. Get Telegram setup: python utils/get_telegram_chat_id.py")
- print("3. Edit .env with your details")
- print("4. See: SETUP_GUIDE.md for detailed instructions")
- return False
-
- self.logger.info("โ
Configuration validation passed")
- return True
-
- def check_stats_persistence(self):
- """Check and report on statistics persistence."""
- stats_file = "trading_stats.json"
- if os.path.exists(stats_file):
- try:
- stats = TradingStats()
- basic_stats = stats.get_basic_stats()
- self.logger.info(f"๐ Existing stats found - {basic_stats['total_trades']} trades since {basic_stats.get('start_date', 'unknown')}")
- return True
- except Exception as e:
- self.logger.warning(f"โ ๏ธ Stats file exists but couldn't load: {e}")
- return False
- else:
- self.logger.info("๐ No existing stats - will create new tracking from launch")
- return False
-
- async def run_bot(self):
- """Run the main bot."""
- global is_shutting_down
-
- try:
- self.logger.info("๐ค Creating TelegramTradingBot instance...")
- self.bot = TelegramTradingBot()
-
- # Set version for bot to use in messages
- self.bot.version = BOT_VERSION
-
- self.logger.info("๐ Checking statistics persistence...")
- self.check_stats_persistence()
-
- self.logger.info("๐ Starting Telegram bot...")
-
- # Run the bot
- await self.bot.run()
-
- except KeyboardInterrupt:
- self.logger.info("๐ Bot stopped by user (Ctrl+C)")
- is_shutting_down = True
-
- except Exception as e:
- self.logger.error(f"โ Bot error: {e}")
- raise
-
- async def start(self):
- """Main entry point."""
- try:
- self.print_banner()
-
- if not self.validate_configuration():
- return False
-
- self.logger.info("๐ฏ All systems ready - starting trading bot...")
- print("๐ก Send /start to your Telegram bot for quick actions")
- print("๐ Press Ctrl+C to stop\n")
-
- await self.run_bot()
-
- return True
-
- except Exception as e:
- self.logger.error(f"โ Fatal error in bot manager: {e}")
- print(f"\n๐ฅ Fatal error: {e}")
- return False
- def signal_handler(signum, frame):
- """Handle shutdown signals gracefully."""
- global is_shutting_down, bot_instance
-
- print("\n๐ Shutdown signal received...")
- is_shutting_down = True
- def main():
- """Main function."""
- global bot_instance
-
- # Set up signal handlers for graceful shutdown
- signal.signal(signal.SIGINT, signal_handler)
- signal.signal(signal.SIGTERM, signal_handler)
-
- try:
- bot_manager = BotManager()
- bot_instance = bot_manager
-
- # Run the bot
- success = asyncio.run(bot_manager.start())
-
- if success:
- print("\nโ
Bot session completed successfully")
- else:
- print("\nโ Bot session failed")
- sys.exit(1)
-
- except KeyboardInterrupt:
- print("\n๐ Bot stopped by user")
- except Exception as e:
- print(f"\n๐ฅ Unexpected error: {e}")
- sys.exit(1)
- finally:
- print("๐ Your trading statistics have been saved")
- if __name__ == "__main__":
- main()
|