Files
TR_Agent/PaPP v2/Modello/README_mean_reversion.md
T
Pietro GiacobazziandDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> afcae4fbf7 PaPP v2 Modello: calibrazione rev (isotonic) + curva precisione/copertura + soglia operativa
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-17 09:59:35 +00:00

163 lines
7.1 KiB
Markdown
Raw 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.
# Fase 3 — Modello di MEAN-REVERSION (rientro alla Mediana)
> Questo è il **modello principale** della Fase 3. Nasce dopo aver dimostrato
> (vedi `README.md` sez. 5b, validazione esterna) che l'edge **direzionale**
> "su/giù" **non generalizza** fuori da EURUSD, mentre la **mean-reversion** è
> universale (rientro alla Mediana entro 20g nell'8790% dei casi su tutti i
> major FX). Quindi modelliamo ciò che è davvero robusto: il **rientro alla
> Mediana**.
---
## 1. Idea
Dopo un incrocio il prezzo tende a tornare sulla Mediana. Non vogliamo prevedere
la direzione, ma **caratterizzare il rientro**. Tre target, costruiti da esiti
già presenti nei CSV (nessuna baseline di regime: sono osservazioni dirette):
| target | tipo | colonna | domanda |
|---|---|---|---|
| `rev` | classificazione | `rev_10` | rientra alla Mediana **entro 10 giorni**? (sì/no) |
| `speed` | regressione | `bars_to_revert` | in **quanti giorni** rientra (solo eventi rientrati) |
| `disc` | regressione | `disc_max_pct` | **quanto si allontana** (max %) prima di rientrare |
Esclusione del banale (`drop_trivial`): gli eventi già praticamente sulla
Mediana (`|dist_med_pct| < 0.05%`) rientrano per costruzione; vengono esclusi per
studiare il rientro "vero".
## 2. Feature (note al momento dell'incrocio)
`abs_dist` (=|dist_med_pct|), `dist_med_pct`, `cluster_pct`, `cluster_exp`,
`slope_a`, `slope_b`, `vel_med`, `acc_med`, `vol_med` (numeriche) +
`pair`, `dir`, `trend`, `dow`, `month` (categoriche). Nessuna colonna di esito
futuro è tra le feature.
## 3. Pooling pulito + validazione (anti-inquinamento)
I 4 major FX (EURUSD, USDJPY, USDCHF, GBPUSD) hanno mean-reversion omogenea →
si possono **mettere in pool**. Le feature sono già in percentuale/relative,
quindi confrontabili tra simboli. Due validazioni, entrambe oneste:
1. **Walk-forward pooled**: train tutti i simboli fino all'anno T, test anno T+1
→ generalizzazione **nel tempo**.
2. **Leave-one-symbol-out (LOSO)**: train su 3 simboli, test sul 4° **mai visto**
→ generalizzazione **tra strumenti** (la prova più severa anti-inquinamento).
Ogni metrica è confrontata con una **baseline banale**:
- classificazione → accuratezza della classe maggioritaria;
- regressione → MAE ottenuto prevedendo sempre la mediana del train
(`skill_% = 1 MAE/MAE_baseline`).
## 4. Risultati (pool 4 major FX, ~39k incroci)
**Walk-forward (nel tempo):**
- `rev` : **AUC ≈ 0.65** (la baseline è 0.5) → il modello sa **ordinare** quali
incroci rientreranno entro 10g e quali no.
- `speed` : skill ≈ **+2%** → marginale (la mediana è ~3g e cambia poco).
- `disc` : skill ≈ **3%** → non meglio della mediana.
**Leave-one-symbol-out (su simbolo mai visto):**
| target | EURUSD | USDJPY | USDCHF | GBPUSD |
|---|---|---|---|---|
| `rev` AUC | 0.677 | 0.687 | 0.682 | 0.688 |
| `speed` skill | +1.3% | +4.8% | 2.9% | +2.8% |
| `disc` skill | +2.0% | +5.8% | 1.1% | 0.1% |
**Lettura:** il classificatore di rientro (`rev`) ha un edge **reale e
generalizzabile** — AUC ~0.68 anche su un simbolo completamente fuori dal
training. I due regressori (`speed`, `disc`) aggiungono poco: la velocità e
l'ampiezza dell'allontanamento sono in pratica vicine alla mediana storica.
## 5. Cosa guida il rientro (importanza, permutation su holdout 2018+)
```
abs_dist +0.104 <- distanza dalla Mediana: di gran lunga il fattore #1
dist_med_pct +0.025 <- il segno della distanza (sopra/sotto)
trend +0.021
cluster_exp +0.017 <- cluster in espansione/contrazione
vel_med +0.010
... (vol_med, cluster_pct ~0)
pair ~0 <- QUALI linee si incrociano e' irrilevante
```
Conferma economica: il rientro dipende da **quanto sei lontano dalla Mediana** e
dal **regime**, non dallo specifico tipo di incrocio. È coerente con la Fase 2 e
con la validazione esterna (il "pattern" di linee era rumore).
## 6. Uso operativo
Il modello `rev` non dice "compra/vendi": stima la **probabilità di rientro
rapido**. Serve da **filtro**: tra i setup di mean-reversion (prezzo lontano
dalla Mediana), privilegiare quelli con alta probabilità ed evitare il ~25% che
tende a NON rientrare in fretta (i casi rischiosi, spesso inizio di trend).
## 7. File e come eseguire
```
Modello/
├── config_mr.yaml parametri del modello di mean-reversion
├── src/
│ ├── mr_labeling.py costruzione dei 3 target + maschere
│ ├── mr_train.py pool + walk-forward + LOSO + modelli finali
│ └── mr_calibrate.py calibrazione + curva precisione/copertura
└── results/
├── mr_wf_<task>.csv metriche walk-forward per anno
├── mr_loso_<task>.csv metriche leave-one-symbol-out
├── mr_precision_coverage.csv soglia -> copertura/precisione/lift
├── mr_calibration_metrics.json Brier prima/dopo + LOSO
├── mr_*.png grafici (affidabilita', precisione/copertura)
└── mr_*.joblib modelli (non versionati)
```
```bash
pip install -r requirements.txt
# copia in ./data i CSV crosses+bars dei 4 simboli (vedi data/README.md), poi:
cd src
python mr_train.py # usa ../config_mr.yaml
python mr_calibrate.py # calibrazione + soglia operativa (sez. 8)
```
## 8. Calibrazione e soglia operativa (`src/mr_calibrate.py`)
Il modello `rev` **ordina** bene gli eventi, ma la probabilità grezza non è
"vera" (vedi curva rossa sotto: un 0.55 grezzo corrispondeva a ~46% di rientri
reali). La **calibrazione isotonica** la rende affidabile nella zona operativa
(0.70.9) e migliora il Brier score da **0.198 → 0.189** (più basso = meglio).
Split temporale onesto: modello base su anni `< 2016`, calibratore su `20162017`,
valutazione su `2018+` (mai visto). LOSO calibrato: AUC 0.670.70 su simbolo mai
visto → regge.
![Affidabilità](results/mr_calibration_reliability.png)
### Curva precisione/copertura (test 2018+, base rate 73%)
Per ogni soglia di probabilità: **copertura** = quanti segnali tieni,
**precisione** = tasso di rientro effettivo tra quelli tenuti.
| soglia | copertura | precisione | lift |
|---|---|---|---|
| 0.50 | 99% | 73.1% | 1.00 |
| 0.70 | 85% | 76.2% | 1.04 |
| **0.75** | **51%** | **81.2%** | **1.11** |
| 0.80 | 42% | 82.2% | 1.13 |
| 0.85 | 28% | 83.3% | 1.14 |
| 0.90 | 6% | 87.0% | 1.19 |
![Precisione vs Copertura](results/mr_precision_coverage.png)
**Soglia consigliata: ~0.75** → l'EA opera su ~metà dei setup di mean-reversion
ma il tasso di rientro sale dal 73% all'**81%**. Chi vuole essere più selettivo
usa 0.800.85 (precisione ~8283%, copertura 2842%). La soglia è un parametro:
la tabella completa è in `results/mr_precision_coverage.csv`.
Nota: tra 0.70 e 0.75 la copertura crolla (85%→51%) perché lì si concentra la
massa delle probabilità; è il punto in cui il filtro inizia a "mordere".
## 9. Prossimi passi
- Aggiungere altri major FX al pool per irrobustire ancora il LOSO.
- **Fase 4**: export del modello `rev` **calibrato** in **ONNX** (skl2onnx) e
inferenza in MT5 come filtro dei segnali di mean-reversion (soglia ~0.75).