Riy777 commited on
Commit
7af6de6
·
verified ·
1 Parent(s): 33d4073

Update ml_engine/monte_carlo.py

Browse files
Files changed (1) hide show
  1. ml_engine/monte_carlo.py +73 -24
ml_engine/monte_carlo.py CHANGED
@@ -1,4 +1,4 @@
1
- # ml_engine/monte_carlo.py (Updated to V6.2 - Stablecoin Guard)
2
  import numpy as np
3
  import pandas as pd
4
  from arch import arch_model
@@ -24,10 +24,8 @@ def _sanitize_results_for_json(results_dict):
24
  return [_sanitize_results_for_json(v) for v in results_dict]
25
  elif isinstance(results_dict, np.ndarray):
26
  return results_dict.tolist()
27
- # (Removed np.float_ which is deprecated in NumPy 2.0)
28
  elif isinstance(results_dict, (np.float64, np.float32)):
29
  return float(results_dict)
30
- # (Removed np.int_ which is deprecated in NumPy 2.0)
31
  elif isinstance(results_dict, (np.int64, np.int32)):
32
  return int(results_dict)
33
  else:
@@ -37,10 +35,74 @@ def _sanitize_results_for_json(results_dict):
37
  class MonteCarloAnalyzer:
38
  def __init__(self):
39
  self.simulation_results = {}
40
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  async def generate_1h_price_distribution(self, ohlcv_data, target_profit_percent=0.005):
42
  """
43
- (المرحلة 1 - سريعة)
44
  """
45
  try:
46
  if not ohlcv_data or '1h' not in ohlcv_data or len(ohlcv_data['1h']) < 30:
@@ -74,13 +136,9 @@ class MonteCarloAnalyzer:
74
  mean_return = np.mean(log_returns)
75
  std_return = np.std(log_returns)
76
 
77
- # 🔴 --- START OF CHANGE (V6.2 - STABLECOIN GUARD) --- 🔴
78
- # واقي العملة المستقرة: إذا كان الانحراف المعياري (التقلب) شبه صفري، أوقف التحليل
79
- if std_return < 1e-5: # (1e-5 هو 0.00001)
80
- print(f" [MC Guard] {ohlcv_data.get('symbol', 'Symbol')} - Zero volatility detected. Stopping MC.")
81
  self.simulation_results = {'error': 'Zero volatility detected (Stablecoin?)'}
82
  return None
83
- # 🔴 --- END OF CHANGE --- 🔴
84
 
85
  num_simulations = 5000
86
  t_df = 10
@@ -129,7 +187,6 @@ class MonteCarloAnalyzer:
129
  'raw_simulated_prices': simulated_prices[:100]
130
  }
131
 
132
- # (Sanitize Phase 1 results as well)
133
  return _sanitize_results_for_json(self.simulation_results)
134
 
135
  except Exception as e:
@@ -140,7 +197,7 @@ class MonteCarloAnalyzer:
140
 
141
  async def generate_1h_distribution_advanced(self, ohlcv_data, target_profit_percent=0.005):
142
  """
143
- (المرحلة 2+3 - متقدمة)
144
  """
145
  try:
146
  if not ohlcv_data or '1h' not in ohlcv_data or len(ohlcv_data['1h']) < 50:
@@ -161,27 +218,20 @@ class MonteCarloAnalyzer:
161
  df['log_returns'] = np.log(df['close'] / df['close'].shift(1)).fillna(0)
162
  log_returns_series = df['log_returns'].replace([np.inf, -np.inf], 0)
163
 
164
- # 🔴 --- START OF CHANGE (V6.2 - STABLECOIN GUARD) --- 🔴
165
- # واقي العملة المستقرة: التحقق من التقلب قبل بدء التحليل
166
  std_return_check = np.std(log_returns_series.iloc[-30:])
167
- if std_return_check < 1e-5: # (1e-5 هو 0.00001)
168
- print(f" [MC Guard Adv] {ohlcv_data.get('symbol', 'Symbol')} - Zero volatility detected. Stopping GARCH/LGBM.")
169
  self.simulation_results = {'error': 'Zero volatility detected (Stablecoin?)'}
170
- # العودة إلى المرحلة 1 (التي ستمسك بها أيضاً وترجع None)
171
  return await self.generate_1h_price_distribution(ohlcv_data, target_profit_percent)
172
- # 🔴 --- END OF CHANGE --- 🔴
173
 
