Files
PythagorasGoal/docs/diary/2026-07-30-vrp-tenor-gate.md
T
Adriano Dal Pastro 36dc55748e research(vrp): buco del tenore chiuso col gate onesto — earns_slot_honest = False
Book, pesi, cron, config INVARIATI.

La griglia strutture del 03/07 si fermava a 10 giorni. Famiglia dichiarata nel
docstring PRIMA di guardare i numeri: 8 tenori (5-35g) x 3 delta corti x 3
lunghi = 72 celle, perche' riaprire il tenore riapre la struttura e i trial si
contano al rialzo.

study_family_honest e' cablato sui candidati direzionali (factory -> target_fn
via candidate_daily) e VRP01 non lo e': usati i suoi tre componenti reali —
selezione in-sample-only, altlib.deflated_sharpe, altlib.marginal_vs_tp01 —
importati e non riscritti (c'e' un test d'identita').

ESITO. Cella scelta al buio 10g -0.28/-0.05 (Sh IS 1.75 / FULL 1.55 / HOLD 1.01)
contro il canonico 7g (1.50/1.32/0.82; rango 17/72 in-sample). Batte il canonico
ma DSR 0.948 < 0.95 FAIL. marginal_vs_tp01 = ADDS per entrambe: il verdetto non
e' 'VRP01 e' rotto', e' che il vantaggio non sopravvive al conto dei trial.

IL BUCO SI CHIUDE SUL CONTENUTO, non sul gate: la regione mai esplorata PERDE.
Miglior cella >10g = 18g, rango 8/72, e solo 3/10 della top-10 sta oltre i 10
giorni -> lo studio conferma il 03/07 invece di ribaltarlo.

IL VINCITORE STA DOVE IL MODELLO SBAGLIA DI PIU': compra l'ala piu' lontana
(delta lungo -0.05), come 5/10 della top-10, cioe' la gamba che il 30/07 ha
misurato sottoprezzata ~2.3x. Sospetto motivato, non dimostrazione: il mediano
non separa -0.10 da -0.05, si separa la coda alta. Ma f non e' misurato fuori
dalla struttura canonica, e la sensibilita' a f uniforme e' la lente sbagliata
per una struttura il cui errore e' concentrato in una gamba sola.

ROBUSTEZZA DEL VERDETTO, PUBBLICATA: DSR 0.983 PASS a N=8, 0.948 FAIL a N=72,
0.909 a N=360. Il verdetto si ribalta col conteggio. La griglia era dichiarata
in anticipo e il conto fatto al rialzo, ma fallisce per 0.002: si cita come
tale, non come refutazione netta. Congelato in un test.

Seguito giusto = una MISURA, non un altro backtest: quanto vale f sul
10g/-0.05 sulle quote vere, ora che la catena la raccogliamo noi ogni ora.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 22:06:31 +00:00

