Spaces:
Paused
Paused
Update ml_engine/processor.py
Browse files- ml_engine/processor.py +63 -138
ml_engine/processor.py
CHANGED
|
@@ -1,15 +1,18 @@
|
|
| 1 |
-
# ml_engine/processor.py
|
| 2 |
-
|
| 3 |
-
|
| 4 |
import asyncio
|
| 5 |
-
import json
|
| 6 |
import traceback
|
|
|
|
| 7 |
|
| 8 |
-
# استيراد
|
| 9 |
-
|
| 10 |
-
from .
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
class MLProcessor:
|
| 15 |
def __init__(self, market_context, data_manager, learning_hub):
|
|
@@ -17,149 +20,71 @@ class MLProcessor:
|
|
| 17 |
self.data_manager = data_manager
|
| 18 |
self.learning_hub = learning_hub
|
| 19 |
|
| 20 |
-
|
| 21 |
-
self.
|
| 22 |
-
self.
|
| 23 |
|
| 24 |
-
#
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
async def process_and_score_symbol_enhanced(self, raw_data
|
| 32 |
"""
|
| 33 |
-
المعالجة المركزية
|
|
|
|
| 34 |
"""
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
ohlcv_data = raw_data.get('ohlcv') # يجب أن يحتوي على {'15m': [], '1h': [], ...}
|
| 38 |
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
analysis_result = {
|
| 43 |
'symbol': symbol,
|
| 44 |
'current_price': raw_data.get('current_price', 0.0),
|
| 45 |
-
|
| 46 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
}
|
| 48 |
|
| 49 |
-
# 2. تشغيل التحليلات المتقدمة بالتوازي لسرعة الأداء
|
| 50 |
-
# (أنماط XGBoost، مؤشرات فنية، مونت كارلو المتقدمة)
|
| 51 |
-
tasks = [
|
| 52 |
-
self._run_xgboost_patterns(ohlcv_data),
|
| 53 |
-
self._run_advanced_indicators(ohlcv_data),
|
| 54 |
-
self._run_advanced_monte_carlo(ohlcv_data)
|
| 55 |
-
]
|
| 56 |
-
patterns, indicators, mc_results = await asyncio.gather(*tasks)
|
| 57 |
-
|
| 58 |
-
analysis_result['pattern_analysis'] = patterns
|
| 59 |
-
analysis_result['advanced_indicators'] = indicators
|
| 60 |
-
analysis_result['monte_carlo_distribution'] = mc_results
|
| 61 |
-
|
| 62 |
-
# 3. دمج بيانات الحيتان (إذا توفرت مسبقاً)
|
| 63 |
-
if preloaded_whale_data and symbol in preloaded_whale_data:
|
| 64 |
-
analysis_result['whale_data'] = preloaded_whale_data[symbol]
|
| 65 |
-
else:
|
| 66 |
-
analysis_result['whale_data'] = {'data_available': False}
|
| 67 |
-
|
| 68 |
-
# 4. حساب الدرجة النهائية الموزونة (V11.0 New Weights)
|
| 69 |
-
final_score = self._calculate_final_weighted_score(analysis_result)
|
| 70 |
-
analysis_result['enhanced_final_score'] = final_score
|
| 71 |
-
|
| 72 |
return analysis_result
|
| 73 |
|
| 74 |
except Exception as e:
|
| 75 |
-
print(f"❌ [Processor] خطأ ف
|
| 76 |
traceback.print_exc()
|
| 77 |
return None
|
| 78 |
|
| 79 |
-
|
| 80 |
-
"""تشغيل محرك الأنماط الجديد على كافة الأطر الزمنية المتاحة"""
|
| 81 |
-
if not self.pattern_engine or not self.pattern_engine.initialized:
|
| 82 |
-
return {'pattern_confidence': 0.0, 'details': {}}
|
| 83 |
-
try:
|
| 84 |
-
# المحرك الجديد يعيد نتيجة مجمعة جاهزة
|
| 85 |
-
return await self.pattern_engine.detect_chart_patterns(ohlcv_data)
|
| 86 |
-
except Exception as e:
|
| 87 |
-
print(f"⚠️ خطأ في تحليل الأنماط: {e}")
|
| 88 |
-
return {'pattern_confidence': 0.0, 'details': {'error': str(e)}}
|
| 89 |
-
|
| 90 |
-
async def _run_advanced_indicators(self, ohlcv_data):
|
| 91 |
-
"""حساب المؤشرات الفنية المتقدمة لأهم الأطر الزمنية"""
|
| 92 |
-
indicators = {}
|
| 93 |
-
try:
|
| 94 |
-
# نركز على 1h و 4h للتحليل الفني العام
|
| 95 |
-
for tf in ['1h', '4h']:
|
| 96 |
-
if tf in ohlcv_data and len(ohlcv_data[tf]) >= 50:
|
| 97 |
-
df = self._create_dataframe(ohlcv_data[tf])
|
| 98 |
-
indicators[tf] = self.technical_analyzer.calculate_all_indicators(df, tf)
|
| 99 |
-
except Exception: pass
|
| 100 |
-
return indicators
|
| 101 |
-
|
| 102 |
-
async def _run_advanced_monte_carlo(self, ohlcv_data):
|
| 103 |
-
"""تشغيل محاكاة مونت كارلو المتقدمة (GARCH+LGBM) على إطار الساعة"""
|
| 104 |
-
try:
|
| 105 |
-
# نستخدم النسخة المتقدمة (المرحلة 2+3) بدلاً من البسيطة
|
| 106 |
-
return await self.monte_carlo_analyzer.generate_1h_distribution_advanced(ohlcv_data)
|
| 107 |
-
except Exception: return None
|
| 108 |
-
|
| 109 |
-
def _calculate_final_weighted_score(self, analysis):
|
| 110 |
-
"""
|
| 111 |
-
(V11.0) حساب الدرجة النهائية بالأوزان الجديدة:
|
| 112 |
-
- التحليل الفني: 85% (أنماط 40%، مؤشرات 30%، مونت كارلو 30% من الـ 85%)
|
| 113 |
-
- الحيتان: 10%
|
| 114 |
-
- الأخبار: 5%
|
| 115 |
-
"""
|
| 116 |
-
try:
|
| 117 |
-
# 1. المكون الفني (Total Technical Score)
|
| 118 |
-
pattern_score = analysis.get('pattern_analysis', {}).get('pattern_confidence', 0.0)
|
| 119 |
-
|
| 120 |
-
# حساب درجة المؤشرات (متوسط بسيط لبعض المؤشرات الرئيسية كمثال)
|
| 121 |
-
inds = analysis.get('advanced_indicators', {}).get('1h', {})
|
| 122 |
-
rsi = inds.get('rsi', 50)
|
| 123 |
-
macd = inds.get('macd_hist', 0)
|
| 124 |
-
ind_score = 0.5
|
| 125 |
-
if rsi > 50: ind_score += 0.1
|
| 126 |
-
if macd > 0: ind_score += 0.1
|
| 127 |
-
# (يمكن تعقيد هذا الجزء أكثر لاحقاً)
|
| 128 |
-
|
| 129 |
-
# درجة مونت كارلو
|
| 130 |
-
mc_prob = analysis.get('monte_carlo_distribution', {}).get('probability_of_gain', 0.5)
|
| 131 |
-
mc_score = max(0.0, min(1.0, (mc_prob - 0.5) * 2.0)) # تطبيع إلى 0-1
|
| 132 |
-
|
| 133 |
-
# دمج المكون الفني (85% من الإجمالي)
|
| 134 |
-
technical_sub_score = (pattern_score * 0.40) + (ind_score * 0.30) + (mc_score * 0.30)
|
| 135 |
-
weighted_technical = technical_sub_score * 0.85
|
| 136 |
-
|
| 137 |
-
# 2. مكون الحيتان (10%)
|
| 138 |
-
whale_score = 0.0
|
| 139 |
-
whale_data = analysis.get('whale_data', {})
|
| 140 |
-
if whale_data.get('data_available'):
|
| 141 |
-
# نفترض وجود درجة ثقة جاهزة من 0 لـ 1
|
| 142 |
-
whale_score = whale_data.get('confidence_score', 0.5)
|
| 143 |
-
weighted_whale = whale_score * 0.10
|
| 144 |
-
|
| 145 |
-
# 3. مكون الأخبار (5%)
|
| 146 |
-
news_score = 0.5 # محايد افتراضياً
|
| 147 |
-
# (سيتم تحديث هذا الجزء لاحقاً عند توفر تحليل الأخبار الحقيقي)
|
| 148 |
-
weighted_news = news_score * 0.05
|
| 149 |
-
|
| 150 |
-
# الدرجة النهائية
|
| 151 |
-
return weighted_technical + weighted_whale + weighted_news
|
| 152 |
-
|
| 153 |
-
except Exception as e:
|
| 154 |
-
# print(f"⚠️ خطأ في حساب الدرجة النهائية: {e}")
|
| 155 |
-
return analysis.get('layer1_score', 0.0) * 0.85 # عودة للدرجة الأولية
|
| 156 |
-
|
| 157 |
-
def _create_dataframe(self, candles):
|
| 158 |
-
if not candles: return pd.DataFrame()
|
| 159 |
-
df = pd.DataFrame(candles, columns=['ts', 'open', 'high', 'low', 'close', 'volume'])
|
| 160 |
-
df[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']].astype(float)
|
| 161 |
-
df['ts'] = pd.to_datetime(df['ts'], unit='ms')
|
| 162 |
-
df.set_index('ts', inplace=True)
|
| 163 |
-
return df
|
| 164 |
-
|
| 165 |
-
print("✅ ML Processor loaded - V11.0 (XGBoost Multi-TF & New Weights)")
|
|
|
|
| 1 |
+
# ml_engine/processor.py
|
| 2 |
+
# (V12.0 - Titan Powered Core)
|
| 3 |
+
|
| 4 |
import asyncio
|
|
|
|
| 5 |
import traceback
|
| 6 |
+
import numpy as np
|
| 7 |
|
| 8 |
+
# استيراد محرك Titan الجديد
|
| 9 |
+
try:
|
| 10 |
+
from ml_engine.titan_engine import TitanEngine
|
| 11 |
+
except ImportError:
|
| 12 |
+
print("❌ [Processor] لم يتم العثور على titan_engine.py! تأكد من إنشائه.")
|
| 13 |
+
TitanEngine = None
|
| 14 |
+
|
| 15 |
+
from ml_engine.monte_carlo import MonteCarloAnalyzer
|
| 16 |
|
| 17 |
class MLProcessor:
|
| 18 |
def __init__(self, market_context, data_manager, learning_hub):
|
|
|
|
| 20 |
self.data_manager = data_manager
|
| 21 |
self.learning_hub = learning_hub
|
| 22 |
|
| 23 |
+
# تهيئة المحركات
|
| 24 |
+
self.titan = TitanEngine() if TitanEngine else None
|
| 25 |
+
self.mc_analyzer = MonteCarloAnalyzer()
|
| 26 |
|
| 27 |
+
# حالة التهيئة
|
| 28 |
+
self.initialized = False
|
| 29 |
+
|
| 30 |
+
async def initialize(self):
|
| 31 |
+
"""تهيئة غير متزامنة لمحرك Titan"""
|
| 32 |
+
if self.titan and not self.titan.initialized:
|
| 33 |
+
await self.titan.initialize()
|
| 34 |
+
self.initialized = True
|
| 35 |
|
| 36 |
+
async def process_and_score_symbol_enhanced(self, raw_data):
|
| 37 |
"""
|
| 38 |
+
المعالجة المركزية باستخدام Titan (Layer 2).
|
| 39 |
+
الآن، Titan هو المسؤول الأول والأخير عن القرار الفني.
|
| 40 |
"""
|
| 41 |
+
# ضمان التهيئة
|
| 42 |
+
if not self.initialized: await self.initialize()
|
|
|
|
| 43 |
|
| 44 |
+
symbol = raw_data.get('symbol')
|
| 45 |
+
ohlcv_data = raw_data.get('ohlcv') # {'5m': [], '15m': [], ...}
|
| 46 |
+
|
| 47 |
+
if not symbol or not ohlcv_data or not self.titan: return None
|
| 48 |
|
| 49 |
+
try:
|
| 50 |
+
# 1. 🧠 استدعاء العقل المدبر (Titan Inference)
|
| 51 |
+
# Titan سيأخذ البيانات الخام، يطبق الهرم المقلوب، ويعطي احتمالية دقيقة
|
| 52 |
+
titan_result = self.titan.predict(ohlcv_data)
|
| 53 |
+
titan_score = titan_result.get('score', 0.0)
|
| 54 |
+
|
| 55 |
+
# 2. 🎲 تحليل مخاطر إضافي (اختياري للدعم)
|
| 56 |
+
# يمكننا تشغيل مونت كارلو سريع كـ "رأي ثانٍ" للتأكيد فقط
|
| 57 |
+
mc_score = 0.5
|
| 58 |
+
if '1h' in ohlcv_data:
|
| 59 |
+
closes = np.array([c[4] for c in ohlcv_data['1h']])
|
| 60 |
+
mc_res = self.mc_analyzer.generate_1h_price_distribution_simple(closes)
|
| 61 |
+
mc_score = mc_res.get('mc_prob_gain', 0.5)
|
| 62 |
+
|
| 63 |
+
# 3. 📊 تجميع النتيجة النهائية
|
| 64 |
+
# في V12.0، نثق بـ Titan بنسبة 100% لأنه تدرب على كل شيء
|
| 65 |
+
final_decision_score = titan_score
|
| 66 |
+
|
| 67 |
+
# هيكل النتيجة الموحد
|
| 68 |
analysis_result = {
|
| 69 |
'symbol': symbol,
|
| 70 |
'current_price': raw_data.get('current_price', 0.0),
|
| 71 |
+
# النتيجة النهائية التي سيعتمد عليها المستكشف والحارس
|
| 72 |
+
'enhanced_final_score': final_decision_score,
|
| 73 |
+
|
| 74 |
+
# تفاصيل للشفافية والتسجيل
|
| 75 |
+
'titan_score': titan_score,
|
| 76 |
+
'mc_validation_score': mc_score,
|
| 77 |
+
'titan_status': titan_result.get('status', 'UNKNOWN'),
|
| 78 |
+
|
| 79 |
+
# الاحتفاظ بالبيانات لاستخدام الحارس لاحقاً
|
| 80 |
+
'ohlcv_sample': {tf: data[-1] for tf, data in ohlcv_data.items() if data}
|
| 81 |
}
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
return analysis_result
|
| 84 |
|
| 85 |
except Exception as e:
|
| 86 |
+
print(f"❌ [Processor] خطأ في معالجة {symbol}: {e}")
|
| 87 |
traceback.print_exc()
|
| 88 |
return None
|
| 89 |
|
| 90 |
+
print("✅ ML Processor V12.0 (Titan Core) loaded.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|