Riy777 commited on
Commit
3b83048
·
1 Parent(s): 0c195bb

Update ml_engine/patterns.py

Browse files
Files changed (1) hide show
  1. ml_engine/patterns.py +20 -19
ml_engine/patterns.py CHANGED
@@ -1,5 +1,5 @@
1
  # ml_engine/patterns.py
2
- # (V8.4 - إصلاح KeyError: استخدام .copy() لعزل السلاسل (Series) + فحوصات أقوى للأعمدة)
3
 
4
  import pandas as pd
5
  import numpy as np
@@ -87,17 +87,17 @@ class ChartPatternAnalyzer:
87
  self.scaler = None
88
  return False
89
 
90
- # 🔴 --- START OF CHANGE (V8.4) --- 🔴
91
- # (V8.4 - إصلاح KeyError: استخدام .copy() لعزل السلاسل (Series) + فحوصات أقوى للأعمدة)
92
  def _extract_features(self, df_window: pd.DataFrame) -> pd.DataFrame:
93
  """
94
- (الوصفة V8 - معدلة - V8.4)
95
  حساب الـ 30 مؤشراً (وظيفياً) مع عزل البيانات
96
  """
97
  if not ta:
98
  raise ImportError("مكتبة pandas-ta غير مثبتة.")
99
 
100
  # (إنشاء DF فارغ بنفس الفهرس (Index) الخاص بآخر صف)
 
101
  df = pd.DataFrame(index=df_window.iloc[-1:].index)
102
 
103
  # (تمرير الأعمدة كـ "نسخ" (.copy()) لعزلها عن df_window)
@@ -107,12 +107,15 @@ class ChartPatternAnalyzer:
107
  l = df_window['low'].copy()
108
  v = df_window['volume'].copy()
109
 
 
 
 
 
110
  try:
111
  # --- حساب المؤشرات وظيفياً ---
112
  df['RSI_14'] = ta.rsi(c, length=14)
113
 
114
  macd_data = ta.macd(c, fast=12, slow=26, signal=9)
115
- # (فحص الحماية V8.4)
116
  if macd_data is not None and not macd_data.empty and 'MACD_12_26_9' in macd_data.columns:
117
  df['MACD_12_26_9'] = macd_data['MACD_12_26_9']
118
  df['MACDh_12_26_9'] = macd_data['MACDh_12_26_9']
@@ -122,7 +125,6 @@ class ChartPatternAnalyzer:
122
  df['EMA_20'] = ta.ema(c, length=20)
123
 
124
  bb_data = ta.bbands(c, length=5, std=2.0)
125
- # (فحص الحماية V8.4)
126
  if bb_data is not None and not bb_data.empty and 'BBL_5_2.0' in bb_data.columns:
127
  df['BBL_5_2.0_2.0'] = bb_data['BBL_5_2.0']
128
  df['BBM_5_2.0_2.0'] = bb_data['BBM_5_2.0']
@@ -131,20 +133,19 @@ class ChartPatternAnalyzer:
131
  df['BBP_5_2.0_2.0'] = bb_data['BBP_5_2.0']
132
 
133
  stoch_data = ta.stoch(h, l, c, k=14, d=3, smooth_k=3)
134
- # (فحص الحماية V8.4)
135
  if stoch_data is not None and not stoch_data.empty and 'STOCHk_14_3_3' in stoch_data.columns:
136
  df['STOCHk_14_3_3'] = stoch_data['STOCHk_14_3_3']
137
  df['STOCHd_14_3_3'] = stoch_data['STOCHd_14_3_3']
138
  df['STOCHh_14_3_3'] = stoch_data['STOCHh_14_3_3']
139
 
140
  adx_data = ta.adx(h, l, c, length=14, adxr=2)
141
- # (فحص الحماية V8.4)
142
  if adx_data is not None and not adx_data.empty and 'ADX_14' in adx_data.columns:
143
  df['ADX_14'] = adx_data['ADX_14']
144
  df['ADXR_14_2'] = adx_data['ADXR_14_2']
145
  df['DMP_14'] = adx_data['DMP_14']
146
  df['DMN_14'] = adx_data['DMN_14']
147
 
 
148
  vwap_series = ta.vwap(h, l, c, v)
149
  if vwap_series is not None: df['VWAP_D'] = vwap_series
150
 
@@ -156,7 +157,6 @@ class ChartPatternAnalyzer:
156
  df['DPO_20'] = ta.dpo(c, length=20)
157
 
158
  kvo_data = ta.kvo(h, l, c, v, fast=34, slow=55, signal=13)
159
- # (فحص الحماية V8.4)
160
  if kvo_data is not None and not kvo_data.empty and 'KVO_34_55_13' in kvo_data.columns:
