Files
trader-ml/docs/ML_STRATEGY_GUIDE.md
Tika cc05ddb7c4 feat: ML-Driven Strategy — apprentissage des patterns TA humains
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>
2026-03-08 17:45:39 +00:00

307 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 × ATR` avant que le LOW descende sous `entry - sl_atr_mult × ATR`
- **SHORT (-1)** : le LOW atteint `entry - tp_atr_mult × ATR` avant que le HIGH monte au-dessus de `entry + 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-folds
- `wf_precision` : précision sur signaux directionnels
- `wf_recall` : recall sur signaux directionnels
- `label_dist` : distribution LONG/SHORT/NEUTRAL
---
## Routes API
### `POST /trading/train`
Lance l'entraînement en arrière-plan.
**Body :**
```json
{
"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 :**
```json
{
"job_id": "uuid",
"status": "pending",
"symbol": "EURUSD",
"timeframe": "1h"
}
```
### `GET /trading/train/{job_id}`
Consulter l'état d'un entraînement.
**Réponse (completed) :**
```json
{
"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)
```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
```python
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_confidence` filtre 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.50` sur 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 |