Riy777 commited on
Commit
a39c9df
·
verified ·
1 Parent(s): 9b16c7d

Upload processor (80).py

Browse files
Files changed (1) hide show
  1. ml_engine/processor (80).py +393 -0
ml_engine/processor (80).py ADDED
@@ -0,0 +1,393 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================
2
+ # 🧠 ml_engine/processor.py (V36.0 - GEM-Architect: The Cybernetic Processor)
3
+ # ============================================================
4
+
5
+ import asyncio
6
+ import traceback
7
+ import logging
8
+ import os
9
+ import sys
10
+ import numpy as np
11
+ from typing import Dict, Any, List, Optional
12
+
13
+ # --- استيراد المحركات (كما هي) ---
14
+ try: from .titan_engine import TitanEngine
15
+ except ImportError: TitanEngine = None
16
+ try: from .patterns import ChartPatternAnalyzer
17
+ except ImportError: ChartPatternAnalyzer = None
18
+ try: from .monte_carlo import MonteCarloEngine
19
+ except ImportError: MonteCarloEngine = None
20
+ try: from .oracle_engine import OracleEngine
21
+ except ImportError: OracleEngine = None
22
+ try: from .sniper_engine import SniperEngine
23
+ except ImportError: SniperEngine = None
24
+ try: from .hybrid_guardian import HybridDeepSteward
25
+ except ImportError: HybridDeepSteward = None
26
+ try: from .guardian_hydra import GuardianHydra
27
+ except ImportError: GuardianHydra = None
28
+
29
+ # ============================================================
30
+ # 📂 مسارات النماذج
31
+ # ============================================================
32
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33
+ MODELS_L2_DIR = os.path.join(BASE_DIR, "ml_models", "layer2")
34
+ MODELS_PATTERN_DIR = os.path.join(BASE_DIR, "ml_models", "xgboost_pattern2")
35
+ MODELS_UNIFIED_DIR = os.path.join(BASE_DIR, "ml_models", "Unified_Models_V1")
36
+ MODELS_SNIPER_DIR = os.path.join(BASE_DIR, "ml_models", "guard_v2")
37
+ MODELS_HYDRA_DIR = os.path.join(BASE_DIR, "ml_models", "guard_v1")
38
+ MODEL_V2_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V2_Production.json")
39
+ MODEL_V3_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Production.json")
40
+ MODEL_V3_FEAT = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Features.json")
41
+
42
+ # ============================================================
43
+ # 🎛️ SYSTEM LIMITS & THRESHOLDS (Dynamic DNA Container)
44
+ # ============================================================
45
+ class SystemLimits:
46
+ """
47
+ GEM-Architect: The Dynamic Constitution.
48
+ يتم تحديث هذه القيم آلياً بواسطة AdaptiveHub بناءً على حالة السوق (Bull/Bear/etc).
49
+ """
50
+
51
+ # --- Layer 1 (Data Manager Control) ---
52
+ L1_MIN_AFFINITY_SCORE = 15.0 # سيتم الكتابة عليها من الـ DNA
53
+
54
+ # --- Layer 2 Weights (Dynamic) ---
55
+ # هذه الأوزان تتغير حسب أداء النماذج (Tactical Loop) وحالة السوق
56
+ L2_WEIGHT_TITAN = 0.40
57
+ L2_WEIGHT_PATTERNS = 0.30
58
+ L2_WEIGHT_MC = 0.10
59
+ # (Hydra/Sniper قد يساهمون في L2 أو L4 حسب التصميم)
60
+
61
+ # إعدادات الأنماط (تتغير حسب الاستراتيجية)
62
+ PATTERN_TF_WEIGHTS = {'15m': 0.40, '1h': 0.30, '5m': 0.20, '4h': 0.10, '1d': 0.00}
63
+ PATTERN_THRESH_BULLISH = 0.60
64
+ PATTERN_THRESH_BEARISH = 0.40
65
+
66
+ # --- Layer 3 (Oracle) ---
67
+ L3_CONFIDENCE_THRESHOLD = 0.65
68
+ L3_WHALE_IMPACT_MAX = 0.10
69
+ L3_NEWS_IMPACT_MAX = 0.05
70
+ L3_MC_ADVANCED_MAX = 0.10
71
+
72
+ # --- Layer 4 (Sniper & Execution) ---
73
+ L4_ENTRY_THRESHOLD = 0.40
74
+ # أوزان داخلية لـ Sniper (ML vs OrderBook)
75
+ L4_WEIGHT_ML = 0.60
76
+ L4_WEIGHT_OB = 0.40
77
+ # نسبة الجدار المسموح بها (تتغير جذرياً بين Bull و Bear)
78
+ L4_OB_WALL_RATIO = 0.40
79
+
80
+ # --- Layer 0: Hydra & Guardian Thresholds ---
81
+ HYDRA_CRASH_THRESH = 0.60
82
+ HYDRA_GIVEBACK_THRESH = 0.70
83
+ HYDRA_STAGNATION_THRESH = 0.50
84
+
85
+ # Legacy Guard Thresholds
86
+ LEGACY_V2_PANIC_THRESH = 0.95
87
+ LEGACY_V3_HARD_THRESH = 0.95
88
+ LEGACY_V3_SOFT_THRESH = 0.85
89
+ LEGACY_V3_ULTRA_THRESH = 0.98
90
+
91
+ @classmethod
92
+ def to_dict(cls) -> Dict[str, Any]:
93
+ return {k: v for k, v in cls.__dict__.items() if not k.startswith('__') and not callable(v)}
94
+
95
+ @classmethod
96
+ def update_from_dict(cls, config: Dict[str, Any]):
97
+ """تحديث القيم من AdaptiveHub"""
98
+ if not config: return
99
+ for k, v in config.items():
100
+ if hasattr(cls, k):
101
+ setattr(cls, k, v)
102
+ # print(f"🔄 [SystemLimits] Updated. TitanW={cls.L2_WEIGHT_TITAN:.2f}, WallRatio={cls.L4_OB_WALL_RATIO}")
103
+
104
+ # ============================================================
105
+ # 🧠 MLProcessor Class
106
+ # ============================================================
107
+ class MLProcessor:
108
+ def __init__(self, data_manager=None):
109
+ self.data_manager = data_manager
110
+ self.initialized = False
111
+
112
+ self.titan = TitanEngine(model_dir=MODELS_L2_DIR) if TitanEngine else None
113
+ self.pattern_engine = ChartPatternAnalyzer(models_dir=MODELS_PATTERN_DIR) if ChartPatternAnalyzer else None
114
+ self.mc_analyzer = MonteCarloEngine() if MonteCarloEngine else None
115
+ self.oracle = OracleEngine(model_dir=MODELS_UNIFIED_DIR) if OracleEngine else None
116
+ self.sniper = SniperEngine(models_dir=MODELS_SNIPER_DIR) if SniperEngine else None
117
+
118
+ self.guardian_hydra = None
119
+ if GuardianHydra:
120
+ self.guardian_hydra = GuardianHydra(model_dir=MODELS_HYDRA_DIR)
121
+
122
+ self.guardian_legacy = None
123
+ if HybridDeepSteward:
124
+ self.guardian_legacy = HybridDeepSteward(
125
+ v2_model_path=MODEL_V2_PATH,
126
+ v3_model_path=MODEL_V3_PATH,
127
+ v3_features_map_path=MODEL_V3_FEAT
128
+ )
129
+
130
+ print(f"🧠 [MLProcessor V36.0] Cybernetic Control Active.")
131
+
132
+ async def initialize(self):
133
+ if self.initialized: return
134
+ print("⚙️ [Processor] Initializing Neural Grid...")
135
+ try:
136
+ tasks = []
137
+ if self.titan: tasks.append(self.titan.initialize())
138
+
139
+ if self.pattern_engine:
140
+ # التكوين الأولي (سيتم تحديثه لاحقاً ديناميكياً)
141
+ self.pattern_engine.configure_thresholds(
142
+ weights=SystemLimits.PATTERN_TF_WEIGHTS,
143
+ bull_thresh=SystemLimits.PATTERN_THRESH_BULLISH,
144
+ bear_thresh=SystemLimits.PATTERN_THRESH_BEARISH
145
+ )
146
+ tasks.append(self.pattern_engine.initialize())
147
+
148
+ if self.oracle:
149
+ if hasattr(self.oracle, 'set_threshold'):
150
+ self.oracle.set_threshold(SystemLimits.L3_CONFIDENCE_THRESHOLD)
151
+ tasks.append(self.oracle.initialize())
152
+
153
+ if self.sniper:
154
+ # التكوين الأولي
155
+ if hasattr(self.sniper, 'configure_settings'):
156
+ self.sniper.configure_settings(
157
+ threshold=SystemLimits.L4_ENTRY_THRESHOLD,
158
+ wall_ratio=SystemLimits.L4_OB_WALL_RATIO,
159
+ w_ml=SystemLimits.L4_WEIGHT_ML,
160
+ w_ob=SystemLimits.L4_WEIGHT_OB
161
+ )
162
+ tasks.append(self.sniper.initialize())
163
+
164
+ if tasks: await asyncio.gather(*tasks)
165
+
166
+ if self.guardian_hydra:
167
+ self.guardian_hydra.initialize()
168
+ print(" 🛡️ [Guard 1] Hydra X-Ray: Active")
169
+
170
+ if self.guardian_legacy:
171
+ if asyncio.iscoroutinefunction(self.guardian_legacy.initialize):
172
+ await self.guardian_legacy.initialize()
173
+ else:
174
+ self.guardian_legacy.initialize()
175
+
176
+ # تطبيق العتبات المبدئية
177
+ self.guardian_legacy.configure_thresholds(
178
+ v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
179
+ v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
180
+ v3_soft=SystemLimits.LEGACY_V3_SOFT_THRESH,
181
+ v3_ultra=SystemLimits.LEGACY_V3_ULTRA_THRESH
182
+ )
183
+ print(f" 🛡️ [Guard 2] Legacy Steward: Active")
184
+
185
+ self.initialized = True
186
+ print("✅ [Processor] All Systems Operational.")
187
+
188
+ except Exception as e:
189
+ print(f"❌ [Processor FATAL] Init failed: {e}")
190
+ traceback.print_exc()
191
+
192
+ async def process_compound_signal(self, raw_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
193
+ """
194
+ L2 Processing:
195
+ هنا يتم دمج الدرجات بناءً على الأوزان الديناميكية الحالية (SystemLimits).
196
+ """
197
+ if not self.initialized: await self.initialize()
198
+
199
+ symbol = raw_data.get('symbol')
200
+ ohlcv_data = raw_data.get('ohlcv')
201
+ current_price = raw_data.get('current_price', 0.0)
202
+
203
+ if not symbol or not ohlcv_data: return None
204
+
205
+ try:
206
+ # 1. Titan Engine
207
+ score_titan = 0.5
208
+ titan_res = {}
209
+ if self.titan:
210
+ titan_res = await asyncio.to_thread(self.titan.predict, ohlcv_data)
211
+ score_titan = titan_res.get('score', 0.5)
212
+
213
+ # 2. Pattern Engine (Inject Dynamic Config First)
214
+ score_patterns = 0.5
215
+ pattern_res = {}
216
+ pattern_name = "Neutral"
217
+ if self.pattern_engine:
218
+ # تحديث التكوين قبل التحليل لضمان استخدام أحدث أوزان الاستراتيجية
219
+ self.pattern_engine.configure_thresholds(
220
+ weights=SystemLimits.PATTERN_TF_WEIGHTS,
221
+ bull_thresh=SystemLimits.PATTERN_THRESH_BULLISH,
222
+ bear_thresh=SystemLimits.PATTERN_THRESH_BEARISH
223
+ )
224
+ pattern_res = await self.pattern_engine.detect_chart_patterns(ohlcv_data)
225
+ score_patterns = pattern_res.get('pattern_confidence', 0.5)
226
+ pattern_name = pattern_res.get('pattern_detected', 'Neutral')
227
+
228
+ # 3. Monte Carlo (Light)
229
+ mc_score = 0.5
230
+ if self.mc_analyzer and '1h' in ohlcv_data:
231
+ closes = [c[4] for c in ohlcv_data['1h']]
232
+ raw_mc = self.mc_analyzer.run_light_check(closes)
233
+ mc_score = 0.5 + (raw_mc * 5.0)
234
+ mc_score = max(0.0, min(1.0, mc_score))
235
+
236
+ # 4. Hybrid Calculation (Using Dynamic Weights from SystemLimits)
237
+ # هذه الأوزان يتم تحديثها بواسطة AdaptiveHub
238
+ w_titan = SystemLimits.L2_WEIGHT_TITAN
239
+ w_patt = SystemLimits.L2_WEIGHT_PATTERNS
240
+ w_mc = SystemLimits.L2_WEIGHT_MC
241
+
242
+ # تطبيع الأوزان (لضمان أن مجموعها 1.0 تقريباً)
243
+ total_w = w_titan + w_patt + w_mc
244
+ if total_w <= 0: total_w = 1.0
245
+
246
+ hybrid_score = ((score_titan * w_titan) + (score_patterns * w_patt) + (mc_score * w_mc)) / total_w
247
+
248
+ return {
249
+ 'symbol': symbol,
250
+ 'current_price': current_price,
251
+ 'enhanced_final_score': hybrid_score,
252
+ 'titan_score': score_titan,
253
+ 'patterns_score': score_patterns,
254
+ 'mc_score': mc_score,
255
+ 'components': {
256
+ 'titan_score': score_titan,
257
+ 'patterns_score': score_patterns,
258
+ 'mc_score': mc_score
259
+ },
260
+ 'pattern_name': pattern_name,
261
+ 'ohlcv': ohlcv_data,
262
+ 'titan_details': titan_res,
263
+ 'pattern_details': pattern_res.get('details', {})
264
+ }
265
+ except Exception as e:
266
+ print(f"❌ [Processor] Error processing {symbol}: {e}")
267
+ return None
268
+
269
+ async def consult_oracle(self, symbol_data: Dict[str, Any]) -> Dict[str, Any]:
270
+ """
271
+ L3 Processing:
272
+ Oracle يستخدم العتبة الحالية من SystemLimits.
273
+ """
274
+ if not self.initialized: await self.initialize()
275
+
276
+ if self.oracle:
277
+ # تحديث العتبة ديناميكياً
278
+ if hasattr(self.oracle, 'set_threshold'):
279
+ self.oracle.set_threshold(SystemLimits.L3_CONFIDENCE_THRESHOLD)
280
+
281
+ decision = await self.oracle.predict(symbol_data)
282
+ conf = decision.get('confidence', 0.0)
283
+
284
+ # طبقة أمان إضافية (Redundant Safety)
285
+ if decision.get('action') in ['WATCH', 'BUY'] and conf < SystemLimits.L3_CONFIDENCE_THRESHOLD:
286
+ decision['action'] = 'WAIT'
287
+ decision['reason'] = f"Processor Veto: Conf {conf:.2f} < Limit {SystemLimits.L3_CONFIDENCE_THRESHOLD}"
288
+
289
+ return decision
290
+ return {'action': 'WAIT', 'reason': 'Oracle Engine Missing'}
291
+
292
+ async def check_sniper_entry(self, ohlcv_1m_data: List, order_book_data: Dict[str, Any]) -> Dict[str, Any]:
293
+ """
294
+ L4 Processing:
295
+ Sniper يستلم إعدادات دفتر الطلبات (DNA) قبل اتخاذ القرار.
296
+ """
297
+ if not self.initialized: await self.initialize()
298
+
299
+ if self.sniper:
300
+ # ✅ الحقن الديناميكي لإعدادات Sniper قبل التنفيذ
301
+ if hasattr(self.sniper, 'configure_settings'):
302
+ self.sniper.configure_settings(
303
+ threshold=SystemLimits.L4_ENTRY_THRESHOLD,
304
+ wall_ratio=SystemLimits.L4_OB_WALL_RATIO,
305
+ w_ml=SystemLimits.L4_WEIGHT_ML,
306
+ w_ob=SystemLimits.L4_WEIGHT_OB
307
+ )
308
+
309
+ return await self.sniper.check_entry_signal_async(ohlcv_1m_data, order_book_data)
310
+
311
+ return {'signal': 'WAIT', 'reason': 'Sniper Engine Missing'}
312
+
313
+ def consult_dual_guardians(self, symbol, ohlcv_1m, ohlcv_5m, ohlcv_15m, trade_context, order_book_snapshot=None):
314
+ """
315
+ L0 Guardians:
316
+ الحراس يستخدمون العتبات الديناميكية (Panic Thresholds) التي قد تختلف بين Bull و Bear.
317
+ """
318
+ response = {'action': 'HOLD', 'detailed_log': '', 'probs': {}}
319
+
320
+ # 1. Hydra
321
+ hydra_result = {'action': 'HOLD', 'reason': 'Disabled', 'probs': {}}
322
+ if self.guardian_hydra and self.guardian_hydra.initialized:
323
+ hydra_result = self.guardian_hydra.analyze_position(symbol, ohlcv_1m, ohlcv_5m, ohlcv_15m, trade_context)
324
+ h_probs = hydra_result.get('probs', {})
325
+ p_crash = h_probs.get('crash', 0.0)
326
+ p_giveback = h_probs.get('giveback', 0.0)
327
+
328
+ # استخدام العتبات الحية
329
+ if hydra_result['action'] == 'HOLD':
330
+ if p_crash >= SystemLimits.HYDRA_CRASH_THRESH:
331
+ hydra_result['action'] = 'EXIT_HARD'
332
+ hydra_result['reason'] = f"Hydra Crash Risk {p_crash:.2f}"
333
+ elif p_giveback >= SystemLimits.HYDRA_GIVEBACK_THRESH:
334
+ hydra_result['action'] = 'EXIT_SOFT'
335
+ hydra_result['reason'] = f"Hydra Giveback Risk {p_giveback:.2f}"
336
+
337
+ # 2. Legacy (Volume-Aware Veto)
338
+ legacy_result = {'action': 'HOLD', 'reason': 'Disabled', 'scores': {}}
339
+ if self.guardian_legacy and self.guardian_legacy.initialized:
340
+ # تحديث العتبات قبل التحليل
341
+ self.guardian_legacy.configure_thresholds(
342
+ v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
343
+ v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
344
+ v3_soft=SystemLimits.LEGACY_V3_SOFT_THRESH,
345
+ v3_ultra=SystemLimits.LEGACY_V3_ULTRA_THRESH
346
+ )
347
+
348
+ entry_price = float(trade_context.get('entry_price', 0.0))
349
+ vol_30m = trade_context.get('volume_30m_usd', 0.0)
350
+
351
+ legacy_result = self.guardian_legacy.analyze_position(
352
+ ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price,
353
+ order_book=order_book_snapshot,
354
+ volume_30m_usd=vol_30m
355
+ )
356
+
357
+ # 3. Final Arbitration & Display
358
+ h_probs = hydra_result.get('probs', {})
359
+ l_scores = legacy_result.get('scores', {})
360
+
361
+ h_c = h_probs.get('crash', 0.0)
362
+ h_g = h_probs.get('giveback', 0.0)
363
+ h_s = h_probs.get('stagnation', 0.0)
364
+ l_v2 = l_scores.get('v2', 0.0)
365
+ l_v3 = l_scores.get('v3', 0.0)
366
+
367
+ stamp_str = f"🐲[C:{h_c:.0%}|G:{h_g:.0%}|S:{h_s:.0%}] 🕸️[V2:{l_v2:.0%}|V3:{l_v3:.0%}]"
368
+
369
+ final_action = 'HOLD'
370
+ final_reason = f"Safe. {stamp_str}"
371
+
372
+ if hydra_result['action'] in ['EXIT_HARD', 'EXIT_SOFT', 'TIGHTEN_SL', 'TRAIL_SL']:
373
+ final_action = hydra_result['action']
374
+ final_reason = f"🐲 HYDRA: {hydra_result['reason']} | {stamp_str}"
375
+ elif legacy_result['action'] in ['EXIT_HARD', 'EXIT_SOFT']:
376
+ final_action = legacy_result['action']
377
+ final_reason = f"🕸️ LEGACY: {legacy_result['reason']} | {stamp_str}"
378
+
379
+ return {
380
+ 'action': final_action,
381
+ 'reason': final_reason,
382
+ 'detailed_log': f"{final_action} | {stamp_str}",
383
+ 'probs': h_probs,
384
+ 'scores': l_scores
385
+ }
386
+
387
+ async def run_advanced_monte_carlo(self, symbol, timeframe='1h'):
388
+ if self.mc_analyzer and self.data_manager:
389
+ try:
390
+ ohlcv = await self.data_manager.get_latest_ohlcv(symbol, timeframe, limit=300)
391
+ if ohlcv: return self.mc_analyzer.run_advanced_simulation([c[4] for c in ohlcv])
392
+ except Exception: pass
393
+ return 0.0