Riy777 commited on
Commit
37a49fe
·
1 Parent(s): 29b8ecb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -26
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py (Fully updated to Explorer-Sentry-Executor architecture V5.3 - Fixed Producer Task)
2
  import os
3
  import traceback
4
  import signal
@@ -79,7 +79,7 @@ async def initialize_services():
79
  global learning_hub_global, trade_manager_global, sentiment_analyzer_global
80
  global symbol_whale_monitor_global
81
  try:
82
- print("🚀 بدء تهيئة الخدمات (بنية Sentry الجديدة V5.3)...")
83
  print(" 🔄 تهيئة R2Service..."); r2_service_global = R2Service(); state_manager.set_service_initialized('r2_service'); print(" ✅ R2Service مهيأة")
84
  print(" 🔄 جلب قاعدة بيانات العقود..."); contracts_database = await r2_service_global.load_contracts_db_async(); print(f" ✅ تم تحميل {len(contracts_database)} عقد")
85
 
@@ -244,14 +244,10 @@ async def run_3_layer_analysis_explorer() -> List[Dict[str, Any]]:
244
  print("❌ Services not fully initialized (Explorer)"); return []
245
 
246
  print("\n🔍 Layer 1.1: Rapid Screening (data_manager V7.1)...")
247
- # (هذه الآن ترجع قائمة المرشحين الناجحين من الغربلة الذكية)
248
  layer1_candidates = await data_manager_global.layer1_rapid_screening()
249
  if not layer1_candidates: print("❌ No candidates found in Layer 1.1"); return []
250
  print(f"✅ Selected {len(layer1_candidates)} symbols for Layer 1.2")
251
 
252
- # (لم نعد بحاجة إلى layer1_symbols)
253
- # layer1_symbols = [c['symbol'] for c in layer1_candidates]
254
-
255
  print(f"\n📊 Layer 1.2: Fetching OHLCV data for {len(layer1_candidates)} symbols (Streaming)...")
256
  DATA_QUEUE_MAX_SIZE = 2
257
  ohlcv_data_queue = asyncio.Queue(maxsize=DATA_QUEUE_MAX_SIZE)
@@ -284,10 +280,8 @@ async def run_3_layer_analysis_explorer() -> List[Dict[str, Any]]:
284
 
285
  consumer_task = asyncio.create_task(ml_consumer_task(ohlcv_data_queue, ml_results_list, preloaded_whale_data_dict))
286
 
287
- # 🔴 --- START OF CHANGE (V5.3 - FIX) --- 🔴
288
- # (تمرير layer1_candidates (List[Dict]) بدلاً من layer1_symbols (List[str]))
289
  producer_task = asyncio.create_task(data_manager_global.stream_ohlcv_data(layer1_candidates, ohlcv_data_queue))
290
- # 🔴 --- END OF CHANGE --- 🔴
291
 
292
  await producer_task;
293
  await ohlcv_data_queue.join()
@@ -297,8 +291,6 @@ async def run_3_layer_analysis_explorer() -> List[Dict[str, Any]]:
297
  for batch_result in ml_results_list:
298
  for success_item in batch_result['success']:
299
  symbol = success_item['symbol']
300
-
301
- # (البيانات الأولية موجودة الآن في success_item)
302
  l1_data = success_item
303
 
304
  if l1_data:
@@ -319,7 +311,6 @@ async def run_3_layer_analysis_explorer() -> List[Dict[str, Any]]:
319
 
320
  whale_tasks = []
321
  async def get_whale_data_for_candidate(candidate):
322
- """دالة مساعدة لجلب وتحديث بيانات الحيتان للمرشح"""
323
  symbol = candidate.get('symbol', 'UNKNOWN')
324
  try:
325
  data = await data_manager_global.get_whale_data_for_symbol(symbol)
@@ -433,7 +424,7 @@ async def run_3_layer_analysis_explorer() -> List[Dict[str, Any]]:
433
 
434
 
435
  async def re_analyze_open_trade_async(trade_data):
436
- """(لا تغيير) - هذا لا يزال تحليلاً استراتيجياً (Explorer)"""
437
  symbol = trade_data.get('symbol')
438
  try:
439
  async with state_manager.trade_analysis_lock:
@@ -442,9 +433,9 @@ async def re_analyze_open_trade_async(trade_data):
442
  ohlcv_data_list = []
443
  temp_queue = asyncio.Queue()
444
 
445
- # (إصلاح هنا أيضاً: تمرير قائمة Dict)
446
  await data_manager_global.stream_ohlcv_data(
447
- [{'symbol': symbol, 'layer1_score': 0, 'reasons': ['re-analysis']}],
448
  temp_queue
449
  )
450
 
@@ -461,10 +452,6 @@ async def re_analyze_open_trade_async(trade_data):
461
  if not ohlcv_data_list: print(f"⚠️ Failed to get re-analysis data for {symbol}"); return None
462
  ohlcv_data = ohlcv_data_list[0]
463
 
464
- # (لم نعد بحاجة لهذا، البيانات مدمجة)
465
- # l1_data = await data_manager_global._get_detailed_symbol_data(symbol)
466
- # if l1_data: ohlcv_data.update(l1_data); ohlcv_data['reasons_for_candidacy'] = ['re-analysis']
467
-
468
  re_analysis_whale_data = await data_manager_global.get_whale_data_for_symbol(symbol)
469
 
470
  ml_processor = MLProcessor(market_context, data_manager_global, learning_hub_global)
@@ -497,7 +484,7 @@ async def re_analyze_open_trade_async(trade_data):
497
 
498
  async def run_bot_cycle_async():
499
  """
500
- (لا تغيير) - دورة البوت الرئيسية (المستكشف)
501
  """
502
  try:
503
  if not await state_manager.wait_for_initialization():
@@ -517,17 +504,33 @@ async def run_bot_cycle_async():
517
  if open_trades:
518
  now = datetime.now()
519
  trades_to_reanalyze = [t for t in open_trades if now >= datetime.fromisoformat(t.get('expected_target_time', now.isoformat()))]
 
 
520
  if trades_to_reanalyze:
521
  print(f"🔄 (Explorer) Re-analyzing {len(trades_to_reanalyze)} trades strategically...")
522
  reanalysis_results = await asyncio.gather(*[re_analyze_open_trade_async(trade) for trade in trades_to_reanalyze], return_exceptions=True)
 
523
  for i, result in enumerate(reanalysis_results):
524
  trade = trades_to_reanalyze[i]
525
- if isinstance(result, Exception): print(f" ❌ Re-analysis failed for {trade.get('symbol')}: {result}")
 
 
526
  elif result and result['decision'].get('action') == "UPDATE_TRADE":
527
  print(f" ✅ (Explorer) Updating strategy for {trade.get('symbol')}.");
528
  await trade_manager_global.update_trade_strategy(trade, result['decision'])
529
- elif result: print(f" ℹ️ (Explorer) Holding {trade.get('symbol')} based on re-analysis.")
530
- else: print(f" ⚠️ Re-analysis for {trade.get('symbol')} yielded no decision.")
 
 
 
 
 
 
 
 
 
 
 
531
 
532
  current_open_trades_count = len(await trade_manager_global.get_open_trades())
533
  should_look_for_new_trade = current_open_trades_count == 0
@@ -589,7 +592,7 @@ async def lifespan(application: FastAPI):
589
  await cleanup_on_shutdown()
590
 
591
 
592
- application = FastAPI(lifespan=lifespan, title="AI Trading Bot", description="Explorer-Sentry-Executor Architecture (V5.3)", version="5.3.0")
593
 
594
  @application.get("/")
595
  async def root(): return {"message": "Welcome to the AI Trading System", "system": "Explorer-Sentry-Executor", "status": "running" if state_manager.initialization_complete else "initializing", "timestamp": datetime.now().isoformat()}
@@ -601,7 +604,7 @@ async def run_cycle_api():
601
  return {"message": "Explorer (Layer 1) cycle initiated", "system": "Explorer-Sentry-Executor"}
602
 
603
  @application.get("/health")
604
- async def health_check(): return {"status": "healthy" if state_manager.initialization_complete else "initializing", "initialization_complete": state_manager.initialization_complete, "services_initialized": state_manager.services_initialized, "initialization_error": state_manager.initialization_error, "timestamp": datetime.now().isoformat(), "system_architecture": "Explorer-Sentry-Executor (V5.3)"}
605
 
