- cblib.causale(s, cadenza): spot_series e dvol_series escono causali (asof = ultima chiusura NOTA); il DVOL giornaliero era una seconda serie con lo stesso difetto (fino a 24h avanti), verificato contro l'API pubblica a 1h. Regolamento ST alle 08:00 invece delle 09:00. - §11 riprodotto al millesimo su worktree HEAD (0,714 [0,690-0,779], n=19, flag --al) e rimisurato: 0,712 [0,664-0,732]; solo spot 0,721, solo DVOL 0,693, DVOL orario di controllo 0,717. Mediana onesta BTC 1,45 → 2,12, fee 1,51x/1,87x. r0730: 0,73 → 0,71. §75: ETH pre 0,76, BTC durante 0,89 (orario 0,83). skew panel ≤0,005. vrp_f_watch: f canonico 0,732 → 0,706, differenza +0,097 [+0,042, +0,140]. - r0909 senza doppio shift, contesto sul DVOL del giorno; r0822 regime su date di calendario; r0901 join riallineato (bit-exact). Aperti con costo: DVOL orario (−0,04/+0,06 nel crollo), spot 5m (≤25 min). - test: +3 causalita' in test_cb_chain_vrp, anti-doppio-shift in test_r0909; suite 1011/1011. - revisione fable: 16 segnalazioni, tutte applicate (fra cui un «−1,8% in un'ora» che era +3,9%). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjj5vPEBoAJrB23P6RjKzs
14 KiB
2026-09-09b — Debito §5.18 riparato: cblib causale (spot +1h, DVOL +1 giorno) e §11 rimisurato
Richiesta dell'operatore: "ripara il debito §5.18 su cblib e rimisura §11". Revisione col modello
fable (agente fresco), come da regola.
Esito in una riga: riparato in cblib — spot e DVOL escono gia' causali — e §11 rimisurato allo
stesso taglio: 0,714 [0,690-0,779] → 0,712 [0,664-0,732] (n=19). Il numero non si muove perche' le due
correzioni hanno segno opposto; nessun verdetto cambia; riparando la prima serie ne e' uscita una
seconda con lo stesso difetto (il DVOL giornaliero, fino a 24 ore avanti); il DVOL orario resta un
passo aperto con costo misurato. Libro, config, cron: invariati. Nessun ordine.
0. Il difetto, verificato prima di ripararlo (D6: si controlla col lag, non si assume)
| serie | come e' etichettata | prova | look-ahead di asof(ts) |
|---|---|---|---|
| feed 1h certificato | all'apertura: la barra T contiene la chiusura di T+1h | chiusura 1h a T == chiusura 5m a T+55 nel 100% delle barre (BTC ed ETH, 1-5/06); a T−5 nell'1,7% / 0% | +1 ora |
dvol_{asset}.parquet (giornaliero, fetch_dvol, resolution=86400) |
al giorno D contiene la chiusura delle 23:00 di D | API pubblica a risoluzione 1h, 1-4/06: close 1D del giorno D == close 1h delle 23:00 di D, e open 1D di D+1 == close di D |
fino a +24 ore |
La seconda riga non era nel debito: e' uscita controllando la convenzione dell'altra serie di
contesto che cblib legge con lo stesso asof. Il sleeve (_vrp_weekly_asset) non ha il difetto:
lavora a cadenza giornaliera e accosta la chiusura del giorno D al DVOL del giorno D, che a quella
cadenza e' coerente. Il difetto e' solo di chi entra a un'ora con una serie giornaliera.
1. La riparazione
cblib.causale(s, cadenza) sposta le etichette (mai i valori) dall'apertura all'istante in cui la
chiusura e' nota. spot_series → causale(·, "1h"), dvol_series → causale(·, "1D"). Conseguenze:
asof(ts)= ultima chiusura conosciuta a ts (prima della prima chiusura nota: NaN, non un valore).- il regolamento
ST = S.asof(exp)alle 08:00 e' ora la chiusura della barra 07:00, cioe' il prezzo delle 08:00 — prima era la chiusura della barra 08:00, cioe' il prezzo delle 09:00, un'ora dopo la scadenza. Deribit regola su una TWAP dei 30 minuti prima delle 08:00: l'approssimazione e' ora dalla parte giusta dell'ora. r0909_crash_catturatonon ri-sposta (lospot_causalelocale della mattina e' rimosso: applicato due volte darebbe la chiusura di due ore prima — lo stesso errore col segno opposto). Test di non-regressione sul sorgente.- chi usa
cblib:r0822_vrp_real_quotes(§11),r0822_skew(§5),r0909(§75),vrp_f_watch(cron giornaliero,data/vrp_f_watch/state.json), e — trovati dal revisore, non da me —r0730_vrp_real_quotes(il f 0,73 [0,706-0,805] di CLAUDE.md §2: rigirato stampa 0,71 [0,680-0,756], n=27, 0/27 ≥ 1, f gamba lunga 1,66 → 1,49; verdetto invariato, numero dichiarato in §2) er0901_btc_collar(join del DVOL per giorno: con la serie causale avrebbe accostato l'IV di D al DVOL di D−1 — riallineato concausale(·, "-1D"), bit-exact a prima, §71 non si muove).options_vrp_calibrate.pyha una copia propria dispot_series(numeri del 20/06): non toccato, dichiarato. - la sezione di REGIME di
r0822(date di calendario: «ultimo giorno aperto», IV-rank per anno) e la tabella di contesto dir0909usanocausale(V, "-1D"): li' serve il DVOL del giorno, non l'etichetta causale — altrimenti ogni data stampata slitta di un giorno (trovato dal revisore). r0822_vrp_real_quotesha ora il flag--al <data>(taglio delle scadenze) per riprodurre una misura a una data: senza, "riprodurre il 22/08" era impossibile perche' la catena cresce ogni ora.
2. Prima di pubblicare il numero nuovo, la macchina ha riprodotto quello vecchio (M23)
Worktree di HEAD (git worktree add, data/raw in symlink), stesso script con --al 2026-08-22:
pooled 0,714 (IC95 [0,690, 0,779], n=19) — al millesimo, IC compreso. Poi lo stesso comando sul
codice riparato.
3. Scomposizione: due correzioni di segno opposto (M26) e un controllo orario
| taglio | spot | DVOL | pooled f | IC95 | n |
|---|---|---|---|---|---|
| 22/08 | grezzo | grezzo (com'era) | 0,714 | [0,690, 0,779] | 19 |
| 22/08 | causale | grezzo | 0,721 | [0,685, 0,758] | 19 |
| 22/08 | grezzo | causale (giornaliero) | 0,693 | [0,670, 0,748] | 19 |
| 22/08 | causale | causale (giornaliero) = cblib oggi |
0,712 | [0,664, 0,732] | 19 |
| 22/08 | causale | causale orario (controllo, API pubblica) | 0,717 | [0,667, 0,732] | 19 |
| 09/09 | grezzo | grezzo | 0,720 | [0,717, 0,952] | 23 |
| 09/09 | causale | causale (giornaliero) | 0,712 | [0,677, 0,741] | 23 |
| 09/09 | causale | causale orario | 0,726 | [0,680, 0,738] | 23 |
Il DVOL di fine giornata alzava f: nel rally la vol scende dentro il giorno, la chiusura di D sta sotto quella di D−1 (+1,05 pt di vol mediana su 19/19 trade, misura del revisore) → denominatore piu' basso → f piu' alto; causale: −0,021. Lo spot di un'ora dopo, invece, non e' un meccanismo ma rumore: lo scarto per trade ha segno misto (mediana −0,02% BTC / −0,11% ETH, banda −0,6…+0,9%) e sposta f fino a ±0,15 per trade (lo spread δ−0,28/−0,10 ha delta netto ~0,18: 0,5% di spot vale 15-20% del credito modellato); il +0,007 netto e' la somma di 19 segni. ⚠️ Corollario: lo spot causale resta stantio fino a 25 minuti (snapshot al :25, chiusura nota al :00), cioe' ±0,05-0,10 di f per osservazione; il feed 5m certificato lo porterebbe a ≤5 minuti. Non fatto: dichiarato in §6. Il DVOL giornaliero causale e' stantio fino a 23 ore (agli ingressi delle 08:00: 8 ore): scarto mediano dall'orario 0,2 punti di vol, max 1,1 (22/08) / 3,0 (oggi). Su §11 vale 0,005 di f.
4. Cosa cambia in §11 (taglio 22/08, stesso campione)
| grandezza | prima | dopo | perche' |
|---|---|---|---|
| f pooled | 0,714 [0,690-0,779] | 0,712 [0,664-0,732] | §3 |
| f BTC / ETH | 0,706 / 0,715 | 0,720 / 0,692 | |
| Sharpe canonico BTC (titolo, non citabile) | 32,58 | 29,61 | regolamento alle 08:00 |
| mediana onesta BTC (9 ancore) | 1,45 | 2,12 | banda [−0,19, 29,61] (era [−0,35, 32,58]) |
| Sharpe canonico ETH → mediana onesta | 3,90 → 2,41 | 7,64 → 3,35 | una settimana ETH cambia taglia: 26/06 −27,38 → −12,84 $ (BTC: 31/07 19,88 → 31,69, 14/08 12,94 → 8,68) |
| media BTC fra le ancore | −1,35% → +11,22% | −0,66% → +11,44% | cambia ancora segno; sd 11,1× → 9,2× |
| forfait fee vs listino | 1,44× / 1,80× | 1,51× / 1,87× | credito modellato a DVOL causale |
| peggior mark: mediana / minimo / minimo fra le vincenti | −6,4% / −91,0% / −56,9% | −6,4% / −91,5% / −55,2% | |
| P&L somma 19 settimane | $2.733 | $2.822 (+3,3%) | tutto dal regolamento |
| sottostante nel campione | +25,1% / +44,2% | +21,1% / +40,1% | il vecchio regolamento del 21/08 era il prezzo delle 09:00, che sta +3,9% sopra quello delle 08:00 (76.311 → 79.316): un numero a due estremi pesa un'ora intera. (La prima stesura diceva «−1,8%»: avevo letto l'ora dopo, 09:00 → 10:00. Corretto dal revisore) |
Verdetto di §11: SCARTATO, per le stesse quattro ragioni (il campione non contiene la strategia; il titolo non sopravvive all'ora d'ingresso; la famiglia con storia non e' quella eseguibile; lo spread e' il costo dominante). Nessuna delle quattro dipende da un'ora di spot. Il testo del verdetto nello script riporta i numeri nuovi con i vecchi accanto.
5. Effetti collaterali, misurati (tutto cio' che legge cblib)
§75, crollo catturato (r0909, rigirato): ETH pre-crollo f_net 0,74 [0,65-0,82] → 0,76
[0,71-0,86]; peggior MTM 1,08 [1,07-1,31] → 1,08 [1,06-1,27]; put δ−0,10 1,92× → 1,98×; al picco 0,94 →
0,99; BTC durante 0,79 → 0,89 [0,74-1,05], ETH durante 0,71 → 0,78. Con il DVOL orario BTC durante fa 0,83: nel crollo
il DVOL sale di 5-6 punti al giorno, quindi il giornaliero di fine giornata (com'era) sottostima f e
quello del giorno prima (causale) lo sovrastima — −0,04/+0,06 di f e' il prezzo della stantiezza in un
crollo, ed e' l'argomento per il feed orario. DVOL "pre" 37,3 → 36,4 (BTC): il 37,3 era la chiusura
del primo giorno di crollo (01/06, −3,5%), non del giorno prima — IV-rank pre 0,05 → 0,03. Picco e
percentili invariati (49,1 / 69,2; 29° / 46°) dopo aver corretto la tabella di contesto (§7).
Verdetto invariato.
§5, skew (r0822_skew, rigirato, 66 s): la scomposizione sul panel si muove di ≤0,005 per fattore
(term 0,880 · skew 0,917 · spread 0,910 · fit 0,995 · f_tot 0,729); Q1/Q2 (lag prezzo/skew) non si
toccano (serie proprie ancorate a ts_max). Agli ingressi il controllo f_markfit passa da 1,045 a
0,991 e le osservazioni che lo superano da 22/28 a 25/28: l'ora di spot in piu' stava nel
controllo, non nell'effetto — riparare ha reso il controllo piu' pulito, non il risultato diverso.
vrp_f_watch (sorvegliante in cron_daily, criteri pre-registrati il 30/07 e non toccati):
| prima (state.json del 09/09 mattina) | dopo | |
|---|---|---|
| coppie | 28 | 28 |
| f canonico | 0,732 [0,702-0,784] | 0,706 [0,678-0,745] |
| f candidato | 0,803 [0,741-0,842] | 0,805 [0,771-0,840] |
| differenza | +0,054 [−0,027, +0,105], 18/28 > 0 | +0,097 [+0,042, +0,140], 21/28 > 0 |
| ampiezza IC95 (b ≤ 0,12) | 0,131 — no | 0,098 — OK |
| coppie (a ≥ 40) | no | no |
ready |
False | False |
Lo state.json e' stato riscritto dal mio lancio (21:14Z, senza --quiet; nessun Telegram: notifica
solo a ready); il «prima» completo e' la colonna qui sopra (n_positive 18, esclude_zero False), e il
cron lo rigenera domani. La differenza ora esclude lo zero. Non decide niente: (a) non e' soddisfatto e il candidato resta
bocciato sul deflated-Sharpe, che non dipende da f. Si registra perche' fra un mese qualcuno leggera'
"esclude lo zero" e deve sapere da quando e perche'.
6. Cosa resta aperto, col suo costo
| voce | costo di non farlo | costo di farlo |
|---|---|---|
DVOL orario nel feed (fetch_dvol --res 3600, riga in cron_daily, cblib che lo legge) |
su §11 0,005 di f; su un crollo ±0,05; ogni misura oraria su opzioni a DVOL giornaliero eredita lo scarto | un fetch pubblico gratuito (3.163 barre da maggio in 2 chiamate), una riga di cron, e una decisione: e' un feed nuovo dentro il perimetro (D1, certificazione, backup) |
| spot causale stantio ≤25 min (snapshot :25, chiusura :00): ±0,05-0,10 di f per osservazione | cblib.spot_series sul feed 5m certificato (causale(·, "5m")): cambia di nuovo ogni numero di cblib, quindi con rimisura dichiarata |
|
options_vrp_calibrate.spot_series (copia, 20/06) |
i numeri del 20/06 (f 0,73) restano con l'ora in piu'; §11 li ha gia' sostituiti | riscriverlo su cblib |
| la tabella pubblicata di §5 (x0,869 / x0,904 / x0,920) | ≤0,005 per fattore: sotto la risoluzione del campione (14+14 scadenze) | nulla: nota aggiunta |
7. Errori dell'autore in sessione
asi8in microsecondi scrivendo il test della causalita' (pandas 3): i timestamp sintetici finivano nel 1970 e il test falliva per la fixture, non per il codice. E' la trappola del debito 1, ripagata scrivendo un test sul debito 18. Corretto con(idx − epoch) // Timedelta(ms), la convenzione diload_tf.- La tabella di contesto di
r0909si e' spostata di un giorno dopo la riparazione: mostrava il DVOL del giorno D−1 accanto al prezzo del giorno D, e il picco del crollo cambiava (69,2 → 68,3, 46° → 43°) non per una misura ma per un'etichetta. Trovato col diff degli output, non da un test: una tabella per umani non ha test. Ora il contesto usa la chiusura del giorno (causale(V, "-1D"), dichiarato nel commento) edvol_pre/ivr_prerestano causali. - Il verdetto §7 di
r0822_vrp_real_quotesera prosa con numeri cablati: sarebbe rimasto a 0,714 per sempre (N11 al contrario). Aggiornato con i vecchi accanto; il difetto di forma resta (i numeri del verdetto andrebbero calcolati, non scritti).
8. Revisione (fable, agente fresco) — 16 segnalazioni, verdetto «correggi e committa»
Ha riverificato in proprio la convenzione delle due serie (1h vs 5m su 120 barre: 100%; DVOL contro
l'API oraria) e riprodotto ogni numero dei documenti lanciando gli script. Applicate: #2 «−1,8% in
un'ora» era falso (avevo letto 09:00 → 10:00; il fatto e' +3,9% 08:00 → 09:00) · #3 due delle tre
settimane «ETH» erano BTC · #4 la parentesi sul DVOL era invertita (la chiusura di D e' piu' BASSA,
non piu' alta) · #5 lo spot non e' un meccanismo ma rumore, e resta stantio ≤25 min · #6/#7 due
lettori di cblib non dichiarati: r0730 (0,73 → 0,71, ora in CLAUDE.md §2) e r0901 (riallineato) ·
#8 le date di calendario di r0822 §1 slittavano di un giorno · #9 il test anti-doppio-shift non
catturava causale(spot_series, "1h"): ora conta i causale( · #10 ancora 0,74 → 0,76 nel test
d'integrazione · #11 teste di §75 e memoria 20 §5 con i numeri vecchi come correnti (M28) · #12
«±0,05» → «−0,04/+0,06» · #13 state.json riscritto: dichiarato · #15 lo skew agli ingressi cambia
piu' del panel (correlazioni che cambiano segno): dichiarato in §5. Non applicate: nessuna. Confermati
senza rilievo (#1, #14, #16): verso e taglia degli shift, nessun doppio spostamento, ST alle 08:00
coerente con la TWAP 07:30-08:00, tutti i numeri di §3-§5.
9. Test
tests/test_cb_chain_vrp.py: +3 (causale; spot_series causale sul feed 1h con controllo positivo sulla
serie grezza; dvol_series causale sul giornaliero). tests/test_r0909_crash_catturato.py: il test dello
shift locale diventa "lo script usa le serie di cblib senza ri-spostarle" (sorgente + controllo positivo
su cblib.causale). Suite intera: 1011 passati, 0 falliti (erano 1008), rilanciata dopo le correzioni della revisione: 1011/1011.