Riy777 commited on
Commit
c4d8943
·
verified ·
1 Parent(s): fb4f181

Update ml_engine/hybrid_guardian.py

Browse files
Files changed (1) hide show
  1. ml_engine/hybrid_guardian.py +79 -53
ml_engine/hybrid_guardian.py CHANGED
@@ -1,5 +1,5 @@
1
  # ml_engine/hybrid_guardian.py
2
- # (V23.0 - GEM-Architect: Institutional Fuzzy Logic + Ultra-Confidence Override)
3
 
4
  import os
5
  import json
@@ -14,7 +14,7 @@ class HybridDeepSteward:
14
  def __init__(self, v2_model_path, v3_model_path, v3_features_map_path):
15
  """
16
  The Hybrid Guardian: Combines V2 (Regime Detection) and V3 (Precision Exit).
17
- Uses "Fuzzy Logic" zones instead of hard cutoffs.
18
  """
19
  self.v2_path = v2_model_path
20
  self.v3_path = v3_model_path
@@ -25,19 +25,15 @@ class HybridDeepSteward:
25
  self.v3_feature_names = []
26
  self.initialized = False
27
 
28
- # ⚙️ إعدادات المناطق المنطقية (Institutional Logic Zones)
29
-
30
- # 1. حدود V2 (الرادار - يحدد السياق)
31
- self.V2_SAFE_LIMIT = 0.50 # تحت هذا الرقم: أمان قوي
32
- self.V2_GREY_LIMIT = 0.60 # بين 0.50 و 0.60: منطقة رمادية (قلق بسيط)
33
- self.V2_PANIC_TRIGGER = 0.90 # فوق هذا الرقم: انهيار مؤكد (Panic)
34
 
35
- # 2. حدود V3 (القناص - يحدد التنفيذ)
36
- self.V3_SOFT_EXIT = 0.75 # خروج جزئي/تحذير
37
- self.V3_HARD_EXIT = 0.90 # خروج كامل قياسي
38
- self.V3_ULTRA_CONF = 0.97 # "كسر الفيتو": خروج حتى لو V2 آمن
39
 
40
- # ميزات V2 (ثابتة)
41
  self.V2_FEATURES = [
42
  'log_ret', 'rel_vol', 'rsi_norm', 'macd_hist', 'roc',
43
  'bb_width', 'bb_pct', 'atr_pct', 'dist_ema50', 'dist_ema200',
@@ -45,10 +41,22 @@ class HybridDeepSteward:
45
  ]
46
 
47
  def initialize(self):
48
- """تحميل النماذج"""
 
 
 
 
 
49
  try:
50
- if not os.path.exists(self.v2_path): return False
51
- if not os.path.exists(self.v3_path): return False
 
 
 
 
 
 
 
52
 
53
  self.model_v2 = xgb.Booster()
54
  self.model_v2.load_model(self.v2_path)
@@ -56,27 +64,28 @@ class HybridDeepSteward:
56
  self.model_v3 = xgb.Booster()
57
  self.model_v3.load_model(self.v3_path)
58
 
59
- if os.path.exists(self.v3_features_path):
60
- with open(self.v3_features_path, 'r') as f:
61
- self.v3_feature_names = json.load(f)
62
- else:
63
- return False
64
 
65
  self.initialized = True
66
- print(f"✅ [HybridGuardian V23] Logic: Safe<{self.V2_SAFE_LIMIT} | Grey<{self.V2_GREY_LIMIT} | Panic>{self.V2_PANIC_TRIGGER}")
67
  return True
68
 
69
  except Exception as e:
70
- print(f"❌ [HybridGuardian] Init Failed: {e}")
 
71
  return False
72
 
73
  # ==========================================================================
74
- # 🧠 V2 Feature Logic (Legacy 64-Candle Sequence)
75
  # ==========================================================================
76
  def _engineer_v2_features(self, df, current_price, entry_price):
77
  try:
78
  df = df.copy()
79
- if len(df) < 200: return None
 
 
 
80
 
81
  df['log_ret'] = np.log(df['close'] / df['close'].shift(1))
82
  vol_sma = df['volume'].rolling(window=50).mean()
