import pandas as pd import pandas_ta as ta import xgboost as xgb import joblib import os TIME_MODEL_FILE = "time_model.pkl" def prepare_time_features(df): """ Génère les 'Lags' et l'intelligence temporelle pour XGBoost. C'est ici qu'on capture la dynamique du prix sans faire pleurer ton CPU. """ df = df.copy() # 1. Momentum & Retours (La dynamique de la tendance) df['return_1h'] = df['close'].pct_change(1) df['return_3h'] = df['close'].pct_change(3) df['return_12h'] = df['close'].pct_change(12) # 2. Lags (Mémoire du marché : Que faisait le RSI il y a 1h et 2h ?) df['RSI_lag1'] = df.ta.rsi(length=14).shift(1) df['RSI_lag2'] = df.ta.rsi(length=14).shift(2) # 3. Ratio de Volume (LE SIGNAL DES PROS) # Est-ce que le volume actuel est anormalement élevé par rapport aux 20 dernières heures ? df['vol_mean_20'] = df['vol'].rolling(20).mean() df['VOL_RATIO'] = df['vol'] / df['vol_mean_20'] df['vol_lag1'] = df['vol'].shift(1) # 4. Target (Ce qu'on veut prédire : la prochaine bougie sera-t-elle verte ?) # 1 = Hausse, 0 = Baisse df['target'] = (df['close'].shift(-1) > df['close']).astype(int) # Nettoyage des cases vides (NaN) créées par les calculs du passé df = df.dropna() # Les colonnes que XGBoost va regarder features = [ 'return_1h', 'return_3h', 'return_12h', 'RSI_lag1', 'RSI_lag2', 'vol_lag1', 'VOL_RATIO' ] return df[features], df['target'] def train_time_model(df): """ Entraîne le modèle XGBoost. Ultra-rapide, optimisé pour les 4 threads de ton i7-6500U ! """ print("⏳ [V9] Entraînement du Time Engine (XGBoost) en cours...") X, y = prepare_time_features(df) # Paramétrage Quant : # max_depth=4 (pour ne pas overfitter le bruit de la crypto) # n_jobs=-1 (utilise 100% de ton CPU pendant quelques secondes) model = xgb.XGBClassifier( n_estimators=100, max_depth=4, learning_rate=0.05, objective='binary:logistic', eval_metric='logloss', n_jobs=-1, random_state=42 ) model.fit(X, y) joblib.dump(model, TIME_MODEL_FILE) print("✅ [V9] Time Engine sauvegardé avec succès ! Ton CPU te remercie.") return model def load_time_model(): """Charge le modèle depuis le SSD.""" if os.path.exists(TIME_MODEL_FILE): return joblib.load(TIME_MODEL_FILE) return None def predict_time(model, df): """ Prédit la probabilité de hausse pour la bougie actuelle. Remplace officiellement predict_lstm. """ X, _ = prepare_time_features(df) if len(X) == 0: return 0.5 last_row = X.iloc[[-1]] # predict_proba renvoie [prob_baisse, prob_hausse]. On veut la hausse (indice 1) prob_hausse = model.predict_proba(last_row)[0][1] return prob_hausse