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")