Spaces:
Running
Running
File size: 5,817 Bytes
a28b7a4 3bcda1c 713e0f7 a28b7a4 22184d7 a28b7a4 713e0f7 3bcda1c 22184d7 de73d0d 22184d7 3bcda1c a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 a28b7a4 fd9c5b3 ac3f01d a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 713e0f7 a28b7a4 22184d7 a28b7a4 3bcda1c a28b7a4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# ml_engine/monte_carlo.py (V10.2 - Fix: 1H Horizon with "Any Gain" Target)
import numpy as np
import pandas as pd
from arch import arch_model
import lightgbm as lgb
import traceback
import json
# محاولة استيراد pandas_ta
try:
import pandas_ta as ta
except ImportError:
ta = None
def _sanitize_results_for_json(results_dict):
if isinstance(results_dict, dict):
return {k: _sanitize_results_for_json(v) for k, v in results_dict.items()}
elif isinstance(results_dict, list):
return [_sanitize_results_for_json(v) for v in results_dict]
elif isinstance(results_dict, np.ndarray):
return results_dict.tolist()
elif isinstance(results_dict, (np.float64, np.float32)):
return float(results_dict)
elif isinstance(results_dict, (np.int64, np.int32)):
return int(results_dict)
else:
return results_dict
class MonteCarloAnalyzer:
def __init__(self):
self.simulation_results = {}
# ==================================================================
# 🔴 الدالة المبسطة للرانكر (تم تعديل الهدف V10.2)
# ==================================================================
def generate_1h_price_distribution_simple(self, closes_np: np.ndarray) -> dict:
"""
(V10.2) محاكاة سريعة لساعة واحدة قادمة.
الهدف: حساب احتمالية أن يكون الإغلاق القادم أعلى من السعر الحالي (أي ربح > 0).
"""
try:
if len(closes_np) < 30:
return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
current_price = closes_np[-1]
if current_price <= 0:
return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
# حساب العوائد اللوغاريتمية
log_returns = np.log(closes_np[1:] / closes_np[:-1])
log_returns = log_returns[~np.isnan(log_returns) & ~np.isinf(log_returns)]
if len(log_returns) < 20:
return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
mean_return = np.mean(log_returns)
std_return = np.std(log_returns)
if std_return < 1e-6: # انعدام تقلب شبه كامل
return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
# إعدادات المحاكاة (لساعة واحدة فقط)
num_simulations = 1000
t_df = 10
# Drift & Diffusion لساعة واحدة
drift = (mean_return - 0.5 * std_return**2)
diffusion = std_return * np.random.standard_t(df=t_df, size=num_simulations)
simulated_log_returns = drift + diffusion
simulated_prices_1h = current_price * np.exp(simulated_log_returns)
# 🔴 التعديل الجوهري: احتمالية "أي ربح" بدلاً من ربح محدد
# هل السعر المتوقع بعد ساعة > السعر الحالي؟
probability_of_gain = np.mean(simulated_prices_1h > current_price)
# حساب المخاطرة (VaR 95%)
var95_price = np.percentile(simulated_prices_1h, 5)
var95_pct = (current_price - var95_price) / current_price
return {
'mc_prob_gain': float(probability_of_gain),
'mc_var_95_pct': float(var95_pct),
'error': False
}
except Exception:
return {'mc_prob_gain': 0.5, 'mc_var_95_pct': 0.0, 'error': True}
# ... (الدوال المتقدمة تبقى كما هي أو يمكن تحديثها لاحقاً بنفس المنطق) ...
async def generate_1h_distribution_advanced(self, ohlcv_data, target_profit_percent=0.005):
# (سأترك هذه كما هي حالياً لأنها تستخدم في مراحل متقدمة قد تحتاج هدفاً محدداً،
# لكن يمكننا تعديلها أيضاً إذا أردت توحيد المعايير)
try:
if not ohlcv_data or '1h' not in ohlcv_data or len(ohlcv_data['1h']) < 50: return None
candles = ohlcv_data['1h']
df = pd.DataFrame(candles, columns=['ts', 'o', 'h', 'l', 'c', 'v'])
df[['o', 'h', 'l', 'c', 'v']] = df[['o', 'h', 'l', 'c', 'v']].astype(float)
current_price = df['c'].iloc[-1]
df['log_ret'] = np.log(df['c'] / df['c'].shift(1)).fillna(0)
rets = df['log_ret'].replace([np.inf, -np.inf], 0)
vol_est = np.std(rets.iloc[-30:])
try:
am = arch_model(rets * 100, vol='Garch', p=1, q=1, dist='t', rescale=False)
res = am.fit(disp='off'); vol_est = np.sqrt(res.forecast(horizon=1).variance.iloc[-1,0])/100
except: pass
drift = (np.mean(rets.iloc[-30:]) - 0.5 * vol_est**2)
sim_prices = current_price * np.exp(drift + vol_est * np.random.standard_t(df=10, size=5000))
# هنا أيضاً يمكن تخفيف الهدف إذا أردت، لكن سأبقيه 0.5% للمرحلة المتقدمة
prob_gain = np.mean(sim_prices >= current_price * (1 + target_profit_percent))
var95 = current_price - np.percentile(sim_prices, 5)
return _sanitize_results_for_json({
'probability_of_gain': prob_gain,
'risk_metrics': {'VaR_95_value': var95},
'simulation_model': 'Advanced_GARCH_1h'
})
except Exception: return None
print("✅ ML Module: Monte Carlo V10.2 (Any Gain Target) loaded") |