Trad / ML.py
Riy777's picture
Rename ML (31).py to ML.py
116f6b6
raw
history blame
75.5 kB
# ML.py - الإصدار المحدث مع إصلاح الأخطاء الحرجة
import pandas as pd
import pandas_ta as ta
import numpy as np
from datetime import datetime
import asyncio
from data_manager import DataManager
class AdvancedTechnicalAnalyzer:
def __init__(self):
self.indicators_config = {
'trend': ['ema_9', 'ema_21', 'ema_50', 'ema_200', 'ichimoku', 'adx', 'parabolic_sar', 'dmi'],
'momentum': ['rsi', 'stoch_rsi', 'macd', 'williams_r', 'cci', 'awesome_oscillator', 'momentum'],
'volatility': ['bbands', 'atr', 'keltner', 'donchian', 'rvi'],
'volume': ['vwap', 'obv', 'mfi', 'volume_profile', 'ad', 'volume_oscillator'],
'cycle': ['hull_ma', 'supertrend', 'zigzag', 'fisher_transform']
}
def calculate_all_indicators(self, dataframe, timeframe):
if dataframe.empty:
return {}
indicators = {}
indicators.update(self._calculate_trend_indicators(dataframe))
indicators.update(self._calculate_momentum_indicators(dataframe))
indicators.update(self._calculate_volatility_indicators(dataframe))
indicators.update(self._calculate_volume_indicators(dataframe))
indicators.update(self._calculate_cycle_indicators(dataframe))
return indicators
def _calculate_trend_indicators(self, dataframe):
trend = {}
trend['ema_9'] = float(ta.ema(dataframe['close'], length=9).iloc[-1]) if len(dataframe) >= 9 else None
trend['ema_21'] = float(ta.ema(dataframe['close'], length=21).iloc[-1]) if len(dataframe) >= 21 else None
trend['ema_50'] = float(ta.ema(dataframe['close'], length=50).iloc[-1]) if len(dataframe) >= 50 else None
trend['ema_200'] = float(ta.ema(dataframe['close'], length=200).iloc[-1]) if len(dataframe) >= 200 else None
if len(dataframe) >= 26:
ichimoku = ta.ichimoku(dataframe['high'], dataframe['low'], dataframe['close'])
if ichimoku is not None:
trend['ichimoku_conversion'] = float(ichimoku[0]['ITS_9'].iloc[-1]) if not ichimoku[0]['ITS_9'].empty else None
trend['ichimoku_base'] = float(ichimoku[0]['IKS_26'].iloc[-1]) if not ichimoku[0]['IKS_26'].empty else None
trend['ichimoku_span_a'] = float(ichimoku[0]['ISA_9'].iloc[-1]) if not ichimoku[0]['ISA_9'].empty else None
trend['ichimoku_span_b'] = float(ichimoku[0]['ISB_26'].iloc[-1]) if not ichimoku[0]['ISB_26'].empty else None
if len(dataframe) >= 14:
adx_result = ta.adx(dataframe['high'], dataframe['low'], dataframe['close'], length=14)
if adx_result is not None:
trend['adx'] = float(adx_result['ADX_14'].iloc[-1]) if not adx_result['ADX_14'].empty else None
trend['dmi_plus'] = float(adx_result['DMP_14'].iloc[-1]) if not adx_result['DMP_14'].empty else None
trend['dmi_minus'] = float(adx_result['DMN_14'].iloc[-1]) if not adx_result['DMN_14'].empty else None
if len(dataframe) >= 5:
psar = ta.psar(dataframe['high'], dataframe['low'], dataframe['close'])
if psar is not None:
trend['psar'] = float(psar['PSARl_0.02_0.2'].iloc[-1]) if not psar['PSARl_0.02_0.2'].empty else None
return {key: value for key, value in trend.items() if value is not None}
def _calculate_momentum_indicators(self, dataframe):
momentum = {}
if len(dataframe) >= 14:
rsi = ta.rsi(dataframe['close'], length=14)
momentum['rsi'] = float(rsi.iloc[-1]) if not rsi.empty else None
if len(dataframe) >= 14:
stoch_rsi = ta.stochrsi(dataframe['close'], length=14)
if stoch_rsi is not None:
momentum['stoch_rsi_k'] = float(stoch_rsi['STOCHRSIk_14_14_3_3'].iloc[-1]) if not stoch_rsi['STOCHRSIk_14_14_3_3'].empty else None
momentum['stoch_rsi_d'] = float(stoch_rsi['STOCHRSId_14_14_3_3'].iloc[-1]) if not stoch_rsi['STOCHRSId_14_14_3_3'].empty else None
if len(dataframe) >= 26:
macd = ta.macd(dataframe['close'])
if macd is not None:
momentum['macd_line'] = float(macd['MACD_12_26_9'].iloc[-1]) if not macd['MACD_12_26_9'].empty else None
momentum['macd_signal'] = float(macd['MACDs_12_26_9'].iloc[-1]) if not macd['MACDs_12_26_9'].empty else None
momentum['macd_hist'] = float(macd['MACDh_12_26_9'].iloc[-1]) if not macd['MACDh_12_26_9'].empty else None
if len(dataframe) >= 14:
williams = ta.willr(dataframe['high'], dataframe['low'], dataframe['close'], length=14)
momentum['williams_r'] = float(williams.iloc[-1]) if not williams.empty else None
if len(dataframe) >= 20:
cci = ta.cci(dataframe['high'], dataframe['low'], dataframe['close'], length=20)
momentum['cci'] = float(cci.iloc[-1]) if not cci.empty else None
if len(dataframe) >= 34:
awesome_oscillator = ta.ao(dataframe['high'], dataframe['low'])
momentum['awesome_oscillator'] = float(awesome_oscillator.iloc[-1]) if not awesome_oscillator.empty else None
if len(dataframe) >= 10:
momentum_indicator = ta.mom(dataframe['close'], length=10)
momentum['momentum'] = float(momentum_indicator.iloc[-1]) if not momentum_indicator.empty else None
return {key: value for key, value in momentum.items() if value is not None}
def _calculate_volatility_indicators(self, dataframe):
volatility = {}
if len(dataframe) >= 20:
bollinger_bands = ta.bbands(dataframe['close'], length=20, std=2)
if bollinger_bands is not None:
volatility['bb_upper'] = float(bollinger_bands['BBU_20_2.0'].iloc[-1]) if not bollinger_bands['BBU_20_2.0'].empty else None
volatility['bb_middle'] = float(bollinger_bands['BBM_20_2.0'].iloc[-1]) if not bollinger_bands['BBM_20_2.0'].empty else None
volatility['bb_lower'] = float(bollinger_bands['BBL_20_2.0'].iloc[-1]) if not bollinger_bands['BBL_20_2.0'].empty else None
if all(key in volatility for key in ['bb_upper', 'bb_lower', 'bb_middle']):
volatility['bb_width'] = (volatility['bb_upper'] - volatility['bb_lower']) / volatility['bb_middle']
if len(dataframe) >= 14:
average_true_range = ta.atr(dataframe['high'], dataframe['low'], dataframe['close'], length=14)
volatility['atr'] = float(average_true_range.iloc[-1]) if not average_true_range.empty else None
if volatility['atr']:
volatility['atr_percent'] = volatility['atr'] / dataframe['close'].iloc[-1]
if len(dataframe) >= 20:
keltner_channel = ta.kc(dataframe['high'], dataframe['low'], dataframe['close'], length=20)
if keltner_channel is not None:
volatility['kc_upper'] = float(keltner_channel['KCUe_20_2'].iloc[-1]) if not keltner_channel['KCUe_20_2'].empty else None
volatility['kc_lower'] = float(keltner_channel['KCLe_20_2'].iloc[-1]) if not keltner_channel['KCLe_20_2'].empty else None
if len(dataframe) >= 20:
donchian_channel = ta.donchian(dataframe['high'], dataframe['low'], length=20)
if donchian_channel is not None:
volatility['dc_upper'] = float(donchian_channel['DCU_20_20'].iloc[-1]) if not donchian_channel['DCU_20_20'].empty else None
volatility['dc_lower'] = float(donchian_channel['DCL_20_20'].iloc[-1]) if not donchian_channel['DCL_20_20'].empty else None
if len(dataframe) >= 14:
relative_volatility_index = ta.rvi(dataframe['close'], length=14)
volatility['rvi'] = float(relative_volatility_index.iloc[-1]) if not relative_volatility_index.empty else None
return {key: value for key, value in volatility.items() if value is not None}
def _calculate_volume_indicators(self, dataframe):
volume = {}
if len(dataframe) >= 1:
volume_weighted_average_price = ta.vwap(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'])
volume['vwap'] = float(volume_weighted_average_price.iloc[-1]) if not volume_weighted_average_price.empty else None
on_balance_volume = ta.obv(dataframe['close'], dataframe['volume'])
volume['obv'] = float(on_balance_volume.iloc[-1]) if not on_balance_volume.empty else None
if len(dataframe) >= 14:
money_flow_index = ta.mfi(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'], length=14)
volume['mfi'] = float(money_flow_index.iloc[-1]) if not money_flow_index.empty else None
accumulation_distribution = ta.ad(dataframe['high'], dataframe['low'], dataframe['close'], dataframe['volume'])
volume['ad_line'] = float(accumulation_distribution.iloc[-1]) if not accumulation_distribution.empty else None
if len(dataframe) >= 20:
volume_oscillator = ta.pvo(dataframe['volume'])
if volume_oscillator is not None:
volume['volume_oscillator'] = float(volume_oscillator['PVO_12_26_9'].iloc[-1]) if not volume_oscillator['PVO_12_26_9'].empty else None
volume['volume_avg_20'] = float(dataframe['volume'].tail(20).mean()) if len(dataframe) >= 20 else None
if volume['volume_avg_20'] and volume['volume_avg_20'] > 0:
volume['volume_ratio'] = float(dataframe['volume'].iloc[-1] / volume['volume_avg_20'])
return {key: value for key, value in volume.items() if value is not None}
def _calculate_cycle_indicators(self, dataframe):
cycle = {}
if len(dataframe) >= 9:
hull_moving_average = ta.hma(dataframe['close'], length=9)
cycle['hull_ma'] = float(hull_moving_average.iloc[-1]) if not hull_moving_average.empty else None
if len(dataframe) >= 10:
supertrend = ta.supertrend(dataframe['high'], dataframe['low'], dataframe['close'], length=10, multiplier=3)
if supertrend is not None:
cycle['supertrend'] = float(supertrend['SUPERT_10_3.0'].iloc[-1]) if not supertrend['SUPERT_10_3.0'].empty else None
cycle['supertrend_direction'] = float(supertrend['SUPERTd_10_3.0'].iloc[-1]) if not supertrend['SUPERTd_10_3.0'].empty else None
if len(dataframe) >= 10:
fisher_transform = ta.fisher(dataframe['high'], dataframe['low'], length=10)
if fisher_transform is not None:
cycle['fisher_transform'] = float(fisher_transform['FISHERT_10_1'].iloc[-1]) if not fisher_transform['FISHERT_10_1'].empty else None
return {key: value for key, value in cycle.items() if value is not None}
class PatternEnhancedStrategyEngine:
"""محرك استراتيجيات محسن مع دعم متقدم للأنماط البيانية"""
def __init__(self, data_manager, learning_engine):
self.data_manager = data_manager
self.learning_engine = learning_engine
self.pattern_success_tracker = PatternPerformanceTracker()
async def enhance_strategy_with_patterns(self, strategy_scores, pattern_analysis, symbol):
"""تعزيز درجات الاستراتيجية بناءً على تحليل الأنماط"""
if not pattern_analysis or pattern_analysis.get('pattern_detected') in ['no_clear_pattern', 'insufficient_data']:
return strategy_scores
pattern_confidence = pattern_analysis.get('pattern_confidence', 0)
pattern_name = pattern_analysis.get('pattern_detected', '')
predicted_direction = pattern_analysis.get('predicted_direction', '')
# فقط تعزيز إذا كانت الثقة في النمط عالية
if pattern_confidence >= 0.7:
enhancement_factor = self._calculate_pattern_enhancement(pattern_confidence, pattern_name)
# تحديد الاستراتيجيات المناسبة للنمط
enhanced_strategies = self._get_pattern_appropriate_strategies(pattern_name, predicted_direction)
for strategy in enhanced_strategies:
if strategy in strategy_scores:
strategy_scores[strategy] *= enhancement_factor
print(f"🎯 Enhanced {strategy} for {symbol} by {enhancement_factor:.1%} due to {pattern_name} pattern")
return strategy_scores
def _calculate_pattern_enhancement(self, pattern_confidence, pattern_name):
"""حساب عامل التعزيز بناءً على ثقة النمط ونوعه"""
base_enhancement = 1.0 + (pattern_confidence * 0.5) # حتى 50% زيادة
# أنماط عالية المصداقية تحصل على تعزيز إضافي
high_reliability_patterns = ['Double Top', 'Double Bottom', 'Head & Shoulders', 'Cup and Handle']
if pattern_name in high_reliability_patterns:
base_enhancement *= 1.2
return min(base_enhancement, 2.0) # حد أقصى 100% زيادة
def _get_pattern_appropriate_strategies(self, pattern_name, direction):
"""الحصول على الاستراتيجيات المناسبة لنوع النمط"""
reversal_patterns = ['Double Top', 'Double Bottom', 'Head & Shoulders', 'Triple Top', 'Triple Bottom']
continuation_patterns = ['Flags', 'Pennants', 'Triangles', 'Rectangles']
if pattern_name in reversal_patterns:
if direction == 'down':
return ['breakout_momentum', 'trend_following']
else:
return ['mean_reversion', 'breakout_momentum']
elif pattern_name in continuation_patterns:
return ['trend_following', 'breakout_momentum']
else: # أنماط أخرى
return ['breakout_momentum', 'hybrid_ai']
class PatternPerformanceTracker:
"""متتبع أداء الأنماط البيانية"""
def __init__(self):
self.pattern_performance = {}
self.pattern_success_rates = {}
async def track_pattern_outcome(self, symbol, pattern_analysis, success, profit_percent):
"""تتبع نتيجة النمط البياني"""
if not pattern_analysis:
return
pattern_name = pattern_analysis.get('pattern_detected')
confidence = pattern_analysis.get('pattern_confidence', 0)
if pattern_name not in ['no_clear_pattern', 'insufficient_data']:
if pattern_name not in self.pattern_performance:
self.pattern_performance[pattern_name] = {
'total_trades': 0,
'successful_trades': 0,
'total_profit': 0,
'total_confidence': 0
}
stats = self.pattern_performance[pattern_name]
stats['total_trades'] += 1
stats['total_confidence'] += confidence
if success:
stats['successful_trades'] += 1
stats['total_profit'] += profit_percent
success_rate = stats['successful_trades'] / stats['total_trades']
avg_profit = stats['total_profit'] / stats['successful_trades'] if stats['successful_trades'] > 0 else 0
avg_confidence = stats['total_confidence'] / stats['total_trades']
print(f"📊 Pattern Performance: {pattern_name} - "
f"Success: {success_rate:.1%} - Avg Profit: {avg_profit:.2f}% - "
f"Avg Confidence: {avg_confidence:.1%}")
def get_pattern_reliability(self, pattern_name):
"""الحصول على موثوقية النمط"""
if pattern_name in self.pattern_performance:
stats = self.pattern_performance[pattern_name]
if stats['total_trades'] > 0:
return stats['successful_trades'] / stats['total_trades']
return 0.5 # قيمة افتراضية
class MultiStrategyEngine:
def __init__(self, data_manager, learning_engine):
self.data_manager = data_manager
self.learning_engine = learning_engine
self.pattern_enhancer = PatternEnhancedStrategyEngine(data_manager, learning_engine)
self.strategies = {
'trend_following': self._trend_following_strategy,
'mean_reversion': self._mean_reversion_strategy,
'breakout_momentum': self._breakout_momentum_strategy,
'volume_spike': self._volume_spike_strategy,
'whale_tracking': self._whale_tracking_strategy,
'pattern_recognition': self._pattern_recognition_strategy,
'hybrid_ai': self._hybrid_ai_strategy
}
async def evaluate_all_strategies(self, symbol_data, market_context):
"""تقييم جميع الاستراتيجيات مع استخدام أوزان نظام التعلم - الإصدار المحسّن"""
try:
# ✅ الحصول على الأوزان المحسنة من نظام التعلم
market_condition = market_context.get('market_trend', 'sideways_market')
# ✅ التحقق من وجود learning_engine وتهيئته
if self.learning_engine and hasattr(self.learning_engine, 'initialized') and self.learning_engine.initialized:
try:
optimized_weights = await self.learning_engine.get_optimized_strategy_weights(market_condition)
print(f"🎯 الأوزان المستخدمة: {optimized_weights}")
except Exception as e:
print(f"⚠️ فشل الحصول على الأوزان المحسنة: {e}")
optimized_weights = await self.get_default_weights()
else:
print("⚠️ نظام التعلم غير متوفر، استخدام الأوزان الافتراضية")
optimized_weights = await self.get_default_weights()
strategy_scores = {}
base_scores = {} # ✅ تخزين الدرجات الأساسية
# ✅ تقييم كل استراتيجية مع تطبيق الأوزان
for strategy_name, strategy_function in self.strategies.items():
try:
base_score = await strategy_function(symbol_data, market_context)
base_scores[strategy_name] = base_score # ✅ حفظ الدرجة الأساسية
# ✅ تطبيق الوزن المحسن
weight = optimized_weights.get(strategy_name, 0.1)
weighted_score = base_score * weight
strategy_scores[strategy_name] = min(weighted_score, 1.0)
print(f"📊 {strategy_name}: {base_score:.3f} × {weight:.3f} = {weighted_score:.3f}")
except Exception as error:
print(f"⚠️ Strategy {strategy_name} failed: {error}")
base_score = await self._fallback_strategy_score(strategy_name, symbol_data, market_context)
base_scores[strategy_name] = base_score
strategy_scores[strategy_name] = base_score * optimized_weights.get(strategy_name, 0.1)
# ✅ تعزيز الاستراتيجيات بناءً على تحليل الأنماط
pattern_analysis = symbol_data.get('pattern_analysis')
if pattern_analysis:
strategy_scores = await self.pattern_enhancer.enhance_strategy_with_patterns(
strategy_scores, pattern_analysis, symbol_data.get('symbol')
)
# ✅ تحديد أفضل استراتيجية بناءً على الدرجات الأساسية (بدون أوزان)
if base_scores:
best_strategy = max(base_scores.items(), key=lambda x: x[1])
best_strategy_name = best_strategy[0]
best_strategy_score = best_strategy[1]
symbol_data['recommended_strategy'] = best_strategy_name
symbol_data['strategy_confidence'] = best_strategy_score
print(f"🏆 أفضل استراتيجية (أساسي): {best_strategy_name} بدرجة {best_strategy_score:.3f}")
# ✅ تعزيز اختيار الاستراتيجية إذا كان هناك نمط عالي الثقة
if (pattern_analysis and
pattern_analysis.get('pattern_confidence', 0) > 0.7 and
self._is_strategy_pattern_aligned(best_strategy_name, pattern_analysis)):
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.3
enhanced_confidence = min(best_strategy_score + pattern_bonus, 1.0)
symbol_data['strategy_confidence'] = enhanced_confidence
print(f"🎯 تعزيز ثقة الاستراتيجية بواسطة النمط: {enhanced_confidence:.3f}")
return strategy_scores, base_scores # ✅ إرجاع كلا النوعين
except Exception as error:
print(f"❌ فشل تقييم الاستراتيجيات: {error}")
fallback_scores = await self.get_fallback_scores()
return fallback_scores, fallback_scores
def _is_strategy_pattern_aligned(self, strategy_name, pattern_analysis):
"""التحقق من محاذاة الاستراتيجية مع النمط البياني"""
pattern_direction = pattern_analysis.get('predicted_direction', '')
pattern_type = pattern_analysis.get('pattern_detected', '')
# استراتيجيات التوجه الصعودي
bullish_strategies = ['trend_following', 'breakout_momentum']
# استراتيجيات التوجه الهبوطي
bearish_strategies = ['mean_reversion', 'breakout_momentum']
if pattern_direction == 'up' and strategy_name in bullish_strategies:
return True
elif pattern_direction == 'down' and strategy_name in bearish_strategies:
return True
return False
async def get_default_weights(self):
"""الأوزان الافتراضية عندما لا يتوفر نظام التعلم"""
return {
'trend_following': 0.15, 'mean_reversion': 0.12,
'breakout_momentum': 0.18, 'volume_spike': 0.10,
'whale_tracking': 0.20, 'pattern_recognition': 0.15,
'hybrid_ai': 0.10
}
async def get_fallback_scores(self):
"""درجات احتياطية عند فشل التقييم"""
return {
'trend_following': 0.5, 'mean_reversion': 0.5,
'breakout_momentum': 0.5, 'volume_spike': 0.5,
'whale_tracking': 0.5, 'pattern_recognition': 0.5,
'hybrid_ai': 0.5
}
async def _trend_following_strategy(self, symbol_data, market_context):
"""استراتيجية تتبع الاتجاه المحسنة - درجات أعلى"""
try:
score = 0.0
indicators = symbol_data.get('advanced_indicators', {})
timeframes = ['4h', '1h', '15m']
for timeframe in timeframes:
if timeframe in indicators:
timeframe_indicators = indicators[timeframe]
# تحقق من محاذاة المتوسطات المتحركة
if self._check_ema_alignment(timeframe_indicators):
score += 0.20 # ⬆️ زيادة من 0.15 إلى 0.20
# مؤشر ADX للقوة الاتجاهية
adx_value = timeframe_indicators.get('adx', 0)
if adx_value > 20: # ⬇️ تخفيض من 25 إلى 20
score += 0.15 # ⬆️ زيادة من 0.1 إلى 0.15
# تحليل الحجم
volume_ratio = timeframe_indicators.get('volume_ratio', 0)
if volume_ratio > 1.2: # ⬇️ تخفيض من 1.5 إلى 1.2
score += 0.10 # ⬆️ زيادة من 0.05 إلى 0.10
# ✅ تعزيز بناءً على تحليل الأنماط
pattern_analysis = symbol_data.get('pattern_analysis')
if (pattern_analysis and
pattern_analysis.get('pattern_confidence', 0) > 0.7 and
pattern_analysis.get('predicted_direction') == 'up'):
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.2
score += pattern_bonus
print(f"📈 Trend following enhanced by pattern: +{pattern_bonus:.3f}")
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Trend following strategy error: {error}")
return 0.3 # ⬆️ زيادة من 0.3 إلى 0.3 (نفس القيمة)
def _check_ema_alignment(self, indicators):
"""التحقق من محاذاة المتوسطات المتحركة"""
required_emas = ['ema_9', 'ema_21', 'ema_50']
if all(ema in indicators for ema in required_emas):
return (indicators['ema_9'] > indicators['ema_21'] > indicators['ema_50'])
return False
async def _mean_reversion_strategy(self, symbol_data, market_context):
"""استراتيجية العودة إلى المتوسط المحسنة - درجات أعلى"""
try:
score = 0.0
current_price = symbol_data['current_price']
indicators = symbol_data.get('advanced_indicators', {})
if '1h' in indicators:
hourly_indicators = indicators['1h']
# تحليل Bollinger Bands
if all(key in hourly_indicators for key in ['bb_upper', 'bb_lower', 'bb_middle']):
position_in_band = (current_price - hourly_indicators['bb_lower']) / (hourly_indicators['bb_upper'] - hourly_indicators['bb_lower'])
if position_in_band < 0.1 and hourly_indicators.get('rsi', 50) < 35:
score += 0.45 # ⬆️ زيادة من 0.4 إلى 0.45
if position_in_band > 0.9 and hourly_indicators.get('rsi', 50) > 65:
score += 0.45 # ⬆️ زيادة من 0.4 إلى 0.45
# تحليل RSI
rsi_value = hourly_indicators.get('rsi', 50)
if rsi_value < 30:
score += 0.35 # ⬆️ زيادة من 0.3 إلى 0.35
elif rsi_value > 70:
score += 0.35 # ⬆️ زيادة من 0.3 إلى 0.35
# ✅ تعزيز بناءً على تحليل الأنماط
pattern_analysis = symbol_data.get('pattern_analysis')
if (pattern_analysis and
pattern_analysis.get('pattern_confidence', 0) > 0.7 and
pattern_analysis.get('predicted_direction') in ['up', 'down']):
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.15
score += pattern_bonus
print(f"🔄 Mean reversion enhanced by pattern: +{pattern_bonus:.3f}")
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Mean reversion strategy error: {error}")
return 0.3
async def _breakout_momentum_strategy(self, symbol_data, market_context):
"""استراتيجية كسر الزخم المحسنة - درجات أعلى"""
try:
score = 0.0
indicators = symbol_data.get('advanced_indicators', {})
for timeframe in ['1h', '15m', '5m']: # ✅ إضافة timeframe إضافية
if timeframe in indicators:
timeframe_indicators = indicators[timeframe]
# ✅ تحليل الحجم - عتبات مخفضة
volume_ratio = timeframe_indicators.get('volume_ratio', 0)
if volume_ratio > 1.8: # ⬇️ تخفيض من 2.0 إلى 1.8
score += 0.25 # ⬆️ زيادة من 0.2 إلى 0.25
elif volume_ratio > 1.3: # ✅ إضافة شرط وسيط
score += 0.15
# ✅ تحليل MACD
if timeframe_indicators.get('macd_hist', 0) > 0:
score += 0.20 # ⬆️ زيادة من 0.15 إلى 0.20
# ✅ تحليل VWAP
if 'vwap' in timeframe_indicators and symbol_data['current_price'] > timeframe_indicators['vwap']:
score += 0.15 # ⬆️ زيادة من 0.1 إلى 0.15
# ✅ إضافة شرط RSI إضافي
rsi_value = timeframe_indicators.get('rsi', 50)
if 40 <= rsi_value <= 70: # نطاق RSI صحي
score += 0.10
# ✅ تعزيز بناءً على تحليل الأنماط - تأثير كبير على breakout
pattern_analysis = symbol_data.get('pattern_analysis')
if pattern_analysis and pattern_analysis.get('pattern_confidence', 0) > 0.6:
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.3
score += pattern_bonus
print(f"🚀 Breakout momentum significantly enhanced by pattern: +{pattern_bonus:.3f}")
# ✅ ضمان حد أدنى للدرجة إذا كانت هناك إشارات إيجابية
if score > 0.2:
score = max(score, 0.4) # ⬆️ ضمان حد أدنى 0.4 إذا كانت هناك إشارات
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Breakout momentum strategy error: {error}")
return 0.4 # ⬆️ زيادة من 0.3 إلى 0.4
async def _volume_spike_strategy(self, symbol_data, market_context):
"""استراتيجية ارتفاع الحجم المحسنة - درجات أعلى"""
try:
score = 0.0
indicators = symbol_data.get('advanced_indicators', {})
for timeframe in ['1h', '15m', '5m']:
if timeframe in indicators:
volume_ratio = indicators[timeframe].get('volume_ratio', 0)
if volume_ratio > 3.0:
score += 0.45 # ⬆️ زيادة من 0.4 إلى 0.45
elif volume_ratio > 2.0:
score += 0.25 # ⬆️ زيادة من 0.2 إلى 0.25
elif volume_ratio > 1.5: # ✅ إضافة شرط وسيط
score += 0.15
# ✅ تعزيز بناءً على تحليل الأنماط مع ارتفاع الحجم
pattern_analysis = symbol_data.get('pattern_analysis')
if (pattern_analysis and
pattern_analysis.get('pattern_confidence', 0) > 0.7 and
any(indicators[tf].get('volume_ratio', 0) > 2.0 for tf in ['1h', '15m'] if tf in indicators)):
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.2
score += pattern_bonus
print(f"💧 Volume spike enhanced by pattern: +{pattern_bonus:.3f}")
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Volume spike strategy error: {error}")
return 0.3
async def _whale_tracking_strategy(self, symbol_data, market_context):
"""استراتيجية تتبع الحيتان المحسنة - درجات أعلى"""
try:
score = 0.0
# ✅ الإصلاح: استخدام الدالة الآمنة الجديدة
whale_data = await self.data_manager.get_whale_data_safe_async(symbol_data['symbol'])
# استخدام البيانات الحقيقية فقط
if not whale_data.get('data_available', False):
return 0.2 # ⬆️ زيادة من 0.1 إلى 0.2 (قيمة أساسية أعلى)
total_transactions = whale_data.get('transfer_count', 0)
whale_volume = whale_data.get('total_volume', 0)
# ✅ معايير مرنة للسماح بمزيد من المرشحين
if total_transactions >= 2: # ⬇️ تخفيض من 3 إلى 2
score += 0.35 # ⬆️ زيادة من 0.3 إلى 0.35
elif total_transactions >= 1: # ⬇️ تخفيض من 5 إلى 1
score += 0.25 # ⬆️ زيادة من 0.15 إلى 0.25
if whale_volume > 25000: # ⬇️ تخفيض من 50000 إلى 25000
score += 0.25 # ⬆️ زيادة من 0.2 إلى 0.25
elif whale_volume > 5000: # ⬇️ تخفيض من 10000 إلى 5000
score += 0.15 # ⬆️ زيادة من 0.1 إلى 0.15
# ✅ إضافة نقاط إضافية بناءً على نشاط الحيتان العام
general_whale = market_context.get('general_whale_activity', {})
if general_whale.get('data_available', False) and general_whale.get('transaction_count', 0) > 0:
score += 0.15 # ⬆️ زيادة من 0.1 إلى 0.15
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Whale tracking failed: {error}")
return 0.2 # ⬆️ زيادة من 0.1 إلى 0.2
async def _pattern_recognition_strategy(self, symbol_data, market_context):
"""استراتيجية التعرف على الأنماط المحسنة - درجات أعلى"""
try:
score = 0.0
indicators = symbol_data.get('advanced_indicators', {})
# ✅ تعزيز كبير بناءً على تحليل الأنماط من LLM
pattern_analysis = symbol_data.get('pattern_analysis')
if pattern_analysis and pattern_analysis.get('pattern_confidence', 0) > 0.6:
score += pattern_analysis.get('pattern_confidence', 0) * 0.8
print(f"🎯 Pattern recognition significantly enhanced: +{score:.3f}")
else:
# التحليل التقليدي إذا لم يكن هناك نمط من LLM
for timeframe in ['4h', '1h']:
if timeframe in indicators:
timeframe_indicators = indicators[timeframe]
# نمط الزخم الصعودي
if (timeframe_indicators.get('rsi', 50) > 60 and
timeframe_indicators.get('macd_hist', 0) > 0 and
timeframe_indicators.get('volume_ratio', 0) > 1.5):
score += 0.35 # ⬆️ زيادة من 0.3 إلى 0.35
# نمط الزخم الهبوطي
if (timeframe_indicators.get('rsi', 50) < 40 and
timeframe_indicators.get('stoch_rsi_k', 50) < 20):
score += 0.35 # ⬆️ زيادة من 0.3 إلى 0.35
return min(score, 1.0)
except Exception as error:
print(f"⚠️ Pattern recognition strategy error: {error}")
return 0.3
async def _hybrid_ai_strategy(self, symbol_data, market_context):
"""استراتيجية الهجين الذكية المحسنة - درجات أعلى"""
try:
score = 0.0
monte_carlo_probability = symbol_data.get('monte_carlo_probability', 0.5)
final_score = symbol_data.get('final_score', 0.5)
score += monte_carlo_probability * 0.4
score += final_score * 0.3
# تحليل سياق السوق
if market_context.get('btc_sentiment') == 'BULLISH':
score += 0.25 # ⬆️ زيادة من 0.2 إلى 0.25
elif market_context.get('btc_sentiment') == 'BEARISH':
score -= 0.08 # ⬆️ تخفيض من 0.1 إلى 0.08
# تحليل نشاط الحيتان العام
whale_activity = market_context.get('general_whale_activity', {})
if whale_activity.get('sentiment') == 'BULLISH':
score += 0.15 # ⬆️ زيادة من 0.1 إلى 0.15
# ✅ تعزيز بناءً على تحليل الأنماط
pattern_analysis = symbol_data.get('pattern_analysis')
if pattern_analysis and pattern_analysis.get('pattern_confidence', 0) > 0.7:
pattern_bonus = pattern_analysis.get('pattern_confidence', 0) * 0.25
score += pattern_bonus
print(f"🤖 Hybrid AI enhanced by pattern: +{pattern_bonus:.3f}")
return max(0.0, min(score, 1.0))
except Exception as error:
print(f"⚠️ Hybrid AI strategy error: {error}")
return 0.3
async def _fallback_strategy_score(self, strategy_name, symbol_data, market_context):
"""درجات استراتيجية احتياطية محسنة"""
try:
base_score = symbol_data.get('final_score', 0.5)
if strategy_name == 'trend_following':
indicators = symbol_data.get('advanced_indicators', {})
if '1h' in indicators:
rsi_value = indicators['1h'].get('rsi', 50)
ema_9 = indicators['1h'].get('ema_9')
ema_21 = indicators['1h'].get('ema_21')
if ema_9 and ema_21 and ema_9 > ema_21 and 40 <= rsi_value <= 60:
return 0.6
return 0.4
elif strategy_name == 'mean_reversion':
current_price = symbol_data.get('current_price', 0)
indicators = symbol_data.get('advanced_indicators', {})
if '1h' in indicators:
rsi_value = indicators['1h'].get('rsi', 50)
bb_lower = indicators['1h'].get('bb_lower')
if bb_lower and current_price <= bb_lower * 1.02 and rsi_value < 35:
return 0.7
return 0.3
elif strategy_name == 'breakout_momentum':
volume_ratio = symbol_data.get('advanced_indicators', {}).get('1h', {}).get('volume_ratio', 0)
if volume_ratio > 1.5:
return 0.6
return 0.4
elif strategy_name == 'whale_tracking':
whale_data = symbol_data.get('whale_data', {})
if not whale_data.get('data_available', False):
return 0.2 # ⬆️ زيادة من 0.1 إلى 0.2
total_transactions = whale_data.get('transfer_count', 0)
if total_transactions >= 3:
return 0.5
return 0.3
return base_score
except Exception as error:
print(f"⚠️ Fallback strategy failed for {strategy_name}: {error}")
return 0.3
class MLProcessor:
def __init__(self, market_context, data_manager, learning_engine):
self.market_context = market_context
self.data_manager = data_manager
self.learning_engine = learning_engine
self.technical_analyzer = AdvancedTechnicalAnalyzer()
self.strategy_engine = MultiStrategyEngine(data_manager, learning_engine)
self.pattern_tracker = PatternPerformanceTracker()
def _validate_rsi_safety(self, indicators):
"""التحقق العاجل من سلامة مؤشر RSI"""
rsi_warnings = []
critical_issues = 0
timeframes_to_check = ['5m', '15m', '1h', '4h']
for timeframe in timeframes_to_check:
if timeframe in indicators:
rsi_value = indicators[timeframe].get('rsi')
if rsi_value:
if rsi_value > 80:
rsi_warnings.append(f"🚨 RSI CRITICAL in {timeframe}: {rsi_value} - EXTREME OVERBOUGHT")
critical_issues += 1
elif rsi_value > 75:
rsi_warnings.append(f"⚠️ RSI WARNING in {timeframe}: {rsi_value} - STRONG OVERBOUGHT")
elif rsi_value > 70:
rsi_warnings.append(f"📈 RSI HIGH in {timeframe}: {rsi_value} - OVERBOUGHT")
# إذا كان هناك إطارين زمنيين أو أكثر في منطقة الخطر، نرفض المرشح
is_safe = critical_issues < 2
return is_safe, rsi_warnings
def _validate_indicators_quality_enhanced(self, indicators, current_price):
"""تحسين التحقق من جودة المؤشرات"""
quality_issues = []
# التحقق من RSI
rsi_safe, rsi_warnings = self._validate_rsi_safety(indicators)
if not rsi_safe:
quality_issues.extend(rsi_warnings)
# التحقق من تناقض المؤشرات
bullish_signals = 0
bearish_signals = 0
for timeframe, data in indicators.items():
# إشارات صعودية
if data.get('macd_hist', 0) > 0:
bullish_signals += 1
if data.get('rsi', 50) > 70: # RSI مرتفع يعتبر إشارة بيع
bearish_signals += 1
if 'ema_9' in data and 'ema_21' in data:
if data['ema_9'] > data['ema_21']:
bullish_signals += 1
if bullish_signals > 0 and bearish_signals > bullish_signals:
quality_issues.append("⚠️ Conflicting signals: More bearish than bullish indicators")
return quality_issues
def _calculate_enhanced_score_with_safety(self, base_analysis, strategy_scores, quality_issues):
"""حساب النقاط مع مراعاة عوامل السلامة"""
base_score = base_analysis.get('final_score', 0.5)
strategy_average = sum(strategy_scores.values()) / len(strategy_scores) if strategy_scores else 0.5
# خصم النقاط بناءً على مشاكل الجودة
safety_penalty = 0.0
for issue in quality_issues:
if '🚨 RSI CRITICAL' in issue:
safety_penalty += 0.3
elif '⚠️ RSI WARNING' in issue:
safety_penalty += 0.15
elif '📈 RSI HIGH' in issue:
safety_penalty += 0.05
enhanced_score = (base_score * 0.4) + (strategy_average * 0.6)
enhanced_score = max(0.0, enhanced_score - safety_penalty)
return min(enhanced_score, 1.0)
async def process_and_score_symbol_enhanced(self, raw_data):
"""معالجة وتحليل الرمز مع نظام التعلم والاستراتيجيات - الإصدار المحسّن"""
try:
if not raw_data or not raw_data.get('ohlcv'):
print(f"⚠️ Skipping {raw_data.get('symbol', 'unknown')} - no OHLCV data")
return None
# ✅ تمرير بيانات الشموع الخام للتحليل اللاحق
raw_data['raw_ohlcv'] = raw_data.get('ohlcv', {})
base_analysis = await self.process_and_score_symbol(raw_data)
if not base_analysis:
return None
try:
# التحقق المحسن من الجودة
current_price = base_analysis.get('current_price', 0)
quality_issues = self._validate_indicators_quality_enhanced(
base_analysis.get('advanced_indicators', {}),
current_price
)
# طباعة تحذيرات الجودة
if quality_issues:
print(f"🔍 Quality issues for {base_analysis.get('symbol')}:")
for issue in quality_issues:
print(f" {issue}")
# ✅ تقييم الاستراتيجيات باستخدام نظام التعلم مع التحقق من الوجود
if hasattr(self, 'strategy_engine') and self.strategy_engine:
strategy_scores, base_scores = await self.strategy_engine.evaluate_all_strategies(base_analysis, self.market_context)
base_analysis['strategy_scores'] = strategy_scores
base_analysis['base_strategy_scores'] = base_scores # ✅ حفظ الدرجات الأساسية
# ✅ تحديد أفضل استراتيجية بناءً على الدرجات الأساسية (بدون أوزان)
if base_scores:
best_strategy = max(base_scores.items(), key=lambda x: x[1])
best_strategy_name = best_strategy[0]
best_strategy_score = best_strategy[1]
base_analysis['recommended_strategy'] = best_strategy_name
base_analysis['strategy_confidence'] = best_strategy_score
print(f"🎯 أفضل استراتيجية لـ {base_analysis.get('symbol')}: {best_strategy_name} (ثقة: {best_strategy_score:.3f})")
# ✅ تخفيض عتبة الثقة للسماح بمزيد من الاستراتيجيات
if best_strategy_score > 0.3: # ⬇️ تخفيض من 0.6 إلى 0.3
base_analysis['target_strategy'] = best_strategy_name
print(f"✅ استخدام استراتيجية متخصصة: {best_strategy_name}")
else:
base_analysis['target_strategy'] = 'GENERIC'
print(f"🔄 استخدام استراتيجية عامة (ثقة منخفضة: {best_strategy_score:.3f})")
else:
base_analysis['recommended_strategy'] = 'GENERIC'
base_analysis['strategy_confidence'] = 0.3 # ⬆️ زيادة من 0.5 إلى 0.3
base_analysis['target_strategy'] = 'GENERIC'
print("🔄 استخدام استراتيجية عامة (لا توجد درجات استراتيجية)")
# ✅ استخدام الدالة المحسنة لحساب النقاط
enhanced_score = self._calculate_enhanced_score_with_safety(
base_analysis, strategy_scores, quality_issues
)
base_analysis['enhanced_final_score'] = enhanced_score
else:
print("⚠️ Strategy engine not available, using base analysis only")
base_analysis['strategy_scores'] = {}
base_analysis['enhanced_final_score'] = base_analysis.get('final_score', 0.5)
base_analysis['recommended_strategy'] = 'GENERIC'
base_analysis['strategy_confidence'] = 0.3
base_analysis['target_strategy'] = 'GENERIC'
base_analysis['quality_warnings'] = quality_issues
except Exception as strategy_error:
print(f"⚠️ Strategy evaluation failed for {base_analysis.get('symbol')}: {strategy_error}")
base_analysis['strategy_scores'] = {}
base_analysis['enhanced_final_score'] = base_analysis.get('final_score', 0.5)
base_analysis['recommended_strategy'] = 'GENERIC'
base_analysis['strategy_confidence'] = 0.3 # ⬆️ زيادة من 0.5 إلى 0.3
base_analysis['target_strategy'] = 'GENERIC'
base_analysis['quality_warnings'] = ['Strategy evaluation failed']
return base_analysis
except Exception as error:
print(f"❌ Enhanced processing failed for {raw_data.get('symbol')}: {error}")
return await self.process_and_score_symbol(raw_data)
def _improve_fibonacci_levels(self, daily_dataframe, current_price):
"""تحسين حساب مستويات Fibonacci لتتوافق مع السعر الحالي"""
if len(daily_dataframe) < 50:
return {}
# استخدام آخر 50 يومًا لحساب القمة والقاع
recent_high = float(daily_dataframe['high'].iloc[-50:].max())
recent_low = float(daily_dataframe['low'].iloc[-50:].min())
# إذا كان السعر الحالي خارج النطاق، نعدل النطاق
if current_price > recent_high:
recent_high = current_price * 1.05 # نضيف هامش 5%
if current_price < recent_low:
recent_low = current_price * 0.95 # نخصم هامش 5%
difference = recent_high - recent_low
if difference <= 0: # تجنب القسمة على الصفر
return {}
return {
"0.0%": recent_high,
"23.6%": recent_high - 0.236 * difference,
"38.2%": recent_high - 0.382 * difference,
"50.0%": recent_high - 0.50 * difference,
"61.8%": recent_high - 0.618 * difference,
"78.6%": recent_high - 0.786 * difference,
"100.0%": recent_low
}
async def process_and_score_symbol(self, raw_data):
"""معالجة وتحليل الرمز الأساسي"""
symbol = raw_data['symbol']
ohlcv_data = raw_data['ohlcv']
reasons_for_candidacy = raw_data.get('reasons', [])
if not ohlcv_data:
print(f"❌ No OHLCV data for {symbol}")
return None
try:
all_indicators = {}
for timeframe, candles in ohlcv_data.items():
if candles:
dataframe = pd.DataFrame(candles, columns=['time', 'open', 'high', 'low', 'close', 'volume'])
dataframe[['open', 'high', 'low', 'close', 'volume']] = dataframe[['open', 'high', 'low', 'close', 'volume']].astype(float)
all_indicators[timeframe] = self._calculate_indicators(dataframe, timeframe)
hourly_dataframe = pd.DataFrame(ohlcv_data.get('1h', []), columns=['time', 'open', 'high', 'low', 'close', 'volume'])
if hourly_dataframe.empty:
print(f"❌ Skipping {symbol} due to insufficient 1h data.")
return None
hourly_dataframe[['open', 'high', 'low', 'close', 'volume']] = hourly_dataframe[['open', 'high', 'low', 'close', 'volume']].astype(float)
try:
current_price = float(hourly_dataframe['close'].iloc[-1])
if ohlcv_data.get('5m'):
five_minute_dataframe = pd.DataFrame(ohlcv_data['5m'], columns=['time', 'open', 'high', 'low', 'close', 'volume'])
if not five_minute_dataframe.empty:
five_minute_dataframe[['open', 'high', 'low', 'close', 'volume']] = five_minute_dataframe[['open', 'high', 'low', 'close', 'volume']].astype(float)
current_price = float(five_minute_dataframe['close'].iloc[-1])
liquidity_score = self._calculate_liquidity_score(hourly_dataframe)
daily_dataframe = pd.DataFrame(ohlcv_data.get('1d', []), columns=['time', 'open', 'high', 'low', 'close', 'volume'])
if not daily_dataframe.empty:
daily_dataframe[['open', 'high', 'low', 'close', 'volume']] = daily_dataframe[['open', 'high', 'low', 'close', 'volume']].astype(float)
average_daily_volume = float(daily_dataframe['volume'].mean()) if not daily_dataframe.empty else 0.0
# استخدام الدالة المحسنة لحساب مستويات Fibonacci
fibonacci_levels = self._improve_fibonacci_levels(daily_dataframe, current_price)
try:
whale_data = await self.data_manager.get_whale_data_safe_async(symbol)
except Exception as whale_error:
print(f"⚠️ Whale data failed for {symbol}: {whale_error}. No whale data available.")
whale_data = {
"transfer_count": 0,
"total_volume": 0,
"source": "no_data",
"data_available": False
}
whale_score = self._calculate_whale_activity_score(whale_data)
opportunity_classification = self.classify_opportunity_type(all_indicators, current_price)
initial_score = self._calculate_initial_score(all_indicators, current_price, self.market_context)
monte_carlo_probability = self._run_monte_carlo_simulation(hourly_dataframe)
print(f"🎲 Monte Carlo Simulation for {symbol}: Success Probability = {monte_carlo_probability:.2%}")
final_score = (0.35 * initial_score) + (0.50 * monte_carlo_probability) + (0.15 * whale_score)
final_score *= opportunity_classification['confidence']
normalized_indicators = {timeframe: self._normalize_features_corrected(indicators) for timeframe, indicators in all_indicators.items()}
return {
'symbol': symbol, 'reasons_for_candidacy': reasons_for_candidacy, 'current_price': float(current_price),
'liquidity_score': float(liquidity_score) if not np.isnan(liquidity_score) else 0.0, 'avg_daily_volume': float(average_daily_volume),
'whale_data': whale_data, 'whale_score': float(whale_score), 'opportunity_type': opportunity_classification,
'sentiment_data': self.market_context, 'fibonacci_levels': fibonacci_levels, 'final_score': float(final_score),
'initial_score': float(initial_score), 'monte_carlo_probability': float(monte_carlo_probability),
'indicators': normalized_indicators, 'advanced_indicators': all_indicators, 'strategy_scores': {},
'recommended_strategy': 'GENERIC', 'enhanced_final_score': float(final_score), 'target_strategy': 'GENERIC',
'raw_ohlcv': ohlcv_data # ✅ إضافة بيانات الشموع الخام
}
except (KeyError, IndexError) as error:
print(f"⚠️ Missing data for {symbol}: {error}")
return None
except Exception as error:
print(f"❌ Failed to process {symbol}: {error}")
import traceback
traceback.print_exc()
return None
def _calculate_indicators(self, dataframe, timeframe):
"""حساب المؤشرات الفنية"""
indicators = {}
if dataframe.empty:
return indicators
if not isinstance(dataframe.index, pd.DatetimeIndex):
try:
dataframe['time'] = pd.to_datetime(dataframe['time'], unit='ms')
dataframe = dataframe.set_index('time', drop=True)
except:
dataframe['time'] = pd.to_datetime(dataframe['time'])
dataframe = dataframe.set_index('time', drop=True)
dataframe = dataframe.sort_index()
if len(dataframe) >= 1 and all(column in dataframe.columns for column in ['high', 'low', 'close', 'volume']):
try:
typical_price = (dataframe['high'] + dataframe['low'] + dataframe['close']) / 3
volume_weighted_average_price = (typical_price * dataframe['volume']).cumsum() / dataframe['volume'].cumsum()
if not volume_weighted_average_price.empty and not pd.isna(volume_weighted_average_price.iloc[-1]):
indicators['vwap'] = float(volume_weighted_average_price.iloc[-1])
except Exception as error:
print(f"⚠️ VWAP calculation failed for {timeframe}: {error}")
if len(dataframe) >= 14:
rsi_series = ta.rsi(dataframe['close'], length=14)
if rsi_series is not None and not rsi_series.empty and rsi_series.iloc[-1] is not np.nan:
indicators['rsi'] = float(rsi_series.iloc[-1])
if len(dataframe) >= 26:
macd = ta.macd(dataframe['close'])
if macd is not None and not macd.empty:
if 'MACDh_12_26_9' in macd.columns and macd['MACDh_12_26_9'].iloc[-1] is not np.nan:
indicators['macd_hist'] = float(macd['MACDh_12_26_9'].iloc[-1])
if 'MACD_12_26_9' in macd.columns and macd['MACD_12_26_9'].iloc[-1] is not np.nan:
indicators['macd_line'] = float(macd['MACD_12_26_9'].iloc[-1])
if 'MACDs_12_26_9' in macd.columns and macd['MACDs_12_26_9'].iloc[-1] is not np.nan:
indicators['macd_signal'] = float(macd['MACDs_12_26_9'].iloc[-1])
if len(dataframe) >= 20:
bollinger_bands = ta.bbands(dataframe['close'], length=20, std=2)
if bollinger_bands is not None and not bollinger_bands.empty:
if 'BBL_20_2.0' in bollinger_bands.columns and bollinger_bands['BBL_20_2.0'].iloc[-1] is not np.nan:
indicators['bb_lower'] = float(bollinger_bands['BBL_20_2.0'].iloc[-1])
if 'BBU_20_2.0' in bollinger_bands.columns and bollinger_bands['BBU_20_2.0'].iloc[-1] is not np.nan:
indicators['bb_upper'] = float(bollinger_bands['BBU_20_2.0'].iloc[-1])
if 'BBM_20_2.0' in bollinger_bands.columns and bollinger_bands['BBM_20_2.0'].iloc[-1] is not np.nan:
indicators['bb_middle'] = float(bollinger_bands['BBM_20_2.0'].iloc[-1])
if len(dataframe) >= 14:
average_true_range = ta.atr(high=dataframe['high'], low=dataframe['low'], close=dataframe['close'], length=14)
if average_true_range is not None and not average_true_range.empty and average_true_range.iloc[-1] is not np.nan:
indicators['atr'] = float(average_true_range.iloc[-1])
if len(dataframe) >= 26:
ema_12 = ta.ema(dataframe['close'], length=12)
ema_26 = ta.ema(dataframe['close'], length=26)
if ema_12 is not None and not ema_12.empty and ema_12.iloc[-1] is not np.nan:
indicators['ema_12'] = float(ema_12.iloc[-1])
if ema_26 is not None and not ema_26.empty and ema_26.iloc[-1] is not np.nan:
indicators['ema_26'] = float(ema_26.iloc[-1])
return indicators
def _normalize_features_corrected(self, features):
"""تطبيع الميزات بشكل صحيح"""
normalized_features = {}
for key, value in features.items():
if value is None:
normalized_features[key] = 0.0
continue
if key == 'rsi':
normalized_features[key] = max(0, min(100, value))
elif key in ['macd_hist', 'macd_line', 'macd_signal', 'vwap', 'atr']:
normalized_features[key] = value
elif 'ema' in key or 'bb_' in key:
normalized_features[key] = value
else:
try:
if abs(value) > 1000:
normalized_features[key] = value / 1000
else:
normalized_features[key] = value
except:
normalized_features[key] = value
return normalized_features
def _run_monte_carlo_simulation(self, dataframe, number_of_simulations=1000, number_of_steps=20):
"""تشغيل محاكاة مونت كارلو"""
if dataframe.empty or len(dataframe) < 2:
return 0.0
log_returns = np.log(dataframe['close'] / dataframe['close'].shift(1)).dropna()
if log_returns.empty:
return 0.0
mean_return = log_returns.mean()
volatility = log_returns.std()
initial_price = dataframe['close'].iloc[-1]
success_count = 0
for _ in range(number_of_simulations):
random_values = np.random.normal(0, 1, number_of_steps)
daily_returns = np.exp(mean_return - 0.5 * volatility**2 + volatility * random_values)
simulated_prices = initial_price * daily_returns.cumprod()
if (simulated_prices[-1] / initial_price) > 1.02:
success_count += 1
return success_count / number_of_simulations
def _calculate_initial_score(self, indicators, current_price, market_context):
"""حساب النقاط الأولية"""
score = 0.5
fast_timeframes = ['5m', '15m']
for timeframe in fast_timeframes:
timeframe_indicators = indicators.get(timeframe, {})
if not timeframe_indicators:
continue
if 'rsi' in timeframe_indicators:
rsi_value = timeframe_indicators['rsi']
if isinstance(rsi_value, (int, float)):
if rsi_value < 30:
score += 0.2
elif rsi_value < 40:
score += 0.1
elif rsi_value > 70:
score -= 0.1
if 'macd_hist' in timeframe_indicators and timeframe_indicators['macd_hist'] > 0:
score += 0.15
if all(key in timeframe_indicators for key in ['ema_12', 'ema_26']):
if timeframe_indicators['ema_12'] > timeframe_indicators['ema_26']:
score += 0.15
slow_timeframes = ['1h', '4h', '1d']
for timeframe in slow_timeframes:
timeframe_indicators = indicators.get(timeframe, {})
if not timeframe_indicators:
continue
if all(key in timeframe_indicators for key in ['ema_12', 'ema_26']):
if timeframe_indicators['ema_12'] > timeframe_indicators['ema_26']:
score += 0.10
if all(key in timeframe_indicators for key in ['bb_upper', 'bb_lower']):
if current_price > timeframe_indicators['bb_upper']:
score += 0.10
elif current_price <= timeframe_indicators['bb_lower']:
score += 0.05
if '5m' in indicators and 'vwap' in indicators['5m'] and current_price > indicators['5m']['vwap']:
score += 0.10
if market_context:
bitcoin_sentiment = market_context.get('btc_sentiment')
fear_greed_index = market_context.get('fear_and_greed_index', 50)
if bitcoin_sentiment == 'BULLISH' and fear_greed_index > 60:
score *= 1.2
elif bitcoin_sentiment == 'BEARISH' or fear_greed_index < 30:
score *= 0.8
return min(max(score, 0.0), 1.0)
def _normalize_features(self, features):
return self._normalize_features_corrected(features)
def _prepare_data_for_ml(self, all_indicators, current_price):
feature_vector = []
timeframes = ['5m', '15m', '1h', '4h', '1d']
indicator_keys = ['rsi', 'macd_hist', 'macd_line', 'bb_upper', 'bb_lower', 'atr', 'ema_12', 'ema_26', 'vwap']
for timeframe in timeframes:
timeframe_indicators = all_indicators.get(timeframe, {})
for key in indicator_keys:
feature_vector.append(timeframe_indicators.get(key, 0.0))
feature_vector.append(current_price)
return feature_vector
def _calculate_liquidity_score(self, hourly_dataframe):
if hourly_dataframe.empty:
return 0.0
hourly_dataframe['dollar_volume'] = hourly_dataframe['volume'] * hourly_dataframe['close']
return float(hourly_dataframe['dollar_volume'].mean())
def _calculate_fibonacci_levels(self, daily_dataframe):
"""مهملة: استخدام _improve_fibonacci_levels بدلاً من ذلك"""
return self._improve_fibonacci_levels(daily_dataframe, 0)
def classify_opportunity_type(self, indicators, current_price):
fast_signals = 0
slow_signals = 0
for timeframe in ['5m', '15m']:
timeframe_indicators = indicators.get(timeframe, {})
if not timeframe_indicators:
continue
if timeframe_indicators.get('rsi', 100) < 35:
fast_signals += 1
if timeframe_indicators.get('macd_hist', 0) > 0:
fast_signals += 1
if all(key in timeframe_indicators for key in ['ema_12', 'ema_26']):
if timeframe_indicators['ema_12'] > timeframe_indicators['ema_26']:
fast_signals += 1
if timeframe == '5m' and timeframe_indicators.get('vwap') and current_price > timeframe_indicators['vwap'] * 1.02:
fast_signals += 1
for timeframe in ['1h', '4h', '1d']:
timeframe_indicators = indicators.get(timeframe, {})
if not timeframe_indicators:
continue
if 40 <= timeframe_indicators.get('rsi', 50) <= 60:
slow_signals += 1
if all(key in timeframe_indicators for key in ['ema_12', 'ema_26']):
if timeframe_indicators['ema_12'] > timeframe_indicators['ema_26']:
slow_signals += 1
if timeframe_indicators.get('bb_middle') and current_price > timeframe_indicators['bb_middle']:
slow_signals += 1
if fast_signals >= 3:
return {
"type": "FAST_PUMP", "timeframe": "15m-1h", "take_profit_multiplier": 1.08, "stop_loss_multiplier": 0.97,
"confidence": min(fast_signals / 6.0, 1.0), "description": "فرصة صعود سريع قوية على الأطر الزمنية القصيرة"
}
elif slow_signals >= 3:
return {
"type": "SLOW_GROWTH", "timeframe": "4h-1d", "take_profit_multiplier": 1.05, "stop_loss_multiplier": 0.95,
"confidence": min(slow_signals / 6.0, 1.0), "description": "فرصة نمو مستدام على الأطر الزمنية الطويلة"
}
return {
"type": "NEUTRAL", "timeframe": "N/A", "take_profit_multiplier": 1.05, "stop_loss_multiplier": 0.95,
"confidence": 0.3, "description": "لا توجد إشارات واضحة لنوع محدد من الفرص"
}
def _calculate_whale_activity_score(self, whale_data):
"""حساب درجة نشاط الحيتان بناءً على البيانات الحقيقية فقط"""
if not whale_data.get('data_available', False):
return 0.0
total_transactions = whale_data.get('transfer_count', 0)
total_volume = whale_data.get('total_volume', 0)
score = 0.0
if total_transactions >= 10:
score += 0.3
elif total_transactions >= 5:
score += 0.15
if total_volume > 500000:
score += 0.2
elif total_volume > 100000:
score += 0.1
return min(score, 0.5)
def filter_top_candidates(self, candidates, number_of_candidates=10):
"""تصفية أفضل المرشحين"""
valid_candidates = [candidate for candidate in candidates if candidate is not None]
return sorted(valid_candidates, key=lambda candidate: candidate.get('enhanced_final_score', candidate.get('final_score', 0)), reverse=True)[:number_of_candidates]
# دوال المحاكاة المحلية للاستخدام كبديل
def local_analyze_opportunity(candidate_data):
"""تحليل محسن مع مراعاة مخاطر RSI"""
score = candidate_data.get('enhanced_final_score', candidate_data.get('final_score', 0))
quality_warnings = candidate_data.get('quality_warnings', [])
# التحقق من تحذيرات RSI
rsi_critical = any('🚨 RSI CRITICAL' in warning for warning in quality_warnings)
rsi_warning = any('⚠️ RSI WARNING' in warning for warning in quality_warnings)
if rsi_critical:
return {
"action": "HOLD",
"reasoning": "Local analysis: CRITICAL RSI levels detected - extreme overbought condition. High risk of correction.",
"trade_type": "NONE",
"stop_loss": None,
"take_profit": None,
"expected_target_minutes": 15,
"confidence_level": 0.1,
"model_source": "local_safety_filter",
"strategy": "GENERIC"
}
advanced_indicators = candidate_data.get('advanced_indicators', {})
strategy_scores = candidate_data.get('strategy_scores', {})
if not advanced_indicators:
return {
"action": "HOLD",
"reasoning": "Local analysis: Insufficient advanced indicator data.",
"trade_type": "NONE",
"stop_loss": None,
"take_profit": None,
"expected_target_minutes": 15,
"confidence_level": 0.3,
"model_source": "local",
"strategy": "GENERIC"
}
action = "HOLD"
reasoning = "Local analysis: No strong buy signal based on enhanced rules."
trade_type = "NONE"
stop_loss = None
take_profit = None
expected_minutes = 15
confidence = 0.3
five_minute_indicators = advanced_indicators.get('5m', {})
one_hour_indicators = advanced_indicators.get('1h', {})
buy_conditions = 0
total_conditions = 0
if isinstance(score, (int, float)) and score > 0.70:
buy_conditions += 1
total_conditions += 1
# شرط RSI أكثر تحفظاً
rsi_five_minute = five_minute_indicators.get('rsi', 50)
if 30 <= rsi_five_minute <= 65: # نطاق آمن لـ RSI
buy_conditions += 1
total_conditions += 1
if five_minute_indicators.get('macd_hist', 0) > 0:
buy_conditions += 1
total_conditions += 1
if (five_minute_indicators.get('ema_9', 0) > five_minute_indicators.get('ema_21', 0) and
one_hour_indicators.get('ema_9', 0) > one_hour_indicators.get('ema_21', 0)):
buy_conditions += 1
total_conditions += 1
if five_minute_indicators.get('volume_ratio', 0) > 1.5:
buy_conditions += 1
total_conditions += 1
confidence = buy_conditions / total_conditions if total_conditions > 0 else 0.3
# خصم الثقة بناءً على تحذيرات RSI
if rsi_warning:
confidence *= 0.7 # خصم 30% للتحذيرات
reasoning += " RSI warning applied."
if confidence >= 0.6:
action = "BUY"
current_price = candidate_data['current_price']
trade_type = "LONG"
# وقف خسارة أكثر تحفظاً لـ RSI المرتفع
if rsi_warning:
stop_loss = current_price * 0.93 # 7% stop loss للتحذيرات
else:
stop_loss = current_price * 0.95 # 5% stop loss عادي
if 'bb_upper' in five_minute_indicators:
take_profit = five_minute_indicators['bb_upper'] * 1.02
else:
take_profit = current_price * 1.05
if confidence >= 0.8:
expected_minutes = 10
elif confidence >= 0.6:
expected_minutes = 18
else:
expected_minutes = 25
reasoning = f"Local enhanced analysis: Strong buy signal with {buy_conditions}/{total_conditions} conditions met. Confidence: {confidence:.2f}"
if rsi_warning:
reasoning += " (RSI warning - trading with caution)"
return {
"action": action,
"reasoning": reasoning,
"trade_type": trade_type,
"stop_loss": stop_loss,
"take_profit": take_profit,
"expected_target_minutes": expected_minutes,
"confidence_level": confidence,
"model_source": "local",
"strategy": "GENERIC"
}
def local_re_analyze_trade(trade_data, processed_data):
current_price = processed_data['current_price']
stop_loss = trade_data['stop_loss']
take_profit = trade_data['take_profit']
action = "HOLD"
reasoning = "Local re-analysis: No significant change to trigger an update or close."
if stop_loss and current_price <= stop_loss:
action = "CLOSE_TRADE"
reasoning = "Local re-analysis: Stop loss has been hit."
elif take_profit and current_price >= take_profit:
action = "CLOSE_TRADE"
reasoning = "Local re-analysis: Take profit has been hit."
strategy = trade_data.get('strategy', 'GENERIC')
if strategy == 'unknown':
strategy = trade_data.get('decision_data', {}).get('strategy', 'GENERIC')
return {
"action": action,
"reasoning": reasoning,
"new_stop_loss": None,
"new_take_profit": None,
"new_expected_minutes": None,
"model_source": "local",
"strategy": strategy
}
print("✅ Enhanced ML System Loaded - Integrated with Learning Engine - REAL DATA ONLY - Optimized Strategy Scoring with Pattern Enhancement")