Spaces:
Sleeping
Sleeping
| import ccxt | |
| import pandas as pd | |
| import pandas_ta as ta | |
| import numpy as np | |
| import joblib | |
| from sklearn.mixture import GaussianMixture | |
| from sklearn.preprocessing import StandardScaler | |
| import os | |
| # Fichiers de sauvegarde | |
| # Fichiers de sauvegarde sur le Cloud | |
| REGIME_MODEL_FILE = "regime_model.pkl" | |
| REGIME_SCALER_FILE = "regime_scaler.pkl" | |
| def fetch_macro_data(symbol="BTC/USDT", timeframe="1d", limit=1000): | |
| """ | |
| Récupère l'historique long terme pour comprendre le régime global. | |
| On utilise le Bitcoin car c'est lui qui dicte la météo du marché crypto. | |
| """ | |
| print(f"📥 Téléchargement des données macro pour {symbol} ({timeframe})...") | |
| exchange = ccxt.binance({'enableRateLimit': True}) | |
| data = exchange.fetch_ohlcv(symbol, timeframe=timeframe, limit=limit) | |
| df = pd.DataFrame(data, columns=["ts", "open", "high", "low", "close", "vol"]) | |
| df['ts'] = pd.to_datetime(df['ts'], unit='ms') | |
| return df | |
| def prepare_regime_features(df): | |
| """ | |
| Calcule les variables (features) qui définissent l'état du marché. | |
| Ici on ne cherche pas la direction, mais le "climat" (volatilité, force, panique). | |
| """ | |
| # 1. Volatilité relative (ATR en pourcentage du prix) | |
| df["ATR"] = df.ta.atr(length=14) | |
| df["ATR_pct"] = (df["ATR"] / df["close"]) * 100 | |
| # 2. Pente de la tendance (Est-ce que l'EMA200 monte ou descend ?) | |
| df["EMA200"] = df.ta.ema(length=200) | |
| # Pente sur 10 jours | |
| df["EMA200_slope"] = (df["EMA200"] / df["EMA200"].shift(10)) - 1 | |
| # 3. Drawdown (Chute par rapport au plus haut des 14 derniers jours) | |
| df["Roll_Max"] = df["close"].rolling(14).max() | |
| df["Drawdown"] = (df["close"] / df["Roll_Max"]) - 1 | |
| # 4. Momentum Global | |
| df["RSI_Macro"] = df.ta.rsi(length=14) | |
| # Nettoyage | |
| df = df.dropna().copy() | |
| # On garde uniquement les colonnes qui intéressent l'IA de Régime | |
| features = df[["ATR_pct", "EMA200_slope", "Drawdown", "RSI_Macro"]] | |
| return df, features | |
| def train_regime_model(): | |
| """ | |
| Entraîne le modèle non-supervisé pour découvrir les régimes de marché. | |
| """ | |
| print("🧠 Démarrage de l'entraînement du Détecteur de Régime (Couche 1)...") | |
| df = fetch_macro_data() | |
| df, features = prepare_regime_features(df) | |
| # L'IA a besoin que les données soient à la même échelle (Standardisation) | |
| scaler = StandardScaler() | |
| scaled_features = scaler.fit_transform(features) | |
| # Création du modèle GMM (On lui demande de trouver 4 régimes distincts) | |
| # Par exemple : 0=TREND, 1=RANGE, 2=PANIC, 3=HIGH_VOL (L'ordre sera défini par l'IA) | |
| gmm = GaussianMixture(n_components=4, covariance_type='full', random_state=42) | |
| gmm.fit(scaled_features) | |
| # Sauvegarde des cerveaux | |
| joblib.dump(gmm, REGIME_MODEL_FILE) | |
| joblib.dump(scaler, REGIME_SCALER_FILE) | |
| print(f"✅ Modèle GMM entraîné sur {len(df)} jours et sauvegardé !") | |
| # On va afficher les caractéristiques moyennes de chaque régime | |
| # pour que tu puisses leur donner un nom (BULL, BEAR, PANIC, RANGE) | |
| df['Regime'] = gmm.predict(scaled_features) | |
| print("\n📊 CARACTÉRISTIQUES DES RÉGIMES DÉCOUVERTS :") | |
| summary = df.groupby('Regime')[["ATR_pct", "EMA200_slope", "Drawdown", "RSI_Macro"]].mean() | |
| print(summary) | |
| return gmm, scaler | |
| def detect_current_regime(df_latest): | |
| """ | |
| Fonction qui sera appelée par ton bot V8 en temps réel. | |
| """ | |
| if not os.path.exists(REGIME_MODEL_FILE) or not os.path.exists(REGIME_SCALER_FILE): | |
| return -1 # Erreur ou modèle non prêt | |
| gmm = joblib.load(REGIME_MODEL_FILE) | |
| scaler = joblib.load(REGIME_SCALER_FILE) | |
| _, features = prepare_regime_features(df_latest) | |
| if len(features) == 0: | |
| return -1 | |
| # On prend la toute dernière bougie | |
| last_row = features.iloc[[-1]] | |
| scaled_row = scaler.transform(last_row) | |
| regime = gmm.predict(scaled_row)[0] | |
| return regime | |
| if __name__ == "__main__": | |
| # Si tu lances ce fichier directement, il va s'entraîner ! | |
| train_regime_model() |