import asyncio import logging import signal from src.config import get_config from src.bot.binance_client import BinanceClientWrapper from src.bot.engine import TradingEngine from src.integrations.telegram_notifier import TelegramNotifier from src.integrations.obsidian_logger import ObsidianLogger from src.strategies.dca import DCAStrategy # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) async def main(): """Main bot entry point""" # Load config config = get_config() logger.info(f"Starting bot | Environment: {config.environment} | Pair: {config.trading_pair}") # Select credentials based on environment if config.environment == "testnet": api_key = config.binance_api_key_testnet api_secret = config.binance_api_secret_testnet else: api_key = config.binance_api_key_live api_secret = config.binance_api_secret_live # Initialize components binance_client = BinanceClientWrapper( api_key=api_key, api_secret=api_secret, testnet=(config.environment == "testnet") ) telegram = TelegramNotifier( bot_token=config.telegram_bot_token, chat_id=config.telegram_chat_id ) obsidian = ObsidianLogger( vault_path=config.obsidian_vault_path, trade_log_file=config.obsidian_trade_log_file ) strategy = DCAStrategy( trading_pair=config.trading_pair, dca_amount_usd=config.dca_amount_usd, interval_hours=config.dca_interval_hours, stop_loss_percent=config.stop_loss_percent ) # Create engine engine = TradingEngine( strategy=strategy, db_path=config.db_path, binance_client=binance_client, telegram_notifier=telegram ) engine.dry_run = config.dry_run # Enable dry-run mode if configured # Initialize await engine.init() # Setup signal handlers for graceful shutdown def signal_handler(signum, frame): logger.info("Shutdown signal received") asyncio.create_task(engine.shutdown()) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) # Send startup message startup_msg = f""" ✅ Bot Started Environment: {config.environment} Pair: {config.trading_pair} DCA Amount: ${config.dca_amount_usd} Interval: {config.dca_interval_hours}h Stop Loss: {config.stop_loss_percent}% """ await telegram.send_alert(startup_msg) # Start trading try: await engine.start() except Exception as e: logger.error(f"Bot fatal error: {e}") await telegram.send_alert(f"❌ Bot crashed: {str(e)}") raise finally: await engine.shutdown() if __name__ == "__main__": asyncio.run(main())