174
  # 3. (Phase 2) توقع التقلب باستخدام GARCH(1,1)
175
  try:
176
- # (Rescale by 100, and set rescale=False to stop GARCH from auto-scaling)
177
  garch_model = arch_model(log_returns_series * 100, vol='Garch', p=1, q=1, dist='t', rescale=False)
178
  res = garch_model.fit(update_freq=0, disp='off')
179
  forecast = res.forecast(horizon=1)
180
- # (Divide by 100^2 = 10000)
181
  forecasted_var = forecast.variance.iloc[-1, 0] / (100**2)
182
  forecasted_std_return = np.sqrt(forecasted_var)
183
  except Exception as garch_err:
184
- forecasted_std_return = std_return_check # (استخدام القيمة التي تم التحقق منها)
185
  print(f"⚠️ GARCH failed, using std: {garch_err}")
186
 
187
 
@@ -195,7 +245,7 @@ class MonteCarloAnalyzer:
195
  delta = df['close'].diff()
196
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
197
  loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
198
- rs = gain / (loss + 1e-9) # (Added 1e-9 to prevent zero division)
199
  df['rsi'] = 100 - (100 / (1 + rs))
200
  df['macd_hist'] = df['close'].ewm(span=12).mean() - df['close'].ewm(span=26).mean()
201
 
@@ -281,7 +331,6 @@ class MonteCarloAnalyzer:
281
  'raw_simulated_prices': simulated_prices[:100]
282
  }
283
 
284
- # (Sanitize the results before returning)
285
  return _sanitize_results_for_json(self.simulation_results)
286
 
287
  except Exception as e:
@@ -303,4 +352,4 @@ class MonteCarloAnalyzer:
303
  else: return 1.0
304
  except Exception: return 1.0
305
 
306
- print("✅ ML Module: Advanced Monte Carlo Analyzer loaded (FIXED: NumPy 2.0 & GARCH Scale v2)")
 
1
+ # ml_engine/monte_carlo.py (Updated to V10.0 - Added Simple Sim for Ranker)
2
  import numpy as np
3
  import pandas as pd
4
  from arch import arch_model
 
24
  return [_sanitize_results_for_json(v) for v in results_dict]
25
  elif isinstance(results_dict, np.ndarray):
26
  return results_dict.tolist()
 
27
  elif isinstance(results_dict, (np.float64, np.float32)):
28
  return float(results_dict)
 
29
  elif isinstance(results_dict, (np.int64, np.int32)):
30
  return int(results_dict)
31
  else:
 
35
  class MonteCarloAnalyzer:
36
  def __init__(self):
37
  self.simulation_results = {}
38
+
39
+ # 🔴 --- START OF NEW FUNCTION (V10.0) --- 🔴
40
+ # (هذه الدالة هي التي يحتاجها الرانكر V9.8)
41
+ def generate_1h_price_distribution_simple(self, closes_np: np.ndarray, target_profit_percent=0.005) -> dict:
42
+ """
43
+ (V10.0) نسخة سريعة جداً (غير متزامنة) مخصصة للرانكر.
44
+ تقبل numpy array مباشرة وتُرجع الميزات المطلوبة فقط.
45
+ """
46
+ try:
47
+ # (نحتاج 100 شمعة كما في Colab)
48
+ if len(closes_np) < 30:
49
+ return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
50
+
51
+ current_price = closes_np[-1]
52
+ if current_price <= 0:
53
+ return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
54
+
55
+ log_returns = np.log(closes_np[1:] / closes_np[:-1])
56
+ log_returns = log_returns[~np.isnan(log_returns) & ~np.isinf(log_returns)]
57
+
58
+ if len(log_returns) < 20:
59
+ return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
60
+
61
+ mean_return = np.mean(log_returns)
62
+ std_return = np.std(log_returns)
63
+
64
+ if std_return < 1e-5: # (واقي العملة المستقرة)
65
+ return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
66
+
67
+ num_simulations = 1000 # (سريعة، كما في Colab)
68
+ t_df = 10
69
+ jump_lambda = 0.05
70
+ jump_mean = 0.0
71
+ jump_std = std_return * 3.0
72
+
73
+ drift = (mean_return - 0.5 * std_return**2)
74
+ diffusion = std_return * np.random.standard_t(df=t_df, size=num_simulations)
75
+ jump_mask = np.random.rand(num_simulations) < jump_lambda
76
+ jump_sizes = np.random.normal(jump_mean, jump_std, size=num_simulations)
77
+ jump_component = np.zeros(num_simulations)
78
+ jump_component[jump_mask] = jump_sizes[jump_mask]
79
+
80
+ simulated_log_returns = drift + diffusion + jump_component
81
+ simulated_prices = current_price * np.exp(simulated_log_returns)
82
+
83
+ percentiles = np.percentile(simulated_prices, [5])
84
+ VaR_95_price = percentiles[0]
85
+ # (كنسبة مئوية، مع واقي من القسمة على صفر)
86
+ VaR_95_value = (current_price - VaR_95_price) / (current_price + 1e-9)
87
+
88
+ target_price = current_price * (1 + target_profit_percent)
89
+ probability_of_gain = np.mean(simulated_prices >= target_price)
90
+
91
+ return {
92
+ 'mc_prob_gain': probability_of_gain,
93
+ 'mc_var_95_pct': VaR_95_value,
94
+ 'error': False
95
+ }
96
+
97
+ except Exception:
98
+ # (إرجاع قيم محايدة في حالة الفشل)
99
+ return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
100
+ # 🔴 --- END OF NEW FUNCTION (V10.0) --- 🔴
101
+
102
+
103
  async def generate_1h_price_distribution(self, ohlcv_data, target_profit_percent=0.005):
