Riy777 commited on
Commit
98050cc
·
verified ·
1 Parent(s): 77ebc20

Update ml_engine/processor.py

Browse files
Files changed (1) hide show
  1. ml_engine/processor.py +46 -39
ml_engine/processor.py CHANGED
@@ -1,5 +1,6 @@
1
  # ============================================================
2
- # 🧠 ml_engine/processor.py (V36.0 - GEM-Architect: The Cybernetic Processor)
 
3
  # ============================================================
4
 
5
  import asyncio
@@ -40,23 +41,22 @@ MODEL_V3_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Production.j
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}
@@ -71,10 +71,8 @@ class SystemLimits:
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 ---
@@ -94,12 +92,10 @@ class SystemLimits:
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
@@ -127,7 +123,7 @@ class MLProcessor:
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
@@ -137,7 +133,6 @@ class MLProcessor:
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,
@@ -151,7 +146,6 @@ class MLProcessor:
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,
@@ -173,7 +167,6 @@ class MLProcessor:
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,
@@ -192,7 +185,8 @@ class MLProcessor:
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
 
@@ -200,6 +194,9 @@ class MLProcessor:
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:
@@ -210,12 +207,12 @@ class MLProcessor:
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,
@@ -233,13 +230,11 @@ class MLProcessor:
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
 
@@ -248,7 +243,10 @@ class MLProcessor:
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,
@@ -269,39 +267,48 @@ class MLProcessor:
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
  )
@@ -313,7 +320,8 @@ class MLProcessor:
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
 
@@ -325,7 +333,7 @@ class MLProcessor:
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'
@@ -337,7 +345,6 @@ class MLProcessor:
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,
@@ -354,7 +361,7 @@ class MLProcessor:
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
 
 
1
  # ============================================================
2
+ # 🧠 ml_engine/processor.py
3
+ # (V37.0 - GEM-Architect: Context-Aware Cybernetic Processor)
4
  # ============================================================
5
 
6
  import asyncio
 
41
  MODEL_V3_FEAT = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Features.json")
42
 
43
  # ============================================================
44
+ # 🎛️ SYSTEM LIMITS & THRESHOLDS (Fallback / Global)
45
  # ============================================================
46
  class SystemLimits:
47
  """
48
  GEM-Architect: The Dynamic Constitution.
49
+ يتم تحديث هذه القيم آلياً بواسطة AdaptiveHub وتستخدم كقيم احتياطية (Fallback)
50
+ في حال لم يتم توفير dynamic_limits للعملة.
51
  """
52
 
53
  # --- Layer 1 (Data Manager Control) ---
54
+ L1_MIN_AFFINITY_SCORE = 15.0
55
 
56
  # --- Layer 2 Weights (Dynamic) ---
 
57
  L2_WEIGHT_TITAN = 0.40
58
  L2_WEIGHT_PATTERNS = 0.30
59
  L2_WEIGHT_MC = 0.10
 
60
 
61
  # إعدادات الأنماط (تتغير حسب الاستراتيجية)
62
  PATTERN_TF_WEIGHTS = {'15m': 0.40, '1h': 0.30, '5m': 0.20, '4h': 0.10, '1d': 0.00}
 
71
 
72
  # --- Layer 4 (Sniper & Execution) ---
73
  L4_ENTRY_THRESHOLD = 0.40
 
74
  L4_WEIGHT_ML = 0.60
75
  L4_WEIGHT_OB = 0.40
 
76
  L4_OB_WALL_RATIO = 0.40
77
 
78
  # --- Layer 0: Hydra & Guardian Thresholds ---
 
92
 
93
  @classmethod
94
  def update_from_dict(cls, config: Dict[str, Any]):
 
95
  if not config: return
96
  for k, v in config.items():
97
  if hasattr(cls, k):
98
  setattr(cls, k, v)
 
99
 
100
  # ============================================================
101
  # 🧠 MLProcessor Class
 
123
  v3_features_map_path=MODEL_V3_FEAT
124
  )
125
 
126
+ print(f"🧠 [MLProcessor V37.0] Context-Aware Cybernetics Active.")
127
 
128
  async def initialize(self):
129
  if self.initialized: return
 
133
  if self.titan: tasks.append(self.titan.initialize())
134
 
135
  if self.pattern_engine:
 
