Riy777 commited on
Commit
0be14ec
·
verified ·
1 Parent(s): 7af6de6

Update ml_engine/indicators.py

Browse files
Files changed (1) hide show
  1. ml_engine/indicators.py +65 -66
ml_engine/indicators.py CHANGED
@@ -1,9 +1,18 @@
1
- # ml_engine/indicators.py (V9.1 - Smart Feature Engineering)
2
  import pandas as pd
3
  import pandas_ta as ta
4
  import numpy as np
5
  from typing import Dict
6
 
 
 
 
 
 
 
 
 
 
7
  class AdvancedTechnicalAnalyzer:
8
  def __init__(self):
9
  # (هذا الكونفيغ سيبقى للاستخدامات القديمة مثل الحارس 1m)
@@ -15,16 +24,13 @@ class AdvancedTechnicalAnalyzer:
15
  'cycle': ['hull_ma', 'supertrend', 'zigzag', 'fisher_transform']
16
  }
17
 
18
- # 🔴 --- START OF NEW FUNCTION (V9.1) --- 🔴
19
  def calculate_v9_smart_features(self, dataframe: pd.DataFrame) -> Dict[str, float]:
20
  """
21
- (جديد V9.1) - (العقل الحسابي لنموذج الرانكر V9.1)
22
- حساب "الميزات الذكية" المتقدمة المستوحاة من خطة GPT (للكاشف المصغر V9.1).
23
- هذه الدالة مصممة لتغذية نموذج ML (مثل LightGBM) ببيانات غنية.
24
  """
25
  if dataframe.empty or dataframe is None or len(dataframe) < 100:
26
- # (نحتاج 100 شمعة على الأقل لحساب الميزات الطويلة المدى مثل min(100))
27
- # (ملاحظة: data_manager V9.1 سيطلب 200 شمعة لضمان عمل ema_200)
28
  return {}
29
 
30
  features = {}
@@ -41,84 +47,77 @@ class AdvancedTechnicalAnalyzer:
41
  mfi_series = ta.mfi(high, low, close, volume, length=14)
42
  atr_series = ta.atr(high, low, close, length=14)
43
  adx_data = ta.adx(high, low, close, length=14)
 
44
 
45
- # --- 2. ميزات "نسب السعر" (Price Ratios) - (لتحديد "القاع") ---
46
- # (نسبة السعر إلى المتوسطات المتحركة)
47
  ema_50 = ta.ema(close, length=50).iloc[-1]
48
  ema_200 = ta.ema(close, length=200).iloc[-1]
49
- if ema_50 and ema_50 > 0:
50
- features['price_to_ema_50'] = (current_price / ema_50) - 1
51
- if ema_200 and ema_200 > 0:
52
- features['price_to_ema_200'] = (current_price / ema_200) - 1
53
-
54
- # (نسبة السعر إلى أدنى/أعلى سعر)
55
- min_100 = low.tail(100).min()
56
- max_100 = high.tail(100).max()
57
- if min_100 and min_100 > 0:
58
- features['price_to_min_100'] = (current_price / min_100) - 1
59
- if max_100 and max_100 > 0:
60
- features['price_to_max_100'] = (current_price / max_100) - 1
61
 
62
- # --- 3. ميزات "الميل" (Slope) - (لتحديد "تراكم الزخم") ---
63
  ema_14 = ta.ema(close, length=14).iloc[-1]
64
- if ema_14 and ema_50:
65
- features['slope_14_50'] = (ema_14 - ema_50) / 14
 
 
 
66
 
67
  # --- 4. ميزات "الحجم" (Volume) و "السيولة" ---
68
- # (Z-Score للحجم)
69
- vol_ma_50 = volume.tail(50).mean()
70
- vol_std_50 = volume.tail(50).std()
71
- if vol_std_50 and vol_std_50 > 0:
72
- features['volume_zscore_50'] = (volume.iloc[-1] - vol_ma_50) / vol_std_50
73
-
74
- # (فجوة VWAP)
75
  vwap = ta.vwap(high, low, close, volume).iloc[-1]
76
- if vwap and vwap > 0:
77
- features['vwap_gap'] = (current_price - vwap) / vwap
 
 
 
 
 
 
78
 
79
- # --- 5. ميزات "تجميعية" (Aggregative) - (لفهم السياق) ---
80
- # (إحصائيات RSI)
81
  if rsi_series is not None:
82
- features['rsi_14'] = rsi_series.iloc[-1]
83
- features['rsi_mean_10'] = rsi_series.tail(10).mean()
84
- features['rsi_std_10'] = rsi_series.tail(10).std()
85
-
86
- # (إحصائيات MFI)
87
  if mfi_series is not None:
88
- features['mfi_14'] = mfi_series.iloc[-1]
89
- features['mfi_mean_10'] = mfi_series.tail(10).mean()
90
-
91
- # (مؤشر ADX)
92
- if adx_data is not None:
93
- features['adx_14'] = adx_data['ADX_14'].iloc[-1]
94
 
95
  # --- 6. ميزات "التقلب" (Volatility) ---
96
- # (ATR كنسبة مئوية)
97
  if atr_series is not None:
98
  atr_val = atr_series.iloc[-1]
99
- if atr_val and current_price > 0:
100
- features['atr_percent'] = (atr_val / current_price) * 100
101
-
102
- # (تطبيع العائد بالتقلب)
103
  last_return = close.pct_change().iloc[-1]
104
- if atr_val and atr_val > 0:
105
- features['atr_normalized_return'] = last_return / atr_val
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  except Exception as e:
108
- # (في التداول الحي، من الأفضل تسجيل الخطأ بدلاً من طباعته فقط)
109
- # print(f"⚠️ خطأ في حساب ميزات V9.1 الذكية: {e}")
110
- return {}
111
-
112
- # (تنظيف: إزالة NaN أو Inf وضمان أن القيم أرقام عشرية)
113
- final_features = {}
114
  for key, value in features.items():
115
- if value is not None and np.isfinite(value):
116
- final_features[key] = float(value)
117
- else:
118
- final_features[key] = 0.0 # (استبدال القيم غير الصالحة بـ 0.0)
119
-
120
  return final_features
121
- # 🔴 --- END OF NEW FUNCTION (V9.1) --- 🔴
122
 
123
 
124
  # -----------------------------------------------------------------
@@ -386,4 +385,4 @@ class AdvancedTechnicalAnalyzer:
386
 
387
  return {key: value for key, value in cycle.items() if value is not None and not np.isnan(value)}
388
 
389
- print("✅ ML Module: Technical Indicators loaded (V9.1 - Smart Features Enabled)")
 
1
+ # ml_engine/indicators.py (V10.0 - Super-Brain Features)
2
  import pandas as pd
3
  import pandas_ta as ta
4
  import numpy as np
5
  from typing import Dict
6
 
7
+ try:
8
+ from hurst import compute_Hc
9
+ HURST_AVAILABLE = True
10
+ except ImportError:
11
+ print("⚠️ مكتبة 'hurst' غير موجودة. ميزة "مفتاح النظام" ستكون معطلة.")
12
+ print(" -> قم بتثبيتها: pip install hurst")
13
+ HURST_AVAILABLE = False
14
+
15
+
16
  class AdvancedTechnicalAnalyzer:
17
  def __init__(self):
18
  # (هذا الكونفيغ سيبقى للاستخدامات القديمة مثل الحارس 1m)
 
24
  'cycle': ['hull_ma', 'supertrend', 'zigzag', 'fisher_transform']
25
  }
26
 
27
+ # 🔴 --- START OF UPDATED FUNCTION (V10.0 - Super-Brain) --- 🔴
28
  def calculate_v9_smart_features(self, dataframe: pd.DataFrame) -> Dict[str, float]:
29
  """
30
+ (محدث V10.0) - (العقل الحسابي لنموذج V9.8)
31
+ حساب جميع الميزات المتقدمة (بما في ذلك Hurst, CMF, PPO, VROC)
 
32
  """
33
  if dataframe.empty or dataframe is None or len(dataframe) < 100:
 
 
34
  return {}
35
 
36
  features = {}
 
47
  mfi_series = ta.mfi(high, low, close, volume, length=14)
48
  atr_series = ta.atr(high, low, close, length=14)
49
  adx_data = ta.adx(high, low, close, length=14)
50
+ obv_series = ta.obv(close, volume)
51
 
52
+ # --- 2. ميزات "نسب السعر" (Price Ratios) ---
 
53
  ema_50 = ta.ema(close, length=50).iloc[-1]
54
  ema_200 = ta.ema(close, length=200).iloc[-1]
55
+ if ema_50 and ema_50 > 0: features['price_to_ema_50'] = (current_price / ema_50) - 1
56
+ if ema_200 and ema_200 > 0: features['price_to_ema_200'] = (current_price / ema_200) - 1
57
+ min_100 = low.tail(100).min(); max_100 = high.tail(100).max()
58
+ if min_100 and min_100 > 0: features['price_to_min_100'] = (current_price / min_100) - 1
59
+ if max_100 and max_100 > 0: features['price_to_max_100'] = (current_price / max_100) - 1
 
 
 
 
 
 
 
60
 
61
+ # --- 3. ميزات "الميل" (Slope) ---
62
  ema_14 = ta.ema(close, length=14).iloc[-1]