606
  @application.get("/analyze-market")
607
  async def analyze_market_api():
@@ -654,5 +657,5 @@ def signal_handler(signum, frame): print(f"🛑 Received signal {signum}. Initia
654
  signal.signal(signal.SIGINT, signal_handler); signal.signal(signal.SIGTERM, signal_handler)
655
 
656
  if __name__ == "__main__":
657
- print("🚀 Starting AI Trading Bot (Explorer-Sentry-Executor V5.3)...")
658
  uvicorn.run( application, host="0.0.0.0", port=7860, log_level="info", access_log=True )
 
1
+ # app.py (Fully updated to Explorer-Sentry-Executor architecture V5.4 - Fixed Re-Analysis Timer Bug)
2
  import os
3
  import traceback
4
  import signal
 
79
  global learning_hub_global, trade_manager_global, sentiment_analyzer_global
80
  global symbol_whale_monitor_global
81
  try:
82
+ print("🚀 بدء تهيئة الخدمات (بنية Sentry الجديدة V5.4)...")
83
  print(" 🔄 تهيئة R2Service..."); r2_service_global = R2Service(); state_manager.set_service_initialized('r2_service'); print(" ✅ R2Service مهيأة")
84
  print(" 🔄 جلب قاعدة بيانات العقود..."); contracts_database = await r2_service_global.load_contracts_db_async(); print(f" ✅ تم تحميل {len(contracts_database)} عقد")
85
 
 
244
  print("❌ Services not fully initialized (Explorer)"); return []
245
 
246
  print("\n🔍 Layer 1.1: Rapid Screening (data_manager V7.1)...")
 
247
  layer1_candidates = await data_manager_global.layer1_rapid_screening()
248
  if not layer1_candidates: print("❌ No candidates found in Layer 1.1"); return []
249
  print(f"✅ Selected {len(layer1_candidates)} symbols for Layer 1.2")
250
 
 
 
 
251
  print(f"\n📊 Layer 1.2: Fetching OHLCV data for {len(layer1_candidates)} symbols (Streaming)...")
252
  DATA_QUEUE_MAX_SIZE = 2
253
  ohlcv_data_queue = asyncio.Queue(maxsize=DATA_QUEUE_MAX_SIZE)
 
280
 
281
  consumer_task = asyncio.create_task(ml_consumer_task(ohlcv_data_queue, ml_results_list, preloaded_whale_data_dict))
282
 
283
+ # (V5.3 - FIX)
 
284
  producer_task = asyncio.create_task(data_manager_global.stream_ohlcv_data(layer1_candidates, ohlcv_data_queue))
 
285
 
286
  await producer_task;
287
  await ohlcv_data_queue.join()
 
291
  for batch_result in ml_results_list:
292
  for success_item in batch_result['success']:
293
  symbol = success_item['symbol']
 
 
294
  l1_data = success_item
295
 
296
  if l1_data:
 
311
 
312
  whale_tasks = []
313
  async def get_whale_data_for_candidate(candidate):
 
314
  symbol = candidate.get('symbol', 'UNKNOWN')
315
  try:
316
  data = await data_manager_global.get_whale_data_for_symbol(symbol)
 
424
 
425
 
426
  async def re_analyze_open_trade_async(trade_data):
427
+ """(V5.3) - إصلاح تمرير الوسيط"""
428
  symbol = trade_data.get('symbol')
429
  try:
430
  async with state_manager.trade_analysis_lock:
 
433
  ohlcv_data_list = []
434
  temp_queue = asyncio.Queue()
435
 
436
+ # (V5.3 - FIX: تمرير قائمة Dict)
437
  await data_manager_global.stream_ohlcv_data(
438
+ [{'symbol': symbol, 'layer1_score': 0, 'reasons_for_candidacy': ['re-analysis']}],
439
  temp_queue
440
  )
441
 
 
452
  if not ohlcv_data_list: print(f"⚠️ Failed to get re-analysis data for {symbol}"); return None
453
  ohlcv_data = ohlcv_data_list[0]
454
 
 
 
 
 
455
  re_analysis_whale_data = await data_manager_global.get_whale_data_for_symbol(symbol)
456
 
457
  ml_processor = MLProcessor(market_context, data_manager_global, learning_hub_global)
 
484
 
485
  async def run_bot_cycle_async():
486
  """
487
+ (محدث V5.4) - دورة البوت الرئيسية (المستكشف)
488
  """
489
  try:
490
  if not await state_manager.wait_for_initialization():
 
504
  if open_trades:
505
  now = datetime.now()
506
  trades_to_reanalyze = [t for t in open_trades if now >= datetime.fromisoformat(t.get('expected_target_time', now.isoformat()))]
507
+
508
+ # 🔴 --- START OF CHANGE (V5.4 - TIMER FIX) --- 🔴
509
  if trades_to_reanalyze:
510
  print(f"🔄 (Explorer) Re-analyzing {len(trades_to_reanalyze)} trades strategically...")
511
  reanalysis_results = await asyncio.gather(*[re_analyze_open_trade_async(trade) for trade in trades_to_reanalyze], return_exceptions=True)
512
+
513
  for i, result in enumerate(reanalysis_results):
514
  trade = trades_to_reanalyze[i]
515
+ if isinstance(result, Exception):
516
+ print(f" ❌ Re-analysis failed for {trade.get('symbol')}: {result}")
517
+
518
  elif result and result['decision'].get('action') == "UPDATE_TRADE":
519
  print(f" ✅ (Explorer) Updating strategy for {trade.get('symbol')}.");
520
  await trade_manager_global.update_trade_strategy(trade, result['decision'])
521
+
522
+ elif result and result['decision'].get('action') == "HOLD":
523
+ print(f" ℹ️ (Explorer) Holding {trade.get('symbol')}. Resetting 15-min timer.")
524
+ # (إصلاح الخلل: إعادة ضبط المؤقت حتى لو كان القرار "HOLD" لمنع إعادة التحليل المتكرر)
525
+ await trade_manager_global.update_trade_strategy(trade, result['decision'])
526
+
527
+ elif result:
528
+ # (مثل: CLOSE_TRADE - لا تفعل شيئاً، دع Sentry/Executor يتعامل معها)
529
+ print(f" ℹ️ (Explorer) Re-analysis returned '{result['decision'].get('action')}' for {trade.get('symbol')}. No timer update needed.")
530
+
531
+ else:
532
+ print(f" ⚠️ Re-analysis for {trade.get('symbol')} yielded no decision.")
533
+ # 🔴 --- END OF CHANGE --- 🔴
534
 
535
  current_open_trades_count = len(await trade_manager_global.get_open_trades())
536
  should_look_for_new_trade = current_open_trades_count == 0
 
592
  await cleanup_on_shutdown()
593
 
594
 
595
+ application = FastAPI(lifespan=lifespan, title="AI Trading Bot", description="Explorer-Sentry-Executor Architecture (V5.4)", version="5.4.0")
596
 
597
  @application.get("/")
598
  async def root(): return {"message": "Welcome to the AI Trading System", "system": "Explorer-Sentry-Executor", "status": "running" if state_manager.initialization_complete else "initializing", "timestamp": datetime.now().isoformat()}
 
604
  return {"message": "Explorer (Layer 1) cycle initiated", "system": "Explorer-Sentry-Executor"}
605
 
606
  @application.get("/health")
607
+ async def health_check(): return {"status": "healthy" if state_manager.initialization_complete else "initializing", "initialization_complete": state_manager.initialization_complete, "services_initialized": state_manager.services_initialized, "initialization_error": state_manager.initialization_error, "timestamp": datetime.now().isoformat(), "system_architecture": "Explorer-Sentry-Executor (V5.4)"}
608
 
609
  @application.get("/analyze-market")
610
  async def analyze_market_api():
 
657
  signal.signal(signal.SIGINT, signal_handler); signal.signal(signal.SIGTERM, signal_handler)
658
 
659
  if __name__ == "__main__":
660
+ print("🚀 Starting AI Trading Bot (Explorer-Sentry-Executor V5.4)...")
661
  uvicorn.run( application, host="0.0.0.0", port=7860, log_level="info", access_log=True )