Nexo-S commited on
Commit
d40ef29
·
verified ·
1 Parent(s): e57dc91

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -7
app.py CHANGED
@@ -455,9 +455,38 @@ def run_judge_api():
455
  try:
456
  with sqlite3.connect(DB_NAME, timeout=10) as conn:
457
  conn.row_factory, cursor = sqlite3.Row, conn.cursor()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  cursor.execute("SELECT * FROM signals WHERE status = 'EN_COURS' AND confirmed = 1")
459
  trades = cursor.fetchall()
460
- if not trades: return {"status": "waiting"}
 
 
 
 
461
  closed_trades = []
462
  for t in trades:
463
  try:
@@ -474,17 +503,36 @@ def run_judge_api():
474
 
475
  sl_dyn, peak = t['sl'], t['peak_price']
476
  new_peak = max(peak, current_price) if t['direction'] == 'HAUSSIER' else min(peak, current_price)
477
- progression = abs(current_price - t['price']) / abs(t['tp'] - t['price']) if abs(t['tp'] - t['price']) > 0 else 0
 
 
 
478
 
479
  nouveau_sl = sl_dyn
 
 
 
480
  if t['direction'] == 'HAUSSIER':
481
- if progression >= 0.75: nouveau_sl = max(sl_dyn, t['price'] + (abs(t['tp'] - t['price']) * 0.60))
482
- elif progression >= 0.50: nouveau_sl = max(sl_dyn, t['price'] + (abs(t['tp'] - t['price']) * 0.25))
 
 
 
 
 
 
483
  else:
484
- if progression >= 0.75: nouveau_sl = min(sl_dyn, t['price'] - (abs(t['tp'] - t['price']) * 0.60))
485
- elif progression >= 0.50: nouveau_sl = min(sl_dyn, t['price'] - (abs(t['tp'] - t['price']) * 0.25))
 
 
 
 
 
 
486
 
487
  cursor.execute("UPDATE signals SET peak_price = ?, sl = ? WHERE id = ?", (new_peak, nouveau_sl, t['id']))
 
488
  outcome, reward = None, 0
489
  if t['direction'] == 'HAUSSIER':
490
  if current_price >= t['tp']: outcome, reward = "GAGNÉ ✅", 3
@@ -497,7 +545,9 @@ def run_judge_api():
497
  mutate_agent(t['symbol'], t['timeframe'], t['regime'], success=(reward>0))
498
  cursor.execute("UPDATE signals SET status=? WHERE id=?", (outcome, t['id']))
499
  closed_trades.append({"symbol": t['symbol'], "id": t['id']})
500
- except: pass
 
 
501
  conn.commit()
502
  return {"status": "updates", "data": closed_trades} if closed_trades else {"status": "waiting"}
503
  except Exception as e: return {"status": "error", "message": str(e)}
 
455
  try:
456
  with sqlite3.connect(DB_NAME, timeout=10) as conn:
457
  conn.row_factory, cursor = sqlite3.Row, conn.cursor()
458
+
459
+ # ==============================================================
460
+ # 🧹 1. PURGE DES SIGNAUX ORPHELINS (Le Bras était éteint)
461
+ # ==============================================================
462
+ cursor.execute("SELECT id, date, timeframe FROM signals WHERE status = 'EN_COURS' AND confirmed = 0")
463
+ orphelins = cursor.fetchall()
464
+ current_time = datetime.now(timezone.utc)
465
+ max_age_minutes = {"1m": 15, "5m": 20, "15m": 30, "1h": 60}
466
+
467
+ for o in orphelins:
468
+ try:
469
+ date_str = o['date'].replace('Z', '+00:00')
470
+ signal_time = datetime.fromisoformat(date_str)
471
+ age_minutes = (current_time - signal_time).total_seconds() / 60.0
472
+ max_age = max_age_minutes.get(o['timeframe'], 60)
473
+
474
+ if age_minutes > max_age:
475
+ cursor.execute("UPDATE signals SET status = 'EXPIRÉ ⏰' WHERE id = ?", (o['id'],))
476
+ print(f"🧹 [PURGE] Signal ID {o['id']} ({o['timeframe']}) annulé. Âge: {int(age_minutes)}m > Limite: {max_age}m.")
477
+ except Exception:
478
+ pass
479
+
480
+ # ==============================================================
481
+ # ⚖️ 2. JUGEMENT DES TRADES ACTIFS (Trailing Stop Complet)
482
+ # ==============================================================
483
  cursor.execute("SELECT * FROM signals WHERE status = 'EN_COURS' AND confirmed = 1")
484
  trades = cursor.fetchall()
485
+
486
+ if not trades:
487
+ conn.commit()
488
+ return {"status": "waiting"}
489
+
490
  closed_trades = []
491
  for t in trades:
492
  try:
 
503
 
504
  sl_dyn, peak = t['sl'], t['peak_price']
505
  new_peak = max(peak, current_price) if t['direction'] == 'HAUSSIER' else min(peak, current_price)
506
+
507
+ # Calcul de la progression (0 à 1)
508
+ dist_totale = abs(t['tp'] - t['price'])
509
+ progression = abs(current_price - t['price']) / dist_totale if dist_totale > 0 else 0
510
 
511
  nouveau_sl = sl_dyn
512
+ dist_sl_initial = abs(t['price'] - sl_dyn)
513
+
514
+ # 🛡️ LOGIQUE DU TRAILING STOP À 4 PALIERS
515
  if t['direction'] == 'HAUSSIER':
516
+ if progression >= 0.75:
517
+ nouveau_sl = max(sl_dyn, t['price'] + (dist_totale * 0.60)) # Sécurise 60% du gain
518
+ elif progression >= 0.50:
519
+ nouveau_sl = max(sl_dyn, t['price'] + (dist_totale * 0.25)) # Sécurise 25% du gain
520
+ elif progression >= 0.30:
521
+ nouveau_sl = max(sl_dyn, t['price'] + (dist_totale * 0.05)) # Breakeven + frais
522
+ elif progression >= 0.10:
523
+ nouveau_sl = max(sl_dyn, t['price'] - (dist_sl_initial * 0.50)) # Réduit le risque de 50%
524
  else:
525
+ if progression >= 0.75:
526
+ nouveau_sl = min(sl_dyn, t['price'] - (dist_totale * 0.60))
527
+ elif progression >= 0.50:
528
+ nouveau_sl = min(sl_dyn, t['price'] - (dist_totale * 0.25))
529
+ elif progression >= 0.30:
530
+ nouveau_sl = min(sl_dyn, t['price'] - (dist_totale * 0.05))
531
+ elif progression >= 0.10:
532
+ nouveau_sl = min(sl_dyn, t['price'] + (dist_sl_initial * 0.50))
533
 
534
  cursor.execute("UPDATE signals SET peak_price = ?, sl = ? WHERE id = ?", (new_peak, nouveau_sl, t['id']))
535
+
536
  outcome, reward = None, 0
537
  if t['direction'] == 'HAUSSIER':
538
  if current_price >= t['tp']: outcome, reward = "GAGNÉ ✅", 3
 
545
  mutate_agent(t['symbol'], t['timeframe'], t['regime'], success=(reward>0))
546
  cursor.execute("UPDATE signals SET status=? WHERE id=?", (outcome, t['id']))
547
  closed_trades.append({"symbol": t['symbol'], "id": t['id']})
548
+ except Exception:
549
+ pass
550
+
551
  conn.commit()
552
  return {"status": "updates", "data": closed_trades} if closed_trades else {"status": "waiting"}
553
  except Exception as e: return {"status": "error", "message": str(e)}