docs: plan Phase 4c-bis — CNN image-based (analyse visuelle graphiques chandeliers)
Architecture Conv2D 4-blocs sur images 128×128 RGB rendues par mplfinance. Apprend les patterns visuels sans qu'on les programme (marteaux, double top, etc.) Intégration Ensemble 3 composants : XGB(0.30) + CNN1D(0.30) + CNNImage(0.40) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
182
docs/CNN_IMAGE_PLAN.md
Normal file
182
docs/CNN_IMAGE_PLAN.md
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
# Phase 4c-bis : CNN Image-Based — Analyse Visuelle de Graphiques
|
||||||
|
|
||||||
|
**Date** : 2026-03-10
|
||||||
|
**Statut** : 🟡 En développement
|
||||||
|
**Prérequis** : Phase 4c (CNN 1D + Ensemble) ✅
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Concept
|
||||||
|
|
||||||
|
Contrairement au CNN 1D qui analyse des séquences numériques, le CNN image-based
|
||||||
|
convertit les bougies OHLCV en **vraies images de graphiques** (rendu matplotlib),
|
||||||
|
puis utilise un réseau de neurones de **vision par ordinateur** (Conv2D) pour
|
||||||
|
reconnaître les patterns visuels — exactement comme un trader devant TradingView.
|
||||||
|
|
||||||
|
### Ce que le modèle apprend sans qu'on le programme
|
||||||
|
- Bougies marteau, étoile filante, doji
|
||||||
|
- Double top, double bottom
|
||||||
|
- Rebonds sur support/résistance (zones de consolidation visibles)
|
||||||
|
- Momentum : grande bougie pleine après consolidation
|
||||||
|
- Divergences visibles (mouvement de prix vs volume en bas de l'image)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
OHLCV DataFrame (64 bougies)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
CandlestickImageRenderer
|
||||||
|
- Rendu mplfinance (sans axes, sans texte)
|
||||||
|
- Bougies vertes (hausse) / rouges (baisse)
|
||||||
|
- Volume en bas (20% de l'image)
|
||||||
|
- Image 128×128 pixels, RGB
|
||||||
|
- Normalisation [0..1]
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
CandlestickCNN (Conv2D — vision)
|
||||||
|
Input : (batch, 3, 128, 128)
|
||||||
|
|
||||||
|
Bloc 1 : Conv2d(3→32, 3×3) + BatchNorm + ReLU + MaxPool(2,2) → (32, 64, 64)
|
||||||
|
Bloc 2 : Conv2d(32→64, 3×3) + BatchNorm + ReLU + MaxPool(2,2) → (64, 32, 32)
|
||||||
|
Bloc 3 : Conv2d(64→128, 3×3) + BatchNorm + ReLU + MaxPool(2,2) → (128, 16, 16)
|
||||||
|
Bloc 4 : Conv2d(128→256, 3×3) + BatchNorm + ReLU + AdaptiveAvgPool(1) → (256,)
|
||||||
|
|
||||||
|
Classifieur :
|
||||||
|
Linear(256→128) + Dropout(0.4) + ReLU
|
||||||
|
Linear(128→3) → softmax → [SHORT, NEUTRAL, LONG]
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Signal : 1 (LONG) / -1 (SHORT) / 0 (NEUTRAL)
|
||||||
|
Confidence : max(P_LONG, P_SHORT)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fichiers à créer
|
||||||
|
|
||||||
|
### src/ml/cnn_image/
|
||||||
|
|
||||||
|
| Fichier | Rôle |
|
||||||
|
|---|---|
|
||||||
|
| `__init__.py` | Export CNNImageStrategyModel |
|
||||||
|
| `chart_renderer.py` | CandlestickImageRenderer : encode(df, seq_len=64) → (N, 3, 128, 128) |
|
||||||
|
| `cnn_image_model.py` | CandlestickCNN(nn.Module) : Conv2D 4-blocs + Dense |
|
||||||
|
| `cnn_image_strategy_model.py` | CNNImageStrategyModel : même interface que MLStrategyModel |
|
||||||
|
|
||||||
|
### src/strategies/cnn_image_driven/
|
||||||
|
|
||||||
|
| Fichier | Rôle |
|
||||||
|
|---|---|
|
||||||
|
| `__init__.py` | Export CNNImageDrivenStrategy |
|
||||||
|
| `cnn_image_strategy.py` | CNNImageDrivenStrategy(BaseStrategy), SL/TP ATR-based |
|
||||||
|
|
||||||
|
### docker/requirements/api.txt
|
||||||
|
- Ajouter `mplfinance>=0.12.10b0`
|
||||||
|
- `Pillow>=10.0.0` (probablement déjà présent)
|
||||||
|
- Rebuild trading-api
|
||||||
|
|
||||||
|
### src/api/routers/trading.py
|
||||||
|
- POST `/trading/train-cnn-image`
|
||||||
|
- GET `/trading/train-cnn-image/{job_id}`
|
||||||
|
- GET `/trading/cnn-image-models`
|
||||||
|
|
||||||
|
### src/ml/ensemble/ensemble_model.py
|
||||||
|
- Ajouter `attach_cnn_image(model)` comme 3ème slot
|
||||||
|
- Mettre à jour `DEFAULT_WEIGHTS = {xgboost: 0.30, cnn: 0.30, cnn_image: 0.40, rl: 0.00}`
|
||||||
|
- Mettre à jour `predict()` pour inclure le 3ème modèle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CandlestickImageRenderer — Détails
|
||||||
|
|
||||||
|
```python
|
||||||
|
class CandlestickImageRenderer:
|
||||||
|
"""
|
||||||
|
Convertit des données OHLCV en images de graphiques en chandeliers.
|
||||||
|
|
||||||
|
Paramètres d'image :
|
||||||
|
- Taille : 128×128 pixels
|
||||||
|
- Canaux : RGB (3)
|
||||||
|
- Fond : noir (#0d1117)
|
||||||
|
- Hausse : vert (#26a69a), Baisse : rouge (#ef5350)
|
||||||
|
- Volume : dégradé alpha en bas (20% de l'image)
|
||||||
|
- Pas d'axes, pas de labels, pas de titre
|
||||||
|
"""
|
||||||
|
|
||||||
|
def encode(df, seq_len=64) -> np.ndarray:
|
||||||
|
# Retourne (N, 3, 128, 128), float32, normalisé [0,1]
|
||||||
|
# N = len(df) - seq_len + 1 fenêtres glissantes
|
||||||
|
|
||||||
|
def encode_last(df, seq_len=64) -> np.ndarray:
|
||||||
|
# Retourne (1, 3, 128, 128) — dernière fenêtre uniquement
|
||||||
|
# Utilisé pour la prédiction en temps réel
|
||||||
|
|
||||||
|
def _render_single(df_window) -> PIL.Image:
|
||||||
|
# Rendu mplfinance en mémoire (BytesIO)
|
||||||
|
# style custom : fond noir, pas d'axes
|
||||||
|
# Retourne PIL.Image 128×128 RGB
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CNNImageStrategyModel — Interface
|
||||||
|
|
||||||
|
Identique à `MLStrategyModel` et `CNNStrategyModel` :
|
||||||
|
|
||||||
|
```python
|
||||||
|
model = CNNImageStrategyModel(symbol='EURUSD', timeframe='1h')
|
||||||
|
result = model.train(df_ohlcv) # walk-forward 2 folds
|
||||||
|
signal = model.predict(df) # {signal, confidence, probas, tradeable}
|
||||||
|
model.save() # models/cnn_image_strategy/EURUSD_1h.pt + .json
|
||||||
|
model.load(symbol, timeframe) # chargement depuis disque
|
||||||
|
model.list_trained_models() # liste des modèles disponibles
|
||||||
|
model.get_feature_importance() # retourne [] (CNN = boîte noire)
|
||||||
|
```
|
||||||
|
|
||||||
|
Paramètres entraînement :
|
||||||
|
- `seq_len` : 64 bougies par image
|
||||||
|
- `epochs` : 50 max, early stopping patience=7
|
||||||
|
- `batch_size` : 32
|
||||||
|
- `lr` : 1e-3 (Adam)
|
||||||
|
- Labels : via LabelGenerator partagé (ATR-based, même que XGBoost et CNN 1D)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Intégration Ensemble
|
||||||
|
|
||||||
|
Après cette phase, l'EnsembleModel aura 3 composants :
|
||||||
|
|
||||||
|
```
|
||||||
|
Signal Ensemble =
|
||||||
|
0.30 × XGBoost(TA features)
|
||||||
|
+ 0.30 × CNN 1D(séquences OHLCV)
|
||||||
|
+ 0.40 × CNN Image(graphiques visuels)
|
||||||
|
|
||||||
|
Condition de trade :
|
||||||
|
- Score pondéré ≥ min_confidence (défaut 0.55)
|
||||||
|
- Au moins 2 modèles en accord sur la direction
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TODOs
|
||||||
|
|
||||||
|
- [ ] chart_renderer.py — CandlestickImageRenderer avec mplfinance
|
||||||
|
- [ ] cnn_image_model.py — CandlestickCNN Conv2D 4-blocs
|
||||||
|
- [ ] cnn_image_strategy_model.py — train/predict/save/load
|
||||||
|
- [ ] cnn_image_strategy.py — CNNImageDrivenStrategy(BaseStrategy)
|
||||||
|
- [ ] trading.py — routes /train-cnn-image, /cnn-image-models
|
||||||
|
- [ ] ensemble_model.py — attach_cnn_image(), poids mis à jour
|
||||||
|
- [ ] requirements — mplfinance + rebuild Docker
|
||||||
|
- [ ] Entraînement validé sur EURUSD/1h
|
||||||
|
- [ ] Intégration EnsembleStrategy avec les 3 modèles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4d — RL (après validation CNN image)
|
||||||
|
|
||||||
|
Agent PPO (Proximal Policy Optimization) via `gymnasium` + `stable-baselines3`.
|
||||||
|
Voir docs/CNN_ENSEMBLE_PLAN.md section Phase 4d.
|
||||||
Reference in New Issue
Block a user