Spaces:
Running
Running
| # trade_manager.py (V12.0 - Titan Executor) | |
| import asyncio | |
| import time | |
| from datetime import datetime | |
| from typing import Dict, List, Deque | |
| from collections import deque | |
| import numpy as np | |
| import ccxt.async_support as ccxtasync | |
| class TacticalData: | |
| """مخزن بيانات تكتيكي يدعم متطلبات Titan الكاملة""" | |
| def __init__(self, symbol): | |
| self.symbol = symbol | |
| self.order_book = None | |
| self.trades = deque(maxlen=1000) | |
| self.cvd = 0.0 | |
| # أطر Titan الكاملة | |
| self.ohlcv = {tf: deque(maxlen=500) for tf in ['5m', '15m', '1h', '4h', '1d']} | |
| self.last_update = time.time() | |
| def update_ohlcv(self, tf, candles): | |
| if not candles: return | |
| # تحديث ذكي: نضيف فقط الشموع الجديدة | |
| current = self.ohlcv[tf] | |
| last_ts = current[-1][0] if len(current) > 0 else 0 | |
| new_candles = [c for c in candles if c[0] > last_ts] | |
| current.extend(new_candles) | |
| def get_titan_packet(self): | |
| """تجهيز حزمة البيانات لمحرك Titan""" | |
| # نحتاج على الأقل 200 شمعة في الفريمات الرئيسية ليعمل Titan بدقة | |
| if len(self.ohlcv['5m']) < 200 or len(self.ohlcv['1h']) < 200: | |
| return None | |
| return {tf: list(data) for tf, data in self.ohlcv.items()} | |
| class TradeManager: | |
| def __init__(self, r2_service, data_manager, titan_engine=None): | |
| self.r2 = r2_service | |
| self.dm = data_manager | |
| self.titan = titan_engine # محرك Titan | |
| self.is_running = False | |
| self.watchlist = {} | |
| self.tasks = {} | |
| self.data_cache = {} | |
| self.lock = asyncio.Lock() | |
| self.exchange = None | |
| # استيراد العتبات من DataManager | |
| self.ENTRY_THRESH = self.dm.TITAN_ENTRY_THRESHOLD if self.dm else 0.90 | |
| print(f"⚔️ [TradeManager] Titan Executor Ready. Entry Threshold: {self.ENTRY_THRESH}") | |
| async def initialize_sentry_exchanges(self): | |
| self.exchange = ccxtasync.kucoin({'enableRateLimit': True, 'timeout': 20000}) | |
| await self.exchange.load_markets() | |
| async def start_sentry_loops(self): | |
| self.is_running = True | |
| while self.is_running: | |
| await asyncio.sleep(5) | |
| async with self.lock: | |
| targets = list(self.watchlist.keys()) | |
| for sym in targets: | |
| if sym not in self.tasks: | |
| print(f"🛡️ [Sentry] Starting monitor for {sym}") | |
| self.data_cache[sym] = TacticalData(sym) | |
| self.tasks[sym] = asyncio.create_task(self._monitor_symbol(sym)) | |
| async def stop_sentry_loops(self): | |
| self.is_running = False | |
| for t in self.tasks.values(): t.cancel() | |
| if self.exchange: await self.exchange.close() | |
| async def update_sentry_watchlist(self, candidates): | |
| async with self.lock: | |
| self.watchlist = {c['symbol']: c for c in candidates} | |
| print(f"📋 [Sentry] Watchlist updated: {len(candidates)} targets.") | |
| async def _monitor_symbol(self, symbol): | |
| # حلقة المراقبة: تجلب البيانات وتحللها | |
| while self.is_running and symbol in self.watchlist: | |
| try: | |
| # 1. جلب البيانات الحية لكل الأطر المطلوبة لـ Titan | |
| # نقوم بالجلب بالتوازي للسرعة | |
| tfs = ['5m', '15m', '1h', '4h', '1d'] | |
| tasks = [self.exchange.fetch_ohlcv(symbol, tf, limit=100) for tf in tfs] | |
| # نضيف جلب دفتر الأوامر للتحليل اللحظي | |
| tasks.append(self.exchange.fetch_order_book(symbol, limit=20)) | |
| results = await asyncio.gather(*tasks, return_exceptions=True) | |
| data = self.data_cache[symbol] | |
| for i, tf in enumerate(tfs): | |
| if isinstance(results[i], list): | |
| data.update_ohlcv(tf, results[i]) | |
| if not isinstance(results[-1], Exception): | |
| data.order_book = results[-1] | |
| # 2. استشارة Titan (كل دقيقة تقريباً أو عند اكتمال شمعة 5m) | |
| titan_packet = data.get_titan_packet() | |
| if titan_packet and self.titan: | |
| prediction = self.titan.predict(titan_packet) | |
| score = prediction.get('score', 0.0) | |
| # 3. قرار الدخول | |
| if score >= self.ENTRY_THRESH: | |
| print(f"🚀 [EXECUTOR] Titan Signal! {symbol} Score: {score:.4f} >= {self.ENTRY_THRESH}") | |
| await self._execute_entry(symbol, score) | |
| # إزالة من المراقبة بعد الدخول | |
| async with self.lock: self.watchlist.pop(symbol, None) | |
| break | |
| elif score > 0.7: | |
| # طباعة فقط للتشويق إذا اقتربنا | |
| print(f"👀 [Sentry] {symbol} warming up... Score: {score:.4f}") | |
| await asyncio.sleep(60) # فحص كل دقيقة (كافٍ لنموذج يعتمد على 5m) | |
| except Exception as e: | |
| print(f"⚠️ [Monitor Error] {symbol}: {e}") | |
| await asyncio.sleep(10) | |
| async def _execute_entry(self, symbol, score): | |
| # تنفيذ صفقة (ورقية حالياً) | |
| price = (await self.exchange.fetch_ticker(symbol))['last'] | |
| trade = { | |
| "symbol": symbol, "entry_price": price, "score": score, | |
| "timestamp": datetime.now().isoformat(), "status": "OPEN", | |
| "tp": price * 1.015, "sl": price * 0.9925 | |
| } | |
| # حفظ الصفقة (يمكنك ربطها بـ R2 هنا) | |
| print(f"✅ [TRADE OPENED] {json.dumps(trade, indent=2)}") |