File size: 3,729 Bytes
afc794c
 
59e2e55
afc794c
59e2e55
afc794c
d2bc16a
59e2e55
d2bc16a
719f972
d2bc16a
719f972
afc794c
59e2e55
236992b
 
 
d2bc16a
 
59e2e55
 
afc794c
 
d2bc16a
 
59e2e55
d2bc16a
 
 
 
afc794c
59e2e55
afc794c
719f972
afc794c
719f972
59e2e55
d2bc16a
afc794c
59e2e55
afc794c
 
719f972
afc794c
59e2e55
719f972
 
 
 
 
 
59e2e55
d2bc16a
59e2e55
 
 
 
afc794c
59e2e55
719f972
 
d2bc16a
719f972
59e2e55
719f972
afc794c
59e2e55
d2bc16a
 
719f972
 
d2bc16a
59e2e55
719f972
d2bc16a
59e2e55
 
 
 
 
236992b
 
afc794c
719f972
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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