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