63
+ if ema_14 and ema_50: features['slope_14_50'] = (ema_14 - ema_50) / 14
64
+ if adx_data is not None:
65
+ adx_series = adx_data['ADX_14']
66
+ adx_ema_5 = ta.ema(adx_series, length=5).iloc[-1]; adx_ema_15 = ta.ema(adx_series, length=15).iloc[-1]
67
+ if adx_ema_5 and adx_ema_15: features['adx_slope'] = (adx_ema_5 - adx_ema_15) / 5
68
 
69
  # --- 4. ميزات "الحجم" (Volume) و "السيولة" ---
70
+ vol_ma_50 = volume.tail(50).mean(); vol_std_50 = volume.tail(50).std()
71
+ if vol_std_50 and vol_std_50 > 0: features['volume_zscore_50'] = (volume.iloc[-1] - vol_ma_50) / vol_std_50
 
 
 
 
 
72
  vwap = ta.vwap(high, low, close, volume).iloc[-1]
73
+ if vwap and vwap > 0: features['vwap_gap'] = (current_price - vwap) / vwap
74
+ cmf = ta.cmf(high, low, close, volume, length=20)
75
+ if cmf is not None: features['cmf_20'] = cmf.iloc[-1]
76
+ vroc = ta.roc(volume, length=12)
77
+ if vroc is not None: features['vroc_12'] = vroc.iloc[-1]
78
+ if obv_series is not None:
79
+ obv_ema_10 = ta.ema(obv_series, length=10).iloc[-1]; obv_ema_30 = ta.ema(obv_series, length=30).iloc[-1]
80
+ if obv_ema_10 and obv_ema_30: features['obv_slope'] = (obv_ema_10 - obv_ema_30) / 10
81
 
82
+ # --- 5. ميزات "تجميعية" (Aggregative) ---
 
83
  if rsi_series is not None:
84
+ features['rsi_14'] = rsi_series.iloc[-1]; features['rsi_mean_10'] = rsi_series.tail(10).mean(); features['rsi_std_10'] = rsi_series.tail(10).std()
 
 
 
 
85
  if mfi_series is not None:
86
+ features['mfi_14'] = mfi_series.iloc[-1]; features['mfi_mean_10'] = mfi_series.tail(10).mean()
87
+ if adx_data is not None: features['adx_14'] = adx_data['ADX_14'].iloc[-1]
 
 
 
 
88
 
89
  # --- 6. ميزات "التقلب" (Volatility) ---
 
90
  if atr_series is not None:
91
  atr_val = atr_series.iloc[-1]
92
+ if atr_val and current_price > 0: features['atr_percent'] = (atr_val / current_price) * 100
93
+ vol_of_vol_series = ta.atr(atr_series, length=10) # (Vol-of-Vol)
94
+ if vol_of_vol_series is not None: features['vol_of_vol'] = vol_of_vol_series.iloc[-1]
 
95
  last_return = close.pct_change().iloc[-1]
96
+ if atr_val and atr_val > 0: features['atr_normalized_return'] = last_return / atr_val
 
97
 
98
+ # --- 7. (جديد V9.8) ميزات النظام (Regime Features) ---
99
+ if HURST_AVAILABLE:
100
+ hurst_series = close.tail(100).to_numpy()
101
+ H, c, data = compute_Hc(hurst_series, kind='price', simplified=True)
102
+ features['hurst'] = H
103
+ else:
104
+ features['hurst'] = 0.5 # (محايد إذا لم يتم تثبيت المكتبة)
105
+
106
+ ppo_data = ta.ppo(close, fast=12, slow=26, signal=9)
107
+ if ppo_data is not None:
108
+ features['ppo_hist'] = ppo_data['PPOh_12_26_9'].iloc[-1]
109
+ features['ppo_line'] = ppo_data['PPO_12_26_9'].iloc[-1]
110
+
111
  except Exception as e:
112
+ # print(f"⚠️ خطأ في حساب ميزات V9.8 الذكية: {e}");
113
+ pass # (نتجاهل الأخطاء في التداول الحي ونعيد ميزات جزئية)
114
+
115
+ final_features = {};
 
 
116
  for key, value in features.items():
117
+ if value is not None and np.isfinite(value): final_features[key] = float(value)
118
+ else: final_features[key] = 0.0
 
 
 
119
  return final_features
120
+ # 🔴 --- END OF UPDATED FUNCTION (V10.0) --- 🔴
121
 
122
 
123
  # -----------------------------------------------------------------
 
385
 
386
  return {key: value for key, value in cycle.items() if value is not None and not np.isnan(value)}
387
 
388
+ print("✅ ML Module: Technical Indicators loaded (V10.0 - Super-Brain Features)")