104
  """
105
+ (المرحلة 1 - سريعة) - (للاستخدامات القديمة إن وجدت)
106
  """
107
  try:
108
  if not ohlcv_data or '1h' not in ohlcv_data or len(ohlcv_data['1h']) < 30:
 
136
  mean_return = np.mean(log_returns)
137
  std_return = np.std(log_returns)
138
 
139
+ if std_return < 1e-5: # (واقي العملة المستقرة)
 
 
 
140
  self.simulation_results = {'error': 'Zero volatility detected (Stablecoin?)'}
141
  return None
 
142
 
143
  num_simulations = 5000
144
  t_df = 10
 
187
  'raw_simulated_prices': simulated_prices[:100]
188
  }
189
 
 
190
  return _sanitize_results_for_json(self.simulation_results)
191
 
192
  except Exception as e:
 
197
 
198
  async def generate_1h_distribution_advanced(self, ohlcv_data, target_profit_percent=0.005):
199
  """
200
+ (المرحلة 2+3 - متقدمة) - (للاستخدام في الطبقة 2)
201
  """
202
  try:
203
  if not ohlcv_data or '1h' not in ohlcv_data or len(ohlcv_data['1h']) < 50:
 
218
  df['log_returns'] = np.log(df['close'] / df['close'].shift(1)).fillna(0)
219
  log_returns_series = df['log_returns'].replace([np.inf, -np.inf], 0)
220
 
 
 
221
  std_return_check = np.std(log_returns_series.iloc[-30:])
222
+ if std_return_check < 1e-5: # (واقي العملة المستقرة)
 
223
  self.simulation_results = {'error': 'Zero volatility detected (Stablecoin?)'}
 
224
  return await self.generate_1h_price_distribution(ohlcv_data, target_profit_percent)
 
225
 
226
  # 3. (Phase 2) توقع التقلب باستخدام GARCH(1,1)
227
  try:
 
228
  garch_model = arch_model(log_returns_series * 100, vol='Garch', p=1, q=1, dist='t', rescale=False)
229
  res = garch_model.fit(update_freq=0, disp='off')
230
  forecast = res.forecast(horizon=1)
 
231
  forecasted_var = forecast.variance.iloc[-1, 0] / (100**2)
232
  forecasted_std_return = np.sqrt(forecasted_var)
233
  except Exception as garch_err:
234
+ forecasted_std_return = std_return_check
235
  print(f"⚠️ GARCH failed, using std: {garch_err}")
236
 
237
 
 
245
  delta = df['close'].diff()
246
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
247
  loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
248
+ rs = gain / (loss + 1e-9)
249
  df['rsi'] = 100 - (100 / (1 + rs))
250
  df['macd_hist'] = df['close'].ewm(span=12).mean() - df['close'].ewm(span=26).mean()
251
 
 
331
  'raw_simulated_prices': simulated_prices[:100]
332
  }
333
 
 
334
  return _sanitize_results_for_json(self.simulation_results)
335
 
336
  except Exception as e:
 
352
  else: return 1.0
353
  except Exception: return 1.0
354
 
355
+ print("✅ ML Module: Advanced Monte Carlo Analyzer loaded (V10.0 - Simple Sim Added)")