# 2026-07-30 — VRP01 contro le quote REALI: il f del credito netto è 0.73, non 1.0 **Esito:** nessun cambio a book, pesi, cron o config. Un'ipotesi di VRP01 è **falsificata con misura**, e il dataset che l'ha falsificata entra nel progetto (estrattore + certificazione + harness + test). Il muro dichiarato per il deploy — il *f* di stress — resta in piedi, intatto. ## Da dove viene il dato `/opt/docker/cerbero-bite` accumula dal 2026-06-09 la catena opzioni Deribit **mainnet**: entrambe le ali, scadenze 1g→3 mesi, ora per ora, con la profondità top-3 del book. È la fonte che il progetto cita dal 20/06 (`options_vrp_calibrate.py`) e che finora era stata usata una volta sola, via export manuale in `/tmp`. Il motivo per cui quel dato si **memorizza** invece di richiederlo quando serve: una catena opzioni non è ricostruibile a posteriori — Deribit non serve book storici. Un'ora non raccolta è persa per sempre. Stessa asimmetria dello storico spot certificato, con l'aggravante che qui non esiste un secondo venue da cui recuperarla. ## La domanda `src/portfolio/sleeves.py:136` — `VRP_CFG` gira a **`f=1.0`**, applicato al credito **NETTO**: ```python net_prem = (_bs_put(S0, Ks, T, sig) - _bs_put(S0, Kl, T, sig)) * cfg["f"] ``` cioè assume che il mercato paghi esattamente ciò che Black-Scholes su DVOL-ATM dice, **per entrambe le gambe**. Il caveat di ammissione ("premio MODELLATO su DVOL ATM, skew non esplicito") era dichiarato dal 19/06 e mai quantificato, per mancanza di quote vere. ## D1 — copertura: la struttura c'è Finestra settimanale 4-10 DTE: **8 scadenze su 8** hanno **entrambe** le gambe quotate, per entrambi gli asset. Delta realizzati **−0.270** (target −0.280) e **−0.099** (target −0.100): la struttura misurata è quella del sleeve, non una sua approssimazione. ## D2 — il numero: f = 0.73 Confronto agli **stessi strike** (così il rapporto isola l'errore di *prezzo*, non la scelta dello strike), fill conservativo (vendi al bid, compri all'ask): | grandezza | mediana | p25 | p75 | |---|---|---|---| | f gamba **corta** (venduta) | **1.02** | 0.88 | 1.12 | | f gamba **lunga** (comprata) | **2.30** | 1.68 | 2.87 | | **f credito NETTO** ← quello che entra nel book | **0.73** | 0.71 | 0.82 | | f credito netto, a mid | 0.80 | 0.79 | 0.89 | IC95% bootstrap sulla mediana **[0.698, 0.780]**; **0 osservazioni su 15** arrivano a 1.0. ⚠️ **La calibrazione del 20/06 non è contraddetta, è replicata**: misurava la **sola gamba corta** e trovava f ≈ 1.0; qui la stessa quantità, con implementazione indipendente, dà **1.02**. La differenza è che VRP01 è uno *spread*, e il problema sta nell'altra gamba. ## Il meccanismo (senza il quale il numero sarebbe un artefatto) **IV(corta) − DVOL = +0.8 pp**, **IV(lunga) − DVOL = +7.5 pp**. Il modello prezza entrambe le gambe a vol ATM; l'ala più OTM — quella che si **compra** — sta 8 punti sopra per skew, quindi costa **~2.3× il modello**, e il credito netto si comprime del 27%. Colpisce esattamente il punto su cui VRP01-v2 era stato promosso: *"(a) defined-risk taglia la coda (worst-week −16.6%→−7.4%)"*. Nel modello quell'assicurazione è comprata a vol ATM, cioè quasi gratis. Nel mercato costa più del doppio. **Il difetto non è nel premio incassato, è nella protezione comprata.** ## Conseguenza, misurata VRP01 standalone sostituendo **solo** `f` (replica sana a f=1.0: 1.08 / 0.58 / −11.8% contro i 1.10 / 0.60 / 12% pubblicati): | f | Sh FULL | DD FULL | CAGR | Sh HOLD-OUT | |---|---|---|---|---| | **1.00** (assunto) | 1.08 | −11.8% | 8.2% | **+0.58** | | **0.80** (misurato a mid) | 0.51 | −14.4% | 3.6% | **−0.02** | | **0.73** (misurato, fill conservativo) | 0.31 | −15.3% | 2.0% | **−0.23** | Book a 5 sleeve (VRP01 al 12%), ancore canoniche: FULL 2.215 → **2.146** (Δ −0.069), HOLD 2.347 → **2.244** (Δ −0.103), DD invariato. **Lettura onesta: il book non crolla** — l'effetto è dentro la banda d'ancora (canonico 2.22 contro mediana de-luckata 1.95). Ma il LOO del 26/07 attribuiva a VRP01 **+0.122 di FULL**: **circa metà di quel contributo era il prezzo che il modello si faceva da solo.** L'audit d'ancora aveva corretto la fortuna di calendario; l'ottimismo di *prezzo* non l'aveva corretto nessuno. ## D3 — ciò che solo questo dato permette Le stesse due gambe sono riquotate **~164 volte per trade** (orarie) fino a scadenza. Da qui: - il **50%-profit-take scatterebbe in 13/15 settimane** → la regola di gestione diventa testabile; - **peggior mark infra-settimana** (N=13 trade con path): mediana **−6.9%** del capitale, minimo **−81.7%**, su un trade che è finito **in utile**. ⚠️ Il sleeve marca solo a scadenza: quel minimo **non esiste nei suoi numeri**. È la stessa classe di errore della lente wick accoppiata del 25/07 — *un rischio valutato sul minimo non si misura sulle chiusure*. Il DD 12% di VRP01 è un DD di chiusure settimanali. ## D4 — ciò che il dato NON dice, ed è la ragione per cui si raccoglie **Nella finestra raccolta VRP01 non avrebbe aperto una sola posizione.** IV-rank mediano 0.12 (ETH) e 0.08 (BTC) contro il gate >0.30: **0 settimane su 8** per entrambi. Il massimo di DVOL raccolto sta al **24° percentile** (ETH) e **28°** (BTC) della storia. Quindi il f = 0.73 è misurato nel regime in cui il sleeve **sta flat**. Lo skew è strutturale e in stress si irripidisce, quindi la direzione è robusta — ma **la taglia in stress resta non misurata**, e il criterio dichiarato il 19/06 ("rivalutare quando cerbero-bite cattura un crash") non è stato toccato da questo lavoro. ## Il difetto trovato nel dato, e la certificazione che ora c'è Il feed ha un guasto **in corso** dal 29/07 05:00 UTC: il collettore persiste la riga anche quando il ticker fallisce (rate-limit per-IP), con `bid`/`ask`/`iv`/`delta` NULL. Il **conteggio righe non cambia** — 13.000/giorno prima e dopo — quindi ogni controllo di copertura basato sulle righe dice "tutto bene". Tasso di quote vuote per settimana: 0.4 · 0.7 · 2.2 · 1.5 · 0.5 · 0.4 · 0.3 → **22%**. `scripts/analysis/fetch_cb_chain.py` certifica quattro difetti (quote vuote, book incrociato, premio non monotono nello strike, `depth==0` ambiguo by design) ed è il posto dove è stata imparata la lezione seguente. ⚠️ **La prima stesura della certificazione confrontava "tutto il campione" con "ultimi 7 giorni" — e diluiva un guasto di 2 giorni al 13.5%**, cioè commetteva a 7 giorni lo stesso errore che dichiarava di voler evitare a 3 mesi. Con la statistica giusta (**giorno peggiore** della finestra) lo stesso dato dice **51.7%** e lo status passa da `DEGRADATO` a `QUOTE-VUOTE`. **REGOLA: un guasto IN CORSO non si misura con una media su una finestra — si misura al suo giorno peggiore. Qualunque finestra è abbastanza lunga da nascondere un guasto abbastanza giovane.** Congelata in `test_giorno_peggiore_non_si_lascia_diluire_dalla_media`. ## Cosa NON è stato fatto, e perché **`VRP_CFG["f"]` non è stato cambiato.** La misura sta su 15 osservazioni, 7 settimane, un solo regime — per giunta il regime in cui il sleeve è flat. Sostituire 1.0 con 0.73 significherebbe propagare in tutto il book un numero misurato dove il book non opera. La mossa corretta è il **caveat quantificato**: i numeri 1.10 / 0.60 / 12% si citano d'ora in poi con "a f=1.0; f misurato sulle quote reali 0.73 [0.70, 0.78], a cui l'hold-out standalone è −0.23". Che VRP01 stia al 12% e non sia deployato è, retroattivamente, la decisione giusta **per il motivo giusto**: non "short-vol da modello per prudenza", ma "il modello sovrastima il credito del 27% e lo fa sulla gamba che doveva proteggere". ## Regole nuove 1. **Il *f* di una struttura multi-gamba non è il *f* di una sua gamba.** Misurare la sola gamba venduta dà la risposta sbagliata **con segno rassicurante** (1.02 invece di 0.73). Ogni futura calibrazione su quote reali di una struttura a N gambe si fa sul **netto**. Congelata in `test_il_f_della_gamba_corta_non_e_il_f_dello_spread` (3 ali, identità algebrica `f_net = (1 − f_long·k)/(1 − k)` — una soglia sola sarebbe stata una fixture fortunata). 2. **Un guasto in corso si misura al giorno peggiore, non in media** (sopra). 3. **Una riga presente non è un dato presente.** Il difetto delle quote vuote è invisibile a qualunque controllo che conti righe: va contato ciò che è **quotato**, non ciò che è **scritto**. È la terza occorrenza della stessa famiglia dopo la contabilità a 3 stati di `paper_dvolspread` (26/07) e il silenzio letto come zero di `fresh_5m` (26/07). ## File - `scripts/analysis/fetch_cb_chain.py` — estrazione + certificazione → `data/raw/cb_chain.parquet` - `scripts/research/cblib.py` — harness (loader, `pick_legs`, `f_factors`, `close_cost_path`) - `scripts/research/r0730_vrp_real_quotes.py` — lo studio (D1-D4, meccanismo, sweep f, `--book`) - `tests/test_cb_chain_vrp.py` — 14 casi (rilevatori + controlli positivi + guardia di convenzione)