# 2026-07-26 — Ondata a 3 filoni: esecuzione SKH01, DVOLSPREAD, XSR01 fuori dal crypto **Script:** `r0726_skh_onbook.py` · `r0726_dvolspread_gate.py` · `r0726_xsr_equity.py` **Test:** `tests/test_wave_0726.py` (11 casi) · suite completa **245 verdi** **Book / pesi / cron: INVARIATI.** Una raccomandazione operativa aperta (T1), nessuna modifica fatta. Tre filoni scelti non per esplorare aree nuove — quelle sono in gran parte sature — ma perché il progetto stesso aveva lasciato **tre questioni aperte e decidibili oggi**: | filone | questione aperta | esito | |---|---|---| | **T1** | il degrado del path live di SKH01 (~−0.35 Sh) è recuperabile? | ⚠️ **il degrado era a sua volta fortuna d'ancora**; metà del fix funziona, l'altra metà no | | **T2** | DVOLSPREAD, in limbo dal 21/06, è sleeve o falso positivo? | ✅ **regge i gate che non esistevano allora** — promosso a forward-monitor con parametri onesti | | **T3** | XSR01 regge fuori dal crypto e da 2.6 anni monoregime? | ❌ **no** — e si scopre *perché* | --- ## T1 — Il degrado d'esecuzione di SKH01 era anch'esso un artefatto d'ancora ### La domanda Il book live gira SKH01 con cron orario e uscite **software**. Costo misurato (audit 02/07, riconfermato il 24/07): sleeve FULL 1.46→1.19, HOLD 1.64→1.15, DD 18%→25%. È il buco singolo più grande del progetto, e il 24/07 aveva già stabilito che **un cron più veloce non lo recupera**. L'angolo mai testato è l'unico meccanismo che non è un cron: gli **ordini resting on-book**, dove esiste un'asimmetria che nessuno aveva sfruttato: - il **TP è un limit order**: se il prezzo ci arriva, il fill è al livello **per costruzione** (sei il maker), e per giunta a fee maker invece che taker; - lo **SL è uno stop-market**: al trigger diventa un ordine a mercato, e in un gap riempie peggio. Ipotesi: il grosso del degrado sta sul lato TP, quindi è recuperabile senza rischio nuovo. ### Il risultato, e la trappola che ha nascosto A **offset 0** — la griglia che gira davvero — il quadro sembrava trionfale: l'on-book completo recupera il **94%** del degrado. Ma l'offset 0 è già noto essere al 93-98° percentile dei 23 offset a priori, quindi la lente onesta è la banda. E qui c'è stato un mio errore di statistica, corretto in corso: avevo confrontato **mediana(canonical) − mediana(hourly)**, che confronta offset *diversi* fra loro. Gli offset sono **coppie appaiate**: la statistica giusta è la **mediana delle differenze**. Con quella: | modalità | ΔFULL mediana [min,max] | ΔHOLD mediana | migliora in | |---|---|---|---| | canonical (tetto teorico) | **+0.054** [−0.05,+0.12] | +0.099 | — | | **solo TP a limite** | **+0.054** [−0.03,+0.07] | **+0.061** | **FULL 19/23 · HOLD 21/23 · DD 19/23** | | TP + SL on-book | +0.024 [−0.07,+0.11] | +0.031 | FULL 17/23 · HOLD 14/23 | | *contributo del solo lato SL* | **−0.010** [−0.13,+0.08] | — | **11/23 = una moneta** | **Due conclusioni, entrambe diverse da quella che cercavo.** **(1) Il "−0.35 del path live" è a sua volta un artefatto dell'offset 0.** L'audit del 02/07 aveva de-luckato i numeri *headline* di SKH01 ma aveva misurato il **degrado** solo a offset 0. Sulla banda appaiata il degrado massimo recuperabile è **+0.054 di Sharpe sul book**, non +0.35 sullo sleeve. Il buco più grande del progetto era in buona parte fortuna d'ancora anche lui. **(2) Lo stop on-book PEGGIORA.** Mettere lo SL sul book cristallizza la perdita al livello, mentre l'uscita software ritardata a volte incassa il rimbalzo: contributo mediano **−0.010**, positivo in **11/23** offset = indistinguibile da una moneta. La sensibilità lo conferma: sopra lo **0.50%** di slippage sullo stop l'on-book è **peggio del live di oggi**. Il meccanismo è misurato, non ipotizzato: sulle uscite TP il fill orario batte il livello nel **42%** dei casi (vantaggio medio −0.035%) — è quasi una moneta, quindi il limit TP **converte una lotteria in una certezza** più che aggiungere ritorno. E solo l'**1% degli SL** gappa davvero dentro la barra 5m: il gap-through dei crash è reale ma raro. ### Raccomandazione (NON eseguita) > **Appoggiare il TP come limit resting reduce-only; NON mettere lo SL strategico sul book.** > Guadagno atteso **+0.054 FULL / +0.061 HOLD** sul book, positivo in **19-21 offset su 23**, > più il risparmio taker→maker su un quarto dei trade. È un cambio di **esecuzione**, non di strategia, quindi non passa da `weights_tilt_null`. Ma è piccolo, e va pesato contro il costo operativo vero: ordini orfani se il cron muore, gestione del reduce-only, doppio fill. **Non l'ho implementato**: è una decisione dell'operatore, non un fatto compiuto. Il disaster-SL on-book a −30% resta com'è (è un'altra cosa: protezione, non exit). --- ## T2 — DVOLSPREAD regge i gate che nel giugno non esistevano ✅ ### Chi è, e perché era in limbo `agent_14_dvol_spread` (onda ortho, 21/06) è **l'unico sopravvissuto** al marginal scorer indurito: dei 18 book relative-value che facevano ADDS con lo scorer vecchio, l'indurito ne lasciò in piedi **uno**, questo. Da allora non è mai stato ripreso — non è nel book, non è in un monitor, non è stato rifiutato. Era semplicemente lì. Il segnale: `log(DVOL_btc) − log(DVOL_eth)`, tilt verso la gamba con **vol implicita più ricca** (tesi VRP / fear-reversal), market-neutral per costruzione, eseguibile a $600. Nel frattempo il progetto ha codificato **due gate che il 21/06 non c'erano**, ed erano proprio quelli che colpivano le sue riserve dichiarate: 1. **`deflated_sharpe`** (29/06) — l'agente dichiara *da sé* uno sweep di celle. Nel giugno "72/72 celle ADDS" si leggeva come robustezza; il DSR dice che sono anche 72 tentativi. 2. **`select_cell_insample`** (29/06) — il plateau dell'agente è descritto in termini di **`uplift_hold`**, cioè la cella è stata guardata **sull'hold-out**. È la firma esatta che il gate selection-on-holdout fu scritto per catturare. ### Esito ⚠️ **Prima osservazione: la griglia dichiarata è sbagliata.** Il docstring dice "72-cell sweep", ma il plateau che descrive è 6 assi × 3 valori = **729** combinazioni. Le ho valutate tutte e 729 — scelta **conservativa**, perché più trial abbassano il DSR. **Il plateau è reale e larghissimo:** FULL in [0.60, 0.71], HOLD in [0.68, 0.97], e **729/729 celle con hold-out positivo**. Non è una cella fortunata. **La selection-on-holdout c'è, ma è mite.** La cella pubblicata è **83ª/729 sull'hold-out** ma **471ª/729 in-sample** — la firma è inequivocabile. Solo che, essendo il plateau così piatto, scegliere onestamente la cella in-sample costa poco: | cella | FULL | IS | HOLD | DSR (729 trial) | |---|---|---|---|---| | scelta **IN-SAMPLE** (onesta) | 0.68 | 0.70 | **0.69** | **0.953 PASS** | | scelta sull'hold-out (proibita) | 0.68 | 0.58 | 0.97 | — | | **pubblicata dall'agente** | 0.66 | 0.57 | 0.93 | 0.947 **FAIL** | Cioè: **l'hold-out onesto è 0.69, non il 0.93 pubblicato** — un haircut reale — ma resta chiaramente positivo. E la cella onesta **passa il deflated-Sharpe (0.953)** mentre quella pubblicata lo **fallisce (0.947)**, il che è di per sé una conferma che il gate fa il suo lavoro. Marginale vs TP01 sulla cella onesta: **ADDS**, `robust_oos` ✓, `multicut_persistent` ✓, `is_hedge` ✗, `has_insample_edge` ✓, `beats_noise_null` ✓; corr +0.11, alpha annua **+7.4%**, beta a TP01 +0.117, jackknife_min_uplift **+0.069**; dSharpe sul book **+0.08 FULL / +0.17 HOLD** a w=15%, **+0.11 / +0.25** a w=25%. ### Verdetto: promosso, ma non nel book **DVOLSPREAD esce dal limbo e diventa un candidato in forward-monitor con parametri ONESTI** (`zwin=180, k=2.0, lw=0.6, zw=1.1, tgt=0.17, svw=60` — la cella in-sample), non quelli pubblicati. ### ✅ Monitor CABLATO (stessa sessione) `scripts/live/paper_dvolspread.py`, in `cron_daily.sh` dopo `fetch_dvol.py` (quindi con DVOL fresco), stato in `data/paper_dvolspread/` (gitignored), test `tests/test_paper_dvolspread.py` (10 casi). Inception **2026-07-25**, posizione d'apertura +0.184 → **$111/gamba** (cap $300). **Strumentazione specifica di questo lead** — la ragione per cui non bastava copiare `paper_statarb`: il book va **flat quando il DVOL manca**, quindi un feed rotto produrrebbe una fila di zeri che, contati come evidenza, direbbero *"nessuna perdita"* invece di *"nessuna misura"*. Il monitor tiene una contabilità a **tre stati** — ATTIVE / flat-da-segnale / **flat-senza-dato** — e la finestra forward si misura in **barre attive**, non in giorni di calendario. C'è anche una **guardia sulla config**: se `FROZEN` diverge dallo stato salvato il monitor esce con codice 1 invece di continuare su una finestra non più valida (verificato; nel cron non c'è `set -e`, quindi segnala senza rompere la catena). **Gate pre-registrato (scritto oggi, prima di vedere qualsiasi barra forward):** - **kill anticipato 2026-10-24 (~90g):** Sharpe forward < −0.50 → ritiro; - **decisione 2027-01-24 (~180g):** promozione solo se *tutte e quattro* — (a) Sharpe > 0, (b) marginale ancora ADDS + robust_oos + has_insample_edge, (c) deflated-Sharpe ricalcolato sul campione esteso ≥ 0.95, (d) `weights_tilt_null` superato; - **veto d'integrità:** barre attive < 80% → la finestra non conta, si **estende** invece di decidere su dati mancanti. ⚠️ La soglia (a) è deliberatamente debole — **necessaria, non sufficiente**. Con ~180 barre attive l'errore standard dello Sharpe è ≈1.4: una soglia più alta sarebbe finta precisione. Il peso della decisione sta su (c) — se il margine 0.953, già sul filo, **non migliora** con più dati, l'edge non c'è. **Perché NON entra nel book, dichiarato:** - **campione ATTIVO 1949 giorni su 2691** (72%): prima del 2021-03 non esiste DVOL e il book è correttamente flat. L'**hold-out attivo è 1.6 anni**; - **margine DSR sul filo** (0.953 vs soglia 0.95) — un passaggio, non un'assoluzione; - non ha ancora affrontato `weights_tilt_null`, che ogni cambio di pesi deve superare; - il numero headline che circolava (HOLD 0.93) era gonfiato dalla selezione: **va citato 0.69**. --- ## T3 — XSR01 non generalizza fuori dal crypto ❌ (e si capisce perché) ### La domanda XSR01 ha superato tutto ciò che gli è stato chiesto, ma la sua debolezza numero uno è dichiarata: **2.6 anni monoregime, con l'edge crescente nel tempo** (Sharpe 2024 1.03 / 2025 1.98 / 2026 3.11). Con 2.6 anni non si distingue un meccanismo da un regime fortunato. L'unico modo di guadagnare potenza senza aspettare è portare il meccanismo **congelato** su un pannello lungo decenni. **Non è il test del 25/07.** `r0725_statarb_eq.py` aveva già scartato le azioni, ma testava il meccanismo a **coppie**. XSR01 è la versione **DEMEANATA cross-sezionalmente**, ed è proprio il demeaning ad aver creato l'edge (ampiezza effettiva 4.5 → 37.4). Testare il demean sulle azioni è una domanda diversa, mai posta. ### Esito Meccanismo congelato (W=45, sgn=+1, residuo OLS causale vs **SPY**, z-score, tanh, vol-target 20%, demean giornaliero), split IWM/EFA riparati in lettura, annualizzazione a **√252** (giorni di borsa): | universo | variante | ampiezza eff. | Sharpe **LORDA** | Sharpe netta | maxDD | |---|---|---|---|---|---| | **SECT9** (9 settoriali, 1998+, 26 anni) | coppie | 5.3 | −0.05 | −1.67 | −91% | | **SECT9** | **DEMEAN (= XSR01)** | **6.2** | **+0.24** | −1.61 | −89% | | **ALL28** (tutti gli ETF, 30 anni) | coppie | 8.4 | −0.20 | −1.61 | −92% | | **ALL28** | **DEMEAN** | **11.3** | **−0.14** | −1.82 | −91% | | *XSR01 crypto (25/07, riferimento)* | *DEMEAN* | ***37.4*** | ***+2.70*** | *+1.82* | *−2.6%* | Null di permutazione cross-sezionale **a fee zero** (la lezione XSR01: permutare un segnale ne fa esplodere il turnover, quindi a fee piena il null perderebbe per *costo* e regalerebbe un p-value trionfale e falso): SECT9 candidato +0.24 vs null medio 0.00, **p = 0.193**; ALL28 −0.14, **p = 0.747**. Per decennio (DEMEAN, lordo): SECT9 −0.88 / +0.49 / +0.29 / +0.74 · ALL28 −0.88 / +0.46 / +0.38 / +0.05. Stesso profilo nei due universi: fortemente negativo 1998-2005, debolmente positivo poi — il che somiglia più a un cambio di regime che a un edge. ### Il risultato più interessante non è il Sharpe, è l'ampiezza **Il demeaning non fa sulle azioni quello che fa sul crypto.** Sul crypto porta l'ampiezza effettiva da 4.5 a 37.4 (**8×**); sulle azioni da 5.3 a 6.2 e da 8.4 a 11.3 (**1.2-1.35×**). Il perché è strutturale, e spiega XSR01 meglio di quanto lo spiegasse la sua scoperta: il residuo OLS **rimuove già** il beta al fattore comune. Sul crypto, dopo aver residualizzato su BTC, alle gambe **resta** un enorme fattore comune (ampiezza 4.5 su 50 gambe = quasi una gamba sola) — ed è quello che il demeaning toglie. Sulle azioni il residuo-vs-SPY è **già** quasi indipendente (5.3 su 9 gambe), quindi il demeaning non ha molto da togliere e non c'è guadagno. ### Cosa significa per il gate del 2026-10-23 Il 25/07 aveva già scritto che *«il gate non può appoggiarsi all'argomento fenomeno universale»*. Questo test **lo conferma e chiude la scappatoia** che il test a coppie lasciava aperta: nemmeno la versione demeanata — quella vera di XSR01 — funziona sulle azioni. **Onestà su cosa NON prova:** non prova che XSR01 sia falso. Prova che è **crypto-specifico**, e suggerisce quale sia il meccanismo (l'esistenza di un fattore comune residuo che sopravvive alla residualizzazione, cosa che le azioni non hanno). Il gate del 23/10 resta **interamente** appoggiato sulla finestra forward e sull'haircut di eseguibilità a $5.000, come pre-registrato. Nessuna soglia toccata. --- ## Lezioni da portare avanti 1. **Se si de-lucka una strategia, va de-luckato anche il suo DEGRADO.** L'audit del 02/07 ha corretto i numeri headline di SKH01 per la fortuna d'ancora ma ha misurato il costo d'esecuzione a offset 0 — e quel costo si è rivelato **fortunato quanto i numeri che correggeva**. Ogni Δ fra due varianti misurato su una griglia ancorata eredita la fortuna dell'ancora. 2. **Su una griglia di offset appaiati, la statistica è la mediana delle DIFFERENZE, non la differenza delle mediane.** La seconda confronta offset diversi fra loro e qui ribaltava il verdetto (faceva sembrare l'on-book completo migliore del solo TP, mentre è il contrario). 3. **Un lead lasciato "in forward-monitor" senza monitor e senza data di scadenza è un lead perso.** DVOLSPREAD è stato in limbo 35 giorni. La disciplina che il progetto applica ai candidati nuovi (config congelata + gate pre-registrato + cron) non era stata applicata a lui. 4. **Il claim di multiple-testing di un agente va ricontato, non creduto.** Il docstring diceva 72 celle; la griglia descritta ne contiene 729. Ricontare è conservativo e costa poco. 5. **Quando un meccanismo non generalizza, chiedersi PERCHÉ vale più del fatto che non generalizzi.** Il fallimento di XSR01 sulle azioni ha prodotto la spiegazione migliore di come funziona sul crypto: il demeaning vale quanto vale il fattore comune **residuo** dopo la residualizzazione, ed è una proprietà dell'asset class, non del segnale.