Commit Graph

143 Commits

Author SHA1 Message Date
Adriano Dal Pastro ec8478308f GATE SCALA-01: la chiave di scala esiste, ed e' INERTE (SPEC §8 punti 1-4)
Chiude il debito che CLAUDE.md dichiarava da settimane: la regola "ogni cambio
di scala passa dal cap di config, non da target_vol" NON era implementabile
perche' una chiave di scala non esisteva — qualunque cambio sarebbe finito su
WEIGHT/W_TP01/W_SKH, cioe' codice su un percorso con soldi veri e per giunta
nel posto sbagliato (W_TP01/W_SKH sono il RAPPORTO 75/25, non la taglia).

Specifica gia' scritta in docs/research/SPEC-scale-key.md (618 righe, 9
condizioni di gate, prototipo). Non ho progettato: ho eseguito i punti 1-4.

🚨 config/live.json NON E' STATO TOCCATO. La chiave e' assente, vale 1,00, e
T7 dimostra bit-exact che il libro e' quello di ieri (max|diff| = 0.0).
Verificato anche a runtime: book_execute in dry-run da' gli stessi target del
cron delle 15:47 (BTC $+355, ETH $+214).

LE QUATTRO DECISIONI CHE NON SONO DI COMODO
- La scala si applica DOPO il clamp. Prima, il cap se la mangerebbe proprio
  nei giorni di massima convinzione (a tp=1/sg=+1 il grezzo vale esattamente
  cap => k_eff tornerebbe a 1,00 a ogni k): sarebbe un cambio di FORMA
  travestito da cambio di taglia, e la curva g(k) con cui il gradino viene
  autorizzato non descriverebbe quel libro. Prezzo dichiarato: il cap diventa
  il tetto del libro UNITARIO, e la guardia sulla leva lorda va ricostruita.
- Il tetto e' sul PRODOTTO e sta nel CODICE. Sulla sola chiave lascerebbe
  aperta la porta accanto (frac 0,625 x scala 1,25 = 1,562x); in config
  sarebbe un lucchetto con la chiave attaccata. LEVA_LORDA_MAX 1,25 in
  src/live/book.py => il gradino a 1,50 richiede codice, quindi review.
- Fuori scaletta o fuori tetto = STOP, non clamp. book_execute si ferma, non
  invia, allerta (ScalaNonAutorizzata). E SCALA_LADDER (1,00 · 1,25) rende
  INESPRIMIBILE "solo un po'": 1,05 non e' prudente, e' fuori scaletta.
- La scala vive solo sul percorso fidato (equity illeggibile => 1,00), cosi'
  "il fallback non e' piu' permissivo" e' vero per costruzione. Ma la
  VALIDAZIONE avviene sempre: una config rotta non si nasconde dietro un giro
  in cui l'equity non era leggibile.

