File size: 9,131 Bytes
80c1546
2e06244
80c1546
701d42d
3a93a42
2e06244
 
80c1546
701d42d
2e06244
 
80c1546
2e06244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80c1546
701d42d
 
2e06244
 
 
 
 
ed906df
2e06244
 
 
 
 
 
80c1546
2e06244
 
3e520df
2e06244
 
 
 
 
 
 
80c1546
2e06244
80c1546
 
2e06244
ed906df
2e06244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92c2517
2e06244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1cd9326
2e06244
 
1cd9326
c89ab1f
2e06244
c89ab1f
 
2e06244
 
c89ab1f
1cd9326
80c1546
2e06244
 
 
c89ab1f
2e06244
c89ab1f
 
 
 
 
 
 
2e06244
 
 
c89ab1f
 
 
2e06244
 
ed906df
2e06244
c89ab1f
2e06244
83392dd
c89ab1f
 
 
2e06244
ed906df
2e06244
c89ab1f
2e06244
3a93a42
92c2517
701d42d
2e06244
701d42d
1cd9326
2e06244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# ml_engine/processor.py
# (V13.0 - The Central Nervous System - Full Orchestration)

import asyncio
import traceback
import logging
import os
import numpy as np

# --- استيراد المحركات الفرعية ---
# ملاحظة: نفترض أن جميع الملفات موجودة في نفس المجلد ml_engine
try:
    from .titan_engine import TitanEngine
    from .patterns import ChartPatternAnalyzer
    from .monte_carlo import MonteCarloAnalyzer
    from .oracle_engine import OracleEngine
    from .sniper_engine import SniperEngine
    from .hybrid_guardian import HybridDeepSteward
except ImportError as e:
    # Fallback للإستيراد المحلي إذا تم التشغيل كسكربت منفصل
    print(f"⚠️ [Processor] Import Warning: {e}")
    from titan_engine import TitanEngine
    from patterns import ChartPatternAnalyzer
    from monte_carlo import MonteCarloAnalyzer
    from oracle_engine import OracleEngine
    from sniper_engine import SniperEngine
    from hybrid_guardian import HybridDeepSteward

# إعداد المسارات الافتراضية للنماذج
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MODELS_L2_DIR = os.path.join(BASE_DIR, "ml_models", "layer2")
MODELS_PATTERN_DIR = os.path.join(BASE_DIR, "ml_models", "xgboost_pattern2")
MODELS_UNIFIED_DIR = os.path.join(BASE_DIR, "ml_models", "Unified_Models_V1")
MODELS_GUARD_DIR = os.path.join(BASE_DIR, "ml_models", "guard_v2")

# مسارات الحارس الهجين
GUARD_V2_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_Production_V1.json")
GUARD_V3_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Production.json")
GUARD_V3_FEAT_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Features.json")


