Riy777 commited on
Commit
20d8a3b
·
verified ·
1 Parent(s): f1dbebc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -238
app.py CHANGED
@@ -1,5 +1,6 @@
1
- # app.py (V23.5 - GEM-Architect: Full Enterprise Edition - No Abbreviations)
2
- # النسخة الكاملة: تشمل المنطق، الواجهة، التنسيقات، والربط مع مركز التعلم.
 
3
 
4
  import os
5
  import sys
@@ -33,18 +34,15 @@ try:
33
  from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
34
 
35
  # 3. ⚡ المحرك المركزي (The Brain) ⚡
36
- # يدير Titan, Oracle, Sniper, Patterns, Guardian
37
  from ml_engine.processor import MLProcessor
38
 
39
  # 4. 🎓 مركز التعلم (The Learning Hub) 🎓
40
- # يدير التدريب الذاتي، الأوزان المتكيفة، والأرشفة
41
  from learning_hub.hub_manager import LearningHubManager
42
 
43
  # 5. مدير التداول (The Executor)
44
  from trade_manager import TradeManager
45
 
46
  except ImportError as e:
47
- # إيقاف النظام في حال فقدان أي ملف جوهري
48
  sys.exit(f"❌ [FATAL ERROR] Failed to import core modules: {e}")
49
 
50
  # ==============================================================================
@@ -53,7 +51,7 @@ except ImportError as e:
53
  r2: R2Service = None
54
  data_manager: DataManager = None
55
  ml_processor: MLProcessor = None
56
- hub_manager: LearningHubManager = None # المتغير العام لمركز التعلم
57
  trade_manager: TradeManager = None
58
  whale_monitor: EnhancedWhaleMonitor = None
59
  news_fetcher: NewsFetcher = None
@@ -64,19 +62,16 @@ sys_state: 'SystemState' = None
64
  # 🔄 حالة النظام (System State Tracker)
65
  # ==============================================================================
66
  class SystemState:
67
- """
68
- كلاس بسيط لتتبع حالة النظام العالمية (جاهزية، دورة، تدريب).
69
- """
70
  def __init__(self):
71
  self.ready = False
72
  self.cycle_running = False
73
  self.training_running = False # حالة التدريب النشط
74
- self.auto_pilot = True # التشغيل التلقائي مفعل افتراضياً
75
  self.last_cycle_time: datetime = None
76
  self.last_cycle_error = None
77
  self.app_start_time = datetime.now()
78
  self.last_cycle_logs = "النظام قيد التهيئة... يرجى الانتظار."
79
- self.training_status_msg = "Waiting for data..." # رسالة حالة التدريب
80
 
81
  def set_ready(self):
82
  self.ready = True
@@ -147,7 +142,6 @@ def calculate_duration_str(timestamp_str):
147
  async def auto_pilot_loop():
148
  """
149
  مراقب الخلفية: يفحص النظام كل 10 ثواني ويبدأ دورة البحث إذا كان الوضع آمناً.
150
- كما يقوم بتحديث حالة التدريب.
151
  """
152
  print("🤖 [Auto-Pilot] Daemon started running in background...")
153
  while True:
@@ -155,43 +149,38 @@ async def auto_pilot_loop():
155
  # فاصل زمني لحماية الموارد
156
  await asyncio.sleep(10)
157
 
158
- # التحقق من جاهزية النظام
159
  if not sys_state.ready: continue
160
 
161
- # 1. تحديث حالة جاهزية التدريب (للعرض في الواجهة فقط)
162
  if hub_manager:
163
  is_ready, msg = await hub_manager.check_training_readiness()
164
  sys_state.training_status_msg = msg
165
 
166
- # 2. منطق تشغيل الدورة (Trading Cycle)
167
- # الشروط: الطيار الآلي مفعل + لا دورة تعمل + لا تدريب يعمل
168
  if sys_state.auto_pilot and not sys_state.cycle_running and not sys_state.training_running:
169
- # إذا لم تكن هناك صفقات مفتوحة، نبدأ البحث
170
  if trade_manager and len(trade_manager.open_positions) == 0:
171
  asyncio.create_task(run_unified_cycle())
172
- # انتظار إضافي لمنع التداخل
173
  await asyncio.sleep(5)
174
  else:
175
- # في حال وجود صفقة، النظام في وضع "الحراسة" ولا نطلق دورات بحث جديدة
176
  pass
177
 
178
  except Exception as e:
179
  print(f"⚠️ [Auto-Pilot Error] {e}")
180
- # في حال الخطأ ننتظر فترة أطول
181
  await asyncio.sleep(30)
182
 
183
  # ==============================================================================
184
- # 🚀 Lifespan (بدء وإيقاف النظام)
185
  # ==============================================================================
186
  @asynccontextmanager
187
  async def lifespan(app: FastAPI):
188
  global r2, data_manager, ml_processor, hub_manager, trade_manager, whale_monitor, news_fetcher, senti_analyzer, sys_state
189
 
190
- print("\n🚀 [System] Startup Sequence Initiated (Titan V23.5 Enterprise)...")
191
  print("------------------------------------------------------")
192
 
193
  try:
194
- # 1. تهيئة طبقة البيانات والاتصال
195
  print(" [1/7] Initializing R2 & Data Services...")
196
  r2 = R2Service()
197
  data_manager = DataManager(contracts_db={}, whale_monitor=None, r2_service=r2)
@@ -199,40 +188,38 @@ async def lifespan(app: FastAPI):
199
  await data_manager.load_contracts_from_r2()
200
 
201
  # 2. الخدمات المساعدة
202
- print(" [2/7] Starting Auxiliary Services (Whales/News)...")
203
  whale_monitor = EnhancedWhaleMonitor(contracts_db=data_manager.get_contracts_db(), r2_service=r2)
204
  news_fetcher = NewsFetcher()
205
  senti_analyzer = SentimentIntensityAnalyzer()
206
  data_manager.whale_monitor = whale_monitor
207
 
208
- # 3. 🎓 تهيئة مركز التعلم (Learning Hub) - يجب أن يكون قبل المعالج
209
- print(" [3/7] Initializing Learning Hub (The Academy)...")
210
  hub_manager = LearningHubManager(r2_service=r2, data_manager=data_manager)
211
  await hub_manager.initialize()
212
 
213
- # 4. تهيئة المعالج المركزي (Brain)
214
- print(" [4/7] Initializing Central ML Processor (Titan/Oracle/Sniper)...")
215
  ml_processor = MLProcessor(data_manager=data_manager)
216
  await ml_processor.initialize()
217
 
218
- # 🔗 حقن Hub في Processor (للحصول على الأوزان المتكيفة)
219
  ml_processor.hub_manager = hub_manager
220
 
221
  # 5. تهيئة مدير التداول
222
- print(" [5/7] Initializing Trade Manager (The Executor)...")
223
  trade_manager = TradeManager(
224
  r2_service=r2,
225
  data_manager=data_manager,
226
- processor=ml_processor # نمرر المعالج فقط
227
  )
228
-
229
- # 🔗 حقن Hub في TradeManager (لإرسال الصفقات المغلقة للتعلم)
230
- # نقوم بذلك يدوياً لأن TradeManager يتوقع processor في الـ init
231
  trade_manager.learning_hub = hub_manager
232
 
233
  await trade_manager.initialize_sentry_exchanges()
234
 
235
- # 6. إعادة تشغيل حراسة الصفقات المفتوحة (إن وجدت)
236
  print(" [6/7] Restarting Active Sentries...")
237
  await trade_manager.start_sentry_loops()
238
 
@@ -255,9 +242,7 @@ async def lifespan(app: FastAPI):
255
  print("\n🛑 [System] Shutdown Sequence Initiated...")
256
  sys_state.ready = False
257
 
258
- # حفظ حالة التعلم قبل الإغلاق
259
  if hub_manager: await hub_manager.shutdown()