LA GUARDIA CHE MORDE PER PRIMA non e' il peggior giorno (k <= 3,49x) ma il
COSTO di un disaster-SL (k <= 1,67x, 2,1x piu' stringente): l'invariante
n_asset x frac x scala x disaster_sl_pct <= 0,50 scatta anche se qualcuno
allarga lo stop invece di alzare la scala.

TEST T1-T11 (tests/test_book_scale.py, 18 verdi). Il piu' importante e' T1b:
a k=1 l'implementazione simmetrica e quella asimmetrica danno lo STESSO
numero, quindi un test di simmetria scritto sul caso di default ha potenza
ZERO. T1b verifica che le due coincidano a k=1 (il rischio e' reale) e che
fuori da k=1 l'asserzione le SEPARI, con un'implementazione asimmetrica
scritta nel test apposta perche' fallisca.

SORVEGLIANTE scale_watch (cron_daily, 3 domande / 3 azioni / 3 stati, una
allerta per streak, marcatore scritto solo dopo invio riuscito — debito #2).
Riporta la frequenza del ramo di fallback, che sopra il 2% in 90 giorni
invaliderebbe la regola: misurata 0/1.676, coi 19 giri "paper capital"
(pre-finanziamento, dove il libro non invia) contati e dichiarati a parte.
Non puo' impedire la modifica: la rende visibile entro 24h e attribuibile.

CHIUDE il debito #5 di §5: T2/T3 sostituiscono il vecchio
test_leva_massima_da_config (che misurava frac x n_asset mentre la grandezza
vera e' frac x n_asset x scala), e T11 verifica che sia rimasto cancellato.

NON FATTO, deliberato: la chiave in config (punto 2 lo vieta), GATE SCALA-01
(A2 richiede >=30 giorni a 1,00 col sorvegliante attivo — "l'unico modo di
scoprire che il sorvegliante e' rotto mentre la leva e' ancora 1,00"),
r0726_fee_sensitivity rifatto (A7: serve solo al gradino; a 1,25x una
liquidazione costerebbe 1,25% non 1,00%, e ereditarlo sarebbe l'errore).

Nessun ordine. Suite: 825 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 17:44:02 +00:00
Adriano Dal Pastro 05816c49f9 COLLAR01 (§71): il pavimento funziona, il tetto lo paga troppo — e cio' che vince e' VRP01
Chiesto dall'operatore in quattro battute: hold BTC long o short coperto in
opzioni, scadenza <=15gg, "ridurre la vincita ma bloccare la perdita" (=>
collar, non put protettiva), entrata gated da indicatori ("forte bull"), e
uscita dalle opzioni fra il 50% e il 75% del tempo.

PERCHE' SI POTEVA RIAPRIRE DOPO §46. §46 (tail-hedge) fu refutato sul beta
+0,076 del libro — "non si assicura un libro che nei crash e' gia' quasi
piatto". Qui il sottostante e' un hold di BTC, beta 1,0: quel motivo non si
applica. E §46 dichiarava non provata proprio la copertura gated su regime.

L'entrata non aggiunge un solo parametro: tsmom_blend media tre np.sign() su
(30,90,180) => valori in {-1,-1/3,+1/3,+1}, quindi "forte bull" = |blend|==1
(52,5% dei giorni) contro il confronto dichiarato |blend|>=1/3 (97,1%).

RISULTATI (lente lunga 2021-03 -> 2026-09, 5,44 anni; griglia 48 celle
dichiarata prima + 36 di estensione dichiarata):
- A1 CONFERMATA: il pavimento FUNZIONA, maxDD scende in 36/48 (§46: saliva
  in 162/162). La meta' della domanda ha risposta positiva.
- A3 CONFERMATA: il de-levering lo fa meglio in 45/48. Δdrift/ΔmaxDD 7,90
  (gate forte) / 1,98 (largo): 2-8 punti di drift per punto di DD.
- C9 in forma pura: il tetto taglia il 46,2% dei cicli VINCENTI, il pavimento
  para il 6,7% dei PERDENTI — 7x piu' spesso sui vincenti: troncatura.
- M1: collar Sharpe 0,508 vs TP01 0,852; TP01+10% => +0,000 di Sharpe e
  +2,32pp di maxDD.

IL FATTO CHE VALE PIU' DEL VERDETTO. Le 3 celle vincenti stavano tutte sul
BORDO; estesa la famiglia vince 35/36 nell'ANGOLO (dput 0,02 / dcall 0,50,
Sharpe 1,471) — e il limite di quell'angolo e' una COVERED CALL: la pendenza
porta fuori dalla domanda posta e dentro lo short-vol. E quel 1,471 e' il
prezzatore che si paga da solo: DVOL/RV-forward 1,320 a 7g (sopra nel 76,9%
dei giorni) => riprezzato alla vol vera l'angolo cade a 0,511, che e' VRP01
(0,47). Non una scoperta: VRP01 per una strada piu' lunga. §3 lo blocca.

USCITA ANTICIPATA: implementata (exit_frac) e COSTA. Cella onesta gate forte:
drift +9,48% (scadenza) -> +3,84% (50%), esito da VINCE a perde sotto 0,75.
Il meccanismo previsto c'e' (VRP residuo +3,38 -> +1,27pp) ma lo spread lo
travolge. Corregge l'applicazione di §46: "un roll anticipato non paga f"
vale per una copertura solo LONG; in un collar la gamba venduta va
RICOMPRATA, quindi si paga f sulla parte che a scadenza si regolava gratis.
L'asimmetria si INVERTE quando la struttura ha una gamba corta.

CONTROLLI DELL'APPARATO 3/3 (M15): pranzo gratis riconosciuto (maxDD
51,83%->36,76%, drift +10,04%->+35,69%), premio x10 rifiutato, zero-cost
finito. Cinque difetti miei catturati dai controlli, non a occhio: bisezione
zero-cost invertita (dava Sharpe -3,9), dcall=NaN nella cassa, C9 non
consapevole della direzione (S1>S0 non e' "vincente" per uno short), e due di
contabilita' che avrebbero ADULATO il collar (base che rollava lo spot
pagando ~3,6%/a di fee inesistenti; roll che chiudeva lo spot senza motivo).

Corregge anche un muro di §46: il tick da 5 USDC e' della famiglia USDC; la
catena che raccogliamo e' 100% inverse, quindi li' non si applica.

Regole nuove in CLAUDE.md: M29 (un edge da opzioni prezzate a modello si
riprezza alla vol REALIZZATA prima di crederci), M8 esteso (un argmax sul
BORDO e' una pendenza, non una cella), C4 esteso (il segno dell'asimmetria di
f dipende dal verso della gamba).

Libro, pesi, cron, config INVARIATI. Nessun ordine. Suite: 807 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 17:30:18 +00:00
Adriano Dal Pastro 30286ea033 venue_news: sorvegliare cosa il venue ANNUNCIA — e due correzioni dalla KB
Nasce dall'annuncio sulla fine della Proof of Reserves. La notizia in se' vale
poco: si perde un segnale ad alta frequenza e DEBOLE (una PoR auto-pubblicata
prova che gli attivi esistono in un istante, non che coprano le passivita') e si
guadagna un audit annuale indipendente sotto VARA piu' il 90% degli attivi presso
Coinbase come custode. E non l'abbiamo mai sorvegliata: zero occorrenze nel
codice. Rinunciato di proposito a catturare l'ultimo dato — uno snapshot singolo
auto-riportato non regge lo standard di prova e non permetterebbe di stimare `p`.

CONSEGUENZA VERA: la decisione "100% Deribit fino a $20k" ha fra i suoi riapritori
"`p` che diventa stimabile invece che assunto". Dal 1/9 il segnale pubblico passa
da quotidiano ad ANNUALE: da una serie si stima, da un punto all'anno no. Quel
riapritore diventa praticamente irraggiungibile => la decisione e' ora gated SOLO
dal capitale.

TROVATO CERCANDO: esiste un feed RSS degli exchange-update, e conteneva quattro
annunci materiali che nessuno leggeva. Il caso che decide: le specifiche dei perp
USDC sono cambiate il 18/08, ANNUNCIATE IL 14/08. check_specs() e' nato da quella
svista e gira ogni ora, ma rileva la deriva DOPO; il feed l'avrebbe detta quattro
giorni PRIMA. La prima volta e' andata bene solo perche' i cambi erano RIDUZIONI.

Costruito scripts/live/venue_news.py (in cron_daily accanto a fee_watch):
  - NON interpreta: dice "e' uscito questo, guardalo". Nessun automatismo su un
    testo di marketing (P13). Classifica solo l'urgenza.
  - parole-chiave DERIVATE da deribit._CONTRACT e config/live.json, non
    ridichiarate (P1): chi aggiunge un asset allarga la sorveglianza da solo, ed
    e' il test che lo blinda.
  - primo giro semina senza allertare (P9); feed illeggibile -> exit 2, mai
    silenzio implicito (P5).
Debito #8 si RESTRINGE, non si chiude: il Rulebook non ha un feed.

Confermato due volte lo zero USDC: l'espansione del 31/07 non contiene l'Italia
ne' alcun paese UE, mentre San Marino e Citta' del Vaticano SONO idonei. Non
asserisco una causa (ci sono anche Canada e Giappone).

DUE CORREZIONI dalla KB "Cross collateral specifications":
(a) Il saldo negativo costa una collateral fee dello 0,05% AL GIORNO = 18,25%/anno,
    al secondo — 4,3x la resa USDE. Il 30/08 avevo scritto "lo finanzia a
    interesse" SENZA il numero: giusto e vuoto. Col numero, il criterio del
    cuscino di regolamento diventa aritmetica (-14 punti). E il ribilanciamento
    automatico non salva: scatta a $1M assoluti o al 100% della cross equity,
    irraggiungibili a $2k. Non veniamo ribilanciati: sanguiniamo la fee.
(b) L'haircut USDe ufficiale e' 5%, noi abbiamo 0.10 registrato come "verificato
    sul venue" il 26/08 senza traccia di come. NON riparato (P12/M28): si tiene
    0.10 perche' e' il lato conservativo, non e' sul percorso soldi e non morde
    fino al 90% di quota. Divergenza dichiarata in config.
Di lato: BUIDL haircut 2% (sarebbe stato il miglior collaterale del listino, se
si potesse comprare), stETH 7,5% (terza ragione indipendente per lasciarlo stare).
Nessuna fonte documenta un tetto sulle QUANTITA': il ~31,2% resta misurato e non
spiegato — e ora si sa che non e' una svista di lettura.

Suite: 800 passati (5 nuovi su venue_news).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:47:15 +00:00
Adriano Dal Pastro 993d17556a usde: gate CHIUSO IDONEO, quota rinviata a lunedi' — l'APR si legge col suo n
Il 2026-08-28 12:35Z `usde_watch` ha rilevato il primo reward (+0.052055 USDE su
500), e la regola pre-registrata il 26/08 PRIMA dell'esito ha chiuso il gate
USDE-01 su IDONEO. Si apre la decisione di QUOTA, che e' dell'operatore.

DECISIONE DELL'OPERATORE (29/08): la quota si decide lunedi' 31/08, su tre-quattro
finestre invece che su una. Il motivo e' un numero: sul solo pagamento il tasso
implicito e' 3,80% annuo, su DUE finestre — il 27/08 aveva pagato ZERO — e' 1,90%.
Fra i due c'e' tutta la decisione, e il campione e' UN pagamento.

`rendimento()`: APR sulle finestre OSSERVATE, col denominatore sul TEMPO VERO e
non sul numero di finestre pagate — cosi' una finestra che non paga ABBASSA la
stima invece di sparire (P5: quel silenzio e' uno zero). Le letture con trade nel
mezzo si escludono, non si riparano in silenzio (P12). L'APR si stampa sempre col
suo `n`, e sotto 4 finestre la riga dice «un pagamento non e' un tasso». Sulle
letture vere: 1,97% annuo su 1,9 giorni, 1/2 finestre pagate.

`quota_da_decidere()`: vera SOLO se IDONEO E il rinvio e' scaduto. Da lunedi' il
watch manda il 📌 OGNI giorno — quota attuale, tetto di allerta, APR osservato —
finche' non si decide (N9: una decisione rinviata senza promemoria e' rinviata per
sempre). Stesso schema della soglia $15k di GTAA01, con la data al posto del
capitale. Si smette togliendo `DECISIONE_QUOTA_DAL`.

6 test nuovi, incluso il controllo positivo — «la finestra sola darebbe il doppio»
— che e' esattamente la ragione per cui l'APR non si cita senza il suo n.

CONFERMATO il fix IB di ieri: il giro delle 00:30 ha 0 righe
`orders request timed out` (erano 2 per giro, 63 su 63) e tutti e sei gli ETF
scaricati. E una conferma involontaria del debito §5.13: SPY e' passato da
1996-09-04 a 1996-09-05 — la finestra rotolante ha perso un altro giorno in una
notte, come misurato.

Diario: docs/diary/2026-08-29-usde-idoneo-e-ib.md
Suite: 795 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 06:45:47 +00:00
Adriano Dal Pastro 32e1649dcb test: la suite non parla piu' al canale di allarme vero
Difetto trovato addosso: `uv run pytest` mandava messaggi Telegram VERI sul
canale dell'operatore — cinque per giro, col testo delle fixture («Analisi di
ieri.», «rete KO», «Testo dell'agente.») sotto l'intestazione di una voce di
giornale del 21/08. Colpevoli i cinque test di `analista.CLI.scrivi()`, che non
passavano `telegram=False` e percorrevano `invia()` fino a `notifier.send()`.
`_cfg()` legge il token da `.env.mainnet`/`.env`: il fatto che non fosse
nell'ambiente non proteggeva niente.

NON E' COSMETICO. E' P9 al contrario — allarmi finti spesi su un canale che
deve restare credibile il giorno che l'allarme e' vero. Chi riceve cinque
messaggi identici a ogni giro di test impara a non aprirli, ed e' l'unico
canale da cui passano disaster-SL, uscita di fondi e venue giu'.

RIPARAZIONE STRUTTURALE, stessa lezione del watermark (§5.12): si blocca la
RETE in una fixture autouse, non si chiede a ogni autore di ricordarsi un
parametro. Un test che vuole davvero esercitare `send()` continua a funzionare
— patcha `urlopen` nel proprio corpo e vince su questo.

In piu' una guardia di sessione: bloccare non basta, un tentativo va TROVATO e
reso esplicito, o resta li' pronto a tornare vero il giorno che qualcuno cambia
il boundary. Validata su controllo positivo (M15): un test che chiama
`notifier.send()` fa fallire la sessione.

⚠️ E un difetto fatto e corretto nello stesso giro: la prima versione registrava
l'URL, che contiene il BOT TOKEN in chiaro — e quella lista finisce nel
messaggio di un assert, cioe' nell'output della suite e nei log. Ora si registra
solo "telegram sendMessage": serve sapere CHE si e' tentato, non VERSO DOVE.
Il token e' stato esposto una volta nell'output di quella verifica: va ruotato.

Suite: 789 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:04:19 +00:00
Adriano Dal Pastro 418f523be7 gtaa: la decisione tenere/bloccare va a $15k — gate (A) ritirato, soglia sorvegliata
Decisione dell'operatore: GTAA01 NON si blocca oggi, si decide quando il book
arriva a $15k. Il motivo registrato non e' «non contribuisce» — la misura dice
il contrario (+0,095/+0,124 di Sharpe a iso-rischio secondo la fase, positivo in
tutte e cinque, hold-out +0,247, 6 anni su 8, correlazione col resto +0,087).
Il motivo e' che sotto $15k di book lo sleeve NON E' ACCENDIBILE:
GTAA_MIN_CAPITAL e' $3.000 allocati, che al peso 20% fa $15.000 contro i $2.068
attuali. Finora era manutenzione senza beneficio incassabile.

Registrate anche le due ragioni contro il blocco, che restano valide: N7 (uno
sleeve difensivo si giudica sul sinistro, e questa finestra non lo contiene) e
N4 (togliendolo il portafoglio di ricerca diventa 100% cripto su un venue solo).
E il costo che sarebbe andato pagato: GTAA01 e' uno dei quattro nomi di
W_DEPLOY, da cui escono i $313k del muro.

PERCHE' LA DECISIONE NON SI DIMENTICHI (N9). Una decisione parcheggiata su un
numero che nessuno sorveglia e' parcheggiata per sempre. `journal.SOGLIE_CAPITALE`
legge l'equity ogni giorno — il giornale lo fa comunque — e il giorno che supera
la soglia la voce dice quale decisione si sblocca e perche'. Seconda riga: $20k,
dove si riapre «100% Deribit fino a $20k». Una riga si TOGLIE quando la decisione
e' presa. 5 test, incluso «equity non leggibile non e' una soglia superata» (P5).

GATE (A) RITIRATO come pass/fail, congelando il MOTIVO e non l'esito — come il
07/08 col confronto fra ranghi, e per la stessa ragione: il criterio decide su un
margine piu' piccolo del rumore che lo scuote. In piu' una guardia sulla CAUSA
(`test_la_fase_di_ribilanciamento_e_ancora_ancorata_alla_POSIZIONE`) che si rompe
il giorno che qualcuno ancorasse la fase al calendario: quel giorno il gate
potrebbe tornare decidibile, ed e' un fatto da guardare, non da ignorare.
Il test sul margine assoluto si e' auto-ritirato: diceva «se scendesse sotto un
centesimo questo criterio smetterebbe di essere una misura», ed e' sceso a 0,0074.

CLAUDE.md: §3 nuova riga · §5.2 RISOLTO (trasporto allarmi) · §5.4 riscritto (la
domanda fiscale (a) ha una risposta alla fonte: derivati in c-quater al 26%, non
c-sexies al 33% — Circolare AdE 30/E del 27/10/2023, citata verbatim) · §5.13
nuovo debito, la fase che ruota — quantificata e dichiarata INNOCUA oggi (D5):
0,029 di Sharpe a livello di portafoglio, dentro la banda [1,81-2,12].

Diario: docs/diary/2026-08-28-gtaa-fase-e-allarmi.md
Suite: 789 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:54:08 +00:00
Adriano Dal Pastro 801bd13f10 allarmi: il marcatore "gia' detto" si scrive DOPO l'invio, non prima
Debito §5.2 chiuso su decisione dell'operatore. `run_once` salvava lo stato coi
marcatori `alerted` gia' a True e l'invio lo faceva il chiamante DOPO: col 6,9%
di invii falliti misurato (2 su 29), un 🚨 perso restava perso per l'EPISODIO
INTERO — l'ora dopo lo stato diceva "gia' detto" e usciva WATCH/MUTO. Gli
episodi storici durano 200-2.324 ore, quindi il buco non era teorico.

- `run_once(state_path, sender=None)`: il sender e' INIETTATO, non importato —
  e' cio' che tiene la funzione testabile senza rete d'uscita, che era la
  ragione del disegno precedente. Senza sender il comportamento resta quello di
  prima e il report lo DICE (`invio`), invece di lasciar credere che qualcosa
  sia partito.
- Su invio fallito si disfano SOLO i marcatori "gia' detto", non le misure:
  · asset in ALERT -> alerted=False, l'ora dopo ri-allerta;
  · lock MAINT/ALERT -> alerted_soft/hard=False ma le ORE restano a correre,
    cosi' una manutenzione che sfora la grazia sale ad ALERT anche col trasporto
    giu' (disfare anche le ore congelerebbe l'escalation proprio mentre non si
    riesce a parlare);
  · lock RIENTRATO -> si ripristina l'intero LockState, perche' il rientro si
    annuncia una volta sola e senza le ore non ci sarebbe piu' niente da dire.
- `notify(..., tentativi=)`: il retry esisteva in `send` e non arrivava qui.
  venue_watch ora manda con 3 tentativi.
- L'esito dell'invio finisce nel log del cron invece di sparire.

5 test nuovi. Il primo e' quello che conta — dopo un invio fallito, l'ora dopo
ri-allerta — col suo controllo positivo (un invio riuscito consuma l'allarme
UNA volta sola), senza il quale "ri-allerta sempre" passerebbe.

Suite: 782 passati, 2 falliti (i due del gate GTAA, non toccati qui).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:34:44 +00:00
Adriano Dal Pastro 05a698a83e analista: il motivo di un guasto si prende da stdout E da stderr, o si perde
Il 2026-08-28 alle 00:37:00Z la CLI `claude` e' uscita 1 scrivendo
«Failed to authenticate: OAuth session expired and could not be refreshed»
su STDOUT, con stderr VUOTO. `interroga()` componeva il motivo dal solo
stderr, quindi nel DB e' finito `analisi_stato='errore'`,
`analisi_motivi='uscita 1: '` — e su Telegram e' partito
«analisi non disponibile (errore): uscita 1:».

La meccanica ha retto (nessuna analisi di ieri spacciata per quella di oggi,
esito registrato, notifica partita): a mancare era solo il PERCHE'. P4 —
un'allerta risponde a due domande, e con la prima sola la causa si ricostruisce
aprendo a mano il transcript della sessione headless. P3 — quando la diagnosi
serve, il guasto e' gia' rientrato: il motivo si cattura li' o mai.

- `motivo_uscita(returncode, stdout, stderr)`: unisce i due canali (stderr per
  primo), tronca a 300 caratteri.
- Silenzio totale su entrambi i canali -> lo DICE, invece di lasciare i due
  punti a vuoto: «la CLI non ha detto perche'» e «il perche' l'abbiamo perso
  noi» sono guasti diversi e finora si scrivevano uguali.
- 4 test nuovi, fra cui la regressione col messaggio testuale del 28/08.

NON risolve la causa a monte: perche' quella refresh sia fallita non sta in
nessun log locale. Il refresh token era valido (rinnovo automatico riuscito
alle 08:03:35Z dello stesso giorno, scadenza 2026-09-25) e la stessa chiamata
rifatta a mano esce 0 -> guasto transitorio, unico su 24 sessioni locali.
Da qui in avanti, se ricapita, il motivo si legge dalla notifica.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:32:41 +00:00
Adriano Dal Pastro e5052a690f usde: da patch d'emergenza a struttura — config, modulo unico, sorveglianza
- config/live.json sezione `usde` (unica autorita', P1): indice, haircut 10%,
  tetto allerta quota 50%, soglie depeg 0.99/0.95 coi criteri dichiarati (P6)
- src/live/usde.py: config + catena di prezzo (indice pubblico -> ticker ->
  1.0 dichiarato) + valutazione PURA; shadow._collaterale_usde ora deriva da qui
- scripts/live/usde_watch.py + cron_usde.sh (12:35 UTC, dopo la finestra reward):
  reward per delta netto trade (P12: senza inventare attribuzioni), depeg
  (crit ripetuto, resto a transizione, P9), quota anche per deriva passiva (N4);
  applica il verdetto di eligibilita' pre-registrato (>=1 reward entro 29/08)
- serie data/live/usde_watch.jsonl sotto monitor_health (max 30h, P5: un watch
  fermo non deve leggersi come "va tutto bene"); baseline 14:17Z registrata
- GATE USDE-01 in CLAUDE.md §4; test 775 (+17 in tests/test_usde_watch.py)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 15:11:44 +00:00
Adriano Dal Pastro 631e854b29 live: l'equity del book e' il TOTALE cross-collateral — USDE valutato all'indice pubblico
Trovato eseguendo il test di eligibilita' USDE ($500 convertiti alle 13:04Z,
fill 1.0003 fee 0): shadow._equity leggeva solo il conto USDC -> il giro
successivo avrebbe visto -24,3%, mandato un falso "USCITA DI FONDI" e venduto
~$140 di posizioni. Riparato prima del giro delle 13:47: _collaterale_usde()
valuta l'USDE all'indice pubblico usde_usdc (mediana multi-exchange, lezione
Binance 10/10/2025), depeg passa nel sizing, clamp a 1.0 sopra la pari,
fallback 1.0 dichiarato (mai 0: il fallback si sceglie sul danno, P5).
6 test nuovi in tests/test_shadow_usde.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 13:07:29 +00:00
Adriano Dal Pastro d597fc64e8 monitor: advance() consuma solo barre CHIUSE — serie rigenerate, guardia PREMATURO, 4 debiti chiusi
S5.1 RIPARATO E RIGENERATO. Filtro condiviso src/live/paper_guard.py (barra
open-labeled chiusa = ts + cadenza <= adesso) importato da tutti e 6 i monitor;
serie rigenerate dallo stesso start_ts con scripts/live/paper_regen.py (evidenza
in *.pre_regen_20260826.*): statarb +1,95 -> -1,61 (il ribaltamento del gate
27/09 previsto dall'audit), dvolspread -14,73 -> -4,41, xsr -4,98 -> -2,72,
prevday invariato. Nessuna data di gate si sposta. Guardia cablata in
monitor_health: stato PREMATURO (ultima barra che chiude dopo l'mtime, grazia
5 min, open_labeled=False per collect_chain) — sul dato vivo segnala i 5 rotti
e tace sui 2 sani; dopo la rigenerazione 7/7 OK. paper_portfolio non rigenerato
(GTAA su ADJUSTED_LAST: replay != serie registrata, P12), tolta la coda non
chiusa. D6 pagata di nuovo nel fix: asi8 in pandas 3 e' in us, non ns —
blindata con test su tre risoluzioni.

S5.12 ESTESO: conftest devia anche trades.db (wrapper su connect: il default
e' catturato alla definizione) e docs/journal/; book_executions.jsonl
sorvegliato con impronta inizio/fine suite.

S5.5 FATTO: test_leva_massima cancellato con nota (misurava frac*n_asset:
con una chiave di scala avrebbe continuato a passare smettendo di controllare).

S5.9 INDAGATO E RIPARATO (r0826_skh_band_drift): il dato regge (taglio 02/07
riproduce l'audit 1,6376, in-sample identico su ogni taglio); la deriva era la
finestra hold-out — e la sola settimana 15-22/08 vale +0,35 di Sharpe hold-out.
Il test ora taglia il feed al 02/07 e verifica la riproduzione stretta.

Suite: 751 passati, 0 falliti.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 10:12:23 +00:00
Adriano Dal Pastro a51844875b journal: i versamenti non sono piu' P&L — movimenti di capitale scorporati dal trading
Il P&L di giornale era un delta di equity: la voce del 25/08 dichiarava +$1.414,57
di "giorno" quando $1.399,39 erano il deposito USDC, e il cumulato dall'arming
avrebbe mentito per sempre. Nuova `movimenti_capitale()`:
- soglia IMPORTATA da book.EQUITY_JUMP_ALERT, non ridichiarata (P1);
- "movimento" solo se il salto supera di >2x il massimo che il mercato MISURATO
  (feed certificato, tetto di leva da config) poteva produrre fra le due letture;
- altrimenti AMBIGUO: dichiarato con attenzione e NON scorporato (P12 -- un crash
  vero a tutta leva non deve diventare "prelievo"); idem a feed illeggibile (P5).
Scansione dell'intera storia: 1 evento, esattamente il deposito (+209,6% contro
mercato max 0,22%), zero falsi positivi. `concentrazione` ora lavora sul cumulato
di TRADING; le regole sui movimenti stanno sopra l'early-return "nessun giro".
Limite dichiarato (D5): un movimento sotto il 10% dell'equity resta nel P&L.
7 prove nuove (31 -> 37), incluso il controllo M15 al contrario. Voce del 25/08
rigenerata: giorno -> trading +$15,18; cumulato -> trading +$59,14.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 07:35:15 +00:00
Adriano Dal Pastro 426735448e live: diagnosi del guasto venue, disaster-SL scoperto, isolamento per asset, cron :47
Nato da "stato trades" durante una manutenzione Deribit (system_maintenance 11051,
08:57-09:20 UTC). Contati i log invece che ricordarli: 1.499 giri dal 23/06, 3 con
manutenzione, 5 traceback duri — e 4 dei 5 sono il NOSTRO gateway, non il venue.
Le release Deribit escono il martedi' alle 09:00 UTC: il cron al :07 ci cadeva dentro
per costruzione (21/07, 11/08, 18/08, 25/08).

DIAGNOSI (src/live/venue_probe.py, nuovo)
Sonda l'API PUBBLICA Deribit senza gateway e senza credenziali, e classifica il guasto:
VENUE_MANUTENZIONE / VENUE_GIU / GATEWAY / IGNOTO. Prima ogni causa stampava la stessa
riga ("conto non leggibile (offline)") con nota di diagnosi CABLATA — P4 violata, e il
18/08 il codice 11051 era gia' dentro il processo senza arrivare a chi decideva la
gravita'. Parte solo dopo un guasto: sul percorso sano costa zero. P1 rispettata: la
firma 11051 si importa da venue_watch.is_maintenance, non si ridichiara.

P9: la manutenzione dentro lo slot declassa il titolo a info, ma solo su EVIDENZA della
sonda (mai sull'orologio) e solo dentro la durata annunciata — oltre, RIALZA. Un gateway
rotto di martedi' mattina resta al massimo.

DISASTER-SL SCOPERTO (src/live/execution.py)
ensure_disaster_sl cancella i bracket incoerenti PRIMA di ripiazzarne uno: fra le due
chiamate la posizione e' senza stop. Se il ripiazzamento sollevava, l'eccezione risaliva
a main() e il guasto peggiore aveva la faccia di un errore qualunque. Ora: due tentativi,
poi stato `naked`, distinto da `place-failed` (P5). Non e' "non sono riuscito a
proteggere": e' "ho tolto la protezione e non sono riuscito a rimetterla" -> allarme
massimo, mai declassato. La SEQUENZA non e' stata invertita: piazza-poi-cancella sembra
piu' sicuro ma "sembra" non basta con soldi veri senza misurarlo.

ISOLAMENTO PER ASSET (scripts/live/book_execute.py)
Il 21/07 un 502 dentro ensure_disaster_sl su BTC ha ucciso il giro intero: nel log ETH
non compare — ne' ribilanciato ne' verificato nella protezione. Ora un asset che esplode
non ferma il ciclo, e il giro degradato esce con codice 2.

CRON :07 -> :47
Il vincolo vero non era ":07" ma "fuori dai ~26s del minuto tondo" (rate-limit per-IP
auto-saturato dal collettore catena, misura del 30/07). Il :47 lo soddisfa e in piu' sta
fuori dallo slot di release. PREVISIONE DICHIARATA (M12): 3 delle 4 finestre osservate
sono rientrate entro l'ora -> il :47 ne avrebbe scavalcate 3 su 4; se martedi' prossimo
becca comunque la manutenzione, la previsione e' sbagliata.

WATERMARK AVVELENATO DAI TEST (tests/conftest.py, nuovo)
Trovato addosso: lanciando la suite, data/live/equity_seen.json passava a $5.000 e il giro
successivo mandava un allarme Telegram FALSO ("USCITA DI FONDI -86,6%"). Non cosmetico:
cap_fallback = min(cap_config, watermark x frac) sarebbe passato da $334 a $2.500/asset,
~7,5x di leva su un conto da $668, sul ramo eq_fallback che allerta e NON blocca — cioe'
i test potevano armare il pericolo che il watermark esiste per impedire. Riparato con una
fixture AUTOUSE, non per-test: chiedere a ogni autore di ricordarsene ha gia' perso il
26/07 e il 21/08. Resta esposto lo stesso errore su trades.db e book_executions.jsonl.

BLOCCATO, NON RINVIATO
Il fallback diretto ai privati Deribit richiede chiavi API create dall'operatore: in
locale esiste solo CERBERO_TOKEN. Il gateway resta un punto singolo di guasto non
aggirabile (CLAUDE.md 5.11). La sonda dice di chi e' il guasto, non lo aggira.

Test: 20 nuovi, nessuno tocca la rete; controllo positivo fatto (5 su 7 falliscono contro
il codice vecchio). Suite 730 passati, 1 fallito — quello gia' noto di 5.9 (deriva dati).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 10:27:36 +00:00
Adriano Dal Pastro 2751a7efd0 journal: la voce del giorno IN CORSO non si presenta piu' come una giornata
cron_daily (00:30 UTC) faceva DUE chiamate al giornale: chiudeva IERI (giusto)
e apriva OGGI. La pagina di oggi nasceva con ~30 minuti dentro e nessuno la
aggiornava fino alla notte dopo.

Il difetto non era il dato mancante: era che la pagina non lo diceva dove si
legge. Aveva TUTTE le sezioni di una chiusa -> passava ogni controllo di
completezza e freschezza, e la parzialita' stava solo in §Salute, quinta
sezione su otto. Stessa famiglia di "una barra presente non e' una giornata
presente", in veste nuova: la pagina e' presente, il giorno no.

Taglia misurata sul caso reale di oggi: la pagina congelata alle 00:37 diceva
"giorno: $+0.54 (1 letture)" e la regola [pnl] chiosava "senza operare". Alle
08:54 il libro aveva fatto 3 fill, 2 round-trip e +$25.86 ($642.56 -> $667.88).
Avrebbe raccontato una giornata ferma per tutta una giornata operativa.

Riparato in due pezzi indipendenti:
  1. la pagina dichiara la parzialita' nel TITOLO e nella prima riga —
     "PARZIALE (giorno in corso)", copertura esplicita (N giri su 24), il fatto
     che non si aggiorna da sola, e quali numeri sono di quella frazione;
  2. tolta la seconda chiamata dal cron. In docs/journal/ restano solo giorni
     chiusi; lo stato corrente si prende da journal.py a mano (pagina marcata)
     o da trades.db, che cron_book sincronizza ogni ora.

Scelta dichiarata: NON si rigenera ogni ora. Costerebbe una riga in cron_book
ma riscriverebbe un file tracciato da git 24 volte al giorno per un consumatore
che non esiste (l'analista legge il giorno chiuso). Se un domani servisse, la
strada e' RIGENERARLA, non congelarla: e' scritto nel commento del cron.

Prove (test_journal 28 -> 31): una accende la marcatura, una la tiene spenta su
un giorno chiuso (una marcatura sempre accesa non si legge), una e' guardia sul
SORGENTE di cron_daily.sh — ogni chiamata a journal.py deve avere --giorno
esplicito, perche' senza argomenti scrive OGGI.

Regolare docs/journal/2026-08-25.md rigenerato: ora si dichiara PARZIALE (9/24).

NON riparato, e registrato come debito aperto in CLAUDE.md §5:
test_wave_0726::test_t1_canonical_riproduce_il_backtest_ufficiale fallisce, e
falliva gia' prima di questa modifica (verificato con git stash sull'albero
pulito). Sharpe hold-out SKH01 canonical 1,9223 contro la banda cablata
1.3 < h < 1.9: il codice non e' cambiato, sono cambiati i dati (data/raw e'
gitignored, il cron lo ricostruisce ogni notte). La banda NON e' stata
allargata — lezione 07/08. Suite: 710 passati, 1 fallito.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:59:42 +00:00
Adriano Dal Pastro 782c0ce4bc analista: manda l'analisi giornaliera su Telegram, con l'esito registrato
La notifica porta una testata coi numeri che si leggono senza aprire nulla
(equity, delta del giorno, cumulato, posizioni, leva, fill e round-trip) e
sotto l'analisi del modello.

Il trasporto Telegram e' pero' il punto singolo di guasto gia' misurato in
questo progetto: un tentativo, nessun retry, esito mai registrato, 6,9% di
invii persi (2/29). Su un messaggio al giorno sono ~25 messaggi persi
all'anno, quindi qui sono state fatte due delle tre riparazioni dichiarate
il 2026-08-23 e mai eseguite:

(a) `send(text, tentativi=1)` — retry OPZIONALE con backoff. Il default resta
    1, cosi' il comportamento e' invariato per tutti i chiamanti esistenti:
    alzarlo per tutti cambierebbe la latenza degli allarmi di venue_watch e
    book_execute su un percorso con soldi veri, e non e' una modifica da fare
    di straforo dentro un'altra funzionalita'. L'analista chiede 3.
(b) `ultimo_errore()` — il motivo si registra nel punto in cui l'eccezione
    veniva ingoiata, e NON sopravvive a un invio riuscito. Regola gia'
    codificata il 29/07 su un altro percorso e mai applicata al notifier.

La terza (marcare `alerted=True` solo a invio riuscito in venue_watch) cambia
il comportamento degli allarmi e resta una decisione dell'operatore.

L'esito finisce nel DB in tre stati: inviata / non configurato / FALLITA col
motivo. Un invio perso che non lascia traccia, il giorno dopo, non si
distingue da "non e' successo niente".

E se l'analisi manca, il messaggio parte lo stesso dicendo PERCHE': senza
quel ramo un guasto del modello si leggerebbe come una giornata senza nulla
da dire. Taglio a 4096 caratteri dichiarato, mai silenzioso; HTML del modello
neutralizzato.

708 test passano. Strategia, pesi, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:40:56 +00:00
Adriano Dal Pastro f5d9409213 analista di bordo: un modello scrive la prosa del giorno, in un campo suo
Aggiunto il quarto livello della pagina, tenuto separato dagli altri tre:
  numeri   -> misurati dal feed e dal DB
  Lettura  -> regole deterministiche, ognuna col suo id
  Analisi  -> questo: prosa di un modello, che puo' sbagliare
  Nota     -> l'operatore

NON scrive dentro `nota`, che era la richiesta letterale: quel campo e'
dell'operatore, ed e' cio' che a rileggere il giornale fra sei mesi permette
di sapere chi ha scritto cosa. L'agente ha `analisi`, marcato col modello,
con l'ora e con l'esito del controllo sui numeri.

Gira via `claude -p` (verificato con env -i che risponda nell'ambiente nudo
di cron), una chiamata al giorno sul giorno CHIUSO, tolte le tool.

Tre guardie, una per ogni modo in cui una prosa generata rovina un registro:
- NUMERO INVENTATO: numeri_non_supportati() estrae ogni cifra dall'analisi e
  verifica che compaia in cio' che il modello ha ricevuto. Oltre tre numeri
  liberi l'analisi e' RIFIUTATA e la pagina resta senza. E' un controllo
  debole per costruzione, e lo dichiara: prende l'invenzione, non il
  ragionamento sbagliato.
- COMMENTO DI SE': senza_analisi() toglie dalla pagina la sezione dell'agente
  prima di dargliela. Al primo giro reale il modello aveva letto la propria
  uscita precedente e prodotto un paragrafo sull'avviso che si era preso il
  giorno prima — un ciclo di retroazione che in poche settimane avrebbe
  riempito il giornale di meta-commento, e che nessun controllo automatico
  puo' distinguere da prosa valida.
- ANALISI DI IERI SPACCIATA PER OGGI: se il modello non risponde, la pagina
  resta VUOTA e il perche' viene registrato (stato + motivo). Il silenzio non
  diventa continuita'.

Corretto anche un falso positivo mio: il tripwire validava sulla sola pagina
mentre il prompt include anche il blocco storico, quindi bocciava un'equity
vera. Una guardia piu' stretta del contratto produce allarmi che si impara a
ignorare.

Ogni guardia ha un test in entrambe le direzioni. 695 test passano.
Strategia, pesi, config INVARIATI. Nessun ordine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 17:46:29 +00:00
Adriano Dal Pastro 1803e0ac9f giornale: lettura ragionata a regole dichiarate e tracciabili
Non prosa libera: dodici regole, ognuna con un id stampato accanto alla riga
che ha prodotto. Combinano solo numeri gia' presenti nella pagina, tacciono
sul non misurato e non prevedono niente. Il campo `nota` resta l'unico posto
dove puo' finire un giudizio umano.

Le regole: stato del libro e PERCHE' e' flat (componente per componente),
disaccordo fra orizzonti del trend contro esposizione TP01, incoerenza
(trend su ma libro fuori), leva contro il tetto, P&L del giorno, costo che
supera il movimento, concentrazione del cumulato, drawdown dal picco,
implicita contro realizzata col gate IV-rank di VRP01, giornata oltre 2
deviazioni, giri mancanti e feed vecchio, e la taglia del campione.

Ogni regola ha DUE test: uno che la accende e uno che la tiene spenta. Una
regola che si accende sempre non sta leggendo niente, una che non si accende
mai e' indistinguibile da una rotta.

Tre difetti corretti prima di pubblicare, tutti trovati scrivendo i test:
- il tetto di leva era RIDICHIARATO (0.5 cablato) invece che letto da
  config/live.json — quinta occorrenza dello schema che il progetto paga da
  luglio: un sorvegliante che ridichiara il proprio bersaglio continua a
  passare il giorno che il bersaglio cambia. Ora deriva, e se il config non
  si legge lo dice invece di inventare un tetto.
- l'IV-rank era il percentile a UN ANNO etichettato col nome del gate di
  VRP01, che usa un percentile ESPANDENTE. Due statistiche diverse, e oggi
  danno il verdetto OPPOSTO: 0.52 (sopra la soglia, "il sleeve venderebbe")
  contro 0.18 (sotto, sleeve fermo). Il valore giusto combacia con quanto
  gia' misurato il 30/07: 0/8 settimane passano il gate.
- la concentrazione si accendeva su $2,08 di cumulato: vera e inutile. Ora
  ha una soglia di rilevanza, o e' una riga che insegna a saltare la sezione.

62 voci rigenerate. Strategia, pesi, config INVARIATI. 675 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 13:36:05 +00:00
Adriano Dal Pastro 10c373075c libro di bordo: DB dei trade allineato col tempo + giornale giornaliero
I trade erano salvati, ma non allineati col tempo: book_execute.py scriveva
ts_utc = pd.Timestamp(r['last_data']), cioe' la data della BARRA DI SEGNALE.
19 righe su 19 a 00:00:00, e un trade (ETH 0.04 @ 1869.74) registrato SEI
GIORNI prima di essere eseguito — fill vero 2026-07-14T14:00, scritto 08/07.
L'ora vera esisteva solo in logs/cron_book.log, che e' gitignored, fuori dal
backup e ruotabile: la cronologia reale del libro live viveva in un file che
una rotazione avrebbe cancellato senza che nessuno se ne accorgesse.

- src/live/tradesdb.py: parser del cron log (ora vera + contesto del segnale),
  FIFO con fee pro-quota, riconciliazione a tre fonti, sqlite in data/live/
  (dentro il perimetro del backup). Le tre fonti si INCROCIANO e non si
  sovrascrivono: reconcile() riporta le divergenze e non ripara niente da solo.
  Il venue e' autorevole ma TRONCA (1 trade su BTC, 0 su ETH): dichiarato.
- scripts/live/trades_db.py: --sync (idempotente, in cron_book ogni ora),
  --report, --reconcile.
- src/live/journal.py + scripts/live/journal.py: una voce al giorno in
  docs/journal/YYYY-MM-DD.md — mercato (ritorni, RV30, TSMOM sugli orizzonti
  di produzione, DVOL con eta'), libro (TP01/SKH01, target, posizione, leva),
  P&L (equity del venue come autorita', scomposizione locale), salute.
  NIENTE narrativa automatica: il campo `nota` e' l'unico posto per il testo
  libero ed e' dell'operatore, mai riscritto da un ricalcolo.
- book_execute.py: ts_utc = ora vera del fill, bar_ts = barra. Test di
  regressione sulla sorgente: se qualcuno rimette last_data, il test lo dice.
- 62 voci di giornale ricostruite dall'arming a oggi.

Tre difetti trovati dai test mentre scrivevo, non a occhio: il renderer cadeva
in KeyError se mancava il blocco mercato (un giornale che non si scrive non e'
un giornale); "24 giri attesi" su un giorno IN CORSO produceva un allarme a
ogni esecuzione; e libro e P&L leggevano due istanti diversi, quindi la stessa
pagina mostrava due equity.

Strategia, pesi, config INVARIATI. Nessun ordine. 659 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 13:13:02 +00:00
Adriano Dal Pastro eec76424ee research(sol): SOL come terza gamba direzionale — SCARTATO, il guadagno e' un anno solo
Domanda dell'operatore dopo "hai gia' analizzato XRP/SOL/UNI?": si', ma sempre
dentro panieri cross-sectional su Hyperliquid. SOL e' l'UNICO dei tre eseguibile su
Deribit e TP01/SKH01 non erano mai stati misurati su di lui. Ipotesi a priori
registrata PRIMA di guardare: diluisce (trend multi-asset 19/06, corr 0.74).
Confermata.

DATO. Storico ricostruito da Deribit mainnet (SOL/USDC:USDC, 466.776 barre 5m dal
2022-03-15, 0 gap, resample maxΔ 0.00bps) e certificato: >1% da Coinbase nell'1.3%
(2022) e 0.6% (2023) delle barre, med 8.1 -> 3.9 bps dal 2022 al 2026; flat 1h 0.2%,
5m 20.8%. Conferma esatta del verdetto del 19/06. Da qui DUE LENTI dichiarate prima
di misurare: L-FULL (2022-03+) e L-PULITA (2024+).

GAMBE SOLE, meccanismi CONGELATI (nessuna ri-ottimizzazione su SOL): TP01 SOL Sh 0.91
con hold-out -0.24; SKH01 SOL Sh 0.51 con maxDD 40.5%. Quest'ultimo non e' un
dettaglio: SKH01-V2-DD fu SELEZIONATA il 23/06 sul criterio maxDD<30% (BTC 21%,
ETH 27%) -> su un asset nuovo fallisce il criterio per cui la variante esiste.

BOOK, 24 ancore, mediana delle differenze APPAIATE: dSharpe hold-out -0.166 e >0 in
0/24 ancore in ENTRAMBE le lenti. L-PULITA: dSharpe FULL -0.099 (0/24), dCAGR -1.34pp
(0/24). L-FULL: dSharpe FULL +0.094 (24/24) ma dCAGR +0.10pp.

IL DD SCENDE MA E' DE-LEVERING (5a occorrenza dopo VRP-DD, TP01xDVOL, MAT01, azioni
intere UCITS): a pari maxDD, su L-PULITA basta k=0.886 sul book a 2 gambe per avere
Sharpe 1.54 contro 1.30 e CAGR 14.5% contro 12.6%. L'unica lente in cui SOL aggiunge
e' quella costruita sui dati che la certificazione segnala.

E DENTRO QUELLA LENTE IL GUADAGNO E' UN ANNO: dSh 2022 -0.91 / 2023 +1.06 / 2024
-0.29 / 2025 -0.20 / 2026 -0.22 = 4 anni su 5 negativi. La gamba SOL da sola fa
Sh -1.99 / +2.65 / +0.45 / +0.17 / +1.46. Il 2023 e' la risalita post-FTX da ~$8 a
~$100: un evento, non un meccanismo. Corr col book +0.404 (L-FULL) / +0.561
(L-PULITA), vicina allo 0.74 che boccio' il trend multi-asset, e in salita man mano
che il dato migliora.

L'ESEGUIBILITA' NON E' IL VINCOLO: SOL_USDC-PERPETUAL ha min 0.001 SOL = $0.09 contro
il pavimento min_order $5. Primo candidato bocciato senza che il muro sia la taglia
del conto.

EFFETTO COLLATERALE TROVATO SU ME STESSO. Il "guardrail solo dati certi" dichiarato in
CLAUDE.md — load_data("SOL") -> FileNotFoundError — NON e' codice: load_data non ha
whitelist, solleva solo perche' il file non c'e'. Ricostruendo SOL in
data/raw/sol_1h.parquet il guardrail si e' disattivato in silenzio, e quel file non
viene rinfrescato dal cron (--asset BTC ETH) -> sarebbe diventato dato stantio con
l'aspetto di dato attivo. Riparato con la convenzione gia' in uso (hl_/eq_/eqx_/fut_):
SOL vive in data/raw/alt_sol_*.parquet. Congelato in due test, di cui uno DERIVA gli
asset a rischio da rebuild_history.DERIBIT_INSTR. La prima stesura di quel test
elencava i prefissi a mano e bocciava eqx_, fut_, vol_term_, fundnews_ (namespace
veri): l'invariante si deriva dal codice, non si elenca — stessa lezione di fee_watch.

Book, pesi, universo direzionale, config, cron: INVARIATI. Suite 631 verdi.
NB: test_gtaa_band_gate e' tornato VERDE da solo, senza modifiche al codice, perche' il
cron ha riscritto i parquet equity — la conferma in positivo della diagnosi del 07/08.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 07:11:16 +00:00
Adriano Dal Pastro 8cfe15cbd5 fee_watch: sorvegliava i perpetual INVERSE mentre il book trada i LINEARI USDC
Trovato in un check generale. INSTRUMENTS era la tupla cablata
("BTC-PERPETUAL","ETH-PERPETUAL") — gli inverse, regolati in BTC/ETH — mentre
src.live.book.INSTRUMENT punta a BTC_USDC-PERPETUAL / ETH_USDC-PERPETUAL.

Due conseguenze, e la seconda era gia' visibile ogni giorno nel log:

1. Il tier sorvegliato era di un prodotto che il book non tratta. Oggi coincidono
   (3.50/1.50 su entrambe le linee) ma la prova che si muovono in modo indipendente
   e' nel progetto: il cambio del 18/08 tocco' tick e size dei SOLI lineari USDC
   (inverse ancora tick 0.5 / min 10.0, lineari 0.1 / 0.0001). Un aumento sulla sola
   linea lineare sarebbe stato invisibile, e la regola decisa in anticipo
   (<=5bps nulla / >10bps rivedere il peso SKH01) applicata al numero sbagliato.

2. Il cross-check sui trade REALI — la fonte autorevole, cioe' quanto abbiamo
   davvero pagato — non poteva misurare nulla per costruzione: chiedeva la storia di
   uno strumento con zero fill. Stampava "NON MISURATO (nessun trade recente
   leggibile)" anche in un giorno con 4 esecuzioni. Verificato sul conto: inverse
   0 trade, _USDC-PERPETUAL 3 (BTC) e 1 (ETH).

FIX. INSTRUMENTS si DERIVA da src.live.book.INSTRUMENT: la divergenza non e' piu' un
rischio da ricordare, e' impossibile.

E non era un rename di due stringhe: le due famiglie hanno unita' DIVERSE. Inverse
amount = nozionale USD e fee in valuta base; lineare amount = quantita' base e fee
gia' in USDC. Ripuntare senza correggerle avrebbe dato, su un fill vero (0.001 BTC
@ 74.305,80, fee 0,02600703 USDC), ~2,6e8 bps invece di 3,50 — senza sollevare
nulla. Aggiunte convenzione() (lineare / inverse / IGNOTA: una famiglia non nota non
si indovina, si dichiara) e fee_bps_di_un_fill(), entrambe pure. Il cross-check ora
gira e da' 3,50 bps effettivi = il tier esatto; il report stampa lo scarto
effettivo-tier con ⚠️ oltre 1 bps.

Test 13 -> 17, verificati per MUTAZIONE: rimettendo la tupla cablata fallisce
test_sorveglia_esattamente_gli_strumenti_DEL_BOOK; scambiando le convenzioni
fallisce test_le_due_famiglie_hanno_unita_DIVERSE_e_scambiarle_non_fa_rumore, che
contiene il controllo positivo (la convenzione sbagliata NON solleva niente, mente).

3a occorrenza in un giorno della stessa forma di difetto, dopo i test di book_live
(potenza zero a libro flat) e la taratura di venue_watch (misurata con bitfinex
mentre il live girava senza): un controllo puntato su una configurazione diversa da
quella che gira passa sempre, e non sta controllando niente. REGOLA: un sorvegliante
DERIVA il proprio bersaglio dal codice sorvegliato, mai lo ridichiara.

Book, pesi, config, cron, soglie fee: INVARIATI. Suite 625 verdi, 1 rosso noto
(test_gtaa_band_gate). NB: la prima corsa dopo il fix ha inviato una notifica
Telegram legittima ("strumento nuovo nella sorveglianza"); lo stato e' poi assestato.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 19:19:22 +00:00
Adriano Dal Pastro fac9978d87 venue: la taratura ri-misurata — «zero falsi allarmi in 8 anni» non descriveva la produzione
B1 (memoria) + B2 (misura). Il 19/08 stava solo in un diario e in un commit: la
sessione che ha cambiato il tripwire di venue, la tabella _CONTRACT e le referenze
non era in CLAUDE.md — 2a occorrenza dopo edge_watch, e riguarda di nuovo qualcosa
che gira con soldi veri. Ora c'e', insieme al debito che dichiarava.

B2: il debito era «la taratura non e' ri-misurata a tre referenze». Ri-misurandola
(scripts/research/r0821_venue_refs.py, riusa dislocation/episodes/zero_fp_frontier
di r0726) il problema non era dove ci si aspettava.

1. «Zero falsi allarmi in 8 anni» veniva dal consenso Coinbase+Bitstamp+BITFINEX
   dello script di ricerca; il sorvegliante live gira su Coinbase+Bitstamp. Due
   liste di referenze in due posti diversi, e nessun test poteva accorgersene.
   Sull'insieme reale i falsi allarmi sono 1: 2020-03-13 07:00-10:00 UTC, 4 ore a
   -418 bps di picco su BTC = il crash COVID, cioe' proprio l'evento che CLAUDE.md
   elencava come esempio di cio' su cui NON scattava. La firma che lo dimostra: le
   "65.043 ore BTC" citate in memoria sono esattamente le ore utili del set con
   bitfinex; sul set reale sono 69.633.

2. Kraken non lo ripara: su 8 anni porta un mese. Il tetto ~700 candele
   dell'endpoint pubblico e' stato ri-verificato oggi sulla rete (704 barre su
   70.286 richieste = 1,00%), non creduto da un commento del 26/07.

3. Perche' spariva a 3 referenze, ed e' il punto trasferibile: con bitfinex dentro
   1 delle 4 ore diventa BLIND, lo streak si azzera e l'episodio non esiste — ma la
   dislocazione e' ancora li' (mediana -343 bps). Lo zero non veniva da un consenso
   piu' accurato, veniva da un'ora buttata (ore utilizzabili 93,4% vs 100,0%).

4. La direzione dichiarata il 19/08 ("piu' BLIND, allerta di meno") e' confermata ma
   la sua taglia dipende dal venue, non dal numero tre: confronto appaiato sulle
   stesse ore, con bitfinex -13,91 pp di ore utilizzabili, con kraken +0,00 pp.

5. Controllo positivo intatto: Bitfinex 2018-19, 22 episodi, il piu' lungo 2.324h,
   picco 1.136 bps = 11,4x la soglia.

DECISIONE: (100 bps, 4h) NON si tocca, ma la giustificazione cambia. 1 falso allarme
in 8 anni costa 0,031%/anno di equity attesa contro il 100% che un vero positivo
evita (ogni p plausibile e' 16-160x sopra il break-even); alzare a 150 bps per
ripristinare lo zero porterebbe il margine su FTX da 3,0x a 2,0x, sotto la gamba (b)
del criterio dichiarato prima di guardare i dati. La memoria si contraddiceva da
sola — «zero falsi allarmi» al punto (2), «a 1 ogni 8 anni serve p > 0,031%» al
punto (4) — e la meta' giusta era quella dell'economia.

Congelato il MECCANISMO, non il numero: tests/test_venue_watch.py 35 -> 37, due test
puri (lo spread max-min e' monotono nel numero di referenze; una sola ora BLIND
spezza lo streak, con un caso di controllo che DEVE scattare).

Soglie, book, pesi, config, cron: INVARIATI. Suite 621 verdi, 1 rosso noto
(test_gtaa_band_gate, altro asse). Diario: docs/diary/2026-08-21-venue-taratura-*.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 17:55:16 +00:00
Adriano Dal Pastro e69cc5bd81 test(book): i due test della formula del report avevano potenza ZERO a libro flat
I due confronti `abs(net_target - formula) < 1e-6` erano insoddisfacibili per
costruzione: `book_report` PUBBLICA valori arrotondati (`net_target` a 2 decimali,
`tp_frac` a 4) mentre l'ordine viene costruito sul valore non arrotondato
(`build_book_order(inst, net, ...)`), quindi un test che ricalcola la formula dal
`tp_frac` pubblicato eredita DUE arrotondamenti. Nessun ordine e' mai stato sbagliato:
lo scarto e' 0.5-1.5 centesimi su target da $114 e $954, con min_order a $5.

⚠️ Il difetto vero non e' la tolleranza, e' la POTENZA: con `tp_frac=0` e `skh_sign=0`
il target e' esattamente `0.0`, i due arrotondamenti sono esatti e l'invariante passa
senza essere mai esercitata. Dal 2026-06-23 al 2026-08-18 il book e' stato flat quasi
ininterrottamente -> per due mesi questi test non hanno verificato nulla su una formula
di produzione, e il difetto e' emerso solo quando TP01 e SKH01 sono andati long insieme.
Stessa lezione del 26/07 (test_skh_partial_entry): un self-check su eventi rari si
campiona sugli EVENTI, non sulla popolazione.

- `_budget_arrotondamento(equity)`: tolleranza DERIVATA (0.005 del round del net +
  WEIGHT*equity*W_TP01*0.00005 del round del tp_frac propagato), non tarata sul risultato.
- `test_la_formula_del_report_ha_potenza_anche_a_libro_flat`: segnale FORZATO su 4
  frazioni scomode (long+SKH long, long+SKH short, flat+SKH short, cap) con contatore
  che verifica che tutti i casi diano target != 0 -> la copertura non dipende dal mercato.
- `test_il_budget_di_arrotondamento_non_copre_un_errore_di_formula`: controllo POSITIVO,
  i modi reali di rompere la formula (pesi scambiati, cap non applicato, segno invertito)
  devono stare oltre 100x il budget. Una tolleranza che assolve tutto non e' una tolleranza.

Verificato per MUTAZIONE, non a occhio: `round(net, 0)` in book.py -> falliscono tutti e
tre (incluso il nuovo, che e' il punto); `W_TP01 <-> W_SKH` -> falliscono test_net_target_sizing
e il controllo positivo. src/live/book.py ripristinato bit-identico, produzione NON toccata.

38/38 in tests/test_book_live.py; suite 619 passati, 1 fallito (il noto
test_gtaa_band_gate, altro asse, invariato).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 17:17:27 +00:00
Adriano Dal Pastro c932fab304 venue_watch: disciplina degli allarmi, specifiche contratto controllate, terza referenza
Il 18/08 sono usciti quattro 🚨 identici con 'PRIMO PASSO: prelievo di prova'
per una manutenzione Deribit annunciata, e tutti e quattro DOPO che il book
aveva gia' ripreso a eseguire. Il book si era comportato bene (due giri di
astensione, 'non eseguo a cieco'); il difetto era negli allarmi.

1. Il blocco piattaforma era un if secco senza memoria, accanto a un rilevatore
   tarato con cura che allerta una volta per streak. Ora passa da lock_step(),
   pura e testata: manutenzione entro tolleranza = un solo avviso morbido, che
   sfora = un solo 🚨 ('ha SFORATO'), blocco inspiegato = 🚨 subito, rientro
   annunciato una volta. public/status illeggibile NON e' un rientro.

2. Il messaggio diceva 'locked=true' cablato mentre il parser accetta anche
   'partial': dichiarava un valore che non aveva letto, e il runbook manda a
   controllare proprio quel campo. Ora stampa e salva il valore grezzo.

3. Deribit ha cambiato tick e size dei perpetual lineari USDC il 18/08 e la
   tabella _CONTRACT, cablata a mano, non se n'era accorta. Nessun ordine
   rifiutato solo perche' i cambi erano riduzioni: e' andata bene per la
   direzione, non perche' ce ne fossimo accorti. Tabella aggiornata ai valori
   verificati e aggiunto check_specs(), che gira nel venue_watch orario (fuori
   dal percorso ordini) e dichiara la direzione: 'granularita'' = conforme,
   'rifiuto' = il venue rifiuta. La tabella dichiarata resta l'autorita' per
   costruire un ordine, il venue e' il controllore.

4. Aggiunta Kraken come terza referenza: Coinbase ha comprato Deribit, e una
   referenza che e' la casa madre non misura piu' se Deribit scolla dal mondo.
   THRESHOLD_BPS e PERSIST_HOURS invariati, ma il consenso ora e' su tre serie
   e quel numero non e' ri-misurato: dichiarato nel codice e nel diario. La
   direzione dell'errore e' 'allerta di meno', non 'grida al lupo'.

Test 23 -> 35 su venue_watch, suite intera 618 verdi. Book, pesi e config
invariati; dry-run del book verificato. Diario: docs/diary/2026-08-19-*.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 10:10:55 +00:00
Adriano Dal Pastro 02e0cf775f research(capitale): il piano rifatto AL NETTO — il muro si sposta poco, i versamenti molto
Il 07/08 era stato misurato che l'accumulo composto al lordo sovrastima il capitale del
30% a 10 anni, ma i numeri del piano non erano stati rifatti. Qui lo sono.

Il muro usava una convenzione ASIMMETRICA: prelievo lordizzato (€50/g netti → $29.690
lordi) ma capitale che compone senza mai pagare imposte. Coerente (imposte annue dentro
il portafoglio, prelievo gia' netto): perpetua 10.91% → 7.70%, muro $272.061 → $258.338
(-5.0%). I due errori vanno in versi opposti e si compensano quasi — per caso, non per
costruzione.

E' sulle traiettorie che il fisco morde, e si legge nella PROBABILITA':
€250/mese P(entro 20a) 92% → 52%; €500/mese 100% → 99%. Il versamento necessario a P=90%
passa da €237 a €371/mese a 20 anni (+57%), da €509 a €672 a 15 (+32%), da €1.178 a
€1.323 a 10 (+12%): l'errore era composto, quindi cresce con l'orizzonte. Rendita a 20
anni con €250/mese: 91.30 → 46.61 €/g, P(€50/g) 90% → 42%.

Controllo di replica superato prima di guardare i numeri nuovi: a fisco spento la macchina
riproduce $272.061 al dollaro (implementazione separata) e la colonna LORDA riproduce 4
righe su 4 della tabella pubblicata. Trovato per strada: perp_and_wall gira a 2000 path e
a quella taglia da' $269.648 — la terza cifra del muro e' rumore Monte Carlo.

Errore mio catturato prima di pubblicare: la mediana degli anni calcolata sull'INTERO
vettore coi non-arrivi a -1 faceva risultare €250/mese PIU' VELOCE col fisco (15.7 →
15.3 anni) mentre P crollava. Un non-arrivo va codificato +inf, mai -1.

Book/pesi/cron/config INVARIATI: non tocca la produzione.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 19:30:49 +00:00
Adriano Dal Pastro 963776e5d2 research(gtaa): il gate (A) non misurava cio' che dichiarava — e TLT ha 13.5 anni in meno
Il test del gate sulla banda GTAA01 aveva smesso di passare senza che il codice fosse
cambiato (data/raw/ e' gitignored, IB rivede ADJUSTED_LAST all'indietro ogni notte).
Invece di allentare la soglia, misurata la risoluzione del criterio.

`rank_in <= rank_oos` lo passano 14/30 celle (47%) PER COSTRUZIONE: la somma dei ranghi
e' la stessa nelle due finestre. E sulla proposta si decideva su 0.00116 di Sharpe contro
uno spread di griglia di 0.3124. Il 27/07 quel criterio passava, e passava per caso.

Criterio sostituito con quello decidibile: la proposta e' una BANDA (la cadenza settimanale
e' gia' produzione), quindi a cadenza fissa la banda scelta sui soli dati pre-2015 e' 25%
= la proposta, margine +0.0151 (13x il vecchio); chi avesse scelto sull'hold-out avrebbe
preso 40%. Controllo positivo incluso. Regge sull'universo coerente a 5 gambe.

TROVATO PER STRADA: TLT parte dal 2016-02-03 invece che dalla quotazione (2002-07-22) →
GTAA01 gira su CINQUE gambe prima del 2016, e quella assente e' la gamba obbligazionaria.
Non e' di oggi (cosi' dal primo giro nel cron log del 24/06, prima della validazione) e non
e' un fetch da rifare: una richiesta retro esplicita a IB ritorna 0 barre.

Nessuna certificazione l'aveva visto perche' tutte guardano DENTRO la serie: una serie
troncata e' integra, senza gap, senza spike, senza duplicati. Cablate due guardie in
fetch_ib_equities.certify — TRONCATO (storia persa vs disco; il file NON viene sovrascritto
ne' fuso, ADJUSTED_LAST e' ri-aggiustato all'indietro e il giunto creerebbe un salto) e
STORIA-CORTA (parte dopo la quotazione, con distinzione dal tetto della richiesta 30Y).
Controlli negativi obbligatori: giro normale, serie al cap, ETF giovane, simbolo fuori
tabella.

Produzione INVARIATA: REBAL_BAND_USD resta $50, GTAA01 resta non deployabile (PRIIPs).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 19:30:34 +00:00
Adriano Dal Pastro fb01c5714c research(vrp): f misurato sul 10g — il mio sospetto era sbagliato, e il campione non basta ancora
Book, pesi, config INVARIATI. Nuovo sorvegliante in cron_daily.

IL CAMPIONE C'ERA GIA': 8 scadenze utilizzabili per asset su 8, entrambe le
strutture, 16 osservazioni ciascuna. Non serviva aspettare per fare la misura;
serve aspettare per rispondere alla DIFFERENZA, che e' un'altra domanda.

CORREZIONE A UN ARGOMENTO PUBBLICATO POCHE ORE FA. Nel gate del tenore avevo
scritto che la cella vincente 'sta massimizzando l'errore di modello' perche'
compra l'ala piu' lontana. Misurato: il meccanismo e' confermato e piu' forte
del previsto (f_long 5.85 contro 2.23) ma la conclusione era ROVESCIATA —
quell'ala pesa il 3.2% del premio corto invece del 18.4%, quindi sul credito
NETTO l'effetto e' minore: f_net 0.852 contro 0.718, il candidato ha un f
MIGLIORE. Con f_net = (f_short - k*f_long)/(1-k), un f_long grande fa danno
solo moltiplicato per un k grande: avevo guardato il fattore e non il peso.
La decisione (nessun cambio) regge, ma su tre gambe invece di quattro.

Artefatto di tick escluso prima di crederci: l'ask dell'ala sta a 22 tick
mediani, minimo 15, 0% delle osservazioni a <=2 tick.

LA DIFFERENZA NON E' STABILITA: appaiata per (asset, scadenza) fa +0.109 con
IC95 [-0.047, +0.193], 11/16 positive -> contiene lo zero. Replica indipendente
del canonico: 0.718 per un percorso con finestra DTE e pairing diversi da
quello che stamattina dava 0.73.

CRITERIO PRE-REGISTRATO, congelato in un test: >=40 coppie E ampiezza IC95
<=0.12 (oggi 16 e 0.241), prima gamba verso fine ottobre 2026. Il sorvegliante
rifa' la misura ogni giorno e notifica una volta sola quando basta — lezione
DVOLSPREAD, un lead senza sorvegliante e senza data e' un lead perso.

Calibrazione della soglia verificata prima di fidarsene: con differenza vera
nulla lo zero e' escluso nel 5.0/4.0/3.0% dei casi a n=16/40/60, cioe' il 5%
atteso. Il test iniziale su seed fisso falliva perche' quel seed era uno dei 5%
legittimi: sostituito con un test sulla proprieta'.

REGOLE: (a) un fattore di errore si giudica moltiplicato per il suo peso;
(b) prima di credere a un rapporto estremo su un prezzo piccolo, contare i
tick; (c) una soglia sull'ampiezza di un IC richiede di verificarne la
copertura; (d) 'non abbastanza campione' non e' 'nessuna differenza'.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 22:17:11 +00:00
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
Adriano Dal Pastro 04cb572535 research(vrp): profit-take al 50% REFUTED, e una correzione a un numero di stamattina
Book, pesi, cron, config INVARIATI.

VRP01 tiene fino a scadenza (S1 = px[i+tn], nessuna gestione infra-settimana)
e il profit-take era l'unico grado di liberta' non misurato: i 4 overlay del
03/07 erano tutti sul lato del RISCHIO, questo e' sul lato del PROFITTO.
Replica del sleeve bit-exact (max|diff| = 0.0) prima di ogni delta.

VERDETTO con fee reali per gamba: canonico ShFULL 1.32 -> PT25 0.22 /
PT50 -0.18 / PT75 -0.45. Null del de-levering REFUTED 6/6: a PT25 basta
k=0.818 per lo stesso DD con Sharpe 1.32 invece di 0.22.

MECCANISMO (confronto appaiato per ingresso): scatta sull'86-91% dei VINCENTI
e sul 19-25% dei perdenti -> tronca i vincenti del 27% e salva un perdente su
cinque. La peggior settimana e' IDENTICA (-7.27%) in ogni variante: nelle
settimane brutte lo spread non tocca mai +50%, quindi e' pura troncatura
dell'upside.

IPOTESI MIA REFUTATA IN SESSIONE: 'su 7g chi tocca +50% e' chi sarebbe scaduto
senza valore, quindi a scadenze lunghe paga'. Testata su 7/10/14/18/21/28g:
delta Sharpe negativo a tutti e sei. A 18g (il tenore di cerbero-bite) il DD
migliora 7.1->3.8% ma lo Sharpe crolla = firma del de-levering.

CORREZIONE a un numero pubblicato oggi: il sleeve modella le fee come 12.5%
del credito netto, il listino vero e' 0.03% del sottostante per gamba (cap
12.5% del premio della singola opzione, che quasi mai morde) -> sovrastima di
~2x. Il numero onesto di VRP01 con f=0.73 e' ShFULL 0.47, non 0.31.
fee_frac NON cambiato: il forfait e' conservativo e i numeri di ammissione di
questo progetto si tengono conservativi.

A $3.000 la domanda non e' il rendimento: BTC min 0.1 = $6.210 di collaterale
per lotto -> FUORI; ETH min 1 contratto = $1.832 -> 1 lotto. Il sleeve 50/50
diventa ETH-only e al peso di book (12% = $360) sono 0 lotti.

REGOLE: (a) un'uscita si giudica appaiata per INGRESSO, mai allineando le serie
sulla data di USCITA — e' quella che la variante cambia, e l'inner-join tiene
solo i casi in cui non e' successo niente (errore commesso e corretto in
sessione, congelato in un test); (b) una regola d'uscita che scatta piu' spesso
sui vincenti che sui perdenti non e' protezione, e' troncatura; (c) prima del
rendimento a un capitale dato, misurare il lotto minimo del venue.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 21:57:15 +00:00
Adriano Dal Pastro d55eb13533 feat(chain): assorbita la raccolta catena opzioni, cerbero-bite dismesso
cerbero-bite viene eliminato. L'unica sua parte irreversibile e' il DATO:
una catena opzioni non si ricostruisce a posteriori (Deribit non serve book
storici, non c'e' un secondo venue). Il codice si riscrive; le ore non
raccolte no.

ASSORBITO
- scripts/live/collect_chain.py + scripts/cron_chain.sh (cron 25 * * * *):
  raccolta propria, ~570 strumenti/giro, ~3 min.
- scripts/analysis/import_cb_archive.py: archivio 1.23M righe (2026-05-01+)
  + market_snapshots 17.402 righe (2026-03-26+: dealer gamma, gamma flip,
  rischio liquidazioni, funding cross — dati che non abbiamo altrove).
- snapshot sqlite integrale in /opt/docker/backups/manual/ (SHA256).

NON ASSORBITO, con motivo: motore credit-spread ETH (regola "niente
short-vol da modello in deploy", conto a $52 contro minimo $720), GUI, kill
switch/dead-man/audit (abbiamo venue_watch/edge_watch/monitor_health/
fee_watch), dvol_history (fetch_dvol.py ha storia PIU' LUNGA: 2020+ contro
2026-05), decisions/positions (0 posizioni).

TRE DIFETTI DI BITE NON REPLICATI, tutti misurati il 30/07:
1. una chiamata per strumento invece di due (get_order_book?depth=3 da' gia'
   quote+greche+IV+OI+book+underlying) + prefiltro OI in una chiamata sola:
   551 -> ~290 chiamate per asset;
2. pacing invece di raffica. Il carico non e' mai stato il problema: 570
   chiamate/ora = 0.16/s DISTRIBUITE; bite le sparava in 26s (~44/s) e si
   auto-saturava il rate limit per-IP (12.186 risposte 429 in 26h, 96% al
   minuto :00). Primo giro reale: 574 chiamate, 0 risposte 429. Il minuto :25
   e' scelto: :00 era la raffica, :07 e' cron_book (feed 5m di SKH01).
3. quote_status esplicito {ok, no_quote, error} e book_depth NULL su errore
   mai 0. "Book vuoto" e "chiamata fallita" sono cose diverse: e' per questo
   che il guasto del 29/07 (50% di quote perse, 38 ore) non produsse alcun
   segnale. Le righe ereditate restano 'unknown': bite non lo registrava e a
   posteriori non e' ricostruibile.

Battuta di cuore in data/chain_collect/runs.jsonl anche a giro fallito,
sorvegliata da monitor_health (1h, max_age 3h): un collettore fermo non
produce niente, e il niente si legge come "nessun dato quel giorno".

Difetto trovato per strada: due formati ISO nella stessa colonna (92 righe
di backfill senza microsecondi). pd.to_datetime senza `format` ne inferisce
uno solo e manda gli altri a NaT -> il dropna a valle li toglieva in
silenzio, e la serie di contesto perdeva 5 settimane slittando dal 26/03 al
01/05. Corretto con format="ISO8601" e scarto RUMOROSO.

Book, pesi, config, strategia INVARIATI. 537 test verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 20:14:34 +00:00
Adriano Dal Pastro 8c18e82f1a research(vrp): il f del credito netto e' 0.73 sulle quote reali, non 1.0
Prima integrazione della catena opzioni Deribit mainnet accumulata da
cerbero-bite (/opt/docker/cerbero-bite, dal 2026-06-09: entrambe le ali,
1g-3mesi, oraria, con book_depth). E' l'unica fonte di prezzi opzioni VERI
del progetto, e non e' ricostruibile a posteriori: Deribit non serve book
storici, un'ora non raccolta e' persa.

VRP01 prezza entrambe le gambe con BS su DVOL ATM (VRP_CFG f=1.0 sul credito
NETTO). Misurato agli STESSI strike su 8/8 scadenze settimanali con entrambe
le gambe quotate (delta -0.270/-0.099 contro target -0.280/-0.100):

  f gamba corta   1.02   <- replica la calibrazione del 20/06
  f gamba lunga   2.30   <- l'ala che si COMPRA
  f credito NETTO 0.73   IC95% [0.698, 0.780], 0/15 osservazioni >= 1.0

Meccanismo, non rumore: IV(corta)-DVOL +0.8pp ma IV(lunga)-DVOL +7.5pp -> il
modello prezza a vol ATM anche l'ala comprata. Il difetto non e' nel premio
incassato ma nella protezione comprata, cioe' proprio il "defined-risk" per
cui v2 fu promosso.

Conseguenza standalone (solo f): 1.00 -> FULL 1.08 / HOLD +0.58; 0.80 -> 0.51
/ -0.02; 0.73 -> 0.31 / -0.23. Book 5-sleeve: FULL -0.069, HOLD -0.103, DD
invariato = dentro la banda d'ancora, ma ~meta' del contributo LOO di VRP01
era il prezzo che il modello si faceva da solo.

VRP_CFG["f"] NON cambiato: 15 osservazioni, 7 settimane, e 0/8 passano il
gate IV-rank>0.30 -> il f e' misurato nel regime in cui il sleeve sta FLAT.
Caveat quantificato, non nuovo parametro. Il criterio del 19/06 (rivalutare
quando cerbero-bite cattura un crash) e' intatto.

Book, pesi, cron, config INVARIATI.

Regole nuove congelate nei test:
- il f di una struttura multi-gamba non e' il f di una sua gamba (misurare la
  sola gamba venduta da' la risposta sbagliata con segno rassicurante);
- un guasto IN CORSO si misura al GIORNO PEGGIORE, non in media (la prima
  stesura della certificazione diluiva un guasto di 2 giorni da 51.7% a 13.5%);
- una riga presente non e' un dato presente.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 19:51:52 +00:00
Adriano Dal Pastro 7d64dd4c2b live(feed): l'allerta funzionava, la sua CAUSA era una riga cablata
Il 29/07 il feed 5m di SKH01 e' ricaduto sul certificato in 6 giri orari su 8
(eta' 265->685 min, +60 a ogni giro = firma esatta del fallback): latenza
d'uscita da ~1h a ~11h, book flat, nessuna posizione esposta. L'allerta del
26/07 ha segnalato 6/6, poi ha stampato un perche' che non aveva misurato —
la nota "fetch pubblico KO" era cablata, identica in ogni caso, compreso
quello in cui la coda fresca E' attaccata e il vecchio e' il certificato.

E la causa vera non era recuperabile per costruzione: _fetch_recent_5m ingoia
l'eccezione di pagina con un break e a prima pagina fallita ritorna un frame
vuoto, indistinguibile da "il venue non ha barre".

Cablato: livefeed.last_fetch_error() (registra E logga nel punto in cui
l'errore viene ingoiato) -> book_report.skh_feed_errors -> allerta con la
causa. Stesso buco chiuso sul ramo gemello "conto offline", che la ragione
l'aveva gia' in mark_src e non la stampava mai.

La causa del 29/07 resta IGNOTA e va citata cosi': una prima stesura la
attribuiva a un rate limit per-IP come se fosse un fatto -> rimossa, sarebbe
stato lo stesso difetto che stavo correggendo scritto meglio. Cron spostato
al minuto :07 come ripiego da UNA osservazione, dichiarato tale.

Test 11 -> 16 (incluso il caso a meta' paginazione: coda parziale attaccata,
mancano le barre PIU' recenti). Book/pesi/config/strategia INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 12:20:42 +00:00
Adriano Dal Pastro 17b0f2cb47 research(capitale): "5k messi dove" — lo split si ottiene versando di meno
Misura nuova: a $6.050 lo split CON GTAA01 e' impossibile (servirebbe il 50% del conto per
i $3.000 di gamba minima), ma quello in LIQUIDITA' non ha soglie.

Due correzioni prima dei numeri:
- la configurazione vera e' 5.000 + 500/mese (dal commento in config/live.json del 26/07),
  non i 250/mese di tutte le tabelle. Nessuna azione di config: il cap e' gia' armato e
  vale min($3.000, equity_osservata x 0.5) = leva lorda <=1x.
- a $6.050 non si sblocca nulla (GTAA01/XS01/XSR01 tutti fuori portata o sotto gate):
  il book resta TP01+SKH01.

Split in liquidita' (p=1%, 20a): fuori 10% -> P(perso tutto) 18.4% -> 3.5% (0.0% con cassa
in banca), salvati $6.818; 25% -> salvati $17.045, al prezzo di 0.9pp di P(arrivare) e circa
un anno di ritardo mediano.

P(perso tutto) SATURA a qualunque quota > 0: la protezione binaria si compra col fatto di
avere un secondo conto. Cio' che distingue le quote e' il salvataggio.

ERRORE CORRETTO IN SESSIONE: la colonna del salvataggio riportava prima il capitale a 20 anni
condizionato al fallimento ($77k al 10% = 11x il vero), gonfiato dalla convenzione ereditata
dal 26/07 per cui i versamenti si dirottano ai superstiti -> attribuiva allo split il valore
di continuare a versare, che si ottiene comunque aprendo un altro conto. Ora misura il
salvataggio istantaneo, congelato in un test.

simulate() accetta un hazard PER VENUE (una cassa in banca non fallisce come un exchange);
la replica esatta dei numeri del 26/07 e' preservata e testata.

Test: 4 nuovi (508 totali), tutti verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 14:58:50 +00:00
Adriano Dal Pastro fd05307c96 research(capitale): il lump-sum vale 2.45x, e la protezione dalla rovina non passa da GTAA01
Quattro filoni chiesti dall'operatore ("proposte"). Book, pesi, config: INVARIATI.

1. LUMP-SUM + VENUE (r0727_lumpsum_split.py). Tutte le traiettorie del 25-26/07 avevano
   START=600 cablato: mai misurato un versamento iniziale, mentre ~10k EUR stanno fermi
   altrove. Macchineria validata: con lump 0 riproduce IDENTICI i numeri del 26/07.
   - 10k EUR oggi e mai piu' nulla -> traguardo 17.2a, P 62%, rendita 61.58 EUR/g
   - equivalenza onesta: +154 EUR/mese per 13 anni = 24.523 EUR, cioe' 2.45x
     (la prima stesura misurava i versamenti risparmiati: numero giusto, domanda sbagliata)
   - col rischio venue: a 11.500$ lo split e' possibile (quota IB 26%, non 25%) e taglia
     P(perso tutto) da 18.4% a 3.5% a p=1%, costando 1.9-2.6pp di P(arrivare)
   - SPLIT-CASSA: seconda gamba ferma costa altri 0.6-0.8pp e protegge IDENTICO
     -> la protezione non e' bloccata dal PRIIPs: serve un CONTO, non uno sleeve

2. FEE WATCH (scripts/live/fee_watch.py). Nuovo schema Deribit dal 1 agosto senza numeri
   pubblicati -> sorvegliante invece di promemoria. Legge il tier base dall'endpoint
   pubblico (oggi taker 5.00 bps), applica la regola congelata e allerta sui cambiamenti.

3. MONITOR HEALTH (src/live/monitor_health.py). Tre gate pre-registrati si decidono su
   serie forward di cui una sola era sorvegliata. Misura coda E buchi interni: una serie
   bucata ma fresca passa qualunque guardia di freschezza.

4. BANDA GTAA01 25% VALIDATA (r0727_gtaa_band_gate.py). 30 celle, 29.9 anni, dpy=252.
   Non e' selection-on-holdout (4/30 IS, 5/30 OOS), DSR 0.999, tracking OK ma AL BORDO.
   Il modo di fallire non e' il de-levering (la vol non scende) ma la perdita di tracking.
   Impatto sul book: zero -> REBAL_BAND_USD non toccato, si applica al deploy.

Aggiunto anche il bullet edge_watch, cablato il 26/07 e mai finito in CLAUDE.md.

Test: 56 nuovi, 504/504 verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 14:14:39 +00:00
Adriano Dal Pastro 3f0812c7fc research(gtaa): DEGIRO ha tutte e sei le gambe — verificato sul conto reale
Screenshot della watchlist "Pythagoras" su flatexDEGIRO: le 6 gambe ci sono tutte, coi
ticker esatti raccomandati. Era Revolut a non avere R2US.

VERIFICA INDIPENDENTE che le due linee EUR (VUAA, XNAS su Tradegate) siano gli stessi
fondi, dai dati e non dallo screenshot: il rapporto prezzo-IB/prezzo-Degiro dev'essere un
solo cambio -> 1.1341 e 1.1315, scarto 0.23%. Le altre 4 stanno a 0.993-0.998 (gia' USD).
Due fondi diversi non darebbero lo stesso cambio.

ERRORE MIO, dello stesso tipo che avevo codificato come regola un messaggio prima: per
cercare le linee in euro delle altre 4 gambe ho interrogato IB per TICKER sulle borse
tedesche, ottenendo "nessuna linea EUR" su 4/4. Falso. Cercando per ISIN ognuna ce l'ha:
ZPRR (=R2US), IS04 (=IDTL), EGLN (=IGLN, Londra EUR), IS0R (=IHYU). Un "assente" da una
ricerca per ticker su una borsa dove quel ticker non esiste non significa "non esiste".

TURNOVER PER GAMBA a $10k (21 ordini/anno): IDTL 9 ordini / $6.257 = 46% del totale,
poi VUAA 17%, IGLN 12%, XNAS 12%, IHYU 7%, R2US 6%. Il 71% del turnover e' su gambe in
USD ($9.752/anno) -> conversione $24/anno a 25bps. Spostare la sola IDTL sulla linea in
euro (IS04) copre il 64% del turnover convertibile.

Ma non e' un risparmio netto (spread Xetra piu' larghi delle linee primarie di Londra,
tariffa di connettivita' per borsa) e su $10k si parla di decine di dollari l'anno in
entrambe le direzioni: non e' una decisione importante, ed e' piu' utile dirlo che
costruire una precisione finta.

Il prompt W-8BEN di Degiro non riguarda queste sei: sono fondi irlandesi, non titoli USA.

Stato: preparazione, non azione (saldo Degiro EUR 328,92; GTAA01 richiede >=$3k e la
decisione venue tiene tutto su Deribit fino a $20k).

Book, pesi, cron, config INVARIATI. 448 test verdi (+1).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
2026-07-27 11:36:27 +00:00
Adriano Dal Pastro 378f448450 research(gtaa): ZPRR e' R2US (stessa ISIN) + correzione sul verso del costo FX
L'operatore ha verificato su Revolut: R2US assente, ZPRR e SPY4 presenti.

(1) ZPRR (Xetra EUR) == R2US (Londra USD): stessa ISIN IE00BJ38QD84, stessa classe di
quote, stesso NAV. La gamba small cap e' risolta. Regola: si cerca per ISIN, non per
ticker — lo stesso fondo ha ticker diversi su borse diverse.

(2) SPY4 IE00B4YBJ215 NON e' small cap ne' S&P 500: e' SPDR S&P 400 MID cap (l'S&P 500
e' SPY5). Misurato come ripiego su 6.5 anni: Sharpe 0.86 vs 0.86, corr fra i due sleeve
0.991, peggiore in 3/7 anni = moneta. Sulla finestra corta di 3.2 anni sembrava -0.15:
era rumore. Ripiego accettabile per ragione meccanica (small e mid USA correlano ~0.95
giornaliero), NON validato — e' proprio perche' non si distinguono che la scelta non
conta.

(3) CORREZIONE a un'indicazione data ieri. Avevo scritto "una linea in EUR aggiunge la
conversione per ordine". Vero solo per un conto in USD: per un conto in EURO vale
l'opposto. L'esposizione economica e' identica (il fondo detiene attivi USD, nessuna
delle due linee e' coperta) — la valuta di quotazione non copre nulla, decide solo se
serve una conversione. Regola giusta: prendere la linea nella valuta del proprio saldo.
Misurato: turnover lordo $13.655/anno su $10k -> 25bps = -0.07 Sharpe = $34/anno = ~$1.6
per ordine, contro una soglia di $18.90.

Regola generale: un costo di conversione non e' una proprieta' dello strumento ma della
coppia strumento-CONTO.

Book, pesi, cron, config INVARIATI. 447 test verdi (+3).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
2026-07-27 11:25:20 +00:00
Adriano Dal Pastro 842b0e865b research(gtaa): il numero di ordini e' un parametro — il costo smette di essere binding
Correzione dell'operatore: "io ho gia' Revolut e Degiro e li uso da anni, IB sono solo
iscritto". La raccomandazione di ieri (restare su IB) poggiava su "il conto esiste
gia'", che era falso. Il gateway IB serve solo per i DATI del segnale (basta il paper),
quindi il broker di esecuzione e' libero e la scelta si gioca solo sul costo per ordine.

(a) I 77-149 ordini/anno sono la conseguenza di REBAL_EVERY=5 / REBAL_BAND_USD=50,
scelti il 25/07 per il listino IB su azioni USA e a una taglia sola. A cadenza
settimanale allargare la banda NON costa: Sharpe a costo zero 1.27 ($50) -> 1.27 ($400)
con ordini 84 -> 23. Rallentare la cadenza invece costa (1.27 -> 1.12 mensile). La banda
filtra la deriva del vol-target, non il segnale di trend. Controllo fuori finestra: sui
veicoli USA su 10 anni lo Sharpe a costo zero perde 0.02 mentre gli ordini calano del
74% -> non e' un artefatto della finestra UCITS corta.

(b) MA la banda in dollari assoluti e' la parametrizzazione sbagliata: a $3.000 una
banda da $400 e' l'80% della gamba -> 3 ordini/anno, a mercato il 45% del tempo invece
del 66%, con Sharpe 0.71 ancora "accettabile". Null de-levering in veste nuova: non
travestito da meno drawdown ma da meno costi. Il controllo non e' lo Sharpe ma la quota
di tempo a mercato.

(c) Configurazione proposta: banda = 25% della gamba -> 21 ordini/anno a OGNI capitale,
esposizione 66% ovunque, soglia $5.65/ordine a $3k (contro $2.08 del canonico). Proposta,
non cambio di produzione: non passata per study_family_honest ne' deflated-Sharpe, e
GTAA01 non e' deployabile prima dei $20k.

(d) ISIN da contract details IB per la ricerca sul conto reale (VUAA/XNAS/R2US/IDTL/
IGLN/IHYU, tutti IE, Londra in USD). La valuta della linea conta piu' del broker: una
linea in EUR aggiunge ~25bps per ordine = ~0.15 di Sharpe.

Book, pesi, cron, config INVARIATI. 444 test verdi (+9).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
2026-07-27 06:01:01 +00:00
Adriano Dal Pastro be4690375f research(gtaa): la via UCITS e' aperta e costa ~zero — il broker non e' la variabile
Domanda dell'operatore: "usiamo revolut o degiro". Risposta misurata: cambiare
broker non sblocca nulla (il PRIIPs e' una norma, non una politica di IB); cambiare
VEICOLO si', e costa ~zero.

CORREZIONE A UNA MIA AFFERMAZIONE. La nota in gtaa.py diceva che gli UCITS fanno
perdere la validazione a 30 anni. Falso: il PRIIPs vieta di COMPRARE, non di
GUARDARE — i prezzi dei 6 ETF USA restano leggibili, quindi il segnale gira sui 30
anni per sempre e cambia solo il veicolo su cui si incassa.

Misure (3 lenti, un grado di liberta' per volta, 6.3 anni comuni):
  L0 segnale USA + rend. USA   Sh 0.81 / CAGR 3.96%
  L2 segnale UCITS + rend. UCITS Sh 0.84 / CAGR 4.08%
  drag del veicolo +0.10%/anno EW, coerente coi TER; ritenuta USA ~35bps a FAVORE
  dell'UCITS e non inclusa nel drag.

Lo stimatore ovvio sbagliava: la media delle differenze giornaliere dava -0.47%/anno
su CSPX contro -0.06% vero (SE ~7%/anno = 15x la quantita' stimata, piu' drag di
varianza). La deviazione fra veicoli sullo stesso indice si misura sul RAPPORTO
CUMULATO.

Il vincolo non e' il broker ma il prezzo di UNA azione, che e' una scelta: CSPX $802
vs VUAA $144 sullo stesso S&P 500. A $3.000 con azioni intere l'insieme STORIA tiene
4/6 gambe (a mercato il 33%), l'insieme DEPLOY 6/6 (65%) -> il frazionamento non
serve. Letto su gambe-vive+vol, non su Sharpe: il vincolo intero ALZA lo Sharpe
perche' de-leveraggia (null de-levering, 4a occorrenza).

Resta da verificare una cosa sola: 77-149 ordini/anno contro soglie $0.90 ($3k) /
$2.23 ($10k) / $7.62 ($50k) per ordine. Raccomandazione: restare su IB.

Feed equity: aggiunto il CROSS-CHECK che mancava (src/data/eq_crosscheck.py). Il
primo veicolo estero ha trovato subito CSPX 2012-01-13 con open/high in USD e
low/close in EUR (fattore 1.2797 = EURUSD del giorno), invisibile alla guardia
maxret>50% — stesso schema dello split 2:1 del 25/07. Soglia non tarabile sulla
deviazione (rumore 9.90%, margine 2.2x): cambiata statistica in |dev|/movimento del
gemello -> margine 5.3x. Limite EURUSD 1.09 dichiarato e chiuso sul DANNO (dSharpe
mediano -0.003), congelato in un test.

Book, pesi, cron, config INVARIATI. 435 test verdi (+24).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
2026-07-26 23:01:54 +00:00
Adriano Dal Pastro 95caeb87da feat(live): allerta sul salto di equity — conferma il versamento, segnala un prelievo
La verifica "il cap si adegua?" esisteva solo come sorveglianza di sessione, e il
versamento slitta di giorni: una verifica che vive in una chat non e' una verifica. Resa
permanente e generalizzata.

`write_equity_watermark` ora ritorna {prev, new, pct} quando il salto fra due letture
consecutive supera EQUITY_JUMP_ALERT = 10%; `book_report` lo espone come `equity_jump` e
`book_execute` manda un Telegram con il NUOVO DIMENSIONAMENTO accanto (cap/asset, nozionale
lordo, leva), cosi' il messaggio si legge senza aprire il repo.

Il book ha vol ~0.4%/giorno: un salto del 10% fra due giri orari non puo' venire dal
trading. Quindi l'allerta copre DUE casi con un meccanismo solo:
  - VERSAMENTO: conferma che e' atterrato e che il sizing lo ha seguito;
  - USCITA DI FONDI: un prelievo che non hai chiesto, o una perdita anomala. E' questo il
    caso che conta di piu', ed e' il motivo per cui la soglia e' a due code.

Prima lettura in assoluto -> nessun allarme (senza un "prima" non c'e' un salto).
Il watermark si aggiorna ANCHE quando allerta, o il cap resterebbe indietro (test cablato).

411 test verdi (+7). Strategia, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:23:28 +00:00
Adriano Dal Pastro a1b4416ac0 feat: EDGE WATCH — criteri di kill pre-registrati per il book LIVE
"Come faccio a capire se l'edge e' morto?" scopre un buco: il progetto ha gate di kill
pre-registrati per i CANDIDATI (DVOLSPREAD 24/10, XSR01 23/10, STATARB 27/09) e NESSUNO
per il book che gira con soldi veri. La risposta implicita era "si vedra'", cioe' quello
che il progetto non accetta dai candidati.

LA RISPOSTA SCOMODA: non si puo' sapere in fretta. Sharpe rolling a 12 mesi: il 56% dei
casi "edge morto" e' indistinguibile da uno vivo. Un anno brutto e' rumore, non
informazione.

CRITERIO A (ritorno, book intero): Sharpe rolling 36 mesi sotto -0.5. Tarato sul nullo
(edge intatto) -> falso kill 1.8% in 10 anni; controllo positivo (edge morto) -> lo
riconosce nel 91% dei casi, rilevamento mediano 3.8 anni. La lentezza non e' un difetto
della regola ma statistica: a 12 mesi la stessa regola ucciderebbe un edge VIVO nell'80%
dei casi. Non esiste una versione veloce e onesta.

CRITERIO B (TP01, che e' DIFENSIVO): serve un criterio diverso perche' il LOO del 26/07 ha
misurato il contributo hold-out di TP01 negativo nel 99.1% delle configurazioni d'ancora —
firma dell'assicurazione, che paga premio negli anni senza incendio. "Non ha guadagnato"
NON e' evidenza di morte. Criterio: in un anno con DD buy&hold > 10%, il DD di TP01 deve
restare sotto il 75%. Storico 8 anni di sinistro, 8/8 superati (protezione 1.8x-34.4x).
Negli anni SENZA sinistro il criterio non si valuta: non c'e' informazione. Questo criterio
e' VELOCE dove l'altro e' lento.

COSA SUCCEDE SE SCATTANO (dichiarato ora per non deciderlo nel momento sbagliato):
(A) il book NON si spegne da solo -> revisione con weights_tilt_null + deflated-Sharpe sui
dati nuovi; spegnere e' decisione dell'operatore. (B) fallito in DUE anni di sinistro
consecutivi -> TP01 non assicura piu' e il peso 75% va rimesso in discussione.

CABLATO: scripts/live/edge_watch.py in cron_daily.sh, allerta Telegram, non tocca
l'esecuzione. Stato oggi: Sharpe 36m +1.51, protezione 8/8.

IL LIMITE, DETTO: il criterio A rileva la morte ~4 anni dopo, e non e' riparabile con una
regola migliore (e' il contenuto informativo dei dati). La difesa vera e' che il piano
regge a un edge dimezzato (11.6 -> 15.8 anni, P(20a) ancora 77%) e che i rischi VELOCI
(venue, esecuzione, feed) hanno sorveglianze che scattano in ore.

404 test verdi (+11). Book, pesi, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:14:53 +00:00
Adriano Dal Pastro 28b63cf3a3 test: isola il watermark nei test del book (leggevano lo stato di produzione)
Il commit precedente e' stato pushato con un test rosso: la catena `&&` leggeva l'exit
code di `tail`, non di pytest. Errore mio, riparato qui.

LA CAUSA E' PIU' SERIA DEL TEST. `test_cap_falls_back_to_fixed_on_eq_fallback` falliva
perche' `_write_cfg` isolava la CONFIG ma non il nuovo watermark: i test leggevano
`data/live/equity_seen.json` REALE, quindi il loro esito dipendeva da quanto c'e' sul
conto vero. Un test che non menziona il watermark cambiava risposta a ogni deposito.

`_write_cfg` ora monkeypatcha anche EQUITY_WATERMARK su tmp_path e accetta un parametro
`watermark` esplicito. Aggiunti due test sul comportamento nuovo:
  - fallback con watermark $596.92 e cap config $3.000 -> $298/asset, leva <= 1x;
  - fallback con watermark $6.047 -> $3.000/asset (il tetto di config).
Il test storico resta e ora documenta il caso "conto mai visto" -> taglia sicura.

393 test verdi (exit code verificato, non dedotto dal tail).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:56:03 +00:00
Adriano Dal Pastro b023cc2bdf fix(live): cap di fallback legato all'ultima equity osservata + cap config 300 -> 3000
L'operatore ha autorizzato "si alza il cap a 3000". Verificato PRIMA di eseguire: il
deposito non era ancora arrivato (equity reale $596.92), e alzare il cap in quel momento
sarebbe stato pericoloso NEL VERSO OPPOSTO.

IL PROBLEMA. Quando l'equity reale non e' leggibile, shadow_report ripiega su paper_cap =
$2.000 NOMINALI, che non e' il conto vero: il sizing diventa 0.5 x 2000 x (...) = fino a
$1.000/asset, e il cap fisso e' l'unica cosa che impedisce a quel nominale di diventare
leva reale.
  cap $300  -> fallback $600 lordi su $597 = 1.00x  OK
  cap $3000 -> fallback $2.000 lordi su $597 = 3.35x  NO
Cioe' il cap sarebbe stato troppo alto proprio nel momento in cui non si sa quanto c'e'
sul conto, e con disaster_sl_pct -30% quella e' la configurazione peggiore possibile.

LA CORREZIONE. Invece di alzare un numero da ricordare, il cap di fallback e' legato al
conto: cap_fallback = min(cap_fisso_di_config, ultima_equity_reale_osservata * frac), con
watermark in data/live/equity_seen.json scritto da book_report ogni volta che l'equity
reale e' leggibile. Il cap di config torna a essere un TETTO DICHIARATO.
Senza watermark (primo avvio, file cancellato) -> CAP_UNKNOWN_USD = $300: non si sa niente
del conto, si usa la taglia storicamente sicura.

VERIFICATO SUL CONTO VERO, nei due regimi:
  oggi, watermark $596.92    ->   $298.46/asset = leva 1.00x
  dopo il versamento, $6.047 -> $3,000.00/asset = leva 0.99x
Sicuro in entrambi gli ordini di eventi, senza dipendere da un'azione manuale al deposito.

Questo CHIUDE l'azione pre-registrata il 2026-07-02 ("al deposito alzare il cap a
equity/2"), rimasta ineseguita per 24 giorni — non eseguendola, ma rendendola non
necessaria.

REGOLA: un parametro di sicurezza che va aggiornato a mano a ogni cambio di scala e' un
difetto, non una configurazione. Lo stesso numero era sbagliato in un verso prima del
deposito e nell'altro dopo: la soluzione non era scegliere il valore giusto, era legarlo
alla grandezza che lo determina.

Guardie: tests/test_cap_watermark.py (11), A DUE LATI — il cap non puo' ne' superare il
conto reale (leva nascosta) ne' restare sotto dopo un deposito (strozzatura).
Dry-run sul conto reale: cap/asset $298, book flat, nessun ordine. 391 test verdi (+11).

Strategia, pesi, cron INVARIATI. Cambia solo config/live.json e il calcolo del cap di
fallback.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:44:27 +00:00
Adriano Dal Pastro 1227b2baab research: il piano dichiarato EUR 5.000 + EUR 500/mese, e la strozzatura del cap
L'operatore ha dato i numeri veri: EUR 5.000 subito + EUR 500/mese. Cambia la scala
(conto da $597 a $6.047 = 10.1x), quindi ricalcolato in dedicata invece che estrapolato.

QUANDO: traguardo EUR 50/g ($272.061) a p10 9.4a / MEDIANA 11.6a / p90 14.4a;
P(entro 15a) 94%, P(entro 20a) 100%. Rendita mediana: EUR 6.37/g a 3 anni, EUR 11.57/g a
5, EUR 35.18/g a 10, EUR 87.63/g a 15.

VALIDAZIONE INCROCIATA: la variante "solo EUR 500/mese da $600" da' 12.4 anni = esattamente
il numero pubblicato il 25/07 con macchineria diversa.

IL LUMP VALE 0.8 ANNI (12.4 -> 11.6), MENO di quanto suggerisse il "fattore 6" del
calendario, e la ragione e' aritmetica: EUR 5.000 sono ~10 mesi di versamenti a EUR 500,
quindi comprano ~10 mesi. Anticipare vale in proporzione a quanto si anticipa. La mia
aspettativa era piu' alta ed e' corretta.

SOGLIE: $3k e $5k superate il giorno 1 (GTAA01 e XSR01 diventano eseguibili); $13k a ~0.9
anni (GTAA01 entra nel book deployable); $20k a ~1.6 anni = LA DECISIONE VENUE DEL 26/07
SMETTE DI ESSERE UN'IPOTESI E DIVENTA UNA DATA (~19 mesi); $117k a ~7.6 anni (XS01).
Le soglie superate subito NON autorizzano ad anticipare il gate XSR01 del 23/10.

CON IL RISCHIO DI VENUE: P(traguardo) 100% -> 88% a p=1% (P(perso tutto) 23.2%); a p=5% il
capitale mediano e' ZERO. Il piano regge fino a p=2%.

⚠️ AZIONE OPERATIVA TROVATA (non eseguita, e' config su soldi veri): `book._cap` ripiega su
max_notional_per_asset_usd=$300 quando l'equity reale non e' leggibile. A $597 il fallback
era INERTE (equity/2 = $298 ~ $300); dopo il versamento equity/2 vale ~$3.023, quindi un
fallback strozzerebbe il book al ~10% del target, in silenzio. E' l'azione gia'
pre-registrata il 2026-07-02 ("al deposito alzare il cap a equity/2"). Cablato
test_il_cap_fisso_diventa_una_strozzatura_dopo_un_deposito, che FALLISCE se si deposita
senza adeguare il cap.

Aggiunta anche la sezione (F) frontiera di sostenibilita' a r0726_deposits.py: capitale e
rendita per (importo x anni sostenuti), e il confronto "tirare poco tempo vs comodo a
lungo" — EUR 400/m per 5a batte EUR 200/m per 20a, ma EUR 600/m per 3a perde contro
EUR 250/m per 15a.

Book, pesi, cron, config INVARIATI. 380 test verdi (+3).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:34:00 +00:00
Adriano Dal Pastro 4703f75f9f research: i versamenti — le 4 ipotesi che il piano non aveva mai fatto
Tutte le traiettorie del 25-26/07 assumevano versamento PIATTO, ININTERROTTO, PER SEMPRE:
l'ipotesi meno realistica dell'intero piano. Misurate le deviazioni che succedono davvero,
con la stessa macchineria (block bootstrap sui ritorni reali del book live, fattore
d'ancora x0.89 misurato).

(1) SMETTERE — il costo non e' proporzionale ai soldi mancanti. EUR 250/m per K anni poi
stop, orizzonte 20a: 3a ($10.410) -> $202.771 / P(muro) 32.7%; 5a -> $287.081 / 53.3%;
20a ($66.818) -> $496.778 / 90.0%. I PRIMI 5 ANNI SONO IL 25% DEI SOLDI E IL 58% DEL
RISULTATO -> un'interruzione al 12° anno costa poco, una al 3° quasi tutto. Argomento per
partire con un importo sostenibile invece che ambizioso.

(2) CRESCENTE E' PEGGIO DI PIATTO A PARI SOLDI. EUR 150/m +5%/anno versa EUR 67.998 ->
$401.889; piatto EUR 250 versa EUR 66.818 -> $496.778 = +24% con gli stessi soldi, solo
perche' entrano prima. Metrica giusta per confrontare piani di taglia diversa =
$ finale / $ versato (piatti 7.4x, crescenti 5.1-5.9x).

(3) STESSO TOTALE, CALENDARIO DIVERSO = FATTORE 6. EUR 60.000 distribuiti: ultimi 10 anni
$178.494 (11%) / piatto 20a $496.778 (90%) / primi 5 anni $1.104.587 (99.4%). NON
significa "versa tutto subito": un piano che non si sostiene non e' un piano.
Verificato COL RISCHIO DI VENUE DENTRO (il front-load mette piu' capitale sull'exchange
prima = proprio il rischio del giorno): REGGE, 2.22x -> 2.09x a p=2%, perche' il rischio
colpisce il tempo, non il calendario. MA a p=5% il capitale mediano e' $0 PER OGNI
CALENDARIO -> formulazione piu' netta del rischio di venue trovata finora: non erode il
piano, lo CANCELLA.

(4) LA DOMANDA INVERSA — rendita netta EUR/g mediana per versamento e orizzonte. EUR 150/m
-> 23.96/g a 15 anni; EUR 250/m -> 39.11/g a 15a e 91.30/g a 20a (P(EUR 50/g) 90%).
Riformula l'obiettivo: EUR 50/g e' UN punto sulla griglia, non l'unico risultato.
Non-linearita': da 15 a 20 anni la rendita piu' che raddoppia a ogni livello.

(5) FREQUENZA = la decisione meno importante. Mensile fino a ~$2/trasferimento, bimestrale
sopra; differenze 1-3% del capitale finale. Verificato che un deposito NON resta
strozzato: col cap dinamico cap = equity/2 = il nozionale massimo richiedibile.

ORDINE DI IMPORTANZA: versare o no (da mai a 16 anni) > quando (6x) > quanto presto si
smette (5 anni = 58% del risultato) > piatto vs crescente (24%) > frequenza (1-3%).

Book, pesi, cron, config INVARIATI. 377 test verdi (+12).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:23:46 +00:00
Adriano Dal Pastro 1dd26342ca research: rivalutazione della strategia — 0 cambi, 75/25 confermato per la terza volta
Delle sei misure prodotte oggi solo UNA apriva una decisione: il peso 75/25 fu
confermato il 24/07 con la lente HOURLY, e il 26/07 quella lente e' risultata
pessimistica su ENTRAMBI i lati di SKH01 (uscite +0.081, ingressi +0.048 di Sharpe di
book). Se SKH01 vale piu' di come e' stato pesato, 0.25 poteva non essere piu' l'ottimo.
Contro tirava il LOO de-luckato dello stesso giorno (SKH01 = il meno affidabile dei
cinque). Due correzioni in versi opposti: si misura, non si deduce.

MISURA (path live intra_entry=True, 8 offset, mediana delle differenze APPAIATE):
argmax a w=0.35, e 0.30-0.40 batte 0.25 nell'88% degli offset -> il segnale c'e' ed e'
nel verso previsto dalla correzione di lente. Ma il plateau entro 0.05 di Sharpe e'
[0.25 ... 0.50] e il peso live e' DENTRO, e `weights_tilt_null` FALLISCE
(delta_insample -0.0026, gate_pass False).

IL MOTIVO VERO sta in cio' che la mediana nasconde: il guadagno e' tutto nella coda ALTA.
p10 per peso 1.463 / 1.465 / 1.455 / 1.435 / 1.374 mentre il p90 sale monotono
1.915 -> 2.064. Alzare SKH01 non compra Sharpe, compra dipendenza da quale ancora ti e'
capitata (banda da 0.45 a 0.69). Coerente con altre due misure indipendenti dello stesso
giorno: SKH01 ha la frazione d'ancora piu' grande da restituire (LOO) ed e' 4x piu'
fee-sensibile. Tre misure indipendenti dicono che SKH01 e' la gamba fragile del book e
che 0.25 sta all'estremo prudente della regione robusta.

LA RIVALUTAZIONE CHE CONTA NON E' SULLA STRATEGIA. Ordini di grandezza a confronto:
ottimizzare il peso = +0.030 Sharpe (gate fallito); versare EUR 250/mese invece di EUR 0
= da MAI a 16.2 anni (P entro 20a = 92%); perdere il conto Deribit a p=1% = -18% di
probabilita' di arrivare, ripartendo da zero. Il book e' dentro il suo plateau su ogni
asse misurato: la ricerca ha smesso di essere il vincolo binding. I vincoli binding oggi
sono capitale che entra e conto che non sparisce.

Book, pesi, cron, config INVARIATI. Gate pre-registrati alle loro date (anticiparli
sarebbe selezione sull'hold-out). 365 test verdi (+6).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:06:23 +00:00
Adriano Dal Pastro ab5bcace16 feat: VENUE WATCH — tripwire di fallimento exchange, cablato live
Risposta a "trova un sistema di protezione da fallimento exchange" SOTTO IL VINCOLO
della decisione appena presa (100% Deribit fino a $20k). Se non si puo' ridurre
l'ESPOSIZIONE, l'unica leva e' il TEMPO: il modello di rischio del mattino assumeva il
salto a zero istantaneo, ma i fallimenti reali non lo sono (Mt.Gox mesi, FTX ~72h, e
misurato qui: Bitfinex 2018-19 dislocato per 2.324 ore consecutive).

SEGNALE: un venue che gata i prelievi rompe l'ARBITRAGGIO -> il prezzo si stacca dal
consenso e ci resta. E' |scarto|, non il segno (Mt.Gox a premio, un venue in fuga a
sconto: stessa cosa). Consenso = venue USD indipendenti (Coinbase, Bitstamp), mai USDT.
Deribit sta a 3 bps dal consenso in mediana su 8 anni (65.043 ore BTC + 64.541 ETH).

TARATURA CONGELATA: 100 bps persistenti 4h a segno costante. Criterio DICHIARATO PRIMA,
perche' i due ovvi sbagliano in versi opposti (provati entrambi): "minimi bps" -> 25/24h
consuma 24 delle ~72h di FTX; "minime ore" -> 500/2h MANCA FTX (margine 0.6x). Regola:
zero falsi allarmi in 8 anni + margine >=3x sul caso storico piu' debole -> soglia
<=100bps -> poi minima latenza. Margine 3x FTX / 5x Quadriga / 10-20x Mt.Gox, zero falsi
allarmi con crash COVID, maggio 2021, LUNA e novembre 2022 inclusi.

CONTROLLO POSITIVO SUPERATO (un rilevatore tarato per non segnalare e' indistinguibile da
uno rotto): puntato su Bitfinex 2018-19 scatta 22 volte, episodio piu' lungo 2.324h a
+447bps. 22 dove il problema c'era, 0 su Deribit. E la durata risponde alla domanda vera:
un venue gated resta dislocato per settimane, quindi 4h di latenza sono trascurabili.

ECONOMIA: falso allarme = 0.248% atteso (flat 3g misurato sul book reale a ogni data
d'inizio); vero positivo = 100% salvato. Break-even p > (falsi/anno) x 0.00248: a 1 ogni
8 anni serve p > 0.031%. Il valore sta nella SPECIFICITA', non nella sensibilita'.

CABLATO: src/live/venue_watch.py (nucleo puro) + scripts/live/venue_watch.py, in
cron_book.sh PRIMA di book_execute (se Deribit e' in stress l'allarme deve partire anche
quando l'esecuzione fallisce per la stessa ragione). Tre stati OK/ALERT/BLIND — "non
vedo" non e' "va bene". ALLERTA, NON BLOCCA: l'azione e' prelevare (manuale; una chiave
con permesso di prelievo sarebbe essa stessa un rischio) e bloccare non protegge un saldo
che e' a rischio anche stando flat. Runbook pre-deciso nel docstring.

NON COPRE, e non e' un argomento per riaprire il 26/07: un fallimento SENZA finestra
(furto chiavi, sequestro, exit-scam) non lo prende nessun tripwire.

ERRORI CATTURATI IN SESSIONE:
- break-even calcolato sul p5 invece che sulla media (8.3x piu' severo, conclusione
  ribaltata);
- ipotesi meccanica sbagliata: credevo che i crash dislocassero a segno ALTERNATO. Falso,
  sono a segno costante anche loro (perp sotto spot per ore in cascata). A separare sono
  ampiezza e durata, non il segno;
- la prima corsa tronco' il campione da 8 anni a 29 GIORNI per un inner-join con Kraken
  (che serve solo ~700 candele) e la copertura era gia' stampata a video: una diagnostica
  stampata NON e' un controllo. Ora c'e' una guardia che ferma lo script. 2a occorrenza
  in un giorno dopo GTAA01;
- il controllo positivo era finito dentro il ramo `else` -> non girava mai, cioe'
  esattamente il difetto che doveva prevenire.

Book, pesi, config INVARIATI. 359 test verdi (+23).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:38:19 +00:00
Adriano Dal Pastro 3a44171402 research: il muro come punto fisso — la previsione del follow-up era SBAGLIATA
Il follow-up dichiarato stamattina diceva: "i muri usano il book a 2 sleeve da $600
estrapolato a $272k; il book diversificato ha Sharpe piu' alto -> IL MURO VERO E' PIU'
BASSO". Misurato: FALSO. A pari nozionale il muro e' $273.900 contro i $272.061
pubblicati (+1%): l'estrapolazione col book a 2 sleeve era giusta PER CASO.

STRUTTURA: il muro e' un PUNTO FISSO — serve capitale C per girare il book che determina
il muro C, quindi si itera C_{n+1} = muro(book(C_n)). Converge in 1 iterazione perche' il
muro cade SOPRA la soglia XS01 ($117k) e la composizione non cambia; la struttura conta
solo se il muro atterra vicino a una soglia, ma va iterato per saperlo.

BOOK DEPLOYABLE (non il "migliore"): TP01 38 / SKH01 23 / GTAA01 23 / XS01 17. VRP01
escluso per regola permanente (niente short-vol da modello in deploy), XSR01 escluso per
gate pre-registrato 23/10. Costi capital-aware, fattore d'ancora x0.860 misurato su
QUESTO book. Sharpe 1.94, vol 8.9%, CAGR 18.3%.

PERCHE' NON SCENDE: diversificare alza lo Sharpe (1.64 -> 1.94) ma abbassa drift e vol
INSIEME, e la rendita perpetua vive sul DRIFT -> 10.91% -> 10.84%, invariata. Il guadagno
di Sharpe va in meno rischio, non in piu' reddito. E' il fatto gia' misurato il 25/07 §3,
dimenticato scrivendo il follow-up.

E STAVO VIOLANDO UNA REGOLA GIA' CODIFICATA: "un diversificatore a basso CAGR si giudica
a ISO-RISCHIO, mai a iso-nozionale" (25/07 §3). A iso-rischio (leva 1.28x): rendita
13.35%, muro $222.406 = -18% -> replica indipendente del -19% misurato il 25/07 con
macchineria e book diversi. Vale solo se la leva e' disponibile e a costo < uplift: $222k
e' un TETTO, non una stima.

BUG CATTURATO PRIMA DI PUBBLICARE: la prima corsa dava Sharpe 0.95 e muro $854k
("diversificare triplica il muro" — spettacolare e falso). CC.gtaa_banded ritorna la
storia GTAA dal 1996 mentre lo sleeve di produzione tronca a GTAA_BOOK_ACTIVATION; con la
rinormalizzazione per-riga di combine_outer il 75% del campione era GTAA01 DA SOLO al
100%. Preso non da un test ma perche' la somma pesata dei componenti (~18%) non tornava
col drift del combinato (6.8%). Diagnostica decisiva: la copertura per colonna
(TP01 24.6% / SKH01 24.6% / GTAA01 100.0% / XS01 8.6%).

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 18:56:07 +00:00
Adriano Dal Pastro a937e3766f research: nuovo schema fee Deribit (1 ago 2026) — misurata la curva, nessuna azione oggi
L'annuncio (taker piu' bassi, maker rebate piu' bassi, soglie VIP abbassate, VIP7,
liquidation fee 1%, spot a zero) NON contiene numeri, e la tabella nell'articolo
Insights e' un'IMMAGINE: non letta da fonte primaria. I valori indicativi (base ~5bps
taker / 2bps maker, VIP7 2/0) vengono da un riassunto SECONDARIO ed e' dichiarato.

Quindi misurata la CURVA invece di aspettare il numero — vale per qualunque valore esca.
Le repliche parametrizzate riproducono BIT-EXACT gli sleeve di produzione alla fee
canonica (max|dif| = 0.0), altrimenti la curva descriverebbe un'altra strategia.

 bps/lato   %RT |  TP01 Sh | SKH01 Sh | BOOK Sh   CAGR
      0.0  0.00% |   1.322  |   1.567  |  1.849  21.69%
      3.0  0.06% |   1.303  |   1.495  |  1.799  20.99%
      5.0  0.10% |   1.290  |   1.446  |  1.766  20.53%   <- oggi
     10.0  0.20% |   1.258  |   1.324  |  1.682  19.39%
     15.0  0.30% |   1.226  |   1.200  |  1.597  18.26%

Sensibilita' del book: -0.017 Sharpe/bps, -0.23% CAGR/bps. Anche un RADDOPPIO del taker
costa 0.08 di Sharpe, MENO della banda d'ancora dello stesso book (2.222 -> 1.946): la
fee va messa nella sua scala di grandezza.

SKH01 e' ~4x piu' sensibile di TP01 (-0.69% vs -0.09% CAGR/bps: round-trip discreti vs
posizione continua vol-targeted) -> se il taker salisse, il primo parametro da rivedere
e' il peso 75/25.

REGOLA DECISA IN ANTICIPO (per non decidere col numero davanti): taker <=5bps/lato ->
non si tocca nulla; >10bps/lato -> rivedere il peso di SKH01.

Punti irrilevanti e perche': maker (il book manda ordini market; tocca solo la
raccomandazione T1 gia' non implementata); liquidation fee 1% (live.json da' nozionale
lordo max 1.00x l'equity con disaster-SL -30% -> servirebbe un movimento avverso ~100%);
VIP (a $600 il volume 30g e' trascurabile).

La conclusione sulla liquidation fee poggia sul CAP, non sulla strategia: cablata una
guardia di decisione (test_leva_massima_da_config_resta_sotto_o_uguale_a_1x) che ROMPE
se qualcuno alza il cap, invece di lasciarla valida per inerzia.

AZIONE 1 agosto: leggere il tier reale in Account Settings e applicare la regola sopra.

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 18:32:23 +00:00
Adriano Dal Pastro 326229188a research: rischio di VENUE — mai prezzato, e non e' diversificabile dagli sleeve
Domanda dell'operatore: "tutto su Deribit?". Ha scoperto un buco, non un dettaglio.

IL BUCO. Il progetto ha prezzato con ossessione fee, slippage, min-order, pavimento IB,
haircut small-cap, fortuna d'ancora, degrado d'esecuzione, look-ahead, backfill, split
non aggiustati — e MAI la probabilita' che l'exchange sparisca col saldo dentro. E
TP01+SKH01+VRP01 stanno tutti sullo stesso conto: tre sleeve quasi-ortogonali sui
ritorni, PERFETTAMENTE CORRELATI sul fallimento del venue. La matrice di correlazione
del book non lo vede per costruzione.

LIMITE DEI MURI DEL 25-26/07 (dichiarato): book_series gira a alloc=$600 col book a 2
sleeve, quindi portarlo a $272k assumeva gia' "tutto su Deribit" senza dirlo — e
assumeva anche di girare il book da $600 a $272k (falso: a $3k GTAA01, $5k XSR01, $20k
XS01 -> il muro vero e' piu' basso).

LA MISURA (accumulo da $600, 250 EUR/m, 20a, bersaglio $272k, x0.89, jump di venue;
CONC = 100% Deribit vs SPLIT = Deribit 65 / HL 15 / IB 20; bersaglio identico ->
conservativo CONTRO lo split):

  p annua    P(arrivare) CONC / SPLIT    P(perso TUTTO) CONC / SPLIT
  0.5%              87% / 90%                    10% / 0%
  1.0%              81% / 83%                    18% / 0%
  2.0%              69% / 71%                    34% / 4%
  5.0%              42% / 45%                    64% / 27%

Capitale mediano CONC a 20a: $544k (p=0) -> $0 (p=5%).

LA COLONNA CHE CONTA NON E' LA PRIMA. Sulla probabilita' di ARRIVARE la concentrazione
costa 1-3pp; sulla ROVINA fino a 64pp. Motivo strutturale: con un conto solo "almeno un
fallimento" COINCIDE con "perso tutto". Lo SPLIT viene colpito 2.5x piu' spesso ed e'
molto piu' sicuro -> "quante volte vieni colpito" non e' una misura di rischio.

ONESTA': p NON e' stimato (sensibilita', non previsione); i fallimenti sono assunti
indipendenti, ottimistico per Deribit-HL -> la parte solida dello split e' IB, altra
classe di rischio; a $600 lo split e' impossibile, la concentrazione e' forzata.

RISPOSTA: no, ma la domanda ha una DATA. Prima soglia vera ~$3k (GTAA01 su IB). E
converge col 25/07: "max 25% su IB, COSTA ~0.08 EUR/g" era detto su basi di solo
rendimento; sull'asse della rovina quello stesso 25% e' la mossa principale — non e' il
prezzo di un peggioramento, e' il premio di un'assicurazione.

Incluse le aggiunte a r0726_capwall_refresh: drill-down 250 EUR/m e solve_deposit
(10 anni @P=90% = 1.178 EUR/m, $155.923 versati su $272k -> il rendimento fa il 43%,
contro il 77% a 20 anni). Bug catturato: il contatore dei versamenti si congelava al
traguardo mentre il capitale continuava a riceverli -> rapporto gonfiato (46x vs 25x a
30 anni); test di regressione cablato.

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 17:57:53 +00:00
Adriano Dal Pastro 842420ce7b research: follow-up SKH01 chiuso — il blocco non esisteva, il de-luck x0.6 era troppo severo
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>
2026-07-26 16:55:01 +00:00
Adriano Dal Pastro b9b2ef1b26 research: leave-one-out del book DE-LUCKATO sulle ancore — la classifica si ribalta
Domanda: "quale sleeve terrei?". Il leave-one-out ovvio e' misurato all'ancora canonica
di tutti e cinque gli sleeve, quindi NON e' credibile: un LOO e' un Delta, ed eredita la
fortuna d'ancora come ogni Delta (lezione 26/07, altlib.anchor_luck_delta).

Metodo: 2000 estrazioni uniformi indipendenti sullo spazio congiunto 24x10x7x23x5 =
193.200 configurazioni; book completo + 5 LOO alla STESSA configurazione; statistica =
mediana delle differenze appaiate. Sanity bit-exact 5/5 (max|dif| = 0.0) contro gli
sleeve di produzione. Quattro repliche ancorate riusate dagli audit 02/07-03/07, solo
la fase di GTAA01 e' nuova (ed e' l'unica coperta da test dedicato).

RISULTATI
- Livello del book: la stima a occhio del 02/07 era ottimista su 3/3 metriche.
  FULL 2.222 (97.0 pctl) -> 1.95 | HOLD 2.364 (99.6 pctl) -> 1.54 [1.11, 1.91] |
  maxDD 6.07% (12.0 pctl) -> 6.85%. Solo 9 estrazioni su 2000 battono l'hold-out canonico.
  La somma delle fortune marginali NON e' la mediana congiunta: sbagliava di +0.82 di Sharpe.
- SKH01 non e' il motore del book: l'ancora regala 2/3 del FULL, 70% dell'hold-out, 80%
  della protezione DD -> de-luckato e' il meno affidabile dei cinque.
- GTAA01 e' l'unico positivo nel 100% delle estrazioni su tutte e tre le metriche e il
  miglior protettore di DD. Ma attribuzione != eseguibilita': sotto $3k resta non deployabile.
- TP01 e' il maggior contributore (+0.390 FULL, 2000/2000) e il canonico lo SOTTOSTIMAVA.
  Il suo hold-out negativo non e' artefatto d'ancora (negativo nel 99.1%): e' la firma
  dell'assicurazione. Uno sleeve difensivo si giudica sul sinistro, non sul premio.
- XS01: protezione DD esattamente zero (positiva nel 43% = moneta) -> diversificatore di
  rendimento, non di rischio. VRP01: 2a conferma di zero fortuna (canonico all'1.8 pctl).

Corretto in sessione: un "pctl 100%" era arrotondamento di 99.55% con %.0f — un percentile
a 0 decimali mente esattamente agli estremi, che sono l'unico posto dove lo si legge.

Book, pesi, cron, config INVARIATI. Non e' un gate sui pesi (resta weights_tilt_null) e
non e' evidenza out-of-sample: e' attribuzione, de-luckata.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 13:23:36 +00:00