File size: 6,056 Bytes
838c59e
9f940b2
490e45e
f3ca3ad
838c59e
 
 
624c411
838c59e
ac2081d
ea523b5
838c59e
ea523b5
 
838c59e
 
 
 
 
ea523b5
 
838c59e
624c411
838c59e
 
 
 
 
 
 
 
 
 
 
 
708a613
490e45e
838c59e
 
 
 
490e45e
838c59e
 
 
 
e73bb85
838c59e
 
 
 
8631d16
838c59e
 
 
ea523b5
838c59e
ea523b5
 
838c59e
 
 
 
 
 
 
 
 
ea523b5
e607284
ea523b5
838c59e
 
7cc7f1a
838c59e
 
 
 
ea523b5
838c59e
 
 
ea523b5
838c59e
 
 
 
 
 
ac2081d
838c59e
e607284
838c59e
 
 
 
624c411
838c59e
 
 
 
 
 
 
 
a283c15
838c59e
 
 
 
 
 
 
 
 
 
 
 
9f940b2
624c411
838c59e
 
624c411
838c59e
 
 
624c411
838c59e
 
 
624c411
838c59e
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# 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)}")