Il follow-up "book sul path live" era fermo da tre sessioni su questa premessa:
"il simulatore compone per-trade a nozionale unitario, LO SLEEVE E' VOL-TARGETED".
LA PREMESSA ERA FALSA. Verificato in tre modi: _skyhook_returns chiama backtest_signals
con leverage=1.0/position_size=1.0; nessun target_vol/vol_target/realized_vol nel
sorgente; sim_equity(canonical) riproduce backtest_signals a max|diff| = 0.0. Il 20.7%
di vol realizzata dello sleeve e' un PRODOTTO della strategia (uscite % asimmetriche +
poco tempo a mercato), non un parametro: SKH01 e' l'unica delle 5 a NON essere
vol-targeted, il contrario di quanto si credeva. Test permanente cablato.
MISURA (ingressi live vs backtest, de-luckata su 8 offset a priori; sanity 120/120 bin
con ingresso ricostruiti):
- il numero del 26/07 era ~4x troppo grande: like-with-like (mediana PER-ASSET) +0.38 su
3 offset -> +0.097 su 8, e "6/6 non negativi" -> 13/16. Sleeve 50/50: +0.112, 8/8.
- a livello di BOOK lo Sharpe e' una monetina (FULL +0.048, HOLD +0.051) ma il DRIFT e'
+0.73pp positivo nel 100% delle estrazioni: l'ingresso intra-bin prende un prezzo
migliore, i falsi ingressi aggiungono churn, vol e ritorno salgono insieme.
IL FATTORE x0.6 DECOMPOSTO E MISURATO:
(a) fortuna d'ancora sul DRIFT: x0.874 (5-sleeve) / x0.890 (book live). La vol e'
invariata fra le ancore (7.80->7.76%): la fortuna sta tutta nel drift.
(b) path live: NON-NEGATIVO ovunque (uscite +0.081 Sh, ingressi +0.73pp, TP01 ~0).
Il x0.6 implicava un residuo x0.687 attribuito al live oltre l'ancora, che nessuna misura
sostiene -> FATTORE ONESTO x0.87-0.91, troppo severo del 31-34%. Il sospetto registrato
il 25/07 ("conta due volte la degradazione SKH01") e' confermato quantitativamente.
MURI DI CAPITALE ricalcolati con la stessa macchineria del 25/07: perpetua 6.00% ->
10.91%, muro per 50 EUR/g $494.758 -> $272.061 (-45%) a leva 1.0. La conclusione
STRUTTURALE non cambia: $272k restano ~453x il conto di oggi.
IPOTESI MIA REFUTATA nella stessa sessione: che la grid timing-luck di SKH01 fosse un
artefatto della lente a chiusura-di-bin. Dispersione LIVE/CANONICO = 1.59x -> il live e'
PIU' disperso. L'audit del 02/07 resta valido com'e'. (Nata su 2 offset, chiusa a 8.)
Trovato per strada: simulate() in r0726_skh_partial_entry.py non era mai chiamata da
main() — i numeri headline di quel diario venivano da una corsa mai committata.
Book, pesi, cron, config INVARIATI.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
10 KiB
2026-07-26 — Follow-up SKH01 "vol-targeted": il blocco non esisteva. E il ×0.6 era troppo severo del 31-34%.
Richiesta: "fai il follow-up SKH01 vol-targeted".
Script: r0726_skh_sigcache.py (cache), r0726_skh_live_book.py (misura),
r0726_deluck_factor.py (decomposizione), r0726_capwall_refresh.py (muri ricalcolati).
Test: tests/test_skh_live_book.py (8). Book, pesi, cron, config: INVARIATI.
0. Il follow-up era mal diagnosticato
Portato avanti come bloccante per tre sessioni, con questa motivazione registrata in CLAUDE.md:
il book ricalcolato sul path live e' bloccato da una incompatibilita' di lenti — il simulatore SKH01 compone per-trade a nozionale unitario, lo sleeve e' vol-targeted; combinarle darebbe un numero preciso e falso.
Lo sleeve SKH01 non e' vol-targeted. Tre verifiche indipendenti:
_skyhook_returnschiamabacktest_signals(..., leverage=1.0, position_size=1.0)— che nel suo docstring dice "ogni trade muove capital di position_size * leverage * ret_netto": compounding per-trade a nozionale pieno, la stessa lente del simulatore;- nel sorgente dello sleeve non compare
target_vol/vol_target/realized_vol; r0702_anchor_skh01.sim_equity(mode='canonical')riproducebacktest_signalscon max|diff| = 0.0.
Vol annualizzata realizzata per sleeve: SKH01 20.7%, TP01 12.2%, XS01 20.9%, GTAA01 5.4%. Il 20.7% e' probabilmente cio' che aveva suggerito "vol-target 20%" — ma e' un prodotto della strategia (uscite % asimmetriche + poco tempo a mercato), non un parametro. SKH01 e' l'unica delle cinque a NON essere vol-targeted, ed e' il contrario di quanto si credeva.
Lezione: un blocco dichiarato va ri-verificato prima di costruirci sopra, non ereditato. Qui il costo e' stato tre sessioni di follow-up rimandato per un ostacolo inesistente, e la verifica che lo ha smontato e' durata due minuti.
1. La misura: ingressi live vs backtest, de-luckata
Due path identici in tutto (livelli, uscite intra-barra, cap max_per_day, fee, non-overlap)
tranne quando si valuta l'ingresso: LIVE = a ogni confine orario dentro il bin 230m (cio' che
il cron fa), BACKTEST = solo a chiusura di bin.
Riusa la macchina a stati fedele del 26/07 (r0726_skh_partial_entry.simulate). ⚠️ Trovato per
strada: simulate non e' mai chiamata da main() di quello script — i numeri headline del suo
diario vennero da una corsa ad hoc mai committata. Qui il driver e' committato.
Costo: la ricostruzione del segnale a ogni osservazione oraria costa ~9 min per (asset, offset). Su 2 core con il cron live da non affamare, la griglia piena (23 offset) era fuori portata → sottocampione uniforme dichiarato a priori: 8 offset, uno ogni 90m su [0,690). E' un sottocampione per costo, non una selezione; la banda che ne esce ha 8 punti invece di 23.
Sanity superato prima di tutto (campionato sugli EVENTI, non sulla popolazione — lezione del 26/07): 120/120 bin con ingresso ricostruiti su entrambi gli asset.
off CANON ShBT ShLIVE dSharpe trade LIVE trade BT falsi
0 +1.446 +1.174 +1.204 +0.029 534 447 68
90 +1.043 +1.182 +1.194 +0.011 538 472 67
180 +1.467 +1.505 +1.698 +0.193 544 469 60
270 +1.231 +1.199 +1.205 +0.006 605 477 179
360 +0.761 +1.069 +1.397 +0.328 570 478 109
450 +0.921 +0.917 +2.025 +1.108 530 484 36
540 +0.751 +0.374 +0.445 +0.071 531 411 138
630 +0.871 +0.991 +1.144 +0.154 460 412 47
SLEEVE (50/50) mediana appaiata +0.112 positive 8/8 banda [+0.006, +1.108]
PER-ASSET mediana appaiata +0.097 positive 13/16 banda [-0.170, +1.086]
Il numero del 26/07 era ~4x troppo grande. Confrontando like-with-like — quel diario citava la mediana per-asset — si passa da +0.38 su 3 offset a +0.097 su 8, e da "6/6 non negativi" a 13/16. Il segno regge, la taglia no: ennesimo Δ misurato su poche ancore che ne eredita la fortuna. L'outlier a offset 450 (+1.108) mostra perche' la statistica e' la mediana.
⚠️ Le due righe della tabella non sono la stessa grandezza e vanno tenute separate: nel BOOK entra lo sleeve 50/50, dove la diversificazione BTC/ETH cambia il denominatore.
A livello di book
dSharpe FULL mediana +0.048 p10 -0.015 p90 +0.677 >0 in 79.3%
dSharpe HOLD-OUT mediana +0.051 p10 -0.589 p90 +0.721 >0 in 51.2%
d drift annuo mediana +0.731pp p10 +0.044pp p90 +6.800pp >0 in 100.0%
Lo Sharpe e' quasi una monetina, il drift e' positivo nel 100% delle estrazioni. Meccanismo: l'ingresso intra-bin prende un prezzo migliore (piu' drift) ma i falsi ingressi aggiungono churn (530-605 trade live contro 411-484) → vol e ritorno salgono insieme e lo Sharpe non si muove. Per la domanda del ×0.6, che e' sul drift, il numero rilevante e' +0.73pp.
2. Un'ipotesi mia, nata e morta nella stessa sessione
Guardando i primi due offset avevo notato che il canonico oscillava di 0.40 mentre i path del simulatore stavano fermi, e ne avevo tratto un'ipotesi: la grid timing-luck di SKH01 (audit 02/07: 93-98° pctl, "spike non plateau", gate DD<30% che fallisce in 15/23 offset) sarebbe stata in buona parte un artefatto della lente a chiusura-di-bin, non una fragilita' della strategia live — che valuta ogni ora e non e' ancorata al confine del bin.
Refutata. Dispersione dello Sharpe fra gli 8 offset:
path min mediana max range std
CANONICO (chiusura bin) +0.751 +0.982 +1.467 0.716 0.289
BT-sim (chiusura bin) +0.374 +1.122 +1.505 1.131 0.325
LIVE-sim (intra-bin) +0.445 +1.204 +2.025 1.580 0.459
rapporto di dispersione LIVE/CANONICO: 1.59x
Il path live e' piu' disperso fra le fasi della griglia, non meno. L'audit del 02/07 resta valido com'e': la timing-luck di SKH01 e' della strategia, non della lente. L'ipotesi e' nata su 2 offset, si e' incrinata a 4 (1.24x) e si e' chiusa a 8 (1.59x) — e la direzione dell'errore era sempre la stessa, il che e' il motivo per cui 2 punti non bastano mai.
3. Il ×0.6 decomposto, misurato, corretto
Il fattore taglia il drift (b - 0.4*mean(b)) ed era applicato sopra la lente hourly,
cioe' sopra un modello del live gia' pessimistico. Mescolava due cose separabili.
(a) Fortuna d'ancora sul drift — misurata sullo spazio congiunto:
| canonico | pctl | MEDIANA | p10-p90 | |
|---|---|---|---|---|
| book 5-sleeve, drift | 17.33% | 96.0° | 15.15% | [13.88, 16.49] |
| book 5-sleeve, CAGR | 18.56% | 96.0° | 16.00% | [14.55, 17.56] |
| book LIVE 75/25, drift | 19.27% | 93.8° | 17.16% | [15.75, 18.67] |
→ fattore d'ancora ×0.874 (5-sleeve) / ×0.890 (book live). La vol e' invariata fra le ancore (7.80% → 7.76%): la fortuna sta tutta nel drift, non nel rischio.
(b) Degradazione del path live — non-negativa su tutto cio' che e' stato misurato: uscite SKH01 +0.081 Sharpe di book (23/23 offset); ingressi SKH01 +0.73pp di drift (100% delle estrazioni); TP01 barra parziale trascurabile (24 ancore).
Il ×0.6 implicava un residuo ×0.687 attribuito al live oltre l'ancora. Nessuna misura del progetto lo sostiene. Il sospetto gia' registrato in CLAUDE.md — "il ×0.6 sopra il path live rischia di contare DUE VOLTE la degradazione SKH01" — e' confermato quantitativamente.
FATTORE ONESTO: ×0.87 – ×0.91 (5-sleeve) / ≥×0.89 (book live), contro il ×0.60 in uso. Troppo severo del 31-34%.
La componente uscite spingerebbe oltre, ma e' misurata in Sharpe e non in drift: non convertita, per non inventare precisione. Quindi il limite superiore e' esso stesso conservativo.
4. Cosa cambia nei muri di capitale (r0726_capwall_refresh.py)
Stessa macchineria del 25/07 (book_series, survival, _boot_paths importati, non riscritti).
fattore leva SWR-20a PERPETUA capitale
×0.60 (25/07, a occhio) 1.00 7.36% 6.00% $494,758
×0.60 (25/07, a occhio) 1.50 8.16% 8.11% $366,300
×0.89 (26/07, ancora MISURATA) 1.00 10.94% 10.91% $272,061
×0.89 (26/07, ancora MISURATA) 1.50 13.72% 14.87% $199,625
×1.00 (nessun haircut) 1.00 12.48% 12.72% $233,330
Il muro per 50 EUR/g scende del ~45%: da ~$495k a ~$272k (leva 1.0), e il valore vero sta fra la riga ×0.89 e la riga ×1.00 perche' ×0.89 e' un limite inferiore.
Cio' che NON cambia: $272k restano ~453x il conto di oggi. La conclusione strutturale del 25/07 — i 600 euro come CAPITALE sono refutati, come BIGLIETTO (prop) no — regge intatta. Cambia la taglia dell'errore, e cambia che il numero e' misurato invece che scelto.
Rendita sul conto attuale: EUR 0.12/g (×0.6) → EUR 0.18/g (×0.89). A questa taglia sono centesimi: il fattore conta per il MURO e per le soglie prop, non per il conto di oggi.
5. Regole trasferibili
- Un blocco dichiarato e' un'ipotesi, non un fatto. Ri-verificarlo prima di costruirci sopra o di rimandare: qui tre sessioni di attesa contro due minuti di verifica.
- Un Δ su poche ancore eredita la loro fortuna, sempre — terza occorrenza in due giorni (recupero on-book, degrado d'esecuzione, e ora gli ingressi: +0.38 → +0.097).
- Quando un fattore correttivo e' scelto a occhio, decomporlo prima di rifiutarlo o accettarlo. Il ×0.6 non era "sbagliato": era due fattori moltiplicati insieme, uno dei quali contato due volte.
- Sharpe e drift rispondono a cose diverse. L'effetto ingressi e' una monetina sullo Sharpe e certo sul drift: chiedersi quale delle due grandezze entra nella decisione prima di misurare.
- Due punti non fanno una tendenza — nemmeno quando la meccanica sembra spiegarla. L'ipotesi sulla dispersione era plausibile e sbagliata, e il costo di verificarla era basso.