@@ -105,11 +114,12 @@ class HybridDeepSteward:
105
  window = df.iloc[-64:][self.V2_FEATURES].values
106
  if window.shape[0] < 64: return None
107
  return window.reshape(1, -1)
108
- except:
 
109
  return None
110
 
111
  # ==========================================================================
112
- # 🧬 V3 Feature Logic (Advanced Multi-Timeframe)
113
  # ==========================================================================
114
  def _add_v3_indicators(self, df, window_mc):
115
  try:
@@ -171,7 +181,10 @@ class HybridDeepSteward:
171
  df5 = pd.DataFrame(ohlcv_5m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
172
  df15 = pd.DataFrame(ohlcv_15m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
173
 
174
- if len(df1) < 200 or len(df5) < 50 or len(df15) < 50: return None
 
 
 
175
 
176
  df1 = self._add_v3_indicators(df1, window_mc=30)
177
  df5 = self._add_v3_indicators(df5, window_mc=30)
@@ -193,111 +206,124 @@ class HybridDeepSteward:
193
  vector.append(val)
194
 
195
  return np.array(vector).reshape(1, -1)
196
- except:
 
197
  return None
198
 
199
  # ==========================================================================
200
- # 🛡️ The Institutional Hybrid Logic (المنطق المؤسسي الجديد)
201
  # ==========================================================================
202
  def analyze_position(self, ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price):
203
  if not self.initialized:
204
- return {'action': 'HOLD', 'reason': 'Not Initialized'}
 
 
 
 
 
205
 
206
  try:
207
- # 1. الحسابات (Inference)
208
  df_1m_raw = pd.DataFrame(ohlcv_1m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
209
  current_price = df_1m_raw['close'].iloc[-1]
210
 
211
  # V2 Score
212
  feat_v2 = self._engineer_v2_features(df_1m_raw, current_price, entry_price)
213
- score_v2 = float(self.model_v2.predict(xgb.DMatrix(feat_v2))[0]) if feat_v2 is not None else 0.0
 
 
 
 
214
 
215
  # V3 Score
216
  feat_v3 = self._engineer_v3_features(ohlcv_1m, ohlcv_5m, ohlcv_15m)
217
- score_v3 = float(self.model_v3.predict(xgb.DMatrix(feat_v3, feature_names=self.v3_feature_names))[0]) if feat_v3 is not None else 0.0
 
 
 
 
218
 
219
  scores_dict = {'v2': score_v2, 'v3': score_v3}
220
 
221
  # ---------------------------------------------------------
222
- # 🧠 منطق اتخاذ القرار (Decision Logic Tree)
223
  # ---------------------------------------------------------
224
 
225
- # الحالة 1: V2 Panic (انهيار كارثي واضح)
226
  if score_v2 >= self.V2_PANIC_TRIGGER:
227
  return {
228
  'action': 'EXIT_HARD',
229
  'confidence': score_v2,
230
- 'reason': f'🚨 V2 PANIC (S:{score_v2:.2f}) - Market Crash Regime',
231
  'scores': scores_dict
232
  }
233
 
234
- # الحالة 2: V2 Safe Zone (سوق آمن)
235
  elif score_v2 < self.V2_SAFE_LIMIT:
236
- # استثناء الثقة العمياء لـ V3
237
  if score_v3 >= self.V3_ULTRA_CONF:
238
  return {
239
  'action': 'EXIT_HARD',
240
  'confidence': score_v3,
241
- 'reason': f'⚡ V3 ULTRA OVERRIDE (S:{score_v3:.2f} > {self.V3_ULTRA_CONF}) - Sniper detects acute danger in Safe Zone',
242
  'scores': scores_dict
243
  }
244
  else:
245
  return {
246
  'action': 'HOLD',
247
  'confidence': 1.0 - score_v2,
248
- 'reason': f'✅ Safe Regime (V2:{score_v2:.2f} < {self.V2_SAFE_LIMIT}) - V3({score_v3:.2f}) Vetoed',
249
  'scores': scores_dict
250
  }
251
 
252
- # الحالة 3: V2 Grey Zone (منطقة رمادية) - نسمح لـ V3 بالتدخل بشروط
253
  elif self.V2_SAFE_LIMIT <= score_v2 < self.V2_GREY_LIMIT:
254
- if score_v3 >= self.V3_HARD_EXIT: # 0.90
255
  return {
256
  'action': 'EXIT_HARD',
257
  'confidence': score_v3,
258
- 'reason': f'🎯 V3 Sniper (S:{score_v3:.2f}) inside Grey Zone',
259
  'scores': scores_dict
260
  }
261
- elif score_v3 >= self.V3_SOFT_EXIT: # 0.75
262
  return {
263
  'action': 'EXIT_SOFT',
264
  'confidence': score_v3,
265
- 'reason': f'⚠️ V3 Warning (S:{score_v3:.2f}) inside Grey Zone',
266
  'scores': scores_dict
267
  }
268
  else:
269
  return {
270
  'action': 'HOLD',
271
  'confidence': 1.0 - score_v3,
272
- 'reason': f'👀 Grey Zone (V2:{score_v2:.2f}) - V3({score_v3:.2f}) Waiting for signal',
273
  'scores': scores_dict
274
  }
275
 
276
- # الحالة 4: V2 Risk Zone (بوابة الخطر مفتوحة) - V3 يعمل بحرية
277
- else: # 0.60 <= score_v2 < 0.90
278
  if score_v3 >= self.V3_HARD_EXIT:
279
  return {
280
  'action': 'EXIT_HARD',
281
  'confidence': score_v3,
282
- 'reason': f'🔥 V3 Kill (S:{score_v3:.2f}) [Risk Gate Open V2:{score_v2:.2f}]',
283
  'scores': scores_dict
284
  }
285
  elif score_v3 >= self.V3_SOFT_EXIT:
286
  return {
287
  'action': 'EXIT_SOFT',
288
  'confidence': score_v3,
289
- 'reason': f'⚠️ V3 Soft (S:{score_v3:.2f}) [Risk Gate Open V2:{score_v2:.2f}]',
290
  'scores': scores_dict
291
  }
292
  else:
293
  return {
294
  'action': 'HOLD',
295
  'confidence': 1.0 - score_v3,
296
- 'reason': f'🛡️ High Alert (V2:{score_v2:.2f}) but V3({score_v3:.2f}) Holds',
297
  'scores': scores_dict
298
  }
299
 
300
  except Exception as e:
301
  print(f"❌ [HybridGuardian] Inference Error: {e}")
302
  traceback.print_exc()
303
- return {'action': 'HOLD', 'reason': f'Error: {e}'}
 
1
  # ml_engine/hybrid_guardian.py
2
+ # (V23.1 - GEM-Architect: Debug Edition)
3
 
4
  import os
5
  import json
 
14
  def __init__(self, v2_model_path, v3_model_path, v3_features_map_path):
15
  """
16
  The Hybrid Guardian: Combines V2 (Regime Detection) and V3 (Precision Exit).
17
+ Now includes DEBUG logging to find why models return 0.
18
  """
19
  self.v2_path = v2_model_path
20
  self.v3_path = v3_model_path
 
25
  self.v3_feature_names = []
26
  self.initialized = False
27
 
28
+ # ⚙️ إعدادات المناطق المنطقية
29
+ self.V2_SAFE_LIMIT = 0.50
30
+ self.V2_GREY_LIMIT = 0.60
31
+ self.V2_PANIC_TRIGGER = 0.90
 
 
32
 
33
+ self.V3_SOFT_EXIT = 0.75
34
+ self.V3_HARD_EXIT = 0.90
35
+ self.V3_ULTRA_CONF = 0.97
 
36
 
 
37
  self.V2_FEATURES = [
38
  'log_ret', 'rel_vol', 'rsi_norm', 'macd_hist', 'roc',
39
  'bb_width', 'bb_pct', 'atr_pct', 'dist_ema50', 'dist_ema200',
 
41
  ]
42
 
43
  def initialize(self):
44
+ """تحميل النماذج مع فحص الأخطاء"""
45
+ print(f"🛠️ [Guardian Init] Checking paths...")
46
+ print(f" - V2 Path: {self.v2_path}")
47
+ print(f" - V3 Path: {self.v3_path}")
48
+ print(f" - V3 Map : {self.v3_features_path}")
49
+
50
  try:
51
+ if not os.path.exists(self.v2_path):
52
+ print(f"❌ [Guardian Error] V2 Model file NOT FOUND at: {self.v2_path}")
53
+ return False
54
+ if not os.path.exists(self.v3_path):
55
+ print(f"❌ [Guardian Error] V3 Model file NOT FOUND at: {self.v3_path}")
56
+ return False
57
+ if not os.path.exists(self.v3_features_path):
58
+ print(f"❌ [Guardian Error] V3 Features Map NOT FOUND at: {self.v3_features_path}")
59
+ return False
60
 
61
  self.model_v2 = xgb.Booster()
62
  self.model_v2.load_model(self.v2_path)
 
64
  self.model_v3 = xgb.Booster()
65
  self.model_v3.load_model(self.v3_path)
66
 
67
+ with open(self.v3_features_path, 'r') as f:
68
+ self.v3_feature_names = json.load(f)
 
 
 
69
 
70
  self.initialized = True
71
+ print(f"✅ [Guardian Ready] Models Loaded Successfully.")
72
  return True
73
 
74
  except Exception as e:
75
+ print(f"❌ [HybridGuardian] CRITICAL Init Failed: {e}")
76
+ traceback.print_exc()
77
  return False
78
 
79
  # ==========================================================================
80
+ # 🧠 V2 Feature Logic
81
  # ==========================================================================
82
  def _engineer_v2_features(self, df, current_price, entry_price):
83
  try:
84
  df = df.copy()
85
+ # Debug: Check data length
86
+ if len(df) < 200:
87
+ print(f"⚠️ [V2 Warning] Insufficient Data. Need 200+, Got {len(df)}")
88
+ return None
89
 
90
  df['log_ret'] = np.log(df['close'] / df['close'].shift(1))
91
  vol_sma = df['volume'].rolling(window=50).mean()
 
114
  window = df.iloc[-64:][self.V2_FEATURES].values
115
  if window.shape[0] < 64: return None
116
  return window.reshape(1, -1)
117
+ except Exception as e:
118
+ print(f"❌ [V2 Error] Feature Eng Failed: {e}")
119
  return None
120
 
121
  # ==========================================================================
122
+ # 🧬 V3 Feature Logic
123
  # ==========================================================================
124
  def _add_v3_indicators(self, df, window_mc):
125
  try:
 
181
  df5 = pd.DataFrame(ohlcv_5m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
182
  df15 = pd.DataFrame(ohlcv_15m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
183
 
184
+ # Debug: Check lengths
185
+ if len(df1) < 200 or len(df5) < 50 or len(df15) < 50:
186
+ print(f"⚠️ [V3 Warning] Data lengths: 1m={len(df1)}, 5m={len(df5)}, 15m={len(df15)}")
187
+ return None
188
 
189
  df1 = self._add_v3_indicators(df1, window_mc=30)
190
  df5 = self._add_v3_indicators(df5, window_mc=30)
 
206
  vector.append(val)
207
 
208
  return np.array(vector).reshape(1, -1)
209
+ except Exception as e:
210
+ print(f"❌ [V3 Error] Feature Eng Failed: {e}")
211
  return None
212
 
213
  # ==========================================================================
214
+ # 🛡️ The Institutional Hybrid Logic
215
  # ==========================================================================
216
  def analyze_position(self, ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price):
217
  if not self.initialized:
218
+ # هنا يكمن سبب ظهور الأصفار، سنقوم بتعديل الرسالة
219
+ return {
220
+ 'action': 'HOLD',
221
+ 'reason': '⚠️ Models NOT Loaded (Check Logs)',
222
+ 'scores': {'v2': 0.0, 'v3': 0.0}
223
+ }
224
 
225
  try:
226
+ # 1. الحسابات
227
  df_1m_raw = pd.DataFrame(ohlcv_1m, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
228
  current_price = df_1m_raw['close'].iloc[-1]
229
 
230
  # V2 Score
231
  feat_v2 = self._engineer_v2_features(df_1m_raw, current_price, entry_price)
232
+ if feat_v2 is not None:
233
+ score_v2 = float(self.model_v2.predict(xgb.DMatrix(feat_v2))[0])
234
+ else:
235
+ print("⚠️ [Guardian] V2 Features returned None (Defaulting to 0)")
236
+ score_v2 = 0.0
237
 
238
  # V3 Score
239
  feat_v3 = self._engineer_v3_features(ohlcv_1m, ohlcv_5m, ohlcv_15m)
240
+ if feat_v3 is not None:
241
+ score_v3 = float(self.model_v3.predict(xgb.DMatrix(feat_v3, feature_names=self.v3_feature_names))[0])
242
+ else:
243
+ print("⚠️ [Guardian] V3 Features returned None (Defaulting to 0)")
244
+ score_v3 = 0.0
245
 
246
  scores_dict = {'v2': score_v2, 'v3': score_v3}
247
 
248
  # ---------------------------------------------------------
249
+ # 🧠 منطق اتخاذ القرار
250
  # ---------------------------------------------------------
251
 
252
+ # الحالة 1: V2 Panic
253
  if score_v2 >= self.V2_PANIC_TRIGGER:
254
  return {
255
  'action': 'EXIT_HARD',
256
  'confidence': score_v2,
257
+ 'reason': f'🚨 V2 PANIC (S:{score_v2:.2f})',
258
  'scores': scores_dict
259
  }
260
 
261
+ # الحالة 2: V2 Safe Zone
262
  elif score_v2 < self.V2_SAFE_LIMIT:
 
263
  if score_v3 >= self.V3_ULTRA_CONF:
264
  return {
265
  'action': 'EXIT_HARD',
266
  'confidence': score_v3,
267
+ 'reason': f'⚡ V3 ULTRA OVERRIDE',
268
  'scores': scores_dict
269
  }
270
  else:
271
  return {
272
  'action': 'HOLD',
273
  'confidence': 1.0 - score_v2,
274
+ 'reason': f'✅ Safe Regime',
275
  'scores': scores_dict
276
  }
277
 
278
+ # الحالة 3: V2 Grey Zone
279
  elif self.V2_SAFE_LIMIT <= score_v2 < self.V2_GREY_LIMIT:
280
+ if score_v3 >= self.V3_HARD_EXIT:
281
  return {
282
  'action': 'EXIT_HARD',
283
  'confidence': score_v3,
284
+ 'reason': f'🎯 V3 Sniper Grey',
285
  'scores': scores_dict
286
  }
287
+ elif score_v3 >= self.V3_SOFT_EXIT:
288
  return {
289
  'action': 'EXIT_SOFT',
290
  'confidence': score_v3,
291
+ 'reason': f'⚠️ V3 Warning Grey',
292
  'scores': scores_dict
293
  }
294
  else:
295
  return {
296
  'action': 'HOLD',
297
  'confidence': 1.0 - score_v3,
298
+ 'reason': f'👀 Grey Zone',
299
  'scores': scores_dict
300
  }
301
 
302
+ # الحالة 4: V2 Risk Zone
303
+ else:
304
  if score_v3 >= self.V3_HARD_EXIT:
305
  return {
306
  'action': 'EXIT_HARD',
307
  'confidence': score_v3,
308
+ 'reason': f'🔥 V3 Kill Risk',
309
  'scores': scores_dict
310
  }
311
  elif score_v3 >= self.V3_SOFT_EXIT:
312
  return {
313
  'action': 'EXIT_SOFT',
314
  'confidence': score_v3,
315
+ 'reason': f'⚠️ V3 Soft Risk',
316
  'scores': scores_dict
317
  }
318
  else:
319
  return {
320
  'action': 'HOLD',
321
  'confidence': 1.0 - score_v3,
322
+ 'reason': f'🛡️ High Alert',
323
  'scores': scores_dict
324
  }
325
 
326
  except Exception as e:
327
  print(f"❌ [HybridGuardian] Inference Error: {e}")
328
  traceback.print_exc()
329
+ return {'action': 'HOLD', 'reason': f'Error: {e}', 'scores': {'v2':0, 'v3':0}}