136
  self.pattern_engine.configure_thresholds(
137
  weights=SystemLimits.PATTERN_TF_WEIGHTS,
138
  bull_thresh=SystemLimits.PATTERN_THRESH_BULLISH,
 
146
  tasks.append(self.oracle.initialize())
147
 
148
  if self.sniper:
 
149
  if hasattr(self.sniper, 'configure_settings'):
150
  self.sniper.configure_settings(
151
  threshold=SystemLimits.L4_ENTRY_THRESHOLD,
 
167
  else:
168
  self.guardian_legacy.initialize()
169
 
 
170
  self.guardian_legacy.configure_thresholds(
171
  v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
172
  v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
 
185
  async def process_compound_signal(self, raw_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
186
  """
187
  L2 Processing:
188
+ Uses 'dynamic_limits' from raw_data if available (Per-Asset Overrides),
189
+ otherwise falls back to SystemLimits (Global).
190
  """
191
  if not self.initialized: await self.initialize()
192
 
 
194
  ohlcv_data = raw_data.get('ohlcv')
195
  current_price = raw_data.get('current_price', 0.0)
196
 
197
+ # ✅ EXTRACT DYNAMIC LIMITS (Priority: Local > Global)
198
+ limits = raw_data.get('dynamic_limits', {})
199
+
200
  if not symbol or not ohlcv_data: return None
201
 
202
  try:
 
207
  titan_res = await asyncio.to_thread(self.titan.predict, ohlcv_data)
208
  score_titan = titan_res.get('score', 0.5)
209
 
210
+ # 2. Pattern Engine
211
  score_patterns = 0.5
212
  pattern_res = {}
213
  pattern_name = "Neutral"
214
  if self.pattern_engine:
215
+ # Use Global config for pattern internal TFs for now
216
  self.pattern_engine.configure_thresholds(
217
  weights=SystemLimits.PATTERN_TF_WEIGHTS,
218
  bull_thresh=SystemLimits.PATTERN_THRESH_BULLISH,
 
230
  mc_score = 0.5 + (raw_mc * 5.0)
231
  mc_score = max(0.0, min(1.0, mc_score))
232
 
233
+ # 4. Hybrid Calculation (USING DYNAMIC WEIGHTS)
234
+ w_titan = limits.get('w_titan', SystemLimits.L2_WEIGHT_TITAN)
235
+ w_patt = limits.get('w_patt', SystemLimits.L2_WEIGHT_PATTERNS)
236
+ w_mc = SystemLimits.L2_WEIGHT_MC
 
237
 
 
238
  total_w = w_titan + w_patt + w_mc
239
  if total_w <= 0: total_w = 1.0
240
 
 
243
  return {
244
  'symbol': symbol,
245
  'current_price': current_price,
246
+ 'enhanced_final_score': hybrid_score,
247
+ # Pass limits forward for next layers
248
+ 'dynamic_limits': limits,
249
+ 'asset_regime': raw_data.get('asset_regime', 'UNKNOWN'),
250
  'titan_score': score_titan,
251
  'patterns_score': score_patterns,
252
  'mc_score': mc_score,
 
267
  async def consult_oracle(self, symbol_data: Dict[str, Any]) -> Dict[str, Any]:
268
  """
269
  L3 Processing:
270
+ Oracle uses specific threshold from dynamic_limits (Per-Asset).
271
  """
272
  if not self.initialized: await self.initialize()
273
 
274
+ # ✅ EXTRACT DYNAMIC THRESHOLD
275
+ limits = symbol_data.get('dynamic_limits', {})
276
+ threshold = limits.get('l3_oracle_thresh', SystemLimits.L3_CONFIDENCE_THRESHOLD)
277
+
278
  if self.oracle:
 
279
  if hasattr(self.oracle, 'set_threshold'):
280
+ self.oracle.set_threshold(threshold)
281
 
282
  decision = await self.oracle.predict(symbol_data)
283
  conf = decision.get('confidence', 0.0)
284
 
285
+ # Dynamic Veto based on Context
286
+ if decision.get('action') in ['WATCH', 'BUY'] and conf < threshold:
287
  decision['action'] = 'WAIT'
288
+ decision['reason'] = f"Context Veto: Conf {conf:.2f} < Limit {threshold:.2f} ({limits.get('regime','Global')})"
289
 
290
  return decision
291
  return {'action': 'WAIT', 'reason': 'Oracle Engine Missing'}
292
 
293
+ async def check_sniper_entry(self, ohlcv_1m_data: List, order_book_data: Dict[str, Any], context_data: Dict = None) -> Dict[str, Any]:
294
  """
295
  L4 Processing:
296
+ Sniper uses specific wall ratio and thresholds from dynamic_limits.
297
  """
298
  if not self.initialized: await self.initialize()
299
 
300
+ # ✅ EXTRACT DYNAMIC CONFIG
301
+ limits = context_data.get('dynamic_limits', {}) if context_data else {}
302
+
303
+ thresh = limits.get('l4_sniper_thresh', SystemLimits.L4_ENTRY_THRESHOLD)
304
+ wall_r = limits.get('l4_ob_wall_ratio', SystemLimits.L4_OB_WALL_RATIO)
305
+
306
  if self.sniper:
307
+ # Inject Dynamic Config before check
308
  if hasattr(self.sniper, 'configure_settings'):
309
  self.sniper.configure_settings(
310
+ threshold=thresh,
311
+ wall_ratio=wall_r,
312
  w_ml=SystemLimits.L4_WEIGHT_ML,
313
  w_ob=SystemLimits.L4_WEIGHT_OB
314
  )
 
320
  def consult_dual_guardians(self, symbol, ohlcv_1m, ohlcv_5m, ohlcv_15m, trade_context, order_book_snapshot=None):
321
  """
322
  L0 Guardians:
323
+ Ideally, trade_context should also carry 'dynamic_limits' if we want per-asset guarding.
324
+ For now, we use Global SystemLimits which are updated by AdaptiveHub to reflect 'General Market State'.
325
  """
326
  response = {'action': 'HOLD', 'detailed_log': '', 'probs': {}}
327
 
 
333
  p_crash = h_probs.get('crash', 0.0)
334
  p_giveback = h_probs.get('giveback', 0.0)
335
 
336
+ # Using Global SystemLimits (updated by Hub)
337
  if hydra_result['action'] == 'HOLD':
338
  if p_crash >= SystemLimits.HYDRA_CRASH_THRESH:
339
  hydra_result['action'] = 'EXIT_HARD'
 
345
  # 2. Legacy (Volume-Aware Veto)
346
  legacy_result = {'action': 'HOLD', 'reason': 'Disabled', 'scores': {}}
347
  if self.guardian_legacy and self.guardian_legacy.initialized:
 
348
  self.guardian_legacy.configure_thresholds(
349
  v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
350
  v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
 
361
  volume_30m_usd=vol_30m
362
  )
363
 
364
+ # 3. Final Arbitration
365
  h_probs = hydra_result.get('probs', {})
366
  l_scores = legacy_result.get('scores', {})
367