161
  df['KVO_34_55_13'] = kvo_data['KVO_34_55_13']
162
  df['KVOs_34_55_13'] = kvo_data['KVOs_34_55_13']
@@ -166,17 +166,16 @@ class ChartPatternAnalyzer:
166
  df['WILLR_14'] = ta.willr(h, l, c, length=14)
167
 
168
  except Exception as e:
169
- print(f"❌ [PatternEngineV8.4] خطأ أثناء حساب المؤشرات وظيفياً: {e}")
 
170
  pass
171
  # --- (نهاية حساب المؤشرات) ---
172
 
173
- # (نأخذ الصف الأخير فقط)
174
  last_features = df.iloc[-1:].copy()
175
 
176
  last_features.ffill(inplace=True)
177
  last_features.fillna(0, inplace=True)
178
 
179
- # (التأكد من أننا نمرر فقط الخصائص الـ 30 التي يتوقعها النموذج، وبالترتيب)
180
  final_features = pd.DataFrame(columns=self.indicator_features)
181
 
182
  for col in self.indicator_features:
@@ -186,7 +185,6 @@ class ChartPatternAnalyzer:
186
  final_features[col] = 0
187
 
188
  return final_features
189
- # 🔴 --- END OF CHANGE (V8.4) --- 🔴
190
 
191
  async def detect_chart_patterns(self, ohlcv_data: dict) -> dict:
192
  """
@@ -214,10 +212,13 @@ class ChartPatternAnalyzer:
214
  window_candles = candles[-200:]
215
  df_window = pd.DataFrame(window_candles, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
216
 
217
- # (ملاحظة V8.4: لا نزال لا نحتاج إلى set_index هنا،
218
- # لأن _extract_features V8.4 يتعامل مع الفهرس الرقمي بشكل صحيح)
 
 
 
219
 
220
- # 1. استخراج الخصائص (الوصفة V8.4)
221
  features_df = self._extract_features(df_window)
222
 
223
  if features_df is None or features_df.empty:
@@ -242,8 +243,8 @@ class ChartPatternAnalyzer:
242
  })
243
 
244
  except Exception as e:
245
- # (يجب أن تختفي أخطاء KeyError من هنا الآن)
246
- print(f"❌ [PatternEngineV8.4] فشل التنبؤ لـ {timeframe}: {e}")
247
 
248
  # 4. اختيار أفضل نمط من *جميع* الأطر الزمنية
249
  if all_results:
@@ -261,4 +262,4 @@ class ChartPatternAnalyzer:
261
 
262
  return best_match
263
 
264
- print("✅ ML Module: Pattern Engine V8.4 (Isolated Series + Robust Checks) loaded")
 
1
  # ml_engine/patterns.py
2
+ # (V8.5 - الحل النهائي: إعادة الفهرس الزمني لـ VWAP + الإبقاء على .copy() لعزل المؤشرات)
3
 
4
  import pandas as pd
5
  import numpy as np
 
87
  self.scaler = None
88
  return False
89
 
90
+ # (V8.4 - هذا الكود صحيح ويجب الإبقاء عليه كما هو)
 
91
  def _extract_features(self, df_window: pd.DataFrame) -> pd.DataFrame:
92
  """
93
+ (الوصفة V8.4 - لا تغيير هنا)
94
  حساب الـ 30 مؤشراً (وظيفياً) مع عزل البيانات