125 lines
6.6 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.
# 2026-07-30 (4º filone) — il buco del tenore chiuso col gate onesto: nessun cambio a VRP01
**Richiesta dell'operatore:** *«chiudi il buco del tenore con study_family_honest».*
**Esito: `earns_slot_honest = False`. Book, pesi, cron, config INVARIATI.**
Script `scripts/research/r0730_vrp_tenor_gate.py`, test `tests/test_vrp_tenor_gate.py` (12 casi).
## Il buco, e perché era reale
La griglia strutture del 03/07 (`r0703_vrpimp_structgrid`) cercava su `TENOR_GRID = (3, 5, 7, 10)`:
**oltre i 10 giorni non è mai stato guardato.** Lo sweep del 30/07 sul profit-take aveva toccato
14/18/21/28g di passaggio e mostrato che il 18g *sembrava* battere il 7g in hold-to-expiry
(1.51 vs 1.32) — sei celle scelte sul campione pieno, cioè esattamente la selezione che questo
gate esiste per uccidere.
## Perché il gate è composto a mano, e non è una scorciatoia
`altlib.study_family_honest` è cablato sui candidati **direzionali**: vuole
`factory(tf=..., **params) -> target_fn` e passa da `candidate_daily`, che costruisce i rendimenti
da una serie di *posizioni* su BTC/ETH. VRP01 non è direzionale. Si usano quindi i suoi **tre
componenti reali**, nello stesso ordine e con le stesse soglie: selezione in-sample-only →
`altlib.deflated_sharpe` (importato, non riscritto — c'è un test che lo verifica) →
`altlib.marginal_vs_tp01` (importato).
**Famiglia dichiarata nel docstring PRIMA di guardare i numeri:** 8 tenori × 3 delta corti ×
3 delta lunghi = **72 celle**. Riaprire il tenore riapre la struttura, e il conteggio dei trial si
fa **al rialzo** — contarne meno gonfia il deflated-Sharpe.
## Il risultato
| | tenore | δ corto | δ lungo | Sh IS | Sh FULL | Sh HOLD | maxDD | CAGR |
|---|---|---|---|---|---|---|---|---|
| **scelta al buio** | 10g | 0.28 | 0.05 | **1.75** | 1.55 | 1.01 | 9.6% | 13.5% |
| VRP01 canonico | 7g | 0.28 | 0.10 | 1.50 | 1.32 | 0.82 | 10.5% | 10.5% |
Rango del canonico: **17/72 in-sample, 26/72 sul campione pieno**. La selezione al buio sceglie
un'altra cella, e quella cella batte il canonico sia in-sample sia full.
**Ma il gate si chiude sul deflated-Sharpe:**
| | DSR su 72 trial | esito |
|---|---|---|
| cella scelta | **0.948** | **FAIL** (soglia 0.95) |
| VRP01 canonico | 0.885 | FAIL |
`marginal_vs_tp01`**ADDS** a entrambe (corr +0.016, `robust_oos` True, `has_insample_edge`
True, `is_hedge` False). Quindi il verdetto **non** è «VRP01 è rotto» né «il tenore non conta»:
è che il vantaggio apparente non sopravvive al conto dei trial.
## Come il buco si chiude davvero: la regione nuova perde
Questo è il punto che rende la chiusura pulita, più del DSR:
| | cella | Sh IS | rango |
|---|---|---|---|
| miglior cella **≤10g** (già coperta dal 03/07) | 10g 0.28/0.05 | 1.75 | 1/72 |
| miglior cella **>10g** (territorio mai guardato) | 18g 0.28/0.05 | 1.56 | **8/72** |
Solo **3 celle su 10** nella top-10 in-sample stanno oltre i 10 giorni. **Si è aperta la regione
mai esplorata e la regione mai esplorata ha perso** contro celle che il 03/07 aveva già visto e
non promosso. Il buco non è "chiuso perché il gate boccia": è chiuso perché **guardandoci dentro
non c'è niente**.
## ⚠️ Il vincitore sta dove il modello sbaglia di più
La cella scelta compra l'ala **più lontana** (δ lungo 0.05), e 5 delle 10 celle migliori fanno lo
stesso. Il 30/07 ha **misurato** che il modello piatto sottoprezza proprio l'ala che si *compra*
(IV(lunga)DVOL **+7.5pp** contro +0.8pp della corta, ~**2.3×** il modello), e che l'errore cresce
con la distanza dallo strike. Una selezione che premia il δ lungo più piccolo sta plausibilmente
massimizzando **l'errore di modello**, non l'edge.
Onestà su questo punto: è un **sospetto motivato, non una dimostrazione**. Il *mediano* in-sample
non separa 0.10 da 0.05 (1.37 contro 1.37); a separarsi è la **coda alta** della griglia. Ma
basta a spostare l'onere della prova, perché `f` **non è misurato** fuori dalla struttura canonica.
⚠️ E la sensibilità a `f` non risolve: applicandolo uniformemente la cella scelta degrada *meno*
(f=0.73 → 0.84 contro 0.47 del canonico), ma **f uniforme è la lente sbagliata proprio per questa
struttura**, il cui errore è concentrato in una gamba sola. Un numero rassicurante ottenuto con lo
strumento sbagliato non è rassicurazione.
## ⚠️ Quanto è robusto il mio stesso verdetto
Il DSR dipende da quanti trial si dichiarano, e qui il verdetto **si ribalta**:
| conteggio | N | DSR | esito |
|---|---|---|---|
| solo gli 8 tenori | 8 | 0.983 | **PASS** |
| **la griglia dichiarata** | **72** | **0.948** | **FAIL** |
| 72 + 288 simulate del 03/07 | 360 | 0.909 | FAIL |
La griglia è stata dichiarata **prima** di guardare i numeri e il conteggio fatto al rialzo — ma il
verdetto va citato per quello che è: **fallisce per 0.002**, non è una refutazione netta. (L'ultima
riga usa trial *simulati* dalla distribuzione osservata, non le Sharpe vere del 03/07, che vengono
da un motore diverso: indicazione, non misura.) Congelato in
`test_il_verdetto_dipende_dal_numero_di_trial_dichiarati`, così che nessuno possa farlo passare
un domani restringendo il conteggio.
## Decisione
**Nessun cambio a VRP01**, per quattro ragioni in ordine di peso:
1. **Il gate pre-registrato fallisce.** Una soglia dichiarata in anticipo che poi si aggira non è
una soglia.
2. **La regione davvero nuova non vince** — quindi questo studio non ribalta il 03/07, lo conferma.
3. **Il vincitore sta nell'angolo dove abbiamo misurato che il modello è meno affidabile**, e lì
`f` non è misurato.
4. Niente di tutto questo è eseguibile prima di ~$2.6k, e a $3.000 VRP01 è **0 lotti** al peso di
book.
**Il seguito giusto non è un altro backtest, è una misura.** Se il 10g/0.28/0.05 interessa, la
domanda che decide è *quanto vale f su quella struttura sulle quote vere* — e da oggi la catena la
raccogliamo noi ogni ora. Serve però che il collettore accumuli abbastanza scadenze a 10 giorni:
oggi ci sono 15 osservazioni sul solo canonico.
## Regole
- **Quando si riapre un parametro si riapre la sua famiglia**, e i trial si contano al rialzo: il
deflated-Sharpe è l'unico posto dove barare è indolore e invisibile.
- **Dichiarare la griglia prima di guardare i numeri**, e pubblicare la sensibilità del verdetto al
conteggio — un gate che passa solo con la propria griglia preferita non è un gate.
- **Un buco si chiude meglio mostrando che dentro non c'è niente che bocciando il candidato**: qui
la frase che conta non è «DSR 0.948» ma «la regione mai esplorata è ottava».
- **Se la selezione converge dove un difetto di modello è già misurato, il sospetto vale più del
numero** — e si dice che è un sospetto.