Nouveau module complet pour entraîner un modèle XGBoost/LightGBM
qui apprend à détecter des opportunités depuis des indicateurs classiques :
RSI (divergences), MACD (crossovers), Bollinger (squeeze/rebond),
Supports/Résistances (pivots locaux), Points Pivots (classiques + Fibonacci),
patterns chandeliers (marteau, engulfing), alignement EMAs, volume.
Fichiers créés :
- src/ml/features/technical_features.py (~50 features TA)
- src/ml/features/label_generator.py (labels LONG/SHORT/NEUTRAL par forward simulation ATR)
- src/ml/ml_strategy_model.py (entraînement + walk-forward + sauvegarde joblib)
- src/strategies/ml_driven/ml_strategy.py (stratégie compatible StrategyEngine)
Routes API ajoutées :
- POST /trading/train (entraînement async)
- GET /trading/train/{job_id} (état du job)
- GET /trading/ml-models (liste modèles disponibles)
- GET /trading/ml-models/{symbol}/{tf}/importance (feature importance)
Documentation : docs/ML_STRATEGY_GUIDE.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8.5 KiB
ML-Driven Strategy — Guide Complet
Concept
La stratégie ML-Driven remplace les règles codées en dur par un modèle d'apprentissage supervisé (XGBoost/LightGBM) qui apprend à reconnaître les patterns utilisés par les traders humains :
- Rebonds sur supports / résistances
- Divergences RSI / MACD
- Squeeze Bollinger + expansion
- Alignement EMAs (tendance)
- Patterns de chandeliers (marteau, engulfing, étoile filante...)
- Proximité des pivots classiques et Fibonacci
Le modèle apprend quelles combinaisons de ces signaux sont réellement prédictives sur les données historiques, ce qu'un trader expérimenté ferait intuitivement après des années de pratique.
Architecture
src/
├── ml/
│ ├── features/
│ │ ├── technical_features.py # Calcul de ~50 features TA
│ │ └── label_generator.py # Labels LONG/SHORT/NEUTRAL (forward simulation)
│ └── ml_strategy_model.py # Entraînement XGBoost + sauvegarde
└── strategies/
└── ml_driven/
└── ml_strategy.py # Stratégie compatible StrategyEngine
Pipeline de données
Données OHLCV (2 ans, 1h)
↓
TechnicalFeatureBuilder (~50 features par barre)
↓
LabelGenerator (forward simulation : TP/SL atteint dans N barres ?)
↓
XGBoost (entraînement supervisé + walk-forward validation)
↓
MLStrategyModel sauvegardé sur disque (models/ml_strategy/)
↓
MLDrivenStrategy.analyze() → Signal(LONG/SHORT) si confidence >= seuil
Features calculées
RSI
| Feature | Description |
|---|---|
rsi |
Valeur brute RSI(14) |
rsi_oversold |
RSI < 30 (zone survente) |
rsi_overbought |
RSI > 70 (zone surachat) |
rsi_slope |
Pente RSI sur 3 barres |
rsi_bullish_div |
Divergence haussière (prix LL, RSI HL) |
rsi_bearish_div |
Divergence baissière (prix HH, RSI LH) |
MACD
| Feature | Description |
|---|---|
macd |
Ligne MACD (EMA12 - EMA26) |
macd_signal |
Ligne signal (EMA9 du MACD) |
macd_hist |
Histogramme |
macd_hist_slope |
Pente histogramme (momentum) |
macd_cross_up |
Crossover haussier |
macd_cross_down |
Crossover baissier |
Bollinger Bands
| Feature | Description |
|---|---|
bb_position |
Position relative dans les bandes [0..1] |
bb_bandwidth |
Largeur normalisée (indicateur de volatilité) |
bb_squeeze |
Compression < percentile 20 (signal explosion) |
bb_break_up/down |
Cassure de bande |
bb_bounce_low/high |
Rebond depuis bande inf/sup |
Supports / Résistances
| Feature | Description |
|---|---|
dist_to_resistance |
Distance en ATR à la résistance la plus proche |
dist_to_support |
Distance en ATR au support le plus proche |
bounce_from_support |
Prix à < 1 ATR d'un support |
rejection_at_resistance |
Prix à < 1 ATR d'une résistance |
Points Pivots
| Feature | Description |
|---|---|
dist_pivot |
Distance au pivot central |
dist_r1/s1/r2/s2 |
Distance aux niveaux classiques |
dist_r1f/s1f |
Distance aux niveaux Fibonacci |
near_pivot/r1/s1 |
Prix dans une zone de 0.5 ATR |
Chandeliers
| Feature | Description |
|---|---|
hammer |
Marteau (rebond potentiel) |
shooting_star |
Étoile filante (rejet potentiel) |
bullish_engulfing |
Engulfing haussier |
bearish_engulfing |
Engulfing baissier |
doji |
Doji (indécision) |
body_ratio |
Corps / mèche totale |
Tendance / EMA
| Feature | Description |
|---|---|
trend_bull |
EMA8 > EMA21 > EMA50 |
trend_bear |
EMA8 < EMA21 < EMA50 |
ema21_slope |
Pente EMA21 sur 5 barres |
above_ema200 |
Prix au-dessus de l'EMA200 |
ema_X_dist |
Distance % du prix à chaque EMA |
Temporel
| Feature | Description |
|---|---|
is_london |
Session Londres (8h-16h UTC) |
is_ny |
Session New York (13h-21h UTC) |
is_overlap |
Chevauchement London+NY (13h-16h) |
day_of_week |
Jour de la semaine |
Génération des Labels
Méthode ATR-based (recommandée)
Pour chaque barre i, on simule un trade dans les horizon barres suivantes :
- LONG (1) : le HIGH atteint
entry + tp_atr_mult × ATRavant que le LOW descende sousentry - sl_atr_mult × ATR - SHORT (-1) : le LOW atteint
entry - tp_atr_mult × ATRavant que le HIGH monte au-dessus deentry + sl_atr_mult × ATR - NEUTRAL (0) : ni TP ni SL atteint dans l'horizon
Paramètres par défaut : tp_atr_mult=2.0, sl_atr_mult=1.0 → R:R = 2:1
Méthode pourcentage fixe
Même logique avec des seuils en % : tp_pct=0.003 (0.3%), sl_pct=0.002 (0.2%).
Validation
Walk-forward cross-validation (3 folds temporels) :
- Fold 1 : entraîné sur 0..33%, testé sur 33..67%
- Fold 2 : entraîné sur 0..67%, testé sur 67..100%
- etc.
Métriques retournées :
wf_accuracy: accuracy moyenne inter-foldswf_precision: précision sur signaux directionnelswf_recall: recall sur signaux directionnelslabel_dist: distribution LONG/SHORT/NEUTRAL
Routes API
POST /trading/train
Lance l'entraînement en arrière-plan.
Body :
{
"symbol": "EURUSD",
"timeframe": "1h",
"period": "2y",
"model_type": "xgboost",
"tp_atr_mult": 2.0,
"sl_atr_mult": 1.0,
"horizon": 30,
"min_confidence": 0.55
}
Réponse :
{
"job_id": "uuid",
"status": "pending",
"symbol": "EURUSD",
"timeframe": "1h"
}
GET /trading/train/{job_id}
Consulter l'état d'un entraînement.
Réponse (completed) :
{
"job_id": "...",
"status": "completed",
"n_samples": 8760,
"n_features": 52,
"wf_accuracy": 0.58,
"wf_precision": 0.61,
"label_dist": {"long": 1200, "short": 1150, "neutral": 6410},
"trained_at": "2026-03-08T12:00:00"
}
GET /trading/ml-models
Liste tous les modèles entraînés.
GET /trading/ml-models/{symbol}/{timeframe}/importance
Top features les plus importantes du modèle.
Sauvegarde des Modèles
Les modèles sont sauvegardés dans models/ml_strategy/ :
models/ml_strategy/
├── EURUSD_1h_xgboost.joblib # Modèle + scaler + feature names
└── EURUSD_1h_xgboost_meta.json # Métriques et configuration
Au redémarrage, MLDrivenStrategy tente de charger automatiquement le modèle
existant pour le symbole/timeframe configuré (auto_load=True).
Utilisation Manuelle (Python)
from src.ml.ml_strategy_model import MLStrategyModel
# Entraînement
model = MLStrategyModel(symbol='EURUSD', timeframe='1h', model_type='xgboost')
metrics = model.train(df_ohlcv)
print(f"WF Accuracy : {metrics['wf_metrics']['avg_accuracy']:.2%}")
# Prédiction
result = model.predict(df_recent)
print(f"Signal : {result['signal']}, Confidence : {result['confidence']:.2%}")
# → {'signal': 1, 'confidence': 0.72, 'tradeable': True, 'probas': {...}}
# Chargement depuis disque
model = MLStrategyModel.load('EURUSD', '1h', 'xgboost')
# Importance des features
for f in model.get_feature_importance(top_n=10):
print(f" {f['feature']}: {f['importance']:.4f}")
Intégration avec la Stratégie
from src.strategies.ml_driven import MLDrivenStrategy
config = {
'name': 'ml_driven',
'symbol': 'EURUSD',
'timeframe': '1h',
'risk_per_trade': 0.01,
'model_type': 'xgboost',
'min_confidence': 0.55,
'tp_atr_mult': 2.0,
'sl_atr_mult': 1.0,
'auto_load': True, # Charge automatiquement si modèle existant
}
strategy = MLDrivenStrategy(config)
# Génération d'un signal
signal = strategy.analyze(df_ohlcv)
if signal:
print(f"{signal.direction} @ {signal.entry_price}, conf={signal.confidence:.2%}")
Considérations
Overfitting
- La walk-forward validation (3 folds temporels) protège contre l'overfitting in-sample
- Utiliser au minimum 1 an de données (≥ 8 000 barres en 1h)
- Éviter les périodes trop courtes (
period < 6m)
Déséquilibre des classes
- En général : ~15% LONG, ~15% SHORT, ~70% NEUTRAL
- XGBoost gère naturellement le déséquilibre
- Le seuil
min_confidencefiltre les signaux peu sûrs
Re-entraînement
- Recommandé tous les 3-6 mois pour capturer les changements de régime
- Ou après un changement de volatilité significatif (crise, FOMC...)
Métriques cibles
wf_accuracy > 0.55(mieux que le hasard)wf_precision > 0.50sur signaux directionnels- Distribución LONG/SHORT relativement équilibrée
Historique
| Date | Version | Description |
|---|---|---|
| 2026-03-08 | v1.0 | Création initiale — XGBoost/LightGBM + features TA classiques |