import sqlite3 import os import numpy as np DB_FILE = "alphatrade_v31_dino.db" # 🦖 Base de données V30/V33 def get_dynamic_weights(symbol, timeframe, regime): # 1. Poids de base selon le timeframe if timeframe in ["1m", "5m"]: w_time, w_ml, w_dino, w_sent = 0.50, 0.25, 0.15, 0.10 else: w_time, w_ml, w_dino, w_sent = 0.30, 0.30, 0.25, 0.15 # 2. Ajustement contextuel (Régime de marché) if regime == 0: w_dino += 0.05; w_ml -= 0.05 elif regime == 1: w_time += 0.05; w_dino -= 0.05 elif regime == 2: w_ml += 0.05; w_time -= 0.05 if not os.path.exists(DB_FILE): total = w_time + w_ml + w_dino + w_sent return w_time/total, w_ml/total, w_dino/total, w_sent/total try: with sqlite3.connect(DB_FILE, timeout=2) as conn: cursor = conn.cursor() # On cherche les 10 derniers trades clôturés (vrai résultat) cursor.execute('''SELECT direction, status, prob_time, prob_ml, prob_lstm FROM signals WHERE symbol=? AND timeframe=? AND (status LIKE '%GAGNÉ%' OR status LIKE '%PERDU%') ORDER BY id DESC LIMIT 10''', (symbol, timeframe)) trades = cursor.fetchall() # 3. AUTO-LEARNING (Le juge des cerveaux) if len(trades) >= 3: time_score, ml_score, dino_score = 0, 0, 0 for t in trades: direction, status, p_time, p_ml, p_dino = t # Le marché a-t-il vraiment pump ou dump ? actual_up = ('GAGNÉ' in status and direction == 'HAUSSIER') or ('PERDU' in status and direction == 'BAISSIER') # Distribution des bons points if (p_time > 0.5) == actual_up: time_score += 1 if (p_ml > 0.5) == actual_up: ml_score += 1 if (p_dino > 0.5) == actual_up: dino_score += 1 # 4. REWARD : On booste le meilleur cerveau if time_score > ml_score + 2 and time_score > dino_score + 2: w_time += 0.10; w_ml -= 0.05; w_dino -= 0.05 elif dino_score > time_score + 2 and dino_score > ml_score + 2: w_dino += 0.10; w_time -= 0.05; w_ml -= 0.05 elif ml_score > dino_score + 2 and ml_score > time_score + 2: w_ml += 0.10; w_dino -= 0.05; w_time -= 0.05 except Exception as e: print(f"⚠️ Erreur Auto-Learning Ensemble : {e}") # 🛡️ SÉCURITÉ V33 : On empêche les poids de tomber à 0 ou en négatif w_time, w_ml, w_dino, w_sent = max(0.05, w_time), max(0.05, w_ml), max(0.05, w_dino), max(0.05, w_sent) # Normalisation stricte pour que la somme fasse exactement 1.0 total = w_time + w_ml + w_dino + w_sent return w_time/total, w_ml/total, w_dino/total, w_sent/total def combine_scores(symbol, timeframe, t, m, dino, sent, r): # Récupération des poids intelligents w_t, w_m, w_d, w_s = get_dynamic_weights(symbol, timeframe, r) # Si le sentiment est parfaitement neutre (0.5), on l'exclut et on redistribue if sent == 0.5: w_s = 0.0 total = w_t + w_m + w_d w_t, w_m, w_d = w_t/total, w_m/total, w_d/total # L'équation finale de l'Ensemble final_p = (t * w_t) + (m * w_m) + (dino * w_d) + (sent * w_s) # 🛡️ PROTECTION ANTI-CRASH V33 if np.isnan(final_p) or np.isinf(final_p): final_p = 0.5 # 🛑 GARDE-FOU TENDANCE : Empêche l'IA de shorter un Bull Run ou longer un Bear Run if r == 0 and final_p < 0.45: final_p = 0.45 elif r == 1 and final_p > 0.55: final_p = 0.55 return final_p, w_t, w_m, w_d, w_s