class MLProcessor:
    """
    💎 GEM-Architect Design:
    وحدة المعالجة المركزية (CPU) للمنصة.
    هي الوحيدة المخولة بالتواصل مع جميع المحركات الفرعية (Titan, Patterns, Oracle, Sniper, Guardian).
    """

    def __init__(self, data_manager=None):
        self.data_manager = data_manager # للاستخدام المستقبلي إذا احتاج المعالج جلب بيانات بنفسه
        
        # 1. تهيئة الكائنات (Instances) للمحركات
        self.titan = TitanEngine(model_dir=MODELS_L2_DIR)
        self.pattern_engine = ChartPatternAnalyzer(models_dir=MODELS_PATTERN_DIR)
        self.mc_analyzer = MonteCarloAnalyzer()
        self.oracle = OracleEngine(model_dir=MODELS_UNIFIED_DIR)
        self.sniper = SniperEngine(models_dir=MODELS_GUARD_DIR)
        
        # الحارس الهجين يتطلب مسارات ملفات محددة
        self.guardian = HybridDeepSteward(
            v2_model_path=GUARD_V2_PATH,
            v3_model_path=GUARD_V3_PATH,
            v3_features_map_path=GUARD_V3_FEAT_PATH
        )

        self.initialized = False
        print("🧠 [MLProcessor V13] Central Brain Created. Waiting for initialization...")

    async def initialize(self):
        """تهيئة متوازية لجميع المحركات الفرعية لتقليل وقت التشغيل"""
        if not self.initialized:
            print("⚙️ [Processor] بدء تهيئة النظام العصبي الكامل...")
            try:
                # تجميع مهام التهيئة غير المتزامنة
                tasks = []
                
                # Titan
                if hasattr(self.titan, 'initialize'): tasks.append(self.titan.initialize())
                # Patterns
                if hasattr(self.pattern_engine, 'initialize'): tasks.append(self.pattern_engine.initialize())
                # Oracle
                if hasattr(self.oracle, 'initialize'): tasks.append(self.oracle.initialize())
                # Sniper
                if hasattr(self.sniper, 'initialize'): tasks.append(self.sniper.initialize())
                
                # تشغيل المهام المتزامنة
                if tasks:
                    await asyncio.gather(*tasks)

                # الحارس الهجين (متزامن حالياً)
                if hasattr(self.guardian, 'initialize'):
                    self.guardian.initialize()

                self.initialized = True
                print("✅ [Processor] جميع المحركات جاهزة للعمل.")
                
            except Exception as e:
                print(f"❌ [Processor FATAL] فشل في تهيئة أحد المحركات: {e}")
                traceback.print_exc()

    # ==========================================================================
    # 🔍 واجهات الاستخدام (API Methods for App.py)
    # ==============================================================================

    # --- 1. التحليل الأولي (L1 Screening & Patterns) ---
    async def process_compound_signal(self, raw_data):
        """
        تشغيل Titan + Patterns + Simple MC للحصول على تقييم أولي (L1/L2 Score).
        يستبدل `process_and_score_symbol_enhanced` القديمة.
        """
        if not self.initialized: await self.initialize()
        
        symbol = raw_data.get('symbol')
        ohlcv_data = raw_data.get('ohlcv')
        current_price = raw_data.get('current_price', 0.0)

        if not symbol or not ohlcv_data: return None

        try:
            # أ. تشغيل Titan & Patterns بالتوازي
            titan_task = asyncio.to_thread(self.titan.predict, ohlcv_data)
            pattern_task = self.pattern_engine.detect_chart_patterns(ohlcv_data)
            
            # ب. تشغيل مونت كارلو السريع (على 1h)
            mc_score = 0.5
            if '1h' in ohlcv_data:
                 closes = np.array([c[4] for c in ohlcv_data['1h']])
                 mc_res = self.mc_analyzer.generate_1h_price_distribution_simple(closes)
                 mc_score = mc_res.get('mc_prob_gain', 0.5)

            # انتظار النتائج
            titan_res, pattern_res = await asyncio.gather(titan_task, pattern_task)
            
            # استخراج الدرجات
            score_titan = titan_res.get('score', 0.0)
            score_patterns = pattern_res.get('pattern_confidence', 0.0)

            # المعادلة الهجينة
            hybrid_score = (score_titan * 0.50) + (score_patterns * 0.40) + (mc_score * 0.10)

            return {
                'symbol': symbol,
                'current_price': current_price,
                'enhanced_final_score': hybrid_score,
                'components': {
                    'titan_score': score_titan,
                    'patterns_score': score_patterns,
                    'mc_score': mc_score
                },
                'ohlcv': ohlcv_data, # تمرير البيانات للمراحل التالية
                'titan_details': titan_res,
                'pattern_details': pattern_res.get('details', {})
            }

        except Exception as e:
            print(f"❌ [Processor] Error processing {symbol}: {e}")
            return None

    # --- 2. التحليل الإحصائي المتقدم (L2 Boosting) ---
    async def run_advanced_monte_carlo(self, ohlcv_data):
        """واجهة لاستدعاء مونت كارلو المتقدم"""
        return await self.mc_analyzer.generate_1h_distribution_advanced(ohlcv_data)

    # --- 3. العقل الاحتمالي (L3 Oracle) ---
    async def consult_oracle(self, symbol_data):
        """واجهة لاستشارة Oracle"""
        if not self.initialized: await self.initialize()
        return await self.oracle.predict(symbol_data)

    # --- 4. القناص (L4 Entry Sniper) ---
    async def check_sniper_entry(self, ohlcv_1m_data):
        """واجهة لاستدعاء Sniper"""
        if not self.initialized: await self.initialize()
        return await self.sniper.check_entry_signal_async(ohlcv_1m_data)
    
    def set_sniper_threshold(self, threshold):
        """تعديل حساسية القناص"""
        if self.sniper:
            self.sniper.set_entry_threshold(threshold)

    # --- 5. الحارس الهجين (Active Trade Management) ---
    def consult_guardian(self, ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price):
        """
        واجهة لاستشارة الحارس الهجين (Hybrid Guardian).
        يعيد قرار: HOLD, EXIT_SOFT, EXIT_HARD
        """
        if not self.guardian or not self.guardian.initialized:
            return {'action': 'HOLD', 'reason': 'Guardian Disabled'}
            
        return self.guardian.analyze_position(ohlcv_1m, ohlcv_5m, ohlcv_15m, float(entry_price))

    # --- 6. الوصول إلى الخصائص الداخلية (للإحصائيات فقط) ---
    @property
    def guardian_instance(self):
        """إتاحة الوصول المباشر للحارس فقط لأغراض عرض الإحصائيات في app.py"""
        return self.guardian

print("✅ ML Processor V13.0 (Unified Orchestrator) loaded.")