260
-
261
  if trade_manager: await trade_manager.stop_sentry_loops()
262
  if data_manager: await data_manager.close()
263
  print("✅ [System] Shutdown Complete.")
@@ -266,13 +251,9 @@ async def lifespan(app: FastAPI):
266
  # 🧠 Helper Task: Analyze Single Symbol
267
  # ==============================================================================
268
  async def _analyze_symbol_task(symbol: str) -> Dict[str, Any]:
269
- """
270
- مهمة لجلب بيانات عملة واحدة وإرسالها للمعالج (Processor) للحصول على التقييم المركب.
271
- """
272
  global data_manager, ml_processor
273
  try:
274
  required_tfs = ["5m", "15m", "1h", "4h", "1d"]
275
- # جلب البيانات بالتوازي
276
  data_tasks = [data_manager.get_latest_ohlcv(symbol, tf, limit=250) for tf in required_tfs]
277
  all_data = await asyncio.gather(*data_tasks)
278
 
@@ -280,14 +261,13 @@ async def _analyze_symbol_task(symbol: str) -> Dict[str, Any]:
280
  for tf, data in zip(required_tfs, all_data):
281
  if data and len(data) > 0: ohlcv_data[tf] = data
282
 
283
- # التحقق من توفر البيانات الأساسية
284
  if '5m' not in ohlcv_data or '15m' not in ohlcv_data or '1h' not in ohlcv_data:
285
  return None
286
 
287
  current_price = await data_manager.get_latest_price_async(symbol)
288
  raw_data = {'symbol': symbol, 'ohlcv': ohlcv_data, 'current_price': current_price}
289
 
290
- # ⚡ طلب التحليل من المعالج المركزي (L1/L2 Analysis) ⚡
291
  return await ml_processor.process_compound_signal(raw_data)
292
 
293
  except Exception:
@@ -297,48 +277,35 @@ async def _analyze_symbol_task(symbol: str) -> Dict[str, Any]:
297
  # 🚀 Unified Smart Cycle (Logic Flow)
298
  # ==============================================================================
299
  async def run_unified_cycle():
300
- """
301
- دورة العمل الرئيسية:
302
- 1. مزامنة الحالة.
303
- 2. إدارة الصفقات المفتوحة.
304
- 3. البحث (Screening).
305
- 4. التحليل (Analysis).
306
- 5. الاستشارة (Oracle).
307
- 6. التنفيذ (Sniper).
308
- """
309
  log_buffer = StringIO()
310
-
311
  def log_and_print(message):
312
  print(message)
313
  log_buffer.write(message + '\n')
314
 
315
- # التحقق من حالة الدورة
316
  if sys_state.cycle_running:
317
- log_and_print("⚠️ [Cycle] الدورة قيد التشغيل بالفعل. تم تجاهل الطلب.")
318
  return
319
 
320
  if sys_state.training_running:
321
- log_and_print("⚠️ [Cycle] النظام مشغول بالتدريب (Training in progress).")
322
  return
323
 
324
  if not sys_state.ready:
325
- log_and_print("⚠️ [Cycle] النظام غير جاهز بعد.")
326
  return
327
 
328
  sys_state.set_cycle_start()
