Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -25,6 +25,7 @@ llm_service_global = None
|
|
| 25 |
learning_engine_global = None
|
| 26 |
trade_manager_global = None
|
| 27 |
sentiment_analyzer_global = None
|
|
|
|
| 28 |
|
| 29 |
class StateManager:
|
| 30 |
def __init__(self):
|
|
@@ -37,7 +38,8 @@ class StateManager:
|
|
| 37 |
'llm_service': False,
|
| 38 |
'learning_engine': False,
|
| 39 |
'trade_manager': False,
|
| 40 |
-
'sentiment_analyzer': False
|
|
|
|
| 41 |
}
|
| 42 |
|
| 43 |
async def wait_for_initialization(self, timeout=30):
|
|
@@ -54,6 +56,7 @@ class StateManager:
|
|
| 54 |
state_manager = StateManager()
|
| 55 |
|
| 56 |
async def monitor_market_async():
|
|
|
|
| 57 |
global data_manager_global, sentiment_analyzer_global
|
| 58 |
|
| 59 |
if not await state_manager.wait_for_initialization():
|
|
@@ -69,15 +72,13 @@ async def monitor_market_async():
|
|
| 69 |
await asyncio.sleep(60)
|
| 70 |
continue
|
| 71 |
|
| 72 |
-
whale_analysis = market_context.get('general_whale_activity', {})
|
| 73 |
-
is_critical = whale_analysis.get('critical_alert', False)
|
| 74 |
bitcoin_sentiment = market_context.get('btc_sentiment')
|
| 75 |
fear_greed_index = market_context.get('fear_and_greed_index')
|
| 76 |
|
| 77 |
should_halt_trading, halt_reason = False, ""
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
should_halt_trading, halt_reason = True, "ظروف سوق هابطة"
|
| 82 |
|
| 83 |
if should_halt_trading:
|
|
@@ -95,27 +96,19 @@ async def monitor_market_async():
|
|
| 95 |
await asyncio.sleep(60)
|
| 96 |
|
| 97 |
async def analyze_market_strategy(market_context):
|
|
|
|
| 98 |
try:
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
prompt = f"Analyze current market conditions and determine trading strategy.\n\nMarket Data:\n- BTC Sentiment: {market_context.get('btc_sentiment')}\n- Fear & Greed Index: {market_context.get('fear_and_greed_index')}\n- Whale Analysis: {whale_analysis.get('sentiment')}\n- Critical Alert: {whale_analysis.get('critical_alert')}\n- Net Flow: ${netflow_analysis.get('net_flow', 0):,.0f}\n\nOutput JSON:\n{{\"primary_strategy\": \"STRATEGY_NAME\",\"reasoning\": \"Brief reasoning\",\"risk_tolerance\": 5,\"optimal_scan_count\": 100}}"
|
| 102 |
response = await llm_service_global._call_llm(prompt)
|
| 103 |
try:
|
| 104 |
from helpers import parse_json_from_response
|
| 105 |
json_str = parse_json_from_response(response)
|
| 106 |
strategy_data = json.loads(json_str)
|
| 107 |
except:
|
| 108 |
-
|
| 109 |
-
if net_flow > 1000000:
|
| 110 |
-
fallback_strategy = "AGGRESSIVE_GROWTH"
|
| 111 |
-
elif net_flow < -1000000:
|
| 112 |
-
fallback_strategy = "CONSERVATIVE"
|
| 113 |
-
elif whale_analysis.get('critical_alert'):
|
| 114 |
-
fallback_strategy = "CONSERVATIVE"
|
| 115 |
-
else:
|
| 116 |
-
fallback_strategy = "GENERIC"
|
| 117 |
strategy_data = {
|
| 118 |
-
"primary_strategy":
|
| 119 |
"reasoning": "Fallback strategy due to analysis error",
|
| 120 |
"risk_tolerance": 5,
|
| 121 |
"optimal_scan_count": 100
|
|
@@ -131,6 +124,7 @@ async def analyze_market_strategy(market_context):
|
|
| 131 |
}
|
| 132 |
|
| 133 |
async def find_strategy_specific_candidates(strategy, scan_count):
|
|
|
|
| 134 |
try:
|
| 135 |
all_candidates = await data_manager_global.find_high_potential_candidates(scan_count * 2)
|
| 136 |
if not all_candidates:
|
|
@@ -176,7 +170,82 @@ async def find_strategy_specific_candidates(strategy, scan_count):
|
|
| 176 |
print(f"�� Advanced filtering failed: {error}")
|
| 177 |
return []
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
async def find_new_opportunities_async():
|
|
|
|
| 180 |
try:
|
| 181 |
print("🎯 بدء البحث عن فرص تداول جديدة...")
|
| 182 |
await r2_service_global.save_system_logs_async({"opportunity_scan_started": True})
|
|
@@ -255,18 +324,19 @@ async def find_new_opportunities_async():
|
|
| 255 |
print("❌ لا توجد مرشحات نهائية")
|
| 256 |
return
|
| 257 |
|
| 258 |
-
print("🤖 بدء تحليل النموذج الضخم للمرشحين...")
|
| 259 |
for candidate in top_candidates:
|
| 260 |
try:
|
| 261 |
if not validate_candidate_data_enhanced(candidate):
|
| 262 |
print(f"⚠️ تخطي {candidate['symbol']} - بيانات غير صالحة")
|
| 263 |
continue
|
| 264 |
|
| 265 |
-
print(f"🧠 تحليل {candidate['symbol']}
|
| 266 |
-
|
| 267 |
-
|
|
|
|
| 268 |
if not llm_analysis_data:
|
| 269 |
-
print(f"⚠️ فشل
|
| 270 |
continue
|
| 271 |
|
| 272 |
if llm_analysis_data.get('action') == "HOLD":
|
|
@@ -284,10 +354,13 @@ async def find_new_opportunities_async():
|
|
| 284 |
"new_opportunity_found": True,
|
| 285 |
"symbol": candidate['symbol'],
|
| 286 |
"action": llm_analysis_data.get('action'),
|
| 287 |
-
"strategy": final_strategy
|
|
|
|
|
|
|
| 288 |
})
|
| 289 |
|
| 290 |
print(f"🎯 فرصة تداول مثبتة: {candidate['symbol']} - {llm_analysis_data.get('action')} - {final_strategy}")
|
|
|
|
| 291 |
|
| 292 |
return {
|
| 293 |
"symbol": candidate['symbol'],
|
|
@@ -296,8 +369,7 @@ async def find_new_opportunities_async():
|
|
| 296 |
"strategy": final_strategy
|
| 297 |
}
|
| 298 |
except Exception as error:
|
| 299 |
-
print(f"❌ خطأ في
|
| 300 |
-
# استمرار مع المرشح التالي بدلاً من التوقف
|
| 301 |
continue
|
| 302 |
|
| 303 |
print("❌ لم يتم العثور على فرص تداول مناسبة")
|
|
@@ -310,6 +382,7 @@ async def find_new_opportunities_async():
|
|
| 310 |
})
|
| 311 |
return None
|
| 312 |
|
|
|
|
| 313 |
async def re_analyze_open_trade_async(trade_data):
|
| 314 |
symbol = trade_data.get('symbol')
|
| 315 |
try:
|
|
@@ -354,7 +427,6 @@ async def re_analyze_open_trade_async(trade_data):
|
|
| 354 |
)
|
| 355 |
|
| 356 |
try:
|
| 357 |
-
# التصحيح: إضافة await للدالة غير المتزامنة
|
| 358 |
re_analysis_decision = await llm_service_global.re_analyze_trade_async(trade_data, processed_data)
|
| 359 |
except Exception:
|
| 360 |
re_analysis_decision = local_re_analyze_trade(trade_data, processed_data)
|
|
@@ -484,7 +556,7 @@ async def run_bot_cycle_async():
|
|
| 484 |
|
| 485 |
@asynccontextmanager
|
| 486 |
async def lifespan(application: FastAPI):
|
| 487 |
-
global r2_service_global, data_manager_global, llm_service_global, learning_engine_global, trade_manager_global, sentiment_analyzer_global
|
| 488 |
|
| 489 |
initialization_successful = False
|
| 490 |
try:
|
|
@@ -497,6 +569,13 @@ async def lifespan(application: FastAPI):
|
|
| 497 |
contracts_database = await r2_service_global.load_contracts_db_async()
|
| 498 |
print("✅ Contracts database loaded")
|
| 499 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
from whale_news_data import EnhancedWhaleMonitor
|
| 501 |
whale_monitor_global = EnhancedWhaleMonitor(contracts_database)
|
| 502 |
print("✅ Whale Monitor initialized")
|
|
@@ -574,7 +653,8 @@ async def health_check():
|
|
| 574 |
"llm_service": "initialized" if llm_service_global else "uninitialized",
|
| 575 |
"data_manager": "initialized" if data_manager_global else "uninitialized",
|
| 576 |
"learning_engine": "active" if learning_engine_global and learning_engine_global.initialized else "inactive",
|
| 577 |
-
"trade_manager": "active" if trade_manager_global else "inactive"
|
|
|
|
| 578 |
},
|
| 579 |
"market_state_ok": state.MARKET_STATE_OK,
|
| 580 |
"learning_engine": learning_metrics
|
|
@@ -606,7 +686,11 @@ async def get_performance_stats():
|
|
| 606 |
"active_trades": len(trade_manager_global.monitoring_tasks) if trade_manager_global else 0,
|
| 607 |
"is_running": trade_manager_global.is_running if trade_manager_global else False
|
| 608 |
},
|
| 609 |
-
"learning_engine": learning_stats
|
|
|
|
|
|
|
|
|
|
|
|
|
| 610 |
}
|
| 611 |
return stats
|
| 612 |
except Exception as error:
|
|
@@ -628,7 +712,7 @@ async def get_logs_status():
|
|
| 628 |
raise HTTPException(status_code=500, detail=f"Failed to get logs status: {str(error)}")
|
| 629 |
|
| 630 |
async def cleanup_on_shutdown():
|
| 631 |
-
global r2_service_global, data_manager_global, trade_manager_global, learning_engine_global
|
| 632 |
print("🛑 Shutdown signal received. Cleaning up...")
|
| 633 |
|
| 634 |
if trade_manager_global:
|
|
@@ -647,6 +731,10 @@ async def cleanup_on_shutdown():
|
|
| 647 |
await data_manager_global.close()
|
| 648 |
print("✅ Data manager closed")
|
| 649 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
if r2_service_global:
|
| 651 |
try:
|
| 652 |
await r2_service_global.save_system_logs_async({"application_shutdown": True})
|
|
|
|
| 25 |
learning_engine_global = None
|
| 26 |
trade_manager_global = None
|
| 27 |
sentiment_analyzer_global = None
|
| 28 |
+
symbol_whale_monitor_global = None # ⬅️ إضافة مراقب الحيتان الجديد
|
| 29 |
|
| 30 |
class StateManager:
|
| 31 |
def __init__(self):
|
|
|
|
| 38 |
'llm_service': False,
|
| 39 |
'learning_engine': False,
|
| 40 |
'trade_manager': False,
|
| 41 |
+
'sentiment_analyzer': False,
|
| 42 |
+
'symbol_whale_monitor': False # ⬅️ إضافة الخدمة الجديدة
|
| 43 |
}
|
| 44 |
|
| 45 |
async def wait_for_initialization(self, timeout=30):
|
|
|
|
| 56 |
state_manager = StateManager()
|
| 57 |
|
| 58 |
async def monitor_market_async():
|
| 59 |
+
"""مراقبة السوق بدون نظام الحيتان العام"""
|
| 60 |
global data_manager_global, sentiment_analyzer_global
|
| 61 |
|
| 62 |
if not await state_manager.wait_for_initialization():
|
|
|
|
| 72 |
await asyncio.sleep(60)
|
| 73 |
continue
|
| 74 |
|
|
|
|
|
|
|
| 75 |
bitcoin_sentiment = market_context.get('btc_sentiment')
|
| 76 |
fear_greed_index = market_context.get('fear_and_greed_index')
|
| 77 |
|
| 78 |
should_halt_trading, halt_reason = False, ""
|
| 79 |
+
|
| 80 |
+
# استخدام مؤشرات السوق الأخرى فقط (بدون الحيتان العامة)
|
| 81 |
+
if bitcoin_sentiment == 'BEARISH' and (fear_greed_index is not None and fear_greed_index < 30):
|
| 82 |
should_halt_trading, halt_reason = True, "ظروف سوق هابطة"
|
| 83 |
|
| 84 |
if should_halt_trading:
|
|
|
|
| 96 |
await asyncio.sleep(60)
|
| 97 |
|
| 98 |
async def analyze_market_strategy(market_context):
|
| 99 |
+
"""تحليل استراتيجية السوق بدون اعتماد على الحيتان العامة"""
|
| 100 |
try:
|
| 101 |
+
# استخدام مؤشرات السوق الأساسية فقط
|
| 102 |
+
prompt = f"Analyze current market conditions and determine trading strategy.\n\nMarket Data:\n- BTC Sentiment: {market_context.get('btc_sentiment')}\n- Fear & Greed Index: {market_context.get('fear_and_greed_index')}\n\nOutput JSON:\n{{\"primary_strategy\": \"STRATEGY_NAME\",\"reasoning\": \"Brief reasoning\",\"risk_tolerance\": 5,\"optimal_scan_count\": 100}}"
|
|
|
|
| 103 |
response = await llm_service_global._call_llm(prompt)
|
| 104 |
try:
|
| 105 |
from helpers import parse_json_from_response
|
| 106 |
json_str = parse_json_from_response(response)
|
| 107 |
strategy_data = json.loads(json_str)
|
| 108 |
except:
|
| 109 |
+
# استراتيجية افتراضية في حال فشل التحليل
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
strategy_data = {
|
| 111 |
+
"primary_strategy": "GENERIC",
|
| 112 |
"reasoning": "Fallback strategy due to analysis error",
|
| 113 |
"risk_tolerance": 5,
|
| 114 |
"optimal_scan_count": 100
|
|
|
|
| 124 |
}
|
| 125 |
|
| 126 |
async def find_strategy_specific_candidates(strategy, scan_count):
|
| 127 |
+
"""البحث عن مرشحين متوافقين مع الاستراتيجية"""
|
| 128 |
try:
|
| 129 |
all_candidates = await data_manager_global.find_high_potential_candidates(scan_count * 2)
|
| 130 |
if not all_candidates:
|
|
|
|
| 170 |
print(f"�� Advanced filtering failed: {error}")
|
| 171 |
return []
|
| 172 |
|
| 173 |
+
async def enhanced_llm_analysis_with_whale_data(candidate):
|
| 174 |
+
"""تحليل محسن يشمل بيانات حيتان KuCoin للمرشحين النهائيين"""
|
| 175 |
+
global symbol_whale_monitor_global
|
| 176 |
+
|
| 177 |
+
try:
|
| 178 |
+
print(f"🧠 بدء التحليل المتقدم لـ {candidate['symbol']}...")
|
| 179 |
+
|
| 180 |
+
# 1. الحصول على تحليل النموذج الضخم الأساسي
|
| 181 |
+
llm_analysis = await llm_service_global.get_trading_decision(candidate)
|
| 182 |
+
if not llm_analysis:
|
| 183 |
+
print(f"❌ فشل التحليل الأساسي لـ {candidate['symbol']}")
|
| 184 |
+
return None
|
| 185 |
+
|
| 186 |
+
# 2. إضافة بيانات الحيتان للمرشحين النهائيين فقط
|
| 187 |
+
print(f"🐋 جلب بيانات الحيتان لـ {candidate['symbol']}...")
|
| 188 |
+
whale_analysis = await symbol_whale_monitor_global.get_symbol_whale_activity(
|
| 189 |
+
candidate['symbol'],
|
| 190 |
+
candidate.get('contract_address')
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
# 3. دمج النتائج
|
| 194 |
+
enhanced_analysis = {
|
| 195 |
+
**llm_analysis,
|
| 196 |
+
'whale_analysis': whale_analysis['llm_friendly_summary'], # ⬅️ نرسل الملخص المفيد فقط
|
| 197 |
+
'combined_confidence': await calculate_combined_confidence(
|
| 198 |
+
llm_analysis.get('confidence_level', 0.5),
|
| 199 |
+
whale_analysis['trading_signal'].get('confidence', 0.5)
|
| 200 |
+
),
|
| 201 |
+
'analysis_timestamp': datetime.now().isoformat(),
|
| 202 |
+
'analysis_source': 'enhanced_with_whale_data'
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
# 4. تطبيق قواعد السلامة بناء على نشاط الحيتان
|
| 206 |
+
if whale_analysis['trading_signal'].get('critical_alert'):
|
| 207 |
+
enhanced_analysis = apply_whale_safety_filters(enhanced_analysis, whale_analysis)
|
| 208 |
+
|
| 209 |
+
print(f"✅ اكتمل التحليل المتقدم لـ {candidate['symbol']}")
|
| 210 |
+
return enhanced_analysis
|
| 211 |
+
|
| 212 |
+
except Exception as error:
|
| 213 |
+
print(f"❌ خطأ في التحليل المتقدم لـ {candidate.get('symbol')}: {error}")
|
| 214 |
+
# العودة للتحليل الأساسي في حالة الخطأ
|
| 215 |
+
return await llm_service_global.get_trading_decision(candidate)
|
| 216 |
+
|
| 217 |
+
async def calculate_combined_confidence(llm_confidence, whale_confidence):
|
| 218 |
+
"""حساب الثقة المجمعة مع إعطاء وزن أكبر لبيانات الحيتان"""
|
| 219 |
+
# وزن بيانات الحيتان 60% والتحليل الأساسي 40%
|
| 220 |
+
combined = (llm_confidence * 0.4) + (whale_confidence * 0.6)
|
| 221 |
+
return min(combined, 0.95) # حد أقصى 95%
|
| 222 |
+
|
| 223 |
+
def apply_whale_safety_filters(analysis, whale_analysis):
|
| 224 |
+
"""تطبيق فلاتر السلامة بناء على نشاط الحيتان الحرج"""
|
| 225 |
+
|
| 226 |
+
whale_signal = whale_analysis['trading_signal']
|
| 227 |
+
|
| 228 |
+
if whale_signal['action'] in ['STRONG_SELL', 'SELL']:
|
| 229 |
+
# إذا كان هناك ضغط بيعي قوي من الحيتان
|
| 230 |
+
if analysis['action'] == 'BUY':
|
| 231 |
+
analysis.update({
|
| 232 |
+
'action': 'HOLD',
|
| 233 |
+
'reasoning': f"{analysis.get('reasoning', '')} | تصحيح بسبب نشاط الحيتان: {whale_signal['reason']}",
|
| 234 |
+
'confidence_level': analysis.get('confidence_level', 0.5) * 0.7
|
| 235 |
+
})
|
| 236 |
+
elif analysis['action'] == 'HOLD':
|
| 237 |
+
analysis['confidence_level'] = analysis.get('confidence_level', 0.5) * 0.9
|
| 238 |
+
|
| 239 |
+
elif whale_signal['action'] in ['STRONG_BUY', 'BUY']:
|
| 240 |
+
# إذا كان هناك تراكم شرائي قوي من الحيتان
|
| 241 |
+
if analysis['action'] == 'BUY':
|
| 242 |
+
analysis['confidence_level'] = min(analysis.get('confidence_level', 0.5) * 1.2, 0.95)
|
| 243 |
+
analysis['reasoning'] = f"{analysis.get('reasoning', '')} | تعزيز بسبب نشاط الحيتان الإيجابي"
|
| 244 |
+
|
| 245 |
+
return analysis
|
| 246 |
+
|
| 247 |
async def find_new_opportunities_async():
|
| 248 |
+
"""البحث عن فرص تداول جديدة مع دمج بيانات الحيتان للمرشحين النهائيين"""
|
| 249 |
try:
|
| 250 |
print("🎯 بدء البحث عن فرص تداول جديدة...")
|
| 251 |
await r2_service_global.save_system_logs_async({"opportunity_scan_started": True})
|
|
|
|
| 324 |
print("❌ لا توجد مرشحات نهائية")
|
| 325 |
return
|
| 326 |
|
| 327 |
+
print("🤖 بدء تحليل النموذج الضخم المحسن للمرشحين...")
|
| 328 |
for candidate in top_candidates:
|
| 329 |
try:
|
| 330 |
if not validate_candidate_data_enhanced(candidate):
|
| 331 |
print(f"⚠️ تخطي {candidate['symbol']} - بيانات غير صالحة")
|
| 332 |
continue
|
| 333 |
|
| 334 |
+
print(f"🧠 تحليل متقدم لـ {candidate['symbol']}...")
|
| 335 |
+
|
| 336 |
+
# استخدام التحليل المحسن ببيانات الحيتان
|
| 337 |
+
llm_analysis_data = await enhanced_llm_analysis_with_whale_data(candidate)
|
| 338 |
if not llm_analysis_data:
|
| 339 |
+
print(f"⚠️ فشل التحليل المتقدم لـ {candidate['symbol']}")
|
| 340 |
continue
|
| 341 |
|
| 342 |
if llm_analysis_data.get('action') == "HOLD":
|
|
|
|
| 354 |
"new_opportunity_found": True,
|
| 355 |
"symbol": candidate['symbol'],
|
| 356 |
"action": llm_analysis_data.get('action'),
|
| 357 |
+
"strategy": final_strategy,
|
| 358 |
+
"with_whale_analysis": True,
|
| 359 |
+
"combined_confidence": llm_analysis_data.get('combined_confidence', 0.5)
|
| 360 |
})
|
| 361 |
|
| 362 |
print(f"🎯 فرصة تداول مثبتة: {candidate['symbol']} - {llm_analysis_data.get('action')} - {final_strategy}")
|
| 363 |
+
print(f" 📊 الثقة المجمعة: {llm_analysis_data.get('combined_confidence', 0.5):.2f}")
|
| 364 |
|
| 365 |
return {
|
| 366 |
"symbol": candidate['symbol'],
|
|
|
|
| 369 |
"strategy": final_strategy
|
| 370 |
}
|
| 371 |
except Exception as error:
|
| 372 |
+
print(f"❌ خطأ في التحليل المتقدم لـ {candidate.get('symbol', 'unknown')}: {error}")
|
|
|
|
| 373 |
continue
|
| 374 |
|
| 375 |
print("❌ لم يتم العثور على فرص تداول مناسبة")
|
|
|
|
| 382 |
})
|
| 383 |
return None
|
| 384 |
|
| 385 |
+
# باقي الدوال (re_analyze_open_trade_async, run_bot_cycle_async) تبقى كما هي بدون تعديل
|
| 386 |
async def re_analyze_open_trade_async(trade_data):
|
| 387 |
symbol = trade_data.get('symbol')
|
| 388 |
try:
|
|
|
|
| 427 |
)
|
| 428 |
|
| 429 |
try:
|
|
|
|
| 430 |
re_analysis_decision = await llm_service_global.re_analyze_trade_async(trade_data, processed_data)
|
| 431 |
except Exception:
|
| 432 |
re_analysis_decision = local_re_analyze_trade(trade_data, processed_data)
|
|
|
|
| 556 |
|
| 557 |
@asynccontextmanager
|
| 558 |
async def lifespan(application: FastAPI):
|
| 559 |
+
global r2_service_global, data_manager_global, llm_service_global, learning_engine_global, trade_manager_global, sentiment_analyzer_global, symbol_whale_monitor_global
|
| 560 |
|
| 561 |
initialization_successful = False
|
| 562 |
try:
|
|
|
|
| 569 |
contracts_database = await r2_service_global.load_contracts_db_async()
|
| 570 |
print("✅ Contracts database loaded")
|
| 571 |
|
| 572 |
+
# ❌ إزالة النظام العام للحيتان
|
| 573 |
+
# ✅ استخدام النظام الخاص فقط للمرشحين النهائيين
|
| 574 |
+
from whale_news_data import EnhancedWhaleMonitor
|
| 575 |
+
symbol_whale_monitor_global = EnhancedWhaleMonitor(contracts_database, r2_service_global)
|
| 576 |
+
state_manager.set_service_initialized('symbol_whale_monitor')
|
| 577 |
+
print("✅ Symbol Specific Whale Monitor initialized")
|
| 578 |
+
|
| 579 |
from whale_news_data import EnhancedWhaleMonitor
|
| 580 |
whale_monitor_global = EnhancedWhaleMonitor(contracts_database)
|
| 581 |
print("✅ Whale Monitor initialized")
|
|
|
|
| 653 |
"llm_service": "initialized" if llm_service_global else "uninitialized",
|
| 654 |
"data_manager": "initialized" if data_manager_global else "uninitialized",
|
| 655 |
"learning_engine": "active" if learning_engine_global and learning_engine_global.initialized else "inactive",
|
| 656 |
+
"trade_manager": "active" if trade_manager_global else "inactive",
|
| 657 |
+
"symbol_whale_monitor": "active" if symbol_whale_monitor_global else "inactive"
|
| 658 |
},
|
| 659 |
"market_state_ok": state.MARKET_STATE_OK,
|
| 660 |
"learning_engine": learning_metrics
|
|
|
|
| 686 |
"active_trades": len(trade_manager_global.monitoring_tasks) if trade_manager_global else 0,
|
| 687 |
"is_running": trade_manager_global.is_running if trade_manager_global else False
|
| 688 |
},
|
| 689 |
+
"learning_engine": learning_stats,
|
| 690 |
+
"whale_monitoring": {
|
| 691 |
+
"symbol_specific_active": symbol_whale_monitor_global is not None,
|
| 692 |
+
"monitoring_type": "FINAL_CANDIDATES_ONLY"
|
| 693 |
+
}
|
| 694 |
}
|
| 695 |
return stats
|
| 696 |
except Exception as error:
|
|
|
|
| 712 |
raise HTTPException(status_code=500, detail=f"Failed to get logs status: {str(error)}")
|
| 713 |
|
| 714 |
async def cleanup_on_shutdown():
|
| 715 |
+
global r2_service_global, data_manager_global, trade_manager_global, learning_engine_global, symbol_whale_monitor_global
|
| 716 |
print("🛑 Shutdown signal received. Cleaning up...")
|
| 717 |
|
| 718 |
if trade_manager_global:
|
|
|
|
| 731 |
await data_manager_global.close()
|
| 732 |
print("✅ Data manager closed")
|
| 733 |
|
| 734 |
+
if symbol_whale_monitor_global:
|
| 735 |
+
await symbol_whale_monitor_global.cleanup()
|
| 736 |
+
print("✅ Symbol whale monitor cleaned up")
|
| 737 |
+
|
| 738 |
if r2_service_global:
|
| 739 |
try:
|
| 740 |
await r2_service_global.save_system_logs_async({"application_shutdown": True})
|