95
  """
96
  if not ta:
97
  raise ImportError("مكتبة pandas-ta غير مثبتة.")
98
 
99
  # (إنشاء DF فارغ بنفس الفهرس (Index) الخاص بآخر صف)
100
+ # (مهم: df_window *يجب* أن يكون مفهرساً بالوقت هنا)
101
  df = pd.DataFrame(index=df_window.iloc[-1:].index)
102
 
103
  # (تمرير الأعمدة كـ "نسخ" (.copy()) لعزلها عن df_window)
 
107
  l = df_window['low'].copy()
108
  v = df_window['volume'].copy()
109
 
110
+ # (V8.5) تمرير الفهرس الزمني صراحة إلى VWAP
111
+ # (على الرغم من أن .copy() قد تزيله، فإن df_window.index لا يزال متاحاً)
112
+ # (تحديث: يبدو أن ta.vwap يأخذ الفهرس من السلاسل (Series) h,l,c,v)
113
+
114
  try:
115
  # --- حساب المؤشرات وظيفياً ---
116
  df['RSI_14'] = ta.rsi(c, length=14)
117
 
118
  macd_data = ta.macd(c, fast=12, slow=26, signal=9)
 
119
  if macd_data is not None and not macd_data.empty and 'MACD_12_26_9' in macd_data.columns:
120
  df['MACD_12_26_9'] = macd_data['MACD_12_26_9']
121
  df['MACDh_12_26_9'] = macd_data['MACDh_12_26_9']
 
125
  df['EMA_20'] = ta.ema(c, length=20)
126
 
127
  bb_data = ta.bbands(c, length=5, std=2.0)
 
128
  if bb_data is not None and not bb_data.empty and 'BBL_5_2.0' in bb_data.columns:
129
  df['BBL_5_2.0_2.0'] = bb_data['BBL_5_2.0']
130
  df['BBM_5_2.0_2.0'] = bb_data['BBM_5_2.0']
 
133
  df['BBP_5_2.0_2.0'] = bb_data['BBP_5_2.0']
134
 
135
  stoch_data = ta.stoch(h, l, c, k=14, d=3, smooth_k=3)
 
136
  if stoch_data is not None and not stoch_data.empty and 'STOCHk_14_3_3' in stoch_data.columns:
137
  df['STOCHk_14_3_3'] = stoch_data['STOCHk_14_3_3']
138
  df['STOCHd_14_3_3'] = stoch_data['STOCHd_14_3_3']
139
  df['STOCHh_14_3_3'] = stoch_data['STOCHh_14_3_3']
140
 
141
  adx_data = ta.adx(h, l, c, length=14, adxr=2)
 
142
  if adx_data is not None and not adx_data.empty and 'ADX_14' in adx_data.columns:
143
  df['ADX_14'] = adx_data['ADX_14']
144
  df['ADXR_14_2'] = adx_data['ADXR_14_2']
145
  df['DMP_14'] = adx_data['DMP_14']
146
  df['DMN_14'] = adx_data['DMN_14']
147
 
148
+ # (هنا يتم استخدام الفهرس الزمني الذي ورثته H,L,C,V)
149
  vwap_series = ta.vwap(h, l, c, v)
150
  if vwap_series is not None: df['VWAP_D'] = vwap_series
151
 
 
157
  df['DPO_20'] = ta.dpo(c, length=20)
158
 
159
  kvo_data = ta.kvo(h, l, c, v, fast=34, slow=55, signal=13)
 
160
  if kvo_data is not None and not kvo_data.empty and 'KVO_34_55_13' in kvo_data.columns:
161
  df['KVO_34_55_13'] = kvo_data['KVO_34_55_13']
162
  df['KVOs_34_55_13'] = kvo_data['KVOs_34_55_13']
 
166
  df['WILLR_14'] = ta.willr(h, l, c, length=14)
167
 
168
  except Exception as e:
169
+ # (يجب أن نرى هذا الخطأ فقط إذا فشل VWAP مرة أخرى)
170
+ print(f"❌ [PatternEngineV8.5] خطأ أثناء حساب المؤشرات وظيفياً: {e}")
171
  pass
172
  # --- (نهاية حساب المؤشرات) ---
173
 
 
174
  last_features = df.iloc[-1:].copy()
175
 
176
  last_features.ffill(inplace=True)
177
  last_features.fillna(0, inplace=True)
178
 
 
179
  final_features = pd.DataFrame(columns=self.indicator_features)
180
 
181
  for col in self.indicator_features:
 
185
  final_features[col] = 0
186
 
187
  return final_features
 
188
 
189
  async def detect_chart_patterns(self, ohlcv_data: dict) -> dict:
190
  """
 
212
  window_candles = candles[-200:]
213
  df_window = pd.DataFrame(window_candles, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
214
 
215
+ # 🔴 --- START OF CHANGE (V8.5) --- 🔴
216
+ # (إعادة تفعيل الفهرس الزمني. هذا ضروري لـ VWAP)
217
+ df_window['timestamp'] = pd.to_datetime(df_window['timestamp'], unit='ms')
218
+ df_window.set_index('timestamp', inplace=True)
219
+ # 🔴 --- END OF CHANGE (V8.5) --- 🔴
220
 
221
+ # 1. استخراج الخصائص (الوصفة V8.4 لا تزال قيد الاستخدام)
222
  features_df = self._extract_features(df_window)
223
 
224
  if features_df is None or features_df.empty:
 
243
  })
244
 
245
  except Exception as e:
246
+ # (الآن يجب أن تختفي جميع الأخطاء السابقة)
247
+ print(f"❌ [PatternEngineV8.5] فشل التنبؤ لـ {timeframe}: {e}")
248
 
249
  # 4. اختيار أفضل نمط من *جميع* الأطر الزمنية
250
  if all_results:
 
262
 
263
  return best_match
264
 
265
+ print("✅ ML Module: Pattern Engine V8.5 (Re-indexed + Isolated Series) loaded")