← Назад
""" WT Bot v3 β€” Main Entry Point ================================ Π“Π»Π°Π²Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ»: 1. Nuclear cleanup ΠΏΡ€ΠΈ стартС 2. Recovery ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ 3. ΠšΠ°ΠΆΠ΄Ρ‹Π΅ 5 ΠΌΠΈΠ½ β€” скан Ρ€Ρ‹Π½ΠΊΠ° 4. ΠšΠ°ΠΆΠ΄Ρ‹Π΅ 5 сСк β€” ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° вайтлиста Π½Π° cross + ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ """ import asyncio import logging import sys import os import time # Add project root to path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from src.config import SCAN_INTERVAL_SEC, DATA_DIR from src.exchange import Exchange from src.screener import Screener from src.manager import TradeManager from src.bot import TelegramBot from src.tmm_client import TMMClient # ============================================================ # LOGGING # ============================================================ logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) logger = logging.getLogger("main") # Suppress noisy libs logging.getLogger("urllib3").setLevel(logging.WARNING) logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("telegram").setLevel(logging.WARNING) # ============================================================ # MAIN # ============================================================ async def main(): logger.info("=" * 50) logger.info("WT Bot v3 starting...") logger.info("Strategy: S3_EMA_Filter | TF: 5m | SL 2% / TP 3%") logger.info("=" * 50) # Ensure data dir exists os.makedirs(DATA_DIR, exist_ok=True) # Init components exchange = Exchange() notify_queue = asyncio.Queue() def sync_notify(msg): """Sync wrapper β€” ΠΊΠ»Π°Π΄Ρ‘Ρ‚ сообщСниС Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ для async ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ.""" try: notify_queue.put_nowait(msg) except Exception: pass screener = Screener(exchange, notifier=sync_notify) tmm = TMMClient() bot = TelegramBot(screener=screener, exchange=exchange, tmm=tmm) manager = TradeManager(exchange, screener, notifier=sync_notify, tmm=tmm) screener.get_open_positions = lambda: manager.positions # skip WL for open positions bot.manager = manager # Start Telegram bot await bot.start() logger.info("Telegram bot started") # Startup notification balance = exchange.get_balance() await bot.send_message( f"πŸš€ *WT Bot v3 started*\n" f"Balance: ${balance:.2f}\n" f"Positions: {len(manager.positions)}\n" f"Strategy: S3\\_EMA\\_Filter 5m\n" f"SL 2% / TP 3% | $5Γ—10x" ) # Nuclear cleanup logger.info("Nuclear cleanup...") exchange.nuclear_cleanup() # Recovery logger.info("Recovery check...") manager.recovery() # Main loop last_scan = 0 check_interval = 5 # сСкунд ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°ΠΌΠΈ cross/positions logger.info("Entering main loop...") try: while True: now = time.time() # === SCAN (ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 ΠΌΠΈΠ½) === if now - last_scan >= SCAN_INTERVAL_SEC: try: screener.run_scan() last_scan = now except Exception as e: logger.error(f"Scan error: {e}") last_scan = now # НС спамим ΠΏΡ€ΠΈ ошибкС # === CHECK WHITELIST FOR ENTRIES === try: manager.check_whitelist_for_entries() except Exception as e: logger.error(f"Entry check error: {e}") # === MONITOR POSITIONS === try: manager.check_positions() except Exception as e: logger.error(f"Position check error: {e}") # === TMM RETRY PENDING TAGS === try: tmm.retry_pending_tags() except Exception: pass # === PROCESS NOTIFY QUEUE === while not notify_queue.empty(): try: msg = notify_queue.get_nowait() await bot.send_message(msg) except Exception: break # Sleep await asyncio.sleep(check_interval) except KeyboardInterrupt: logger.info("Shutting down...") except Exception as e: logger.error(f"Fatal error: {e}", exc_info=True) await bot.send_message(f"πŸ’€ *Bot crashed:* {str(e)[:200]}") finally: await bot.stop() logger.info("Bot stopped") if __name__ == "__main__": asyncio.run(main())