329
  log_and_print(f"\n🌀 [Cycle START] {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
330
 
331
  try:
332
- # 0. مزامنة الحالة مع R2
333
  await trade_manager.sync_internal_state_with_r2()
334
 
335
- # 1. التحقق من الصفقات المفتوحة (Priority Management)
336
  if len(trade_manager.open_positions) > 0:
337
  symbol = list(trade_manager.open_positions.keys())[0]
338
  trade = trade_manager.open_positions[symbol]
339
- log_and_print(f"🔒 [Guardian Mode] صفقة نشطة: {symbol}. تخطي البحث للتركيز على الإدارة.")
340
 
341
- # عرض تقرير الحارس (للمعلومات فقط، التنفيذ يتم في الخلفية)
342
  try:
343
  t1 = data_manager.get_latest_ohlcv(symbol, '1m', 300)
344
  t5 = data_manager.get_latest_ohlcv(symbol, '5m', 200)
@@ -347,94 +314,79 @@ async def run_unified_cycle():
347
 
348
  if d1 and d5 and d15:
349
  entry_p = trade['entry_price']
350
- # ⚡ استشارة الحارس ⚡
351
  decision = ml_processor.consult_guardian(d1, d5, d15, entry_p)
352
  scores = decision.get('scores', {})
353
  log_and_print(f" 📊 [Guardian Report] Status: {decision.get('action')}")
354
- log_and_print(f" • V2 (Radar): {scores.get('v2',0):.4f}")
355
- log_and_print(f" • V3 (Sniper): {scores.get('v3',0):.4f}")
356
- log_and_print(f" • Reason: {decision.get('reason')}")
357
  except Exception as e:
358
- log_and_print(f" ⚠️ تعذر جلب تقرير الحارس المباشر: {e}")
359
 
360
  sys_state.set_cycle_end(logs=log_buffer.getvalue())
361
  return
362
 
363
- # 2. البحث الأولي (L1 Screening)
364
- log_and_print(" [1/4] 🔍 L1 Screening (Volume & Liquidity)...")
365
  candidates = await data_manager.layer1_rapid_screening()
366
 
367
  if not candidates:
368
- log_and_print("⚠️ [Cycle] لم يتم العثور على أي عملات تلبي شروط L1.")
369
  sys_state.set_cycle_end(logs=log_buffer.getvalue()); return
370
 
371
- # 3. التحليل المعمق (L2 Analysis - Titan/Patterns)
372
- log_and_print(f" [2/4] 🧠 L2 Deep Analysis for {len(candidates)} candidates...")
373
- analysis_start = time.time()
374
-
375
  tasks = [_analyze_symbol_task(c['symbol']) for c in candidates]
376
  results = await asyncio.gather(*tasks)
377
  valid_l2 = [res for res in results if res is not None]
378
 
379
- # ترتيب حسب الدرجة النهائية المعززة
380
  top_10 = sorted(valid_l2, key=lambda x: x.get('enhanced_final_score', 0.0), reverse=True)[:10]
381
 
382
- log_and_print(f" -> اكتمل التحليل في {time.time() - analysis_start:.2f} ثانية.")
383
 
384
  if not top_10:
385
- log_and_print("⚠️ [Cycle] لم تنجح أي عملة في تجاوز L2.")
386
  sys_state.set_cycle_end(logs=log_buffer.getvalue()); return
387
 
388
- # عرض الجدول
389
  log_and_print("\n" + "="*80)
390
- log_and_print(f"{'SYMBOL':<10} | {'FINAL SCORE':<12} | {'TITAN':<8} | {'PATT':<8} | {'MC':<8}")
391
  log_and_print("-" * 80)
392
  for c in top_10:
393
  comps = c.get('components', {})
394
  log_and_print(f"{c['symbol']:<10} | {c['enhanced_final_score']:.4f} | {comps.get('titan_score',0):.2f} | {comps.get('patterns_score',0):.2f} | {comps.get('mc_score',0):.2f}")
395
  log_and_print("="*80 + "\n")
396
 
397
- # 4. العقل الاحتمالي (L3 Oracle)
398
- log_and_print(f" [3/4] 🔮 L3 Oracle Consultation (Probabilistic Check)...")
399
  approved_signals = []
400
 
401
  for sig in top_10:
402
- # تصفية أولية
403
  if sig['enhanced_final_score'] < 0.60: continue
404
 
405
- # ⚡ استشارة Oracle عبر المعالج ⚡
406
  oracle_dec = await ml_processor.consult_oracle(sig)
407
 
408
  if oracle_dec.get('action') == 'WATCH':
409
- conf = oracle_dec.get('confidence', 0.0)
410
- log_and_print(f" ✅ APPROVED: {sig['symbol']} (Conf: {conf:.2f})")
411
-
412
- # إضافة الأهداف المقترحة
413
  sig['tp_price'] = oracle_dec.get('tp_price')
414
  sig['sl_price'] = oracle_dec.get('sl_price')
415
  approved_signals.append(sig)
416
  else:
417
  log_and_print(f" ❌ REJECTED: {sig['symbol']} ({oracle_dec.get('reason')})")
418
 
419
- # 5. القناص (L4 Sniper Execution)
420
  if approved_signals:
421
- log_and_print(f" [4/4] 🎯 L4 Sniper Execution Batch ({len(approved_signals)} signals)...")
422
-
423
- # التقاط مخرجات TradeManager لإضافتها للسجل
424
  tm_log_buffer = StringIO()
425
  with redirect_stdout(tm_log_buffer), redirect_stderr(tm_log_buffer):
426
- # TradeManager يستدعي القناص داخلياً عبر المعالج
427
  await trade_manager.select_and_execute_best_signal(approved_signals)
428
 
429
  tm_logs = tm_log_buffer.getvalue()
430
  print(tm_logs)
431
  log_buffer.write(tm_logs + '\n')
432
  else:
433
- log_and_print(" -> 🛑 لا توجد إشارات معتمدة من Oracle لإرسالها للقناص.")
434
 
435
- # تنظيف الذاكرة
436
  gc.collect()
437
- log_and_print(f"🌀 [Cycle END] {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
438
  sys_state.set_cycle_end(logs=log_buffer.getvalue())
439
 
440
  except Exception as e:
@@ -446,28 +398,23 @@ async def run_unified_cycle():
446
  # 🎓 Training Logic (منطق التدريب)
447
  # ==============================================================================
448
  async def trigger_training_cycle():
449
- """
450
- يتم استدعاؤه يدوياً من زر الواجهة لبدء التدريب.
451
- """
452
  if sys_state.cycle_running or len(trade_manager.open_positions) > 0:
453
- return "⚠️ Cannot start training while trading or scanning is active."
454
 
455
  if sys_state.training_running:
456
- return "⚠️ Training is already in progress."
457
 
458
- # ضبط الحالة
459
  sys_state.training_running = True
460
- msg = "⏳ Training Started... Check console logs for progress."
461
 
462
- # تشغيل التدريب في الخلفية
463
  asyncio.create_task(_run_training_bg())
464
  return msg
465
 
466
  async def _run_training_bg():
467
- print("\n🏋️‍♂️ [System] Starting Manual Training Cycle (Background Task)...")
468
  try:
469
  if hub_manager:
470
- # استدعاء المدير لتنفيذ الجلسة
471
  result_msg = await hub_manager.execute_training_session()
472
  print(f"🏋️‍♂️ [System] Training Result: {result_msg}")
473
  sys_state.last_cycle_logs = f"🎓 Training Report: {result_msg}"
@@ -477,53 +424,40 @@ async def _run_training_bg():
477
  print(f"❌ [System] Training Failed: {e}")
478
  traceback.print_exc()
479
  finally:
480
- # إعادة الحالة للوضع الطبيعي
481
  sys_state.training_running = False
482
  print("🏋️‍♂️ [System] Training Cycle Ended.")
483
 
484
  # ==============================================================================
485
- # 📊 [UI Logic] منطق العرض والتفاعل (Full Stats Restored)
486
  # ==============================================================================
487
 
488
  async def manual_close_current_trade():
489
- """زر الإغلاق اليدوي"""
490
  if not trade_manager or not trade_manager.open_positions:
491
- return "⚠️ لا توجد صفقة مفتوحة لإغلاقها."
492
-
493
  symbol = list(trade_manager.open_positions.keys())[0]
494
  await trade_manager.force_exit_by_manager(symbol, reason="MANUAL_UI_BUTTON")
495
- return f"✅ تم إرسال أمر إغلاق فوري لـ {symbol}."
496
 
497
  async def reset_stats_handler():
498
- """زر تصفير الإحصائيات"""
499
  if trade_manager and len(trade_manager.open_positions) > 0:
500
- return "⚠️ لا يمكن التصفير أثناء وجود صفقة مفتوحة. أغلقها أولاً."
501
-
502
  success = await r2.reset_all_stats_async()
503
- if success: return "✅ تم تصفير الحساب والسجلات بنجاح."
504
- else: return "❌ فشل عملية التصفير."
505
 
506
  async def toggle_auto_pilot(enable):
507
- """زر تبديل الطيار الآلي"""
508
  sys_state.auto_pilot = enable
509
  status = "مفعل (ON)" if enable else "متوقف (OFF)"
510
- return f"تم تغيير وضع الطيار الآلي إلى: {status}"
511
 
512
  async def run_cycle_from_gradio():
513
- """زر التشغيل اليدوي"""
514
  if sys_state.cycle_running: return "الدورة تعمل بالفعل."
515
  if sys_state.training_running: return "النظام مشغول بالتدريب."
516
-
517
- # تشغيل في الخلفية لعدم تجميد الواجهة
518
  asyncio.create_task(run_unified_cycle())
519
- return "🚀 تم إطلاق الدورة يدوياً... راجع السجلات."
520
 
521
  async def check_live_pnl_and_status(selected_view="Hybrid System"):
522
- """
523
- تحديث دوري للواجهة.
524
- يتم استدعاء هذه الدالة كل 3 ثواني لتحديث الشارت والأرقام.
525
- """
526
- # القيم الافتراضية في حال الخطأ أو التهيئة
527
  empty_chart = go.Figure()
528
  empty_chart.update_layout(
529
  template="plotly_dark", paper_bgcolor="#0b0f19", plot_bgcolor="#0b0f19",
@@ -536,12 +470,10 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
536
  return "Initializing...", "...", empty_chart, "0.0", "0.0", "0.0", "0.0", "0.0%", wl_df_empty, "Loading...", "Loading...", "Checking..."
537
 
538
  try:
539
- # 1. جلب بيانات المحفظة من R2
540
  portfolio = await r2.get_portfolio_state_async()
541
  curr_cap = portfolio.get('current_capital_usd', 100.0)
542
  first_ts = portfolio.get('first_trade_timestamp')
543
-
544
- # حساب وقت التشغيل
545
  uptime_str = calculate_duration_str(first_ts)
546
 
547
  total_t = portfolio.get('total_trades', 0)
@@ -554,7 +486,7 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
554
  net_prof = tot_prof - tot_loss
555
  win_rate = (wins / total_t * 100) if total_t > 0 else 0.0
556
 
557
- # 2. بيانات الصفقة النشطة (إن وجدت)
558
  symbol = None
559
  entry_p = 0.0; tp_p = 0.0; sl_p = 0.0; curr_p = 0.0
560
  pnl_val = 0.0; pnl_pct = 0.0
@@ -563,12 +495,10 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
563
  if trade_manager.open_positions:
564
  symbol = list(trade_manager.open_positions.keys())[0]
565
  trade = trade_manager.open_positions[symbol]
566
-
567
  entry_p = float(trade.get('entry_price', 0.0))
568
  tp_p = float(trade.get('tp_price', 0.0))
569
  sl_p = float(trade.get('sl_price', 0.0))
570
  trade_dur_str = calculate_duration_str(trade.get('entry_time'))
571
-
572
  curr_p = await data_manager.get_latest_price_async(symbol)
573
  if curr_p > 0 and entry_p > 0:
574
  pnl_pct = ((curr_p - entry_p) / entry_p) * 100
@@ -577,7 +507,7 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
577
  final_bal = curr_cap + pnl_val
578
  wallet_color = "#00ff00" if pnl_val >= 0 else "#ff0000"
579
 
580
- # 3. HTML المحفظة (Wallet Box) - تصميم كامل
581
  wallet_md = f"""
582
  <div style='background-color: #1a1a1a; padding: 15px; border-radius: 8px; border: 1px solid #333; text-align:center;'>
583
  <h3 style='margin:0; color:#888; font-size:14px;'>💰 Live Wallet</h3>
@@ -600,28 +530,13 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
600
  </div>
601
  """
602
 
603
- # 4. إحصائيات الذكاء الاصطناعي (Stats Box)
604
- # تحديد المفتاح بناءً على القائمة المنسدلة
605
- key_map = {
606
- "Hybrid System": "hybrid",
607
- "Model V2 (Radar)": "v2",
608
- "Model V3 (Sniper)": "v3"
609
- }
610
  target_key = key_map.get(selected_view, "hybrid")
611
-
612
  stats_data = trade_manager.ai_stats.get(target_key, {"total":0, "good":0, "saved":0.0, "missed":0.0})
613
-
614
  tot_ds = stats_data['total']
615
  ds_acc = (stats_data['good'] / tot_ds * 100) if tot_ds > 0 else 0.0
616
 
617
- # العنوان الديناميكي
618
- title_map = {
619
- "hybrid": "🧠 Hybrid Guardian IQ",
620
- "v2": "📡 Model V2 (Radar)",
621
- "v3": "🎯 Model V3 (Sniper)"
622
- }
623
- stats_title = title_map.get(target_key, "DeepSteward IQ")
624
-
625
  history_md = f"""
626
  <div style='background-color: #1a1a1a; padding: 10px; border-radius: 8px; border: 1px solid #333; font-size: 12px;'>
627
  <h3 style='margin:0 0 5px 0; color:#888; font-size:14px;'>📊 Performance</h3>
@@ -632,10 +547,8 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
632
  <tr><td style='padding:2px;'>Losses:</td><td style='text-align:right; color:#ff0000;'>{losses} (-${tot_loss:,.2f})</td></tr>
633
  <tr><td style='border-top:1px solid #444; padding-top:5px;'>Net Profit:</td><td style='border-top:1px solid #444; text-align:right; padding-top:5px; color:{"#00ff00" if net_prof>=0 else "#ff0000"};'>${net_prof:,.2f}</td></tr>
634
  </table>
635
-
636
  <hr style='border-color:#444; margin: 8px 0;'>
637
-
638
- <h3 style='margin:0 0 5px 0; color: #00e5ff; font-size:14px;'>{stats_title}</h3>
639
  <table style='width:100%; color:white;'>
640
  <tr><td>Interventions:</td><td style='text-align:right;'>{tot_ds}</td></tr>
641
  <tr><td>Accuracy:</td><td style='text-align:right; color:#00e5ff;'>{ds_acc:.1f}%</td></tr>
@@ -645,70 +558,45 @@ async def check_live_pnl_and_status(selected_view="Hybrid System"):
645
  </div>
646
  """
647
 
648
- # 5. الرسم البياني (Chart)
649
  fig = empty_chart
650
  if symbol and curr_p > 0:
651
  ohlcv = await data_manager.get_latest_ohlcv(symbol, '5m', 120)
652
- if ohlcv and len(ohlcv) > 0:
653
  df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
654
  df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
655
-
656
  fig = go.Figure(data=[go.Candlestick(
657
- x=df['datetime'],
658
- open=df['open'], high=df['high'], low=df['low'], close=df['close'],
659
- increasing_line_color='#00ff00', decreasing_line_color='#ff0000',
660
- name=symbol
661
  )])
662
-
663
- # خطوط المستويات
664
- fig.add_hline(y=entry_p, line_dash="dash", line_color="white", opacity=0.5, annotation_text="Entry")
665
  fig.add_hline(y=tp_p, line_color="#00ff00", line_width=1, annotation_text="TP")
666
  fig.add_hline(y=sl_p, line_color="#ff0000", line_width=1, annotation_text="SL")
 
 
 
667
 
668
- fig.update_layout(
669
- template="plotly_dark",
670
- paper_bgcolor="#0b0f19",
671
- plot_bgcolor="#0b0f19",
672
- margin=dict(l=0, r=50, t=30, b=0),
673
- height=400,
674
- xaxis_rangeslider_visible=False,
675
- title=dict(text=f"{symbol} (5m)", x=0.05, font=dict(color="white", size=14)),
676
- yaxis=dict(side='right', gridcolor='#222')
677
- )
678
-
679
- # 6. قائمة المراقبة (Watchlist)
680
  wl_data = [[k, f"{v.get('final_total_score',0):.2f}"] for k, v in trade_manager.watchlist.items()]
681
  wl_df = pd.DataFrame(wl_data, columns=["Coin", "Score"])
682
 
 
683
  status_txt = sys_state.last_cycle_logs
684
  status_line = f"Status: {'SCANNING' if sys_state.cycle_running else 'IDLE'} | Auto-Pilot: {'ON' if sys_state.auto_pilot else 'OFF'}"
685
 
686
- # 7. حالة التدريب
687
  train_status = sys_state.training_status_msg
688
  if sys_state.training_running:
689
  train_status = "🏋️‍♂️ Training In Progress (Please Wait)..."
690
 
691
- return (
692
- status_txt,
693
- status_line,
694
- fig,
695
- f"{curr_p:.6f}",
696
- f"{entry_p:.6f}",
697
- f"{tp_p:.6f}",
698
- f"{sl_p:.6f}",
699
- f"{pnl_pct:+.2f}%",
700
- wl_df,
701
- wallet_md,
702
- history_md,
703
- train_status
704
- )
705
 
706
  except Exception:
707
  traceback.print_exc()
708
  return "Error", "Error", empty_chart, "0", "0", "0", "0", "0%", wl_df_empty, "Err", "Err", "Err"
709
 
710
  # ==============================================================================
711
- # 🚀 Gradio UI Definition (The Dashboard)
712
  # ==============================================================================
713
  def create_gradio_ui():
714
  css = """
@@ -718,118 +606,97 @@ def create_gradio_ui():
718
  .html-box { min-height: 180px; }
719
  """
720
 
721
- with gr.Blocks(title="Titan V23.5 Pro Dashboard", css=css, theme=gr.themes.Monochrome()) as demo:
722
 
723
- gr.Markdown("# 🚀 Titan V23.5 Enterprise (Learning Core)")
724
 
725
- # --- الصف العلوي: الشارت + الإحصائيات ---
726
  with gr.Row():
727
- # العمود الأيسر: الشارت + تفاصيل السعر
728
  with gr.Column(scale=3):
729
  live_chart_plot = gr.Plot(label="Live Chart", container=True)
730
-
731
  with gr.Row():
732
  t_price = gr.Textbox(label="Current Price", interactive=False)
733
  t_pnl = gr.Textbox(label="PnL %", interactive=False)
734
-
735
  with gr.Row():
736
  t_entry = gr.Textbox(label="Entry", interactive=False)
737
  t_tp = gr.Textbox(label="Target (TP)", interactive=False)
738
  t_sl = gr.Textbox(label="Stop (SL)", interactive=False)
739
 
740
- # العمود الأيمن: المحفظة والإحصائيات
741
  with gr.Column(scale=1):
742
  wallet_output = gr.HTML(label="Wallet", elem_classes="html-box")
743
-
744
  stats_dropdown = gr.Dropdown(
745
  choices=["Hybrid System", "Model V2 (Radar)", "Model V3 (Sniper)"],
746
- value="Hybrid System",
747
- label="Select AI View",
748
- interactive=True
749
  )
750
-
751
  history_output = gr.HTML(label="Stats", elem_classes="html-box")
752
  watchlist_output = gr.DataFrame(label="Watchlist", interactive=False)
753
 
754
  gr.HTML("<hr style='border-color: #333;'>")
755
 
756
- # --- الصف السفلي: التحكم والسجلات والتدريب ---
757
  with gr.Row():
758
  with gr.Column(scale=1):
759
- gr.Markdown("## 🎮 Control & Learning")
760
-
761
- auto_pilot_checkbox = gr.Checkbox(
762
- label="✈️ Auto-Pilot",
763
- value=True
764
- )
765
 
766
  with gr.Row():
767
  run_cycle_btn = gr.Button("🚀 Scan Now", variant="primary")
768
  close_trade_btn = gr.Button("🚨 Panic Close", variant="stop")
769
 
770
  with gr.Row():
771
- # زر التدريب الجديد 🎓
772
  train_btn = gr.Button("🎓 Train Model", variant="secondary")
773
  reset_stats_btn = gr.Button("🗑️ Reset Stats")
774
 
775
  status_markdown = gr.Markdown("Initializing...")
776
-
777
- # صندوق حالة التدريب الجديد
778
  train_status_box = gr.Textbox(label="Learning Status", interactive=False, value="Checking data...")
779
  alert_box = gr.Textbox(label="Alerts", interactive=False, visible=True)
780
 
781
  with gr.Column(scale=3):
782
  gr.Markdown("## 📜 System Logs")
783
- cycle_logs_output = gr.Textbox(
784
- lines=12,
785
- autoscroll=True,
786
- max_lines=50,
787
- value="Waiting for logs..."
788
- )
789
 
790
- # --- التفاعلات (Events Wiring) ---
791
  run_cycle_btn.click(fn=run_cycle_from_gradio, inputs=None, outputs=alert_box)
792
  close_trade_btn.click(fn=manual_close_current_trade, inputs=None, outputs=alert_box)
793
  reset_stats_btn.click(fn=reset_stats_handler, inputs=None, outputs=alert_box)
794
  auto_pilot_checkbox.change(fn=toggle_auto_pilot, inputs=auto_pilot_checkbox, outputs=alert_box)
795
  train_btn.click(fn=trigger_training_cycle, inputs=None, outputs=alert_box)
796
 
797
- # المؤقت الدوري (كل 3 ثواني) - يجب أن يطابق عدد المخرجات
798
  timer = gr.Timer(3)
799
  timer.tick(
800
  fn=check_live_pnl_and_status,
801
  inputs=[stats_dropdown],
802
  outputs=[
803
- cycle_logs_output,
804
- status_markdown,
805
- live_chart_plot,
806
- t_price,
807
- t_entry,
808
- t_tp,
809
- t_sl,
810
- t_pnl,
811
- watchlist_output,
812
- wallet_output,
813
- history_output,
814
- train_status_box # المخرج الجديد
815
  ]
816
  )
817
 
818
  return demo
819
 
820
  # ==============================================================================
821
- # 🏁 تشغيل الخادم (Server Entry Point)
822
  # ==============================================================================
823
- app = FastAPI(
 
 
824
  lifespan=lifespan,
825
- title="Titan V23.5 Pro",
826
  description="Titan Enterprise Trading System"
827
  )
828
 
 
829
  gradio_dashboard = create_gradio_ui()
830
- app = gr.mount_gradio_app(app, gradio_dashboard, path="/")
 
 
 
 
 
 
831
 
832
  if __name__ == "__main__":
833
  import uvicorn
834
- # تشغيل الخادم على جميع الواجهات (0.0.0.0)
835
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
+ # app.py (V23.6 - GEM-Architect: Full Stable Enterprise Edition)
2
+ # يتضمن الحل الجذري لمشكلة التهيئة (Application Initialization Fix)
3
+ # وكافة وظائف النظام: التداول، التعلم، الواجهة، والمراقبة.
4
 
5
  import os
6
  import sys
 
34
  from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
35
 
36
  # 3. ⚡ المحرك المركزي (The Brain) ⚡
 
37
  from ml_engine.processor import MLProcessor
38
 
39
  # 4. 🎓 مركز التعلم (The Learning Hub) 🎓
 
40
  from learning_hub.hub_manager import LearningHubManager
41
 
42
  # 5. مدير التداول (The Executor)
43
  from trade_manager import TradeManager
44
 
45
  except ImportError as e:
 
46
  sys.exit(f"❌ [FATAL ERROR] Failed to import core modules: {e}")
47
 
48
  # ==============================================================================
 
51
  r2: R2Service = None
52
  data_manager: DataManager = None
53
  ml_processor: MLProcessor = None
54
+ hub_manager: LearningHubManager = None
55
  trade_manager: TradeManager = None
56
  whale_monitor: EnhancedWhaleMonitor = None
57
  news_fetcher: NewsFetcher = None
 
62
  # 🔄 حالة النظام (System State Tracker)
63
  # ==============================================================================
64
  class SystemState:
 
 
 
65
  def __init__(self):
66
  self.ready = False
67
  self.cycle_running = False
68
  self.training_running = False # حالة التدريب النشط
69
+ self.auto_pilot = True # التشغيل التلقائي مفعل
70
  self.last_cycle_time: datetime = None
71
  self.last_cycle_error = None
72
  self.app_start_time = datetime.now()
73
  self.last_cycle_logs = "النظام قيد التهيئة... يرجى الانتظار."
74
+ self.training_status_msg = "Waiting for data..."
75
 
76
  def set_ready(self):
77
  self.ready = True
 
142
  async def auto_pilot_loop():
143
  """
144
  مراقب الخلفية: يفحص النظام كل 10 ثواني ويبدأ دورة البحث إذا كان الوضع آمناً.
 
145
  """
146
  print("🤖 [Auto-Pilot] Daemon started running in background...")
147
  while True:
 
149
  # فاصل زمني لحماية الموارد
150
  await asyncio.sleep(10)
151
 
 
152
  if not sys_state.ready: continue
153
 
154
+ # 1. تحديث حالة جاهزية التدريب للعرض في الواجهة
155
  if hub_manager:
156
  is_ready, msg = await hub_manager.check_training_readiness()
157
  sys_state.training_status_msg = msg
158
 
159
+ # 2. منطق تشغيل الدورة
 
160
  if sys_state.auto_pilot and not sys_state.cycle_running and not sys_state.training_running:
 
161
  if trade_manager and len(trade_manager.open_positions) == 0:
162
  asyncio.create_task(run_unified_cycle())
 
163
  await asyncio.sleep(5)
164
  else:
165
+ # وضع الحراسة (Sentry Mode) لا يحتاج لإطلاق دورات بحث
166
  pass
167
 
168
  except Exception as e:
169
  print(f"⚠️ [Auto-Pilot Error] {e}")
 
170
  await asyncio.sleep(30)
171
 
172
  # ==============================================================================
173
+ # 🚀 Lifespan (تهيئة وإغلاق النظام)
174
  # ==============================================================================
175
  @asynccontextmanager
176
  async def lifespan(app: FastAPI):
177
  global r2, data_manager, ml_processor, hub_manager, trade_manager, whale_monitor, news_fetcher, senti_analyzer, sys_state
178
 
179
+ print("\n🚀 [System] Startup Sequence Initiated (Titan V23.6 Stable)...")
180
  print("------------------------------------------------------")
181
 
182
  try:
183
+ # 1. تهيئة طبقة البيانات
184
  print(" [1/7] Initializing R2 & Data Services...")
185
  r2 = R2Service()
186
  data_manager = DataManager(contracts_db={}, whale_monitor=None, r2_service=r2)
 
188
  await data_manager.load_contracts_from_r2()
189
 
190
  # 2. الخدمات المساعدة
191
+ print(" [2/7] Starting Auxiliary Services...")
192
  whale_monitor = EnhancedWhaleMonitor(contracts_db=data_manager.get_contracts_db(), r2_service=r2)
193
  news_fetcher = NewsFetcher()
194
  senti_analyzer = SentimentIntensityAnalyzer()
195
  data_manager.whale_monitor = whale_monitor
196
 
197
+ # 3. تهيئة مركز التعلم (Learning Hub)
198
+ print(" [3/7] Initializing Learning Hub...")
199
  hub_manager = LearningHubManager(r2_service=r2, data_manager=data_manager)
200
  await hub_manager.initialize()
201
 
202
+ # 4. تهيئة المعالج المركزي (Brain)
203
+ print(" [4/7] Initializing Central ML Processor...")
204
  ml_processor = MLProcessor(data_manager=data_manager)
205
  await ml_processor.initialize()
206
 
207
+ # 🔗 حقن Hub في Processor
208
  ml_processor.hub_manager = hub_manager
209
 
210
  # 5. تهيئة مدير التداول
211
+ print(" [5/7] Initializing Trade Manager...")
212
  trade_manager = TradeManager(
213
  r2_service=r2,
214
  data_manager=data_manager,
215
+ processor=ml_processor
216
  )
217
+ # 🔗 حقن Hub في TradeManager
 
 
218
  trade_manager.learning_hub = hub_manager
219
 
220
  await trade_manager.initialize_sentry_exchanges()
221
 
222
+ # 6. إعادة تشغيل الحراس
223
  print(" [6/7] Restarting Active Sentries...")
224
  await trade_manager.start_sentry_loops()
225
 
 
242
  print("\n🛑 [System] Shutdown Sequence Initiated...")
243
  sys_state.ready = False
244
 
 
245
  if hub_manager: await hub_manager.shutdown()
 
246
  if trade_manager: await trade_manager.stop_sentry_loops()
247
  if data_manager: await data_manager.close()
248
  print("✅ [System] Shutdown Complete.")
 
251
  # 🧠 Helper Task: Analyze Single Symbol
252
  # ==============================================================================
253
  async def _analyze_symbol_task(symbol: str) -> Dict[str, Any]:
 
 
 
254
  global data_manager, ml_processor
255
  try:
256
  required_tfs = ["5m", "15m", "1h", "4h", "1d"]
 
257
  data_tasks = [data_manager.get_latest_ohlcv(symbol, tf, limit=250) for tf in required_tfs]
258
  all_data = await asyncio.gather(*data_tasks)
259
 
 
261
  for tf, data in zip(required_tfs, all_data):
262
  if data and len(data) > 0: ohlcv_data[tf] = data
263
 
 
264
  if '5m' not in ohlcv_data or '15m' not in ohlcv_data or '1h' not in ohlcv_data:
265
  return None
266
 
267
  current_price = await data_manager.get_latest_price_async(symbol)
268
  raw_data = {'symbol': symbol, 'ohlcv': ohlcv_data, 'current_price': current_price}
269
 
270
+ # استدعاء المعالج للتحليل
271
  return await ml_processor.process_compound_signal(raw_data)
272
 
273
  except Exception:
 
277
  # 🚀 Unified Smart Cycle (Logic Flow)
278
  # ==============================================================================
279
  async def run_unified_cycle():
 
 
 
 
 
 
 
 
 
280
  log_buffer = StringIO()
 
281
  def log_and_print(message):
282
  print(message)
283
  log_buffer.write(message + '\n')
284
 
 
285
  if sys_state.cycle_running:
286
+ log_and_print("⚠️ [Cycle] الدورة قيد التشغيل بالفعل.")
287
  return
288
 
289
  if sys_state.training_running:
290
+ log_and_print("⚠️ [Cycle] النظام مشغول بالتدريب.")
291
  return
292
 
293
  if not sys_state.ready:
294
+ log_and_print("⚠️ [Cycle] النظام غير جاهز.")
295
  return
296
 
297
  sys_state.set_cycle_start()
298
  log_and_print(f"\n🌀 [Cycle START] {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
299
 
300
  try:
 
301
  await trade_manager.sync_internal_state_with_r2()
302
 
303
+ # 1. فحص الصفقات المفتوحة
304
  if len(trade_manager.open_positions) > 0:
305
  symbol = list(trade_manager.open_positions.keys())[0]
306
  trade = trade_manager.open_positions[symbol]
307
+ log_and_print(f"🔒 [Guardian Mode] صفقة نشطة: {symbol}. المراقبة جارية.")
308
 
 
309
  try:
310
  t1 = data_manager.get_latest_ohlcv(symbol, '1m', 300)
311
  t5 = data_manager.get_latest_ohlcv(symbol, '5m', 200)
 
314
 
315
  if d1 and d5 and d15:
316
  entry_p = trade['entry_price']
 
317
  decision = ml_processor.consult_guardian(d1, d5, d15, entry_p)
318
  scores = decision.get('scores', {})
319
  log_and_print(f" 📊 [Guardian Report] Status: {decision.get('action')}")
320
+ log_and_print(f" • V2: {scores.get('v2',0):.4f} | V3: {scores.get('v3',0):.4f}")
321
+ log_and_print(f" • Msg: {decision.get('reason')}")
 
322
  except Exception as e:
323
+ log_and_print(f" ⚠️ Guardian report check failed: {e}")
324
 
325
  sys_state.set_cycle_end(logs=log_buffer.getvalue())
326
  return
327
 
328
+ # 2. البحث الأولي (L1)
329
+ log_and_print(" [1/4] 🔍 L1 Screening (Liquidity)...")
330
  candidates = await data_manager.layer1_rapid_screening()
331
 
332
  if not candidates:
333
+ log_and_print("⚠️ [Cycle] لا توجد عملات مرشحة.")
334
  sys_state.set_cycle_end(logs=log_buffer.getvalue()); return
335
 
336
+ # 3. ال��حليل المعمق (L2)
337
+ log_and_print(f" [2/4] 🧠 L2 Deep Analysis ({len(candidates)} items)...")
 
 
338
  tasks = [_analyze_symbol_task(c['symbol']) for c in candidates]
339
  results = await asyncio.gather(*tasks)
340
  valid_l2 = [res for res in results if res is not None]
341
 
 
342
  top_10 = sorted(valid_l2, key=lambda x: x.get('enhanced_final_score', 0.0), reverse=True)[:10]
343
 
344
+ log_and_print(f" -> تم تحليل {len(valid_l2)} عملة بنجاح.")
345
 
346
  if not top_10:
347
+ log_and_print("⚠️ [Cycle] لم تنجح أي عملة في L2.")
348
  sys_state.set_cycle_end(logs=log_buffer.getvalue()); return
349
 
 
350
  log_and_print("\n" + "="*80)
351
+ log_and_print(f"{'SYMBOL':<10} | {'SCORE':<12} | {'TITAN':<8} | {'PATT':<8} | {'MC':<8}")
352
  log_and_print("-" * 80)
353
  for c in top_10:
354
  comps = c.get('components', {})
355
  log_and_print(f"{c['symbol']:<10} | {c['enhanced_final_score']:.4f} | {comps.get('titan_score',0):.2f} | {comps.get('patterns_score',0):.2f} | {comps.get('mc_score',0):.2f}")
356
  log_and_print("="*80 + "\n")
357
 
358
+ # 4. الاستشارة (L3 Oracle)
359
+ log_and_print(f" [3/4] 🔮 L3 Oracle Check...")
360
  approved_signals = []
361
 
362
  for sig in top_10:
 
363
  if sig['enhanced_final_score'] < 0.60: continue
364
 
 
365
  oracle_dec = await ml_processor.consult_oracle(sig)
366
 
367
  if oracle_dec.get('action') == 'WATCH':
368
+ log_and_print(f" ✅ APPROVED: {sig['symbol']} (Conf: {oracle_dec.get('confidence',0):.2f})")
 
 
 
369
  sig['tp_price'] = oracle_dec.get('tp_price')
370
  sig['sl_price'] = oracle_dec.get('sl_price')
371
  approved_signals.append(sig)
372
  else:
373
  log_and_print(f" ❌ REJECTED: {sig['symbol']} ({oracle_dec.get('reason')})")
374
 
375
+ # 5. التنفيذ (L4 Sniper)
376
  if approved_signals:
377
+ log_and_print(f" [4/4] 🎯 L4 Sniper Execution Batch...")
 
 
378
  tm_log_buffer = StringIO()
379
  with redirect_stdout(tm_log_buffer), redirect_stderr(tm_log_buffer):
 
380
  await trade_manager.select_and_execute_best_signal(approved_signals)
381
 
382
  tm_logs = tm_log_buffer.getvalue()
383
  print(tm_logs)
384
  log_buffer.write(tm_logs + '\n')
385
  else:
386
+ log_and_print(" -> 🛑 لا توجد إشارات معتمدة.")
387
 
 
388
  gc.collect()
389
+ log_and_print(f"🌀 [Cycle END] {datetime.now().strftime('%H:%M:%S')}")
390
  sys_state.set_cycle_end(logs=log_buffer.getvalue())
391
 
392
  except Exception as e:
 
398
  # 🎓 Training Logic (منطق التدريب)
399
  # ==============================================================================
400
  async def trigger_training_cycle():
401
+ """يتم استدعاؤه يدوياً من الزر لبدء التدريب"""
 
 
402
  if sys_state.cycle_running or len(trade_manager.open_positions) > 0:
403
+ return "⚠️ لا يمكن التدريب أثناء التداول أو البحث."
404
 
405
  if sys_state.training_running:
406
+ return "⚠️ التدريب يعمل بالفعل."
407
 
 
408
  sys_state.training_running = True
409
+ msg = "⏳ Training Started... Check console logs."
410
 
 
411
  asyncio.create_task(_run_training_bg())
412
  return msg
413
 
414
  async def _run_training_bg():
415
+ print("\n🏋️‍♂️ [System] Starting Manual Training Cycle...")
416
  try:
417
  if hub_manager:
 
418
  result_msg = await hub_manager.execute_training_session()
419
  print(f"🏋️‍♂️ [System] Training Result: {result_msg}")
420
  sys_state.last_cycle_logs = f"🎓 Training Report: {result_msg}"
 
424
  print(f"❌ [System] Training Failed: {e}")
425
  traceback.print_exc()
426
  finally:
 
427
  sys_state.training_running = False
428
  print("🏋️‍♂️ [System] Training Cycle Ended.")
429
 
430
  # ==============================================================================
431
+ # 📊 [UI Logic] منطق العرض والتفاعل (Full Stats)
432
  # ==============================================================================
433
 
434
  async def manual_close_current_trade():
 
435
  if not trade_manager or not trade_manager.open_positions:
436
+ return "⚠️ لا توجد صفقة مفتوحة."
 
437
  symbol = list(trade_manager.open_positions.keys())[0]
438
  await trade_manager.force_exit_by_manager(symbol, reason="MANUAL_UI_BUTTON")
439
+ return f"✅ تم إرسال أمر إغلاق لـ {symbol}."
440
 
441
  async def reset_stats_handler():
 
442
  if trade_manager and len(trade_manager.open_positions) > 0:
443
+ return "⚠️ أغلق الصفقة أولاً."
 
444
  success = await r2.reset_all_stats_async()
445
+ if success: return "✅ تم التصفير بنجاح."
446
+ else: return "❌ فشل التصفير."
447
 
448
  async def toggle_auto_pilot(enable):
 
449
  sys_state.auto_pilot = enable
450
  status = "مفعل (ON)" if enable else "متوقف (OFF)"
451
+ return f"الطيار الآلي: {status}"
452
 
453
  async def run_cycle_from_gradio():
 
454
  if sys_state.cycle_running: return "الدورة تعمل بالفعل."
455
  if sys_state.training_running: return "النظام مشغول بالتدريب."
 
 
456
  asyncio.create_task(run_unified_cycle())
457
+ return "🚀 تم الإطلاق يدوياً..."
458
 
459
  async def check_live_pnl_and_status(selected_view="Hybrid System"):
460
+ # تهيئة المخرجات الافتراضية
 
 
 
 
461
  empty_chart = go.Figure()
462
  empty_chart.update_layout(
463
  template="plotly_dark", paper_bgcolor="#0b0f19", plot_bgcolor="#0b0f19",
 
470
  return "Initializing...", "...", empty_chart, "0.0", "0.0", "0.0", "0.0", "0.0%", wl_df_empty, "Loading...", "Loading...", "Checking..."
471
 
472
  try:
473
+ # 1. بيانات المحفظة
474
  portfolio = await r2.get_portfolio_state_async()
475
  curr_cap = portfolio.get('current_capital_usd', 100.0)
476
  first_ts = portfolio.get('first_trade_timestamp')
 
 
477
  uptime_str = calculate_duration_str(first_ts)
478
 
479
  total_t = portfolio.get('total_trades', 0)
 
486
  net_prof = tot_prof - tot_loss
487
  win_rate = (wins / total_t * 100) if total_t > 0 else 0.0
488
 
489
+ # 2. الصفقة النشطة
490
  symbol = None
491
  entry_p = 0.0; tp_p = 0.0; sl_p = 0.0; curr_p = 0.0
492
  pnl_val = 0.0; pnl_pct = 0.0
 
495
  if trade_manager.open_positions:
496
  symbol = list(trade_manager.open_positions.keys())[0]
497
  trade = trade_manager.open_positions[symbol]
 
498
  entry_p = float(trade.get('entry_price', 0.0))
499
  tp_p = float(trade.get('tp_price', 0.0))
500
  sl_p = float(trade.get('sl_price', 0.0))
501
  trade_dur_str = calculate_duration_str(trade.get('entry_time'))
 
502
  curr_p = await data_manager.get_latest_price_async(symbol)
503
  if curr_p > 0 and entry_p > 0:
504
  pnl_pct = ((curr_p - entry_p) / entry_p) * 100
 
507
  final_bal = curr_cap + pnl_val
508
  wallet_color = "#00ff00" if pnl_val >= 0 else "#ff0000"
509
 
510
+ # 3. HTML المحفظة
511
  wallet_md = f"""
512
  <div style='background-color: #1a1a1a; padding: 15px; border-radius: 8px; border: 1px solid #333; text-align:center;'>
513
  <h3 style='margin:0; color:#888; font-size:14px;'>💰 Live Wallet</h3>
 
530
  </div>
531
  """
532
 
533
+ # 4. HTML الإحصائيات
534
+ key_map = {"Hybrid System": "hybrid", "Model V2 (Radar)": "v2", "Model V3 (Sniper)": "v3"}
 
 
 
 
 
535
  target_key = key_map.get(selected_view, "hybrid")
 
536
  stats_data = trade_manager.ai_stats.get(target_key, {"total":0, "good":0, "saved":0.0, "missed":0.0})
 
537
  tot_ds = stats_data['total']
538
  ds_acc = (stats_data['good'] / tot_ds * 100) if tot_ds > 0 else 0.0
539
 
 
 
 
 
 
 
 
 
540
  history_md = f"""
541
  <div style='background-color: #1a1a1a; padding: 10px; border-radius: 8px; border: 1px solid #333; font-size: 12px;'>
542
  <h3 style='margin:0 0 5px 0; color:#888; font-size:14px;'>📊 Performance</h3>
 
547
  <tr><td style='padding:2px;'>Losses:</td><td style='text-align:right; color:#ff0000;'>{losses} (-${tot_loss:,.2f})</td></tr>
548
  <tr><td style='border-top:1px solid #444; padding-top:5px;'>Net Profit:</td><td style='border-top:1px solid #444; text-align:right; padding-top:5px; color:{"#00ff00" if net_prof>=0 else "#ff0000"};'>${net_prof:,.2f}</td></tr>
549
  </table>
 
550
  <hr style='border-color:#444; margin: 8px 0;'>
551
+ <h3 style='margin:0 0 5px 0; color: #00e5ff; font-size:14px;'>🧠 AI IQ ({target_key})</h3>
 
552
  <table style='width:100%; color:white;'>
553
  <tr><td>Interventions:</td><td style='text-align:right;'>{tot_ds}</td></tr>
554
  <tr><td>Accuracy:</td><td style='text-align:right; color:#00e5ff;'>{ds_acc:.1f}%</td></tr>
 
558
  </div>
559
  """
560
 
561
+ # 5. الشارت
562
  fig = empty_chart
563
  if symbol and curr_p > 0:
564
  ohlcv = await data_manager.get_latest_ohlcv(symbol, '5m', 120)
565
+ if ohlcv:
566
  df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
567
  df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
 
568
  fig = go.Figure(data=[go.Candlestick(
569
+ x=df['datetime'], open=df['open'], high=df['high'], low=df['low'], close=df['close'],
570
+ increasing_line_color='#00ff00', decreasing_line_color='#ff0000', name=symbol
 
 
571
  )])
572
+ fig.add_hline(y=entry_p, line_dash="dash", line_color="white", annotation_text="Entry")
 
 
573
  fig.add_hline(y=tp_p, line_color="#00ff00", line_width=1, annotation_text="TP")
574
  fig.add_hline(y=sl_p, line_color="#ff0000", line_width=1, annotation_text="SL")
575
+ fig.update_layout(template="plotly_dark", paper_bgcolor="#0b0f19", plot_bgcolor="#0b0f19",
576
+ margin=dict(l=0, r=50, t=30, b=0), height=400, xaxis_rangeslider_visible=False,
577
+ title=dict(text=f"{symbol} (5m)", font=dict(color="white")))
578
 
579
+ # 6. Watchlist
 
 
 
 
 
 
 
 
 
 
 
580
  wl_data = [[k, f"{v.get('final_total_score',0):.2f}"] for k, v in trade_manager.watchlist.items()]
581
  wl_df = pd.DataFrame(wl_data, columns=["Coin", "Score"])
582
 
583
+ # 7. الحالة
584
  status_txt = sys_state.last_cycle_logs
585
  status_line = f"Status: {'SCANNING' if sys_state.cycle_running else 'IDLE'} | Auto-Pilot: {'ON' if sys_state.auto_pilot else 'OFF'}"
586
 
 
587
  train_status = sys_state.training_status_msg
588
  if sys_state.training_running:
589
  train_status = "🏋️‍♂️ Training In Progress (Please Wait)..."
590
 
591
+ return (status_txt, status_line, fig, f"{curr_p:.6f}", f"{entry_p:.6f}", f"{tp_p:.6f}", f"{sl_p:.6f}",
592
+ f"{pnl_pct:+.2f}%", wl_df, wallet_md, history_md, train_status)
 
 
 
 
 
 
 
 
 
 
 
 
593
 
594
  except Exception:
595
  traceback.print_exc()
596
  return "Error", "Error", empty_chart, "0", "0", "0", "0", "0%", wl_df_empty, "Err", "Err", "Err"
597
 
598
  # ==============================================================================
599
+ # 🚀 Gradio UI Definition
600
  # ==============================================================================
601
  def create_gradio_ui():
602
  css = """
 
606
  .html-box { min-height: 180px; }
607
  """
608
 
609
+ with gr.Blocks(title="Titan V23.6 Pro Dashboard", css=css, theme=gr.themes.Monochrome()) as demo:
610
 
611
+ gr.Markdown("# 🚀 Titan V23.6 Enterprise (Full Stats & Learning)")
612
 
 
613
  with gr.Row():
 
614
  with gr.Column(scale=3):
615
  live_chart_plot = gr.Plot(label="Live Chart", container=True)
 
616
  with gr.Row():
617
  t_price = gr.Textbox(label="Current Price", interactive=False)
618
  t_pnl = gr.Textbox(label="PnL %", interactive=False)
 
619
  with gr.Row():
620
  t_entry = gr.Textbox(label="Entry", interactive=False)
621
  t_tp = gr.Textbox(label="Target (TP)", interactive=False)
622
  t_sl = gr.Textbox(label="Stop (SL)", interactive=False)
623
 
 
624
  with gr.Column(scale=1):
625
  wallet_output = gr.HTML(label="Wallet", elem_classes="html-box")
 
626
  stats_dropdown = gr.Dropdown(
627
  choices=["Hybrid System", "Model V2 (Radar)", "Model V3 (Sniper)"],
628
+ value="Hybrid System", label="Select AI View", interactive=True
 
 
629
  )
 
630
  history_output = gr.HTML(label="Stats", elem_classes="html-box")
631
  watchlist_output = gr.DataFrame(label="Watchlist", interactive=False)
632
 
633
  gr.HTML("<hr style='border-color: #333;'>")
634
 
 
635
  with gr.Row():
636
  with gr.Column(scale=1):
637
+ gr.Markdown("## 🎮 Controls & Learning")
638
+ auto_pilot_checkbox = gr.Checkbox(label="✈️ Auto-Pilot", value=True)
 
 
 
 
639
 
640
  with gr.Row():
641
  run_cycle_btn = gr.Button("🚀 Scan Now", variant="primary")
642
  close_trade_btn = gr.Button("🚨 Panic Close", variant="stop")
643
 
644
  with gr.Row():
 
645
  train_btn = gr.Button("🎓 Train Model", variant="secondary")
646
  reset_stats_btn = gr.Button("🗑️ Reset Stats")
647
 
648
  status_markdown = gr.Markdown("Initializing...")
 
 
649
  train_status_box = gr.Textbox(label="Learning Status", interactive=False, value="Checking data...")
650
  alert_box = gr.Textbox(label="Alerts", interactive=False, visible=True)
651
 
652
  with gr.Column(scale=3):
653
  gr.Markdown("## 📜 System Logs")
654
+ cycle_logs_output = gr.Textbox(lines=12, autoscroll=True, max_lines=50, value="Waiting for logs...")
 
 
 
 
 
655
 
656
+ # التفاعلات
657
  run_cycle_btn.click(fn=run_cycle_from_gradio, inputs=None, outputs=alert_box)
658
  close_trade_btn.click(fn=manual_close_current_trade, inputs=None, outputs=alert_box)
659
  reset_stats_btn.click(fn=reset_stats_handler, inputs=None, outputs=alert_box)
660
  auto_pilot_checkbox.change(fn=toggle_auto_pilot, inputs=auto_pilot_checkbox, outputs=alert_box)
661
  train_btn.click(fn=trigger_training_cycle, inputs=None, outputs=alert_box)
662
 
663
+ # المؤقت
664
  timer = gr.Timer(3)
665
  timer.tick(
666
  fn=check_live_pnl_and_status,
667
  inputs=[stats_dropdown],
668
  outputs=[
669
+ cycle_logs_output, status_markdown, live_chart_plot,
670
+ t_price, t_entry, t_tp, t_sl, t_pnl,
671
+ watchlist_output, wallet_output, history_output,
672
+ train_status_box
 
 
 
 
 
 
 
 
673
  ]
674
  )
675
 
676
  return demo
677
 
678
  # ==============================================================================
679
+ # 🏁 تشغيل الخادم (The Initialization Fix)
680
  # ==============================================================================
681
+
682
+ # 1. إنشاء تطبيق FastAPI الأساسي
683
+ fast_api_server = FastAPI(
684
  lifespan=lifespan,
685
+ title="Titan V23.6 Pro",
686
  description="Titan Enterprise Trading System"
687
  )
688
 
689
+ # 2. إنشاء الواجهة
690
  gradio_dashboard = create_gradio_ui()
691
+
692
+ # 3. دمج الواجهة مع الخادم
693
+ app = gr.mount_gradio_app(
694
+ app=fast_api_server,
695
+ blocks=gradio_dashboard,
696
+ path="/"
697
+ )
698
 
699
  if __name__ == "__main__":
700
  import uvicorn
701
+ # تشغيل الخادم
702
  uvicorn.run(app, host="0.0.0.0", port=7860)