Spaces:
Sleeping
Sleeping
| 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 |