409 Commits

Author SHA1 Message Date
Adriano bebfa63213 tradesdb: fill cron_log arricchiti con ora, prezzo e pos_after dal jsonl (#40)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 17:51:15 +00:00
Adriano ae887a3d98 book_execute: pos_after di nuovo nel jsonl, letta subito dopo il rebalance in un try (#39)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 17:42:34 +00:00
Adriano d34b0a81d8 merge lavoro/goldrake-u11 (secondo giro 27/09) 2026-09-27 15:40:43 +00:00
Adriano cfb0e1e57f merge lavoro/goldrake-u10 (secondo giro 27/09) 2026-09-27 15:40:43 +00:00
Adriano 39adfbf267 merge lavoro/goldrake-u9 (secondo giro 27/09) 2026-09-27 15:40:42 +00:00
Adriano 81b495eb10 merge lavoro/goldrake-u8 (secondo giro 27/09) 2026-09-27 15:40:42 +00:00
Adriano 28a6d79e4f tradesdb: refilo di uno spazio in un commento (#37 C11) 2026-09-27 15:26:43 +00:00
Adriano ac6ad7f116 revisione: tetto per-voce dedicato per CLAUDE.md (150k, il generico restava a 90k con margine minimo) e avviso quando una voce supera il 95% del suo tetto (#37 C12) 2026-09-27 15:24:36 +00:00
Adriano ddcd3773a7 cron_book/cron_cuscino: flock -n sul conto, un giro occupato si salta e si scrive (#36)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:19:49 +00:00
Adriano 213dd12bab docstring: execution/deribit/book allineati al codice attuale, niente importi cablati (#35 A9)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:19:37 +00:00
Adriano 3af6e1f0c3 telegram_daily: gate da monitor_health (non cablati), formato giorni a tre casi, header condizionale su flat (#35 C14)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:18:25 +00:00
Adriano 829ebc7f98 book: min_order_usd da config nel report (#35 A7)
book_report costruiva l'ordine con min_usd=5.0 fisso invece di leggere
min_order_usd da config/live.json, come fa gia' scripts/live/book_execute.py
(default 5.0 se assente). Oggi config = 5, nessun cambio di comportamento.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:17:42 +00:00
Adriano 52a905d497 book: leva_tetto unica per cuscino USDE e giornale (#28)
La leva lorda massima del libro era ridichiarata con tre formule diverse:
usde.frazione_cuscino (N_ASSET fisso, senza scala), la regola `leva` del
giornale (senza scala) e journal.movimenti_capitale (con scala). A scala
1,25 il cuscino USDC risultava 0,30 dell'equity invece di 0,375.

Nuova src/live/book.leva_tetto(cfg) = len(ASSETS) x min(WEIGHT, frac) x
scala, al piu' LEVA_LORDA_MAX; su ScalaNonAutorizzata non solleva, ritorna
il tetto di codice (cuscino_watch non deve morire sulla config sbagliata).
usde.frazione_cuscino e la regola `leva` del giornale ora la derivano;
movimenti_capitale idem, nel suo try/except esistente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:17:01 +00:00
Adriano 12291709ed revisione, analista: taglio Telegram sul testo grezzo, prima di escape/markup (#35 C13)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:15:22 +00:00
Adriano 8e75e9c9a7 sleeves+edge_watch: pesi derivati da book (import locale), titolo kill corretto (#35 B12)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:15:07 +00:00
Adriano 13c136cf4b tradesdb: docstring corretto (jsonl ha l'ora vera dal 24/08, non piu' la barra); trades_db sync confronta i conteggi jsonl/DB e notifica una volta per episodio (#37 C11, #35 A9) 2026-09-27 15:14:04 +00:00
Adriano e82f2ee163 venue_probe: atteso hardcoded False in diagnose, l'unico chiamante non cade mai nello slot (#35 B11)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:11:29 +00:00
Adriano d80323ff59 analista: testata mostra trading_giorno (non l'equity grezza) e 'nel giorno', non 'oggi' (#35 C8)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:11:20 +00:00
Adriano d59aea7a0a monitor_health: giro orario dei sorveglianti da 3h con marcatore gia' detto (#30)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:11:10 +00:00
Adriano 31ec767ff5 telegram_daily: soglia di accensione generale su k flip, non il minimo fisso (#35 C3)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:10:04 +00:00
Adriano 95cfb396e7 fee_watch: realized_fee_bps sempre calcolata, divergenza da tier notificata una volta per episodio (#37 B9) 2026-09-27 15:06:40 +00:00
Adriano 604fde689e cuscino_watch: riconverti distingue parziale/fallita rileggendo la quota (#35 B10)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 15:03:02 +00:00
Adriano 841d4c78cd book_execute: integrazione U1+U2 — un solo Telegram in solo protezione, stato unknown, set_open_cap diretto (#18, #21, #22, #24)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 14:14:28 +00:00
Adriano 0e6cf17081 merge lavoro/goldrake-u4 (revisione 27/09) 2026-09-27 13:53:10 +00:00
Adriano dab8a88e1c merge lavoro/goldrake-u3 (revisione 27/09) 2026-09-27 13:53:10 +00:00
Adriano ed4f8fd39b merge lavoro/goldrake-u2 (revisione 27/09) 2026-09-27 13:53:10 +00:00
Adriano 8405fe2a7d merge lavoro/goldrake-u1 (revisione 27/09) 2026-09-27 13:53:10 +00:00
Adriano 7234625863 usde_convert: residui cercati sotto USDC e USDE (#26)
Non e' verificato sotto quale valuta Deribit elenchi lo spot USDE_USDC: la
quotazione (USDC) o la base (USDE). cancella_residui interroga entrambe e
unisce per order_id prima di applicare il filtro instrument+label, cosi' un
residuo elencato sotto USDE non si accumula in eterno per non essere mai
letto. Se una delle due letture solleva, solleva come prima (nessun try
aggiunto attorno al giro).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:45:04 +00:00
Adriano 9ce924d97c book_execute: chiama set_open_cap (U1) se il trader lo espone, prima di rebalance_signed
hasattr perche' U1 e U2 si uniscono dopo questo rilascio: DeribitTrader oggi non ha
set_open_cap, e l'hasattr evita che l'unione dei due rami rompa in un senso o nell'altro.
Si toglie l'hasattr al merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:41:07 +00:00
Adriano 7c72308852 live/deribit,execution: open_orders non ingoia gli errori; ensure_disaster_sl -> unknown (#24)
open_orders solleva RuntimeError se 'all' o 'trigger_all' falliscono, invece di ritornare []
(un bracket disaster-SL perso su 'trigger_all' e' lo stesso difetto di una posizione persa su
'all'). ensure_disaster_sl avvolge la lettura di posizione+open_orders in try/except: su
eccezione ritorna {"state": "unknown", "notes": ...} senza cancellare ne' piazzare, distinto
da "naked" (protezione tolta e non rimessa). shadow.shadow_report chiama open_orders gia'
dentro try/except (non toccato).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:40:50 +00:00
Adriano 65a7f0d8fc book_execute: SOLO PROTEZIONE su equity/SKH ignoti; fill mai persi su rebalance parziale (#21, #22, #23)
Prima, con equity reale non leggibile il giro dimensionava comunque un ordine sul paper_cap
($2.000 nominali) e lo mandava; con SKH ignoto il target restava quello (fail-safe solo nel
segno). Ora: se non si sa quanto vale il conto o qual e' il segnale, nessun rebalance_signed —
ma il disaster-SL si controlla LO STESSO per ogni asset (dipende da posizione/mark, non da
equity/segnale). Giro degradato -> exit 2, solo se armato (non in anteprima dry-run).

Fill persi: rebalance_signed puo' eseguire un fill (es. il close di un flip) e poi sollevare nel
passo successivo (l'open dall'altra parte) — quel fill spariva perche' la lettura di `newpos`,
PRIMA del giro che lo registrava, andava in eccezione a sua volta. Estratta la registrazione in
_registra_fill(...), chiamata SUBITO dopo ogni fill (anche quelli di RebalanceParziale, nuova
eccezione di execution.py con .fills/.causa) e PRIMA di leggere la posizione; la lettura ora e'
in un try separato, non fatale (pos_after=None + "reconcile: pos illeggibile" se fallisce).

Aggiornati due test che assumevano il comportamento vecchio (eq_fallback "prosegue" sul paper
capital) e il guard sulla sorgente di test_tradesdb.py (bar_ts ora e' un parametro di
_registra_fill, non piu' `r['last_data']` inline).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:40:15 +00:00
Adriano f79fb54221 live/execution: tetto di apertura per strumento da config, non solo MAX_AMOUNT fisso (#18)
DeribitTrader.set_open_cap(instrument, usd_cap, mark) deriva amount_max = 1,10*usd_cap/mark
dal cap di config del libro; _submit lo usa quando presente, MAX_AMOUNT resta il DEFAULT per
chi non lo chiama (il micro-test). Firma per chi la richiama prima di rebalance_signed (U2):
trader.set_open_cap(inst, r["cap_per_asset"] * r["scala"], mark).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:39:54 +00:00
Adriano 4725839041 usde_watch: notify affidabile (allertati) e quota derivata, non piu' rinviata (#29 B2, #35 B3/B4)
#29 B2: lo stato si salvava PRIMA dell'invio e il ritorno di notify() non si
leggeva — un invio fallito restava "gia' detto" per l'episodio intero. Schema
di cuscino_watch.py: nuove_condizioni()/rec["allertati"] contano una
condizione come "gia' detta" solo se l'invio precedente e' RIUSCITO; un
record vecchio senza `allertati` vale come "tutto allertato" (nessun rispam
retroattivo). Lo stato si scrive una volta sola, a fine giro.

#35 B3/B4: la quota non e' piu' una decisione dell'operatore rinviata a
lunedi' — dal 10/09 (issue #7) e' DERIVATA dal cuscino USDC
(usde._nota_cuscino) — quindi tolti DECISIONE_QUOTA_DAL, quota_da_decidere()
e la notify "la decisione di QUOTA e' dovuta". Il tetto di allerta IDONEO
legge c["quota_max_frac"] invece del 50% cablato. La riga "margine" non dice
piu' "conto SEGREGATO" (il modello e' Cross X:SM dal 31/08): stampa il totale
USDC + USDE scontato del cross, coi numeri che la funzione ha gia'.

Le due modifiche toccano lo stesso blocco (allarmi + STATE write + stampa) e
non si possono separare per hunk senza rischio: un solo commit per il file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:38:46 +00:00
Adriano 5acc31e390 venue_watch: BLIND ha una severity propria, il titolo non chiede piu' il prelievo (#31)
Con un asset BLIND e nessun ALERT, severity restava None e il titolo del
runner cadeva sul default piu' forte ("PRIMO PASSO: prelievo di prova") per
un episodio che e' "non vedo", non "stress misurato". run_once ora assegna
severity="blind" quando c'e' un BLIND senza ALERT (ALERT resta piu' forte, P9);
_titolo distingue il caso con "venue_watch CIECO — referenze non leggibili,
nessun giudizio sul venue". La ripetizione oraria di BLIND non e' toccata.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:38:35 +00:00
Adriano dda5d41f38 fee_watch: save_state solo se l'invio necessario e' riuscito (#29 B8)
save_state girava sempre dopo l'eventuale notify, anche quando l'invio
falliva: il giro dopo diff_vs confrontava lo stato nuovo con se stesso e il
cambiamento (o il livello AZIONE) spariva senza essere mai stato detto. Ora
lo stato si salva solo se non serviva un invio, o se l'invio e' riuscito.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:38:28 +00:00
Adriano f0193f013d usde_convert: cancella i residui GTC delle proprie label, nel ciclo e all'avvio (#26)
Il gateway cerbero-mcp non accetta time_in_force (PlaceOrderReq non ha il
campo): un limit riempito solo in parte restava APERTO per sempre e si
accumulava a ogni giro. cancella_residui() pulisce lo spot USDE_USDC dai
residui con label "usde-quota-*" prima del ciclo; nel ciclo, un ordine con
filled < amt viene cancellato subito dopo, e una cancellazione fallita ferma
il ciclo (mai un secondo ordine con un residuo vivo).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:38:20 +00:00
Adriano 0c19c804d1 analista: --secco non scrive piu' nel DB (#34)
scrivi() chiamava J.salva() prima del controllo su --secco: un giro "a secco" scriveva
comunque le sezioni misurate nel giornale. Ora salva() (e scrivi_file, che era gia' dopo
il return) girano solo quando non e' secco; rendi_markdown() tollera l'assenza della riga
in DB (nota/analisi vuote, verificato).

Test nuovo in tests/test_analista.py (non c'e' un test_analista_u4.py: l'analisi indicava
i due file journal/tradesdb, questo fix e' su analista.py e segue la convenzione un
file-di-test-per-modulo del resto della suite).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:38:10 +00:00
Adriano 2bf4f9cceb live/deribit: position_usd legge il segno da direction, non dal solo size (#17)
Il gateway manda size/size_currency in assoluto e il segno a parte in direction:
letta com'era, uno short risultava un long e close()/ensure_disaster_sl decidevano
lato ordine e prezzo dello stop dal segno sbagliato.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:37:36 +00:00
Adriano b8c2bba320 tradesdb: lotti con segno (short) e fill a qty<=0 fuori dal FIFO (#32 C2, C10)
C2: fifo_roundtrips ora apre un lotto SHORT quando un sell non trova lotti long da chiudere
(prima il resto spariva in silenzio), chiude prima il lato opposto e apre l'eccedenza nel
segno del fill — anche a meta' dello stesso fill (inversione long<->short). stato_aperto e
report() portano la direzione del lotto residuo.
C10: un fill "NON VERIFICATO" a qty 0 (place_order error) non entra piu' nel FIFO ne' in
stato_aperto (WHERE qty > 0 in rebuild_roundtrips/stato_aperto); resta nel DB marcato
(verified=0), non e' scomparso.

test_fifo_non_mescola_gli_asset aggiornato: una vendita ETH senza lotti long ora apre uno
short invece di sparire (era il comportamento che C2 corregge). Test nuovi in
tests/test_tradesdb_u4.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:37:20 +00:00
Adriano ac21e1c97d journal: dichiarati nello stesso intervallo si sommano, giro corrente, finestra 7gg, DD netto (#27, #35)
#27: due movimenti dichiarati nello stesso intervallo si sommavano al posto di sovrascriversi
(l'aggancio "dichiarato+rilevato" ora cerca solo fonte=="rilevato").
#35 C9: salute() non conta piu' il giro dell'ora corrente prima che scatti (minuto :47 +
margine, MINUTO_GIRO costante di modulo).
#35 C15: la finestra "ultimi 7 giorni" della concentrazione ora copre 7 giorni di calendario,
non 8 (baseline = ultima lettura al o prima di giorno-7 fine giornata).
#35 C7: il drawdown si calcola sulla serie equity al netto dei movimenti di capitale certi,
cosi' un prelievo non si legge come perdita di trading e un versamento non alza il picco.

Test nuovi in tests/test_journal_u4.py; tests/test_journal.py aggiornato (l'orologio del
test su salute() era reale e non deterministico, ora e' fissato).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:35:08 +00:00
Adriano cfc42653cc shadow: USDE illeggibile -> equity IGNOTA non 0; online richiede tutti i mark mainnet (#20, #25)
Un'eccezione sulla lettura del conto USDE valeva 0 USDE: se il conto ne aveva davvero, l'equity
totale risultava sottostimata senza che nulla lo dicesse. Ora _collaterale_usde ritorna None +
la nota dell'eccezione, e _equity propaga l'ignoto (real_eq None -> eq_fallback, non un numero
falso). shadow_report.online guardava solo il mark di BTC: con ETH in fallback il giro si
considerava comunque online. Ora richiede TUTTI i mark da mainnet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 13:33:48 +00:00
Adriano 1a7f670966 sei sorveglianti registrano i giri e stanno in monitor_health (Fixes #16)
src/live/giri.registra_giro: una riga jsonl {ts ms, campi} dopo una misura completata,
mai un'eccezione. edge_watch, fee_watch, scale_watch, vrp_f_watch, venue_news (cron_daily)
e venue_watch (cron_book, orario) scrivono data/<dir>/runs.jsonl; niente riga senza misura.
monitor_health: sei MonitorSpec (30h i giornalieri, 3h venue_watch), open_labeled=False.
Stessa riparazione di cc01 (#10, #12), generalizzata. Primo giro notturno: NUOVO, non allerta.
Test: incrocio P1 percorso/RUNS, misura -> una riga, non-misura -> nessuna. Suite: 1098 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 08:48:07 +00:00
Adriano e4efdaaa53 analista: niente capitale cablato nelle istruzioni, round-trip = lotto FIFO (Fixes #13)
ISTRUZIONI diceva «capitale ~$635» (equity reale ~$4.5k dal 04/09): valore ridichiarato,
forma di P1, e fuori pagina per la regola 1 delle istruzioni stesse. Ora il capitale e'
l'equity in pagina. Aggiunto che fifo_roundtrips chiude un round-trip per lotto: piu'
round-trip che fill nello stesso giorno e' atteso (l'analista lo segnalava come anomalia).
Test: nessun importo in ISTRUZIONI; FIFO e lotto nominati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 08:48:07 +00:00
Adriano b46041d11d CLAUDE.md: §1 tetto allerta USDE 0,85 e frase ricucita, garanzia dell'ombra anche per permesso; §4 soglie STATARB verbatim (Fixes #14, Fixes #15)
- §1: «tetto ALLERTA quota 50%» contro config usde.quota_max_frac 0.85 (dal 06/09;
  0.50 resta default di codice in src/live/usde.py). Frase «dopo un bonifico si» troncata
  dal 10/09 (37d1565), ricucita.
- §1 OMBRA: dal 21/09 il token dell'ombra e' a scope di sola lettura (Adriano/TradingBook#19),
  misura del 21/09 riportata; il segreto resta pieno, la chiave read-only la crea l'operatore.
- §4 STATARB: regola del 24/07 copiata verbatim da scripts/research/r0724_statarb_deploy_gate.py
  (esiti, guardie, addendum 25/07 non binding). Nessun verdetto anticipato.
Autorizzato da Adriano il 21/09 dopo la revisione settimanale.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 08:48:07 +00:00
Adriano 4b04831352 giornali 17-20/09 (cron_daily 00:30Z) e revisione settimanale 21/09 — solo dati
Commit di soli dati dalla produzione: le pagine le scrive cron_daily e la
revisione cron_review, nessun cron le committa (commit a mano da sempre).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 08:25:38 +00:00
Adriano 8007158eb5 giornale 2026-09-16 (cron_daily 00:30Z)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 05:31:42 +00:00
Adriano 31f5915a41 ombra di TradingBook documentata al §1; cc01_regime_watch registra i giri e sta in monitor_health (Fixes #11, Fixes #12)
- CLAUDE.md §1 OMBRA: cron :44 sulla stessa crontab, legge il conto con la STESSA chiave live di
  cerbero-mcp (verificato per hash), scrive solo nel suo albero (3 giri misurati, nessun file di
  data/ o logs/ di qui cambiato), non invia per assenza di codice e non per permesso. §12 rimanda.
- cc01: ogni giro con entrambi gli asset misurati scrive data/cc01_regime/runs.jsonl (ts ms,
  stato, funding 30g/7g); se non vede, non scrive e lo dice. monitor_health: MonitorSpec
  giornaliera, max_age 30h, percorso incrociato con cc01.RUNS da un test (P1).
- tests/test_cc01_regime_watch.py (4, rossi prima). Suite completa: 1074 passed.
Autorizzato da Adriano il 16/09 dopo la revisione settimanale.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 21:10:12 +00:00
Adriano e42ab5369f giornali 10-15/09 e revisioni 14/09 (NON eseguita, limite Fable) e 16/09 (rilancio a mano, esito sospetta)
Solo documenti generati da cron_daily e revisione.py, nessun codice. Su richiesta di Adriano 16/09.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 19:46:36 +00:00
Adriano a6a49d9c65 cc01_regime_watch: ROOT in sys.path, moriva ogni notte dal 03/09 su from src.live.cli (Fixes #10)
Eccezione alla regola «PG non si tocca» autorizzata da Adriano il 16/09, solo questo file.
Verificato: --help exit 0, giro completo QUIET (BTC 30g +9,0%, ETH +9,4%), test_cli_flag 55 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 19:36:33 +00:00
Adriano Dal Pastro a4e942c8bb r0910: risk-off ±2h intorno a FOMC/CPI su TP01 REFUTED 0/3 (ΔSh −0,097, −1,24%/anno; le ore dei dati sono fra le migliori)
Calendario letto dal web (Fed 61 riunioni + BLS 88 release CPI, 2019-2026), TP01 orario dalla stessa
held di sleeves, null location-matched 1000 estrazioni (Δ vero al 4,2° pctl), per anno 2/8.
Registro §78, memoria 20-ondate (D-bis), diario 2026-09-10b.

Fixes #9

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
2026-09-10 14:56:29 +00:00
Adriano Dal Pastro 5b72a4b188 §3: quota USDE 0,64 derivata dal cuscino e' decisione vincolante dell'operatore (10/09)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
2026-09-10 14:19:31 +00:00
Adriano Dal Pastro a2b03aa2b6 USDE allineato a quota 0,64 su ordine dell'operatore (238 USDE venduti, slack +$266 = OK)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
2026-09-10 14:17:43 +00:00
Adriano Dal Pastro 37d1565a1e cuscino_watch: riacquisto automatico di USDE con isteresi (ECCEDENTE), bande in config, escape HTML nel sink di notify
Decisione dell'operatore 10/09 («riportarla a quota in autonomia»). Verificato da revisione fable
(10 segnalazioni, 9 applicate; loop numerico su usde_convert.piano: nessuna sequenza vendita→acquisto).

- quarto stato ECCEDENTE: slack > cuscino_riacquisto_frac (0,40) x cuscino => acquisto di USDE fino
  allo stesso bersaglio della vendita, q* = 1 - 0,30 x (1 + cuscino_margine_frac 0,20) = 0,64.
  Isteresi [0 ; 0,40] x cuscino con bersaglio unico 0,20: per oscillare servono +-8,6% di equity
  USDC (~$380); un bonifico alza lo slack di 0,7 x importo e sopra ~9% dell'equity ricompra da solo.
- le tre frazioni (preavviso/margine/riacquisto) in config/live.json sezione usde, lette da
  usde.bande_cuscino() che verifica l'ordine; quota_target 0,70 TOLTO (slack zero per costruzione).
- notifier.notify: html.escape su titolo e valori — la prima allerta vera (13:53Z) era andata persa
  per un '<' nudo; allerta_errore registrato nel record (P3).
- da ECCEDENTE un fallimento si ritenta ogni 24h (non 4 Telegram/giorno per sempre); bande fuori
  ordine => BLIND con motivo, non un traceback ingoiato dal cron.
- CLAUDE.md §1/§4/§5.17, config _nota_usde/_nota_cuscino, diario. 0,64 e' una DERIVAZIONE
  dell'autore, non la quota decisa il 30/08 (0,70): dichiarato, da confermare.
- test: 1070 (+8 netti).

Fixes #7

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
2026-09-10 14:14:29 +00:00
Adriano Dal Pastro f82f685528 cinque punti della revisione 09/09: usde_watch a 1000 trade + finestra 24h, cuscino_watch (equity USDC, riconverte da solo), PREVDAY-01 kill/veto cablati, SCALA-01 al 2027-02-28, versamento 04/09 dichiarato
Decisi dall'operatore il 2026-09-10, verificati da revisione fable (15 segnalazioni, 12 applicate).

- usde_watch: TRADE_LIMIT 1000 (count max Deribit) e trade_copertura(): lista troncata o ultima
  lettura oltre la finestra di 24h del gateway => somma NON leggibile, reward non attribuito (P12).
  Riga del 07/09 corretta nel log con campo `correzione` (400 USDE erano acquisti, non reward).
- cuscino_watch.py (cron :53, monitor_health): equity USDC contro cuscino derivato da
  usde.cuscino_richiesto_usd (formula spostata in src/live/usde.py, usde_convert la importa);
  OK/PREAVVISO/SCOPERTO/BLIND; sotto zero lancia usde_convert --quota quota_ripristino(0.20)=0.64
  --esegui con guardie (execution_enabled, depeg_warn, 1 tentativo/6h). Primo giro: PREAVVISO, +$26.
- usde_convert: il tetto del venue vale solo in ACQUISTO (bloccava la vendita).
- paper_prevday: GATE PREVDAY-01 cablato (2027-06-21, kill Sharpe giornaliero < -0,50 su >=180 g
  attivi, veto >=80% barre ricostruibili + divergenze non crescenti con soglia materiale).
  Oggi: +0,95 su 81 g, 1942/1943 ricostruibili, kill NON MATURO.
- CLAUDE.md: arming 20/06 (TP01) / 23/06 (BOOK); piano EUR 5.000 chiuso col versamento 04/09
  ($2.414,68 dal balance, dichiarato); SCALA-01 non prima del 2027-02-28 (A2 dal 01/09);
  PREVDAY-01 con data, kill, veto; §5.17 riparato con i limiti dichiarati (ratchet, slack zero a 0,70).
- test: 1062 (+31): test_cuscino_watch (16), test_paper_prevday_gate (8), test_usde_watch (+5).

Fixes #2
Fixes #3
Fixes #4
Fixes #5
Fixes #6

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kqvff47UBGeYfj1QeN4zE
2026-09-10 13:24:28 +00:00
Adriano Dal Pastro 79afe41ec2 giornale 2026-09-09 (cron_daily 00:30Z)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjj5vPEBoAJrB23P6RjKzs
2026-09-10 04:32:48 +00:00
Adriano Dal Pastro 8f2e6c5c2c revisione settimanale in sola lettura: revisore fable, rapporto firmato + Telegram, lunedi' 06:15 UTC
- src/live/revisione.py: materiale (CLAUDE.md, config, crontab, git, monitor_health, stati dei
  sorveglianti, 7 g di giornale e diari, ~195k caratteri), prompt con dieci regole (sola lettura, fonte
  per ogni segnalazione, solo numeri del materiale, §3 non si ripropone, idee nuove solo citando la
  memoria, gate con data e criterio), guardia sui numeri, rapporto firmato (P13), Telegram = Sintesi
  con taglio dichiarato; modello muto o risposta senza titoli -> rapporto «NON eseguita» + 🚨 (P5).
- scripts/live/revisione.py (guardia cli.valida, --secco/--no-telegram/--quiet/--giorno/--modello),
  scripts/cron_review.sh, crontab `15 6 * * 1`.
- primo giro reale: il prompt su argv moriva con `Argument list too long` senza rapporto ne' allerta ->
  prompt su stdin, ogni eccezione diventa errore dichiarato; `analista.pulisci` toglieva i titoli.
  Secondo giro: docs/revisioni/2026-09-09.md, stato sospetta (cifre in formato italiano), nessun URGENTE.
- scartati con la memoria: autoregolazione dei parametri, generazione automatica di strategie, macro
  da internet (diario 2026-09-09c, memoria 40).
- test: tests/test_revisione.py (18) + 2 in test_cli_flag; suite 1031/1031.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjj5vPEBoAJrB23P6RjKzs
2026-09-09 22:07:50 +00:00
Adriano Dal Pastro 0a2f780d3c cblib causale: spot +1h e DVOL +1 giorno (debito §5.18); §11 rimisurato 0,714 → 0,712, verdetti invariati
- cblib.causale(s, cadenza): spot_series e dvol_series escono causali (asof = ultima chiusura NOTA);
  il DVOL giornaliero era una seconda serie con lo stesso difetto (fino a 24h avanti), verificato contro
  l'API pubblica a 1h. Regolamento ST alle 08:00 invece delle 09:00.
- §11 riprodotto al millesimo su worktree HEAD (0,714 [0,690-0,779], n=19, flag --al) e rimisurato:
  0,712 [0,664-0,732]; solo spot 0,721, solo DVOL 0,693, DVOL orario di controllo 0,717. Mediana onesta
  BTC 1,45 → 2,12, fee 1,51x/1,87x. r0730: 0,73 → 0,71. §75: ETH pre 0,76, BTC durante 0,89 (orario 0,83).
  skew panel ≤0,005. vrp_f_watch: f canonico 0,732 → 0,706, differenza +0,097 [+0,042, +0,140].
- r0909 senza doppio shift, contesto sul DVOL del giorno; r0822 regime su date di calendario; r0901
  join riallineato (bit-exact). Aperti con costo: DVOL orario (−0,04/+0,06 nel crollo), spot 5m (≤25 min).
- test: +3 causalita' in test_cb_chain_vrp, anti-doppio-shift in test_r0909; suite 1011/1011.
- revisione fable: 16 segnalazioni, tutte applicate (fra cui un «−1,8% in un'ora» che era +3,9%).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjj5vPEBoAJrB23P6RjKzs
2026-09-09 21:41:23 +00:00
Adriano Dal Pastro bb40e87d13 crolli: il libro perde nel giorno e chiude > 0 in 8/8 finestre dal 2022 (SKH01 short); crollo catturato a vol bassa, XRP diluisce come SOL
Quattro misure (r0909_*), nessun cambio a libro/pesi/config:
- libro nei crolli: −0,48%/g nei 160 giorni ≤ −5%, positivo per finestra dal 2022
  per la gamba short di SKH01 (108% dei guadagni); beta 0,0769 riprodotto (§46);
  il peso di SKH01 resta chiuso dal gate (in-sample).
- crollo catturato 1-5/06/2026 a quote vere: f_net 0,74 = rally; put δ−0,10
  1,92× il modello; a vol bassa e fuori dal gate di VRP01 → §3 non si riapre.
- XRP terza gamba (harness r0822_sol_leg): hold-out −0,169 in 0/24, un anno buono.
- universo Deribit: liquidi solo BTC/ETH/XRP/SOL; XS01 13/19; BTCDVOL future
  non negoziabile; PAXG non misurato.
Revisione fable: due conclusioni smontate (MTM 2,6× era un artefatto di quote;
«8/12 guadagna» era l'ordine delle classi). Debito §5.18: cblib.spot_series
+ asof guarda un'ora avanti (feed 1h etichettato all'apertura).
Test Opus: 92 nuovi, suite 1008/1008; due difetti del verdetto XRP corretti.
Docs: diario, RESULTS §74-77, CLAUDE.md, memoria 20/50, README; journal 07-08/09.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zJjHUS7mf4pnGE6pq9RTt
2026-09-09 16:33:54 +00:00
Adriano Dal Pastro 9f55652d99 usde al 68,7%: il tetto del venue del 30-31/08 non c'era piu'; il versamento di prova del 25/08 dichiarato, TWR +7,83%
Su autorizzazione dell'operatore («usa piu' USDE», «cerca % massima raggiungibile»):
- usde_convert al 31,8% (774 USDE), poi sonda a saldo crescente r0906_usde_tetto_sonda.py
  (passi 100->20->4->1, doppio rifiuto prima di scendere, conferma a saldo neutro): da 31,8%
  a 68,7% in 39 ordini @ 1,0005, ZERO rifiuti. Fermata dal cuscino di regolamento (70%,
  derivato da config), non dal venue. «Il 70% non e' raggiungibile ne' ora ne' mai» (31/08)
  e' falsificato: il tetto e' sparito, non scalato. Non spiegato, puo' tornare.
- config: venue_cap_frac -> null (misura in venue_cap_misurato), quota_max_frac 0,50 -> 0,85
  (il valore scelto dall'operatore il 30/08 per questo scenario).
- debito §5.17: nessuno sorveglia il cuscino USDC (slack $58; una perdita del libro lo consuma
  da sola).

Versamento di prova di EUR 25 il 25/08 08:00Z (dichiarato dall'operatore): +3,3% su $647, sotto
la soglia del 10% del rilevatore, contato per 12 giorni come trading.
- data/live/movimenti_dichiarati.jsonl (append-only, nel backup) letto da
  journal.movimenti_dichiarati; movimenti_capitale lo fonde coi rilevati (fonte dichiarato,
  importo dell'operatore, dopo = prima + importo; dichiarato+rilevato se coincide; fuori
  letture o riga rotta -> avvisi). Report e nota di giornale lo dicono.
- trading da arming +87,35 -> +62,45; TWR +11,98% -> +7,83%. CLAUDE.md §2 aggiornato.
- tests: +6 in test_journal (conftest isola il file). Suite 916 verdi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KSnordG9FT4q8M4MVm85GQ
2026-09-07 05:49:15 +00:00
Adriano Dal Pastro 95424f0755 docs: il README era fermo a 15 giorni PRIMA del reset — riscritto contro lo stato vero
Ultimo commit del README: 2026-06-04. Reset v2.0.0: 2026-06-19. Per 75 giorni la prima pagina
del repo ha pubblicato la libreria pre-reset (FADE/HONEST/PAIRS/TSMOM/SHAPE, PORT01-06) con
Sharpe 7,84/10,06 e CAGR ~79% come risultati correnti — cioe' esattamente i numeri che §2
elenca sotto "non citare", dalla libreria che il reset aveva dichiarato artefatto. Meta' dei
file citati non esiste piu' (strategies.yml, portfolios.yml, scripts/waste, scripts/portfolios,
src/live/multi_runner.py), e l'esecuzione descritta era su TESTNET, che e' la causa del reset.

- README riscritto (423 -> 152 righe): cosa gira adesso (TP01+SKH01 75/25, ~$2.050, cadenza
  oraria :47), i numeri nella lente di §2 (TWR +10,6%, non la crescita del conto), la riga che
  ordina il piano, il metodo e i suoi sei requisiti, il dato, la struttura VERIFICATA file per
  file, i comandi, i gate con le loro date, l'obiettivo con la sua onesta'.
- CLAUDE.md §0 e memoria 40: registrato il difetto e la lezione — un reset invalida anche i
  documenti che nessuno rilegge; l'inventario di cosa cita numeri morti va fatto il giorno del
  reset, non 75 giorni dopo per caso.
- Diario 02/09c: sezione col confronto riga per riga; coda dichiarata (l'inventario completo
  degli altri documenti pre-reset non e' stato fatto).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
2026-09-02 15:53:42 +00:00
Adriano Dal Pastro de83909db9 un flag sconosciuto non e' l'azione di default: guardia su 18 script, indice USDE orario, pulizia
MISURATO oggi durante la revisione: `trades_db.py --help` non stampava l'uso, cadeva in sync()
e riscriveva meta.ultimo_sync. Nessuno dei 18 script di scripts/live/ usava argparse: un flag
sbagliato era il ramo else. Su journal.py avrebbe scritto pagina e riga di DB, su analista.py
avrebbe speso una chiamata al modello e mandato un Telegram.

- src/live/cli.valida: prima istruzione di ogni __main__, prima di connect()/sync/rete.
  --help -> 0 con l'uso; flag ignoto, valore mancante o posizionale -> 2 con l'elenco dei
  previsti (P4). NIENTE argparse: cambierebbe messaggi, codici d'uscita e --help di script
  che il cron gia' chiama.
- 18 script cablati (i 3 che scrivono + 14 + cc01), flag invariati.
- tests/test_cli_flag.py (30): elenco DERIVATO dalla cartella (P1), valida come prima
  istruzione, uso che documenta i flag, e i flag che il CRON usa davvero restano accettati
  (P15/P16); end-to-end su --help e flag ignoto con trades.db non toccato (M15).
  Verificato a mano: monitor_health --quiet, trades_db --sync --quiet, book_execute dry-run.

Debito §5.15, primo passo: balance_watch (orario) registra `usde_usdc` a ogni campione — None
con la ragione se illeggibile, mai 1,0. Il cablaggio nel bound quando la serie ha storia.

Pulizia dalla revisione: tests/helpers.carica_script al posto della 15a copia del loader
importlib (5 file del libro live); il fill di prova via upsert_fills invece di un INSERT che
lasciava verified NULL; asserzioni non ancorate al padding; movimenti_capitale accetta le
righe gia' lette (una SELECT invece di due ai due lati di una scrittura del cron).

Test 910 verdi (+52). Diario 2026-09-02c.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
2026-09-02 15:49:40 +00:00
Adriano Dal Pastro 1279ea605a revisione 02/09, seconda tornata: il classificatore dei movimenti era cieco ~23 ore al giorno
Il feed 1h certificato si ferma alle 00:00: per le letture successive `asof` dava la stessa
barra a t0 e t1, mercato "fermo" = 0, e qualunque calo >=10% del giorno sarebbe stato un
"movimento" scorporato come prelievo (giornale dal 25/08, report da oggi). Con feed assente
tutto era "ambiguo" e il report stampava e1/e0-1 sotto l'etichetta TWR.

- journal.movimenti_capitale: stato "mercato non misurabile" (feed fermo/assente/barra
  mancante) => ambiguo con la ragione; leva_tetto = min(frac x n x scala, LEVA_LORDA_MAX) (P1).
- journal.rendimento_twr: salto non classificabile => twr E trading None con motivo.
- journal.pnl_giorno CHIAMA rendimento_twr (prima rifaceva cum - certi: "entrambi la chiamano"
  era falso); la pagina stampa il TWR; analista qualifica il cumulato "di cui versati".
- trades_db --report: la classe di ogni salto con la sua misura (mercato max a leva piena).
- book_execute docstring: banda dello stop -33,5%/-26,5% (era invertita), "non costa ordini"
  -> micro-ordini di ri-taglia (22/48, C2), latenza <=1h solo con feed fresca, conteggi di
  r0823 al posto di "raddoppia" (2 contro 1 e' rotolante vs pavimento sulla riga 4h; la
  peggiore misurata e' 24h).
- test_book_cadenza: LTF_MIN importato da skyhook; tutte le righe attive della crontab (una
  sola); tre stati dello skip (col progetto ma senza cron_book => ROSSO); slot di release
  testato con venue_probe (il :07 come controllo positivo); parser regolare, passo > 0.
- r0823_sl_anchor: guardia sul :47 (era sul vecchio :07), prosa al passato; cron_chain.sh idem.
- CLAUDE.md: §5.7 frase invertita corretta, §5.14 limite vero (non l'artefatto della fixture),
  §2 ora della LETTURA (13:47Z), nuovo debito §5.15 (USDE fuori dal bound di mercato).
- diari: tempi "scritto" corretti coi commit; sezione "Seconda tornata".

Test +11 (858 verdi).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
2026-09-02 15:33:13 +00:00
Adriano Dal Pastro 835e0c8666 revisione 02/09: il rotolante si CONTROLLA ogni ora (non "si ri-ancora"), TWR con limiti dichiarati e tre stati
Quattro segnalazioni della revisione sui commit di oggi, tutte verificate e riparate.

1. book_execute.py (+ CLAUDE.md §5.7, memoria 40): «il disaster-SL rotolante si ri-ancora ogni
   ora» era falso — ensure_disaster_sl lascia il bracket finche' lo stop e' entro il 5% e la
   taglia entro il 10%; il giro orario CONTROLLA, ri-ancora oltre la tolleranza (mark
   +5,263%/-4,762%). Lo stop siede fra -26,3% e -33,3% dal mark corrente.
2. journal.rendimento_twr: limite dichiarato (D5) — l'intervallo che contiene un movimento
   certo esce intero dal rendimento, il suo P&L di mercato va in `certi`; errore massimo meta'
   del movimento per costruzione (25/08: ~$0,5). Non si stima (P12). Segmenti a lunghezza zero
   non prodotti; nessun tempo a mercato -> 0,0 dichiarato numero.
3. base di equity zero: `twr` E `trading` None con motivo (il salto 0->X e' invisibile al
   classificatore, `trading` valeva l'intero conto); il report stampa n/d.
4. test_book_cadenza: la guardia estrae ogni prescrizione «ogni/every N unita'» e pretende 60
   minuti, con controllo positivo (M15); limite P13 dichiarato.

Test +5 (847 verdi). Diari 02/09 e 02/09b con la sezione "Revisione".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RziUCB336YPUUyDJ29x4Ke
2026-09-02 15:17:05 +00:00
Adriano Dal Pastro 861cc7fc27 debito 7: la cadenza del libro e' ORARIA — docstring riscritto, tre fonti tenute d'accordo da un test
Il docstring di book_execute.py prescriveva «ogni ~230 minuti» mentre il cron gira ogni ora
(47 * * * *). Era il docstring a sbagliare: sulla riga 4h BTC raddoppia gli scatti del
disaster-SL rotolante (r0823_sl_anchor.py), e chi avesse "corretto" il cron verso il
docstring avrebbe spostato il libro sulla riga peggiore.

- scripts/live/book_execute.py: CADENZA: ORARIA, la riga di crontab, la ragione (giro
  idempotente, latenza SKH01 <=1h, ri-ancoraggio orario) e il divieto esplicito con la data.
- tests/test_book_cadenza.py (10): deriva e confronta docstring, intestazione di
  cron_book.sh e crontab installata (crontab -l; SALTATO se illeggibile, non verde);
  parser a 5 campi solo per cadenze regolari; 60 < 230 < 240; minuto != :00.
- docs: CLAUDE.md §5.7 chiuso, §13 conteggio 842; memoria 40; diario 02/09b.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RziUCB336YPUUyDJ29x4Ke
2026-09-02 14:38:53 +00:00
Adriano Dal Pastro 2f701b8469 debito 14: il report stampa il TWR (+10,61%), non il bonifico (+243%)
`trades_db.py --report` calcolava e1/e0-1 sulla serie grezza di equity: il 96,3% del
numero era il versamento di $1.399,39 del 25/08. La riparazione (journal.movimenti_capitale)
esisteva e non aveva attraversato il confine fra i due lettori della stessa serie (P1).

- src/live/journal.py: `rendimento_twr` — funzione unica, spezza la serie sui movimenti
  CERTI e moltiplica i segmenti; gli ambigui restano dentro, dichiarati (P12); tre stati.
- scripts/live/trades_db.py: report() la chiama; stampa TWR con segmenti datati, movimenti
  elencati, trading al netto, delta $ etichettato "movimenti INCLUSI"; il % grezzo sparisce.
- test: +5 in test_journal.py (incl. riproduzione del +10,80% del diario 01/09, M23),
  +2 in test_trades_report.py sul testo stampato con connect() deviato in tmp. 832 verdi.
- docs: CLAUDE.md §5.14 chiuso, §2 e §13 aggiornati; memoria 40; diario 02/09.

Limite ereditato e dichiarato (D5): +10% di trading fra due letture consecutive tocca la
soglia del rilevatore e a mercato fermo verrebbe classificato movimento.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RziUCB336YPUUyDJ29x4Ke
2026-09-02 14:22:50 +00:00
Adriano Dal Pastro bc43218a12 docs: soldi fermi §73 — l'operatore sceglie di versare (piano 27/07: €5k dentro, ~€1k fuori)
Conclusione dell'operatore (02/09): "mettere gli XEON su Deribit col
sistema attivo". Si', ed e' cio' che la memoria aveva scritto il 27/07.
Tre precisazioni, tutte gia' misurate e ora registrate:
- €5.000, non €6.043: la protezione venue satura a qualunque quota > 0,
  l'ultimo migliaio dentro compra ~€100/anno e butta via l'assicurazione;
- il "~€600" e' un'attesa a banda larga, non un tasso (libro a mercato il
  22% dei giorni, TWR +10,8% in 70g, hold-out TP01 ~+0,05, fisco −30%/10a);
- fondo d'emergenza da dichiarare.
Nessuna azione di config (cap dinamico, rilevatore collaudato il 25/08).
In attesa di importo e data; al deposito una riga di giornale, scritta
prima e non ricostruita dopo. N9: le opzioni sicure (+€52-62/anno) sono
state viste e messe da parte con motivo.

- CLAUDE.md §1: riga "soldi fermi" + indice §1-73
- RESULTS §73 + riga d'indice
- memoria 30-piano-capitale-fisco: voce
- diario 2026-09-01d: §7 la conclusione dell'operatore
- docs/journal/2026-09-01.md (voce del cron, non era committata)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 06:06:15 +00:00
Adriano Dal Pastro d95fabf060 soldi fermi: i modi esistono e valgono €5/mese — BOT/conto deposito +€52-62/anno, sUSDe distrugge lo split
On-venue chiuso con l'elenco intero: 4/50 valute remunerate = le 4 gia'
chiuse il 31/08. L'USDC su Deribit non e' fermo (base di sizing + cuscino).
I €6k in XEON sono lo split-cassa. Tassi dal web con fonte (BOT 2,768%
asta 08/2026, DFR 2,25%, conti deposito 3,25-3,50%, sUSDe ~9%). In euro
netti su €6k: XEON 81, BOT 133, conto deposito 143, sUSDe 350 (ma stesso
emittente dell'USDE: split distrutto), libro ~600 (trading, split
distrutto). Miglior guadagno sicuro: +€62/anno. €100/mese di bonifico =
+4,07%/anno di drift. Non sono pareri fiscali. Nessun ordine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 21:21:14 +00:00
Adriano Dal Pastro 1c0549080c PAVIMENTO-LEVA (§72): il pavimento non licenzia taglia, 0/16 — e corregge §71
Domanda dell'operatore: "possiamo usare quanto conosciamo del pavimento per
studiare una strategia". L'inverso di COLLAR01: non "quanto DD mi risparmia
il pavimento a taglia fissa" (perdeva contro il de-levering) ma "quanta
TAGLIA mi autorizza a DD fisso" — l'unica cosa che il de-levering non puo'
comprare (cambia la FORMA, non la proporzione), e la grandezza su cui vive
il tetto di leva del progetto (n·frac·scala·sl <= 0,50 => 1,67x).

RISULTATO: 0/16. La sola put a premio reale PEGGIORA il maxDD in 16/16 celle
(FORTE 51,83% -> 55,4-75,8%; LARGO 71,94% -> 74,8-81,7%), quindi k_f = 1,000
ovunque: niente da licenziare. Monotono nella protezione: piu' la put e'
vicina, peggio va — il bleed del premio E' il drawdown.

🚨 CORREGGE §71 (stesso giorno). Stamattina A1 diceva "il pavimento funziona
davvero". E' il COLLAR a ridurre il DD, non il pavimento: a premio zero la
put lo riduce (51,83 -> 36,76, il controllo), a premio reale lo peggiora =>
tutto il beneficio e' mangiato dal premio, e oltre. Nel collar la riduzione
viene dal TETTO: il suo premio compensa il bleed, e cappare l'upside abbassa
il picco da cui il DD si misura — un picco piu' basso, non protezione.
Premio di pareggio: 36-79% del reale; il DVOL sta 1,32x sopra la RV, quindi
un prezzo equo (~76%) sfiora il pareggio nelle celle migliori e lo manca
nelle altre. Il motivo di §46 (beta) non si applica — a beta 1,0 la put
paga davvero — ma il verdetto di §46, "il maxDD SALE", si riproduce per un
motivo diverso. Corretti il diario di §71 (titolo e A1), RESULTS, memoria.

IL MECCANISMO (B2), trasferibile: i drawdown di BTC sono GRIND. maxDD FORTE
2021-07-20 -> 2022-05-06 = 290 giorni; LARGO fino al 2023-10-16 = 818. Una
put a 7-14g copre UNA finestra; il DD che conta dura 20-60 finestre; la put
scade OTM ogni settimana (para nel 0-9% dei cicli) mentre il premio sanguina.
Non protegge nemmeno la finestra peggiore: 14g FORTE -22,9% nudo -> -23,6%
col pavimento. Su BTC il pavimento compra protezione contro la cosa sbagliata.

LA LICENZA DEL DISASTER-SL E' DI CARTA (B3), scritto prima che sia comodo:
con la put a 5d/14g a 21,9% dallo spot, sostituire sl con quella distanza
darebbe 2,28x. Ma l'invariante limita UN episodio, la put limita UNA
finestra, e il massimo su finestre consecutive non e' limitato da nulla:
1 finestra -23,6% (coperta), 8 finestre -33,6% (non coperte) => a 2,28x un
grind di 112 giorni costerebbe il 77% dell'equity. disaster_sl_pct NON si
sostituisce con la distanza di un pavimento. Aggiunto a CLAUDE.md §3.

GATED SULL'IV (B4) — la copertura dinamica che §46 non aveva provato: put
ON solo sotto il 25°/50° pctl di DVOL/RV. Migliora molto (FORTE +3,8% ->
+8,4%) ma resta sotto la base (+10,04%) e il DD resta >=. L'incollatura
ignora lo spread delle transizioni A FAVORE del gated: perde a maggior ragione.

Quattro attese a priori (B1-B4) scritte prima, tutte confermate.

NON MISURATO, dichiarato: nessun DSR (cade al primo gate); nessuna lente
reale; nessun pavimento a scadenza lunga (30-90g, che coprirebbe piu'
finestre di grind) perche' l'operatore ha vincolato a <=15 giorni — e'
l'unica variante che B2 lascia aperta, e sta fuori dal vincolo.

Libro, pesi, cron, config INVARIATI. Nessun ordine. Test 25/25 sui filoni.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:45:02 +00:00
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 5bcf212923 stato trades: il "+243%" del report e' per il 96,3% un bonifico — TWR +10,80%
`trades_db.py --report` stampa `$598,06 -> $2.051,84 (+243,08%)` accanto a
`netto +40,77`. La serie di 1.657 letture orarie contiene UN SOLO salto: il
versamento di $1.399,39 del 25/08 11:47Z. Confermato dal classificatore
ufficiale del progetto (`journal.movimenti_capitale`: certi 1399.39,
ambigui 0.0, classe `movimento`).

Al netto: TWR +10,80% spezzato sul versamento (+11,61% fino al 25/08,
-0,73% dopo), equity +$54,39 in 69 giorni. Il giornale, che lo scorporo lo
fa gia', concorda: $+62,00 al 31/08, -7,61 di marcatura fino a oggi.

Il difetto non e' nuovo — e' la stessa riparazione che NON ha attraversato
il confine. `journal.py:121` porta il caso d'origine nel docstring (la voce
del 25/08 che dichiarava «+$1.414,57» di giornata); `trades_db.py:83`
calcola `100*(e1/e0-1)` sulla serie grezza e non chiama
`movimenti_capitale()`, che e' a un import di distanza. Variante di P1: non
un sorvegliante che ridichiara il bersaglio, ma una riparazione che non si
e' propagata al secondo lettore della stessa serie. Danno sui soldi nessuno
(sola lettura); danno di citazione si', ed e' l'unico numero fuorviante che
il progetto produce su richiesta di un comando pubblicato in §13.

Codice NON toccato: sta su uno script che legge il libro vivo. Debito #14.

Stato del libro al 01/09 16:47Z, per il resto invariato: 45 fill (ultimo
31/08 15:47), 29 round-trip (21 in utile, netto +40,77), posizioni BTC
0,0045 @ $79.208,11 e ETH 0,0872 @ $2.473,04, non realizzato -$11,72, leva
lorda 0,27x. Nessun fill da 25 ore = banda morta del min_order_usd $5, non
un blocco (il cron logga «gia' al target» a ogni giro). monitor_health 8/8
OK, riconcilio 44/45 con 0 prezzi divergenti (l'unica coppia scoperta e' il
difetto noto dei sei giorni fra log e jsonl sullo stesso fill).

- CLAUDE.md §2: riga nella tabella dei numeri da non citare
- CLAUDE.md §5: debito #14
- docs/diary/2026-09-01-stato-trades.md
- docs/journal/2026-08-31.md (voce del cron, non era committata)

Suite: 800 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 16:52:48 +00:00
Adriano Dal Pastro 8d391ed29a margini: la pagina si ricostruisce dal gateway — e l'"IM %" non e' il margine delle posizioni
L'operatore ha incollato la riga CROSS col modello ATTIVO invece che proiettato:
Available $2.010,81 · IM 2,15% · MM 0,37%. Il gateway, letto allo stesso minuto, dice
available_funds = 2010,82299383. Scarto $0,01.

(a) LO SCREENSHOT NON SERVE PIU'. La riga CROSS della pagina E' `available_funds`, che
leggiamo da soli a ogni giro. Ieri quella schermata era l'UNICA fonte per l'haircut e per il
modello attivo, e per averla e' servito un passaggio dall'operatore e da Wasabi.
r0831_margini_conto.live() la ricostruisce.

(b) TERZA CONFERMA DEL 5%, E LA PRIMA ESATTA:
    1.400,71 + 0,95x654,176 + 0,20 dust - 11,553 IM = $2.010,82   contro pagina $2.010,81
Scarto $0,007. Il 10% della vecchia config non e' improbabile: invertendo la stessa riga da'
IM = -$21,16, aritmeticamente impossibile. Tre strade indipendenti, stesso numero.

(c) MIA LETTURA SBAGLIATA, CORRETTA. L'"IM %" della pagina e'
(margin_balance - available)/margin_balance, non il margine delle posizioni:
    haircut USDE  $32,71 = 1,592%   +   IM vera  $11,55 = 0,562%   =  2,153%
Il 74% di quella percentuale e' HAIRCUT. E' salita da 2,13% a 2,15% perche' abbiamo comprato
collaterale a rendimento — letta come rischio direbbe che ieri sera abbiamo alzato la leva
comprando USDE, l'opposto di quello che e' successo. La MM invece e' pulita ($7,60) e non puo'
contenere l'haircut, che da solo la renderebbe negativa: le due colonne hanno basi DIVERSE e la
pagina non lo dice. Regola: una percentuale letta da una schermata va INVERTITA nella sua
definizione prima di essere confrontata (P7 su superficie nuova).

(d) LA BOCCIATURA DI X:PM ESCE RAFFORZATA. La KB da' USDe al 5% sotto entrambi i modelli:
l'haircut si cancella e l'inversa da' il margine di POSIZIONE sulle stesse due posizioni,
stesso istante — X:SM $11,64 contro X:PM $88,23, 7,6x, e 9,3x la MM. Due misure pulite,
stesso verso. E la riga X:SM era una PROIEZIONE di un modello inattivo che oggi si riproduce
al centesimo: anche la riga X:PM era affidabile, quindi decidere senza provare era corretto.
Ora si sa perche', non solo che.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmkQty4a99pVmvwGfxAMQ9
2026-08-31 08:39:45 +00:00
Adriano Dal Pastro 62025e7840 docs: X:SM ri-sondato e X:PM scartato — il modello di margine entra nel tetto ma non lo spiega
Le due misure di ieri sera vivevano solo in chat. Ora sono nei documenti, con i numeri
e con cio' che le riapre.

X:SM vs S:SM, stessa notte, stesso conto:
  S:SM  tetto [643,18 - 644,18)  equity $2.055,56  ->  31,29% - 31,34%
  X:SM  tetto [654,18 - 655,18)  equity $2.054,90  ->  31,84% - 31,88%
+0,55pp = +11 USDE ~ $11. L'ipotesi "il tetto dipende dal modello di margine" e' VERA e
INUTILE: per arrivare al 70% mancano ~38 punti, un fattore 2,2x. Un'ipotesi confermata al
terzo decimale e falsa all'ordine di grandezza si archivia come falsa — il tetto resta
misurato e non spiegato.

La lezione di metodo vale piu' del risultato: il primo probe fu un BUY 20, RIFIUTATO, e da
solo avrebbe chiuso la questione con "tetto invariato". Falso: il tetto si era mosso di 11,
cioe' MENO della taglia del probe. Un probe unico di taglia sbagliata produce un falso
negativo che si legge come risultato — la taglia si sceglie sulla risoluzione dell'effetto
che si cerca (M13 in veste nuova).

X:PM valutato e SCARTATO senza provarlo: la pagina margini lo dice gia'. Available Balance
$1.935,14 contro $2.011,73 (-$76,59), MM 3,43% contro 0,37% (~9x). Il PM e' basato su
scenari e premia il rischio che si compensa; due long direzionali nudi sono il suo caso
peggiore. La MM e' la riga che decide: non morde a 0,28x ma sposta il punto di liquidazione.
NON "PM e' peggio" ma "PM e' peggio PER QUESTO portafoglio" — cosa lo riapre: il deploy di
VRP01 o di un altro sleeve di opzioni, che fa compensare il rischio e cambia il segno del
confronto.

Registrato anche il prezzo del cross, che non e' zero: sotto segregato l'USDE era ring-fenced
dalle perdite del libro, sotto cross risponde l'intero conto. Non morde oggi (perdita massima
plausibile ~$617, dentro il solo USDC), ma il verso e' cambiato e tornare a S:SM lo ri-recinta.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BmkQty4a99pVmvwGfxAMQ9
2026-08-31 08:30:51 +00:00
Adriano Dal Pastro 4705d71ceb tetto ri-sondato sotto X:SM: il modello entra ma non spiega — +11 USDE
L'operatore e' passato a Cross: Standard Margin. Verificato dal gateway:
available_funds USDC da ~$1.400 a $2.011,09 contro $2.010,90 attesi con haircut
5% (scarto $0,19) — seconda conferma indipendente del 5%, da una lettura
completamente diversa dallo screenshot.

RI-SONDATO il tetto a saldo neutro, stesso metodo del 31/08:
  SEGREGATO S:SM  [643,18 - 644,18)  equity $2.055,56  = 31,29-31,34%
  CROSS     X:SM  [654,18 - 655,18)  equity $2.054,90  = 31,84-31,88%
Il modello ENTRA nel tetto ma NON lo spiega: +0,55pp = +11 USDE (~$11), non le
centinaia che servirebbero per il 70% (manca ancora un fattore ~2,2x).
L'ipotesi "il tetto dipende dal modello segregato" e' quantitativamente demolita
come spiegazione, pur essendo tecnicamente non nulla.

Nota di metodo: il primo probe (BUY 20) era stato rifiutato e avrebbe fatto
concludere "tetto invariato". Era solo troppo grosso: il test a saldo neutro con
passi piccoli ha mostrato che il tetto si era mosso di 11. Un probe unico di
taglia sbagliata produce un falso negativo che si legge come risultato.

config: venue_cap_frac 0.312 -> 0.318 (bordo basso del bracket CROSS, che e' il
modello attivo; se si torna a S:SM va rimesso a 0.312).

E il costo del passaggio, che va detto: sotto SEGREGATO l'USDE era RING-FENCED
dalle perdite del libro (solo il silo USDC rispondeva); sotto CROSS risponde
l'intero conto. Non morde oggi (perdita massima plausibile ~$617 col disaster-SL,
dentro il solo USDC) ma il rischio strutturale ha cambiato verso. Il cross ha
comprato $611 di margine utilizzabile — inutile a 0,28x, serve sopra ~1,4x che
non e' autorizzata — piu' $11 di capienza.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 08:12:31 +00:00
Adriano Dal Pastro fd7595e819 margini: haircut 5% (la config aveva torto) — e il conto NON e' cross-collateral
Lo screenshot della pagina margini era su Wasabi (rclone remote wasabi:, bucket
adp-work, cartella _scambio), non sulla VPS: per questo il percorso non esisteva.
Riconciliazione riproducibile in scripts/research/r0831_margini_conto.py (N11).

(a) HAIRCUT = 5%. La pagina non lo espone come numero: si ricava per differenza,
perche' il CROSS conta l'USDE scontato e il SEGREGATO non lo conta affatto.
  S:SM (attivo)  USDC Available 1.400,86  vs  equity 1.412,28 - IM 11,55 = 1.400,73
  X:SM           CROSS Available 2.011,73
  contributo USDE al cross = $610,81 su $643,05  ->  5,0137%
    5% (KB)     atteso $610,89  scarto $ 0,09  TORNA
   10% (nostra) atteso $578,74  scarto $32,06  NON torna
config/live.json: haircut 0.10 -> 0.05. Il 26/08 il 10% fu registrato come
"verificato sul venue" senza traccia di COME, e non lo era.

(b) 🚨 IL CONTO NON E' CROSS-COLLATERAL: modello attivo "Segregated: Standard
Margin" (S:SM). Nella tabella del modello attivo l'USDE NON COMPARE: non fa
margine per i perp USDC-settled del book, e l'haircut oggi non si applica. Il che
spiega a posteriori perche' la misura di stamattina trovava $0,0000 accantonati:
non stavo guardando nel secchio sbagliato, cercavo un parametro che sul nostro
conto non e' in vigore.

NON MORDE: al massimo lordo del libro (1,0x = ~$2.056 di nozionale) l'IM sarebbe
~$41 contro $1.400 di USDC disponibile, 34x di copertura. Nessuna decisione
operativa cambia oggi.

Ma la premessa in CLAUDE.md era falsa, e il modo in cui lo era e' istruttivo:
"l'equity del book e' il TOTALE cross-collateral" metteva due cose sotto un nome
solo. Come RICCHEZZA sommare USDC+USDE e' giusto ed era il punto della riparazione
del 26/08 (evito' il falso "USCITA DI FONDI -24%"); come CAPACITA' DI MARGINE e'
sbagliato, perche' nel modello attivo l'USDE vale zero. Finche' il margine non
morde le due coincidono nell'uso, e infatti non era mai emerso.

Corretta anche la riga di usde_watch che stampava "margine utilizzabile ~$2.013
(haircut 10%)": era falsa due volte insieme. Ora stampa il solo silo USDC e,
accanto, cosa darebbe il cross.

La quota USDE non e' "collaterale diversificato": e' cassa a rendimento FUORI dal
sistema di margine. Passare a X:SM aggiungerebbe $610,87 di margine utilizzabile
ma porta la meccanica cross (collateral fee 0,05%/giorno sul saldo negativo,
ribilanciamento automatico): decisione dell'operatore, oggi non serve.

Ipotesi nuova e non verificata: il tetto del ~31,2% potrebbe dipendere proprio dal
modello segregato. Si saprebbe passando a X:SM e ri-sondando.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 08:01:21 +00:00
Adriano Dal Pastro c8be83ef6e haircut: la divergenza non si chiude dal gateway — misurato perche', non supposto
Richiesta: leggere la pagina margini del conto per chiudere il 5% (KB) vs 10%
(nostra config). NON E' RAGGIUNGIBILE da qui: account_summary per la valuta USD
da' "Invalid currency", il parametro `extended` viene ignorato, e il gateway
filtra a 8 campi senza initial_margin/maintenance_margin (debito #11).

E non e' che si sia guardato nel secchio sbagliato: la contabilita' TORNA ESATTA
senza alcun termine di haircut.
  USDC equity 1412.281074  available 1400.728093  riservato 11.5530
  USDE equity  643.175691  available  643.175691  riservato  0.0000
  posizioni lorde $577.65 -> IM al 2% = $11.5530 -> RESIDUO -$0.0000
Un haircut al 5% chiederebbe $32,16 accantonati, al 10% $64,32: non ci sono.
=> L'haircut non e' osservabile in ALCUN campo esposto. O e' applicato solo nella
vista cross/USD che il gateway filtra, o non e' applicato al nostro conto: da qui
le due cose non si distinguono, e non le si sceglie tirando a indovinare.

La divergenza resta APERTA, ma con la ragione MISURATA invece che supposta. La
chiudono 30 secondi sulla web UI o delle chiavi API Deribit (la decisione gia'
dichiarata nel debito #11, non un refactor). Nel frattempo non morde nulla di
osservabile: l'IM e' il 2% del nozionale e l'USDE resta interamente disponibile,
quindi 5% o 10% non cambia una cifra operativa.

L'operatore ha dichiarato che il conto e' STANDARD MARGIN. Aggancia due cose:
  - la colonna da leggere e' Haircut (X:SM), che per USDe dice 5% come la PM:
    ora si sa con certezza quale numero ufficiale contraddice il nostro;
  - spiega perche' l'IM misurata e' esattamente 1/50: il nuovo modello di margine
    del 05/08 si applica ai "standard margin accounts", tier 1 C1=50. Un fatto
    dichiarato dall'operatore e una misura fatta senza conoscerlo si confermano
    a vicenda — ed e' la PRIMA affermazione del venue che il conto conferma questa
    settimana, dopo l'APR USDC e "all users can buy BUIDL".

Lo screenshot non e' arrivato: il percorso sta sul desktop dell'operatore, non
sulla VPS.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:53:26 +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 41f83b5dd8 BUIDL-01 CHIUSO: non entrabile — e la frase pubblicata da Deribit e' falsa per noi
Esito del test pre-registrato dieci minuti prima (7b8e356). Si chiude con un esito
che NON era fra i due previsti: i criteri contemplavano ">=1 reward -> IDONEO" e
"zero reward -> NON IDONEO", ma non si riesce a comprare BUIDL affatto, quindi la
domanda sull'eligibilita' ai reward e' priva di oggetto. Un gate puo' fallire sulla
sua PRECONDIZIONE invece che sul suo criterio, e va scritto cosi'.

Undici ordini rifiutati con not_enough_funds_in_currency, fino a 1 unita' a limite
1,0100 contro ask 1,0004 con 10.730 di profondita', tenendo ZERO BUIDL e avendo
$1.412 disponibili per comprarne $1. Esclusi uno per uno tutti i sospetti che
sull'USDE avevano portato fuori strada: prezzo (incrocia di 96 bps), liquidita',
taglia (il minimo dello strumento), fondi, tetto sul livello (teniamo zero), wallet
(account_summary risponde). Costo del test: $0, nessun fill.

🚨 "All Deribit users are permitted to buy and sell BUIDL tokens in the spot markets
on Deribit, with no extra requirements" — insights.deribit.com. NON per noi.
Motivo plausibile e non verificato: BUIDL e' un titolo (fondo BlackRock via
Securitize), distribuzione ristretta a monte dell'exchange. Il fatto misurato e' il
rifiuto, non il suo motivo.

REGOLA (due affermazioni pubblicate smentite dal conto in due giorni — APR USDC
3,40% e "all users can buy BUIDL"): una capacita' PUBBLICATA dal venue non e' una
capacita' del CONTO. Si verifica sul conto, prima che entri in un piano, e costa un
ordine da $1. E' N10 un passo piu' in la': non basta il sito, non basta il venue,
serve il conto.

SOTTOPRODOTTO che vale piu' del test: not_enough_funds_in_currency e' il messaggio
GENERICO di Deribit per "non puoi acquisire altra di questa valuta" — permesso
(BUIDL, zero in mano) o tetto (USDE, ~31,2% dell'equity), mai i fondi. Chi lo
incontra salti subito alla domanda giusta invece di inseguire taglia, cadenza e
prezzo come e' successo il 30/08.

=> L'USDE resta l'unico collaterale a rendimento che il conto puo' usare, ed e' al
suo tetto; i $1.412 di USDC continuano a rendere zero. Non per mancanza di
alternative: le tre alternative sono chiuse per giurisdizione (USDC), per permesso
(BUIDL) e perche' non e' un dollaro (stETH).

balance_watch esteso a BUIDL: se l'accesso si aprisse, un balance non nullo lo
direbbe da solo. Suite: 795 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:35:32 +00:00
Adriano Dal Pastro 7b8e35633d BUIDL-01: criteri pre-registrati PRIMA dell'esecuzione e dell'esito
Test di eligibilita' sul collaterale BlackRock (Treasury USA tokenizzati), taglia
500 BUIDL come il test USDE del 26/08. Nasce dalla domanda su stETH: stETH rende
2,22% (meta' dell'USDE) ed e' ETH, non un dollaro — coprirlo e' CC01, gia'
parcheggiato a scala 20k+. I custodi sono istituzionali e comunque nessuna via
custodiale restituisce i reward USDC (esclusione italiana per giurisdizione).

BUIDL invece e' comprabile, liquido, in cross-collateral, e soprattutto e' un
emittente DIVERSO: oggi il conto ha $1.412 di USDC che rendono zero e il rischio
emittente concentrato al 100% su Ethena.

Criteri dichiarati adesso, esito da leggere il 2026-09-04:
  ELIGIBILITA': >=1 reward entro le 23:00 UTC del 03/09 -> IDONEO; zero -> NON
  IDONEO, si riconverte e la pista si chiude. Tre finestre feriali piene.
  TETTO: sondato a saldo neutro, registrato col suo bracket E l'equity del
  momento (sull'USDE il tetto e' una frazione, non un livello).
  HAIRCUT: dichiarato NON misurabile a questa taglia, e non vincolante.

Committato PRIMA dell'esecuzione: l'ordine dei fatti sta in git.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:30:40 +00:00
Adriano Dal Pastro f151316bdf usde: il tetto e' una FRAZIONE dell'equity (~31,2%), non un livello — e ora e' in config
Fonte: articolo ufficiale Deribit "Yield/reward bearing coins" (WebFetch lo prende
403, si legge dall'API Help Center in JSON). Tre correzioni alle conclusioni di
ieri.

1) L'ITALIA e' nella lista delle giurisdizioni escluse dai reward USDC. Lo zero
misurato e' confermato dalla fonte, ma la mia ipotesi MiCA era SBAGLIATA: la
lista contiene Canada e Giappone, non e' il perimetro MiCA. E' policy di
giurisdizione Deribit. M27: una fonte normativa si verifica, non si deduce.

2) La finestra di pagamento USDC e' di DUE SETTIMANE ("within the first two
weeks of the following month"), non tre giorni. Avevo verificato su 8/14 e 3/14
giorni. Rifatto sulle finestre vere: LUGLIO conclusivo (atteso $1,72 contro
un'escursione TOTALE dell'equity di $0,48 in 1-16/08, zero scalini compatibili),
GIUGNO no (il libro opera da meta' mese, rumore della taglia del segnale). La
conclusione non cambia, ma l'evidenza e' UNA finestra piu' la lista ufficiale,
non due: il "172x" del 30/08 era sovra-affermato.

3) IL TETTO NON E' UN LIVELLO, E' UNA FRAZIONE. L'articolo documenta un Cap
ETHENA che diluisce il TASSO a livello di exchange e nessun limite sulle
quantita' detenibili: il muro non aveva base documentale e andava ri-sondato.
Fatto il 31/08 (giorno UTC nuovo -> non e' un limite giornaliero): ieri si
tornava a 644,18, oggi no, con l'equity scesa di $8.
    30/08  tetto [644,18 · 645,18)  equity $2.063,79  = 31,21-31,26%
    31/08  tetto [643,18 · 644,18)  equity $2.055,56  = 31,29-31,34%
0,05pp di scarto, dentro il rumore dell'equity (+-$2-8/ora). Candidato pulito
5/16 = 31,25%, ma a questa risoluzione non si distingue da una regola sul
collaterale scontato dell'haircut (~29%): si cita la banda (M25).
=> Il tetto SCALA col conto: la quota resta ~31%, il valore in dollari cresce
col capitale, il 70% non e' raggiungibile ne' ora ne' mai. E, essendo pinnati
al tetto, il rischio emittente resta una frazione COSTANTE del conto.

Cablato (rispondeva a "dove e' scritto il valore del tetto": in tre note di
testo e in nessun posto che il codice leggesse, tanto che usde_convert --quota
0.70 dichiarava "piano valido" per un ordine che il venue rifiuta):
  - config/live.json usde.venue_cap_frac 0.312 + venue_cap_misurato
  - src/live/usde.py lo porta nei default (unica autorita', P1)
  - usde_convert.piano() rifiuta il bersaglio sopra il tetto PRIMA di sparare
    e stampa il massimo raggiungibile. Verificato su entrambi i rami.

Anche: l'USDe ha un fee Deribit del 5% mai nominato prima. Il nostro misurato
(~4,5%/anno) e' gia' netto: e' l'unico numero da citare.

Stato: USDE 643,175691 (31,29%, al tetto), USDC $1.412,40, totale $2.055,57.
Suite: 795 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:27:23 +00:00
Adriano Dal Pastro c250c04371 usde: l'USDC NON frutta sul nostro conto — misurato, e §6 di stasera era sbagliata
Domanda dell'operatore: "verifica se l'USDC frutta davvero sul nostro conto".

Sembrava dover aspettare: il gateway non espone il Transaction Log
(get_transaction_log, get_settlement_history, get_deposits, get_transfers,
get_interest_history: tutti 404 — debito #11) e l'unica serie storica e'
trades.db.equity, oraria ma arrotondata a 2 decimali e sporcata dal P&L non
realizzato (+-$2-8/ora a posizioni aperte), dove $0,13/giorno sparisce.

La fonte ufficiale Deribit ha spostato il problema dal rumore al calendario: i
reward USDC si pagano UNA VOLTA AL MESE ("paid out as a single monthly payment
early in the following month"), accrual alle 00:00 UTC sulla minima equity —
non ogni giorno come l'USDE. Ecco perche' una sorveglianza giornaliera non
poteva vederli. E un accredito mensile da qualche dollaro si vede benissimo
anche a 2 decimali, purche' il libro sia FLAT: allora equity == balance == USDC
e ogni scalino e' un accredito.

MISURA, due confini di mese entrambi a libro flat:
  29/06 -> 08/07  equity 598,06 costante, 237/237 ore ferme, 0 scalini  (attesi $0,45)
  31/07 -> 03/08  equity 596,92 costante per 4 giorni pieni             (attesi $1,72)
Il secondo e' decisivo: $1,72 contro una risoluzione di $0,01, 172x. Zero
MISURATO, non zero sotto soglia.

=> La premessa originale del gate USDE-01 e' RESTAURATA: il guadagno di tenere
USDE e' il tasso pieno ~4,1%, non lo spread 0,71 punti che avevo scritto poche
ore fa. Sui $644: ~$26/anno, non ~$4,6.

Cosa avevo sbagliato: ho letto `apr: 3.4` in public/get_currencies e l'ho
trattato come una proprieta' del NOSTRO CONTO. Era un listino del VENUE. La
"conferma indiretta" che invocavo provava che il listino e' reale per l'USDE e
non diceva nulla sull'idoneita' dell'USDC. Un tasso pubblicato non e' un tasso
incassato: si verifica sul conto — ed e' costato una query su una serie che
avevamo gia'.

Esclusione plausibile ma NON verificata: MiCA (USDC e' e-money token, USDe no);
Deribit dice solo "eligibility is based on their location". Il fatto misurato
e' lo zero, non il suo motivo.

Nuovo: scripts/live/balance_watch.py + scripts/cron_balance.sh (orario al
minuto :42, libero fra :25/:35/:47, sola lettura). Registra il BALANCE a 8
decimali per valuta — la serie che mancava — col conteggio dei fill dall'ultimo
campione e il nozionale lordo, cosi' una finestra sporca si riconosce invece di
essere mediata dentro. Etichetta PULITA le finestre a 0 fill e libro flat, dove
il delta USDC E' l'interesse, e ne stampa l'APR implicita.

Suite: 795 passati. L'ERROR di teardown e' il falso positivo dichiarato dalla
guardia stessa: il cron :47 ha scritto un fill reale (ETH BUY $+9, 23:47:19)
mentre la suite girava.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 23:48:52 +00:00
Adriano Dal Pastro a45794d2cb usde: il venue mette un TETTO al 31,21% — e l'USDC paga gia' 3,40%
Richiesta dell'operatore: "porta in usde tutto il capitale che non viene
usato". Il margine consuma $11 su $2.063 e l'USDE e' cross-collateral: preso
alla lettera vale una quota ~99%, cioe' il 100% che il gate esclude. Portata
all'operatore con le cifre, ha scelto 70%.

Il 70% non e' un argmax (M8): e' il massimo compatibile col CUSCINO DI
REGOLAMENTO, il vincolo che r0830_usde_quota non aveva guardato. P&L e funding
dei perp USDC-lineari si regolano in USDC, non nel collaterale, quindi la
quota non la limita l'haircut ma il saldo USDC che deve reggere il disaster-SL
sulla massima esposizione: 2 x 0,5 x 0,30 = 30% dell'equity, che lascia il 70%.

ESEGUITO +144 USDE (500,1757 -> 644,175691), quota 24,24% -> 31,21%, fee 0.
Poi il muro.

(a) TETTO DEL VENUE, misurato e non documentato da nessuna parte. Provato a
saldo neutro: BUY 20 rifiutato, SELL 20 OK, BUY 20 OK, BUY 5 rifiutato, con
$1.408 disponibili. E' un tetto sul LIVELLO. Il messaggio del venue
(not_enough_funds_in_currency) e' fuorviante e ha fatto inseguire tre ipotesi
sbagliate: taglia (falso, ma min_trade_amount=1 e' vero), rate-limit (falso),
prezzo (vero in parte: il book REST pubblico e' in ritardo sul matching engine
e prezzavo l'ordine sull'INDICE invece che sul BOOK — l'indice marca il
collaterale, il book prezza lo scambio). La cronaca resta nel diario: chi
rilegge non deve rifare il giro.

(b) L'USDC PAGA 3,40%. public/get_currencies: USDE 4,1071%, USDC 3,4000%, e i
nostri reward USDE misurati (~4,5%/anno) confermano che quelle APR sono reali.
Il guadagno non e' il tasso, e' lo SPREAD: 0,71 punti, ~$4,6/anno sui $644 che
teniamo, non i $21 che il gate implicava. Il gate ha misurato il reward
dell'USDE e non ha mai chiesto cosa facesse l'USDC fermo: manca il
controfattuale, M1 in un'altra veste. NON dimostrato che sia accreditato sul
nostro conto — da verificare su un giorno senza trade.

Nuovo attrezzo scripts/live/usde_convert.py: dry-run di default, banda prezzo,
tetto hard di quota, cuscino di regolamento derivato da config. NON passa da
execution.ALLOWED, che resta ai soli due perp.

config: quota_target 0.70 registrato; quota_max_frac alzato a 0.85 e RIMESSO a
0.50 nella stessa sessione — la soglia larga presupponeva un 70% che non
esiste, e lasciarla avrebbe disarmato la guardia per uno scenario che non si e'
verificato.

Suite: 795 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 20:18:31 +00:00
Adriano Dal Pastro 3cf884fa39 CLAUDE.md: la riga USDE-01 cita il tasso con la sua banda — 3,26% [1,13-4,51], n=4
Citava "3,80% su UNA finestra, 1,90% su DUE": due letture di n=1 e n=2, senza banda,
cioe' esattamente cio' che la §2 vieta. A quattro finestre il numero e' 3,26% annuo
con banda bootstrap [1,13% - 4,51%], e la larghezza (3,4 punti su un livello di 3,2%)
E' il risultato: a n=4 il tasso non e' misurato.

Aggiunto il risultato che governa la decisione di domani: l'EV e' lineare in q, quindi
non puo' scegliere una quota interna. E i tre numeri che la incorniciano: il margine
non e' il vincolo (l'haircut non morde fino al 90% di quota, nemmeno a leva 1,50x con
USDE marcato alla soglia critica 0,95 — 29x di cuscino), la resa vale $16/anno cioe'
meno di un mese di versamento, e aspettare quattro settimane costa $1,33 per 8x le
finestre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 17:41:14 +00:00
Adriano Dal Pastro 035bd086a2 usde: l'EV non puo' scegliere la quota — e aspettare 4 settimane costa $1,33
La decisione di quota e' dovuta lunedi' 31/08. Il risultato strutturale, dichiarato
prima di guardare i numeri: l'EV e' LINEARE in q, quindi il suo argmax e' sempre un
angolo (0% o 100%) e non puo' produrre una quota interna. Ogni quota intermedia nasce
da un criterio sulla CODA, che va dichiarato e non ottimizzato (M8). Lo script quindi
non sceglie: mette il prezzo accanto a ogni criterio candidato.

Misure:
- rendimento 3,26% annuo su n=4 finestre (3 pagate), banda bootstrap 95%
  [1,13% - 4,51%] su 200.000 ricampionamenti. Larga 3,4 punti su un livello di 3,2%:
  a n=4 il tasso non e' misurato, e' abbozzato. Il punto stimato si DERIVA da
  usde_watch.rendimento() invece di essere ridichiarato (P1), e la divergenza fra i
  due denominatori (0,06 punti) e' stampata, non appianata (P12).
- l'hazard annuo di pareggio E' l'APR: la quota e' EV-positiva se e solo se si crede
  che Ethena stia sotto il 3,3%/anno di evento catastrofico. Numero ASSUNTO, non
  stimato, come il p di Deribit del 26/07 — il cui framework P=1-(1-p)^20 lo script
  riproduce prima di usarlo (10/18/33/64% contro 10/18/34/64% registrati).
- il haircut 10% NON morde a nessuna quota testata, fino al 90%: il libro gira al
  2,00% di margine ($11,37 su $568,64), tre ordini di grandezza sotto il collaterale.
  Il vincolo non e' il margine (D5: buco quantificato e innocuo).
- il churn da depeg critico vale ~$52 di nozionale a quota 50%: secondo ordine.

Il numero che decide (N10 — una data si giustifica col COSTO della misura): la
conversione e' fee 0 e ~3 bps di spread, quindi la decisione e' reversibile a
~6 bps. Alzare a 50% fra quattro settimane invece che domani costa $1,33 di resa non
incassata e porta il campione da 4 a 32 finestre, stringendo la banda da ~3,4 punti
a ~1,2.

Due letture del rischio che non si annullano (M28): l'USDE fa perdere soldi solo nel
mondo in cui Ethena salta E Deribit sopravvive, quindi il rischio aggiunto e' di
secondo ordine — ma e' un terzo strato sullo stesso conto, e N4 dice che un rischio
di venue si compra con un secondo CONTO. La prima dice che costa poco, la seconda
che non e' li' che si compra sicurezza.

Verdetto a runtime: risoluzione insufficiente per alzare · nessun vincolo operativo ·
scala (la resa di oggi vale $16/anno, meno di UN mese di versamento: la leva binding
resta il bonifico) · asimmetria (gia' a 24,2% l'evento emittente vale 3,1x il maxDD
dell'intero libro) · reversibile e quasi gratis da rimandare.

La scelta resta dell'operatore: lo script mette i prezzi, non ne sceglie uno (N4).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 17:38:35 +00:00
Adriano Dal Pastro fc24ee5f52 journal: voce COMPLETA del 29/08 sostituisce la parziale — 24/24 giri
Il cron notturno (00:37Z del 30/08) ha riscritto la pagina come annunciato
dalla versione parziale. I numeri di GIORNO passano dalla frazione di 7 giri
al giorno intero: equity $2,056.87 (era $2,051.29), P&L giorno +$4.51 (era
-$1.07), trading cumulato +$59.42, DD dal picco -0.81%.

Implicita ancora sotto la realizzata su entrambe le gambe (BTC 37.4 vs 44.0,
ETH 51.1 vs 68.9), DVOL al 19° e 18° percentile dell'anno: VRP01 resta fermo
per costruzione, IV-rank 0.07 e 0.12 sotto la soglia 0.30 del gate.

Aggiunta la sezione Analisi (agente), assente nella parziale. Salute pulita:
24/24 giri di book_execute, feed SKH a 0 min.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 13:11:48 +00:00
Adriano Dal Pastro bb33df472f journal: voce PARZIALE del 29/08 — implicita al 24° e 17° percentile, VRP01 resta fermo
Scritta a mano alle 06:49Z, quindi marcata PARZIALE: copre 7 giri su 24 e non si
aggiorna da sola. Il cron la riscrive completa dopo le 00:30 di domani.

Equity $2.051,29, nozionale $555, leva 0.27x. Giornata -$1,07 su 7 letture, 1 fill
e 1 round-trip (+$0,02 netto). Cumulato dall'arming +$1.453,23, di cui $1.399,39
versati -> trading +$53,84. Entrambe le gambe a target, SKH01 flat su tutte e due:
il rischio resta interamente TP01.

Due cose che la Lettura tira fuori:
- l'implicita e' crollata in un giorno — DVOL BTC dal 47° al 24° percentile di un
  anno, ETH dal 45° al 17° — MENTRE la realizzata 30g saliva (44,1% e 68,9%). E'
  lo spread in cui vivrebbe VRP01, ma il suo gate guarda l'IV-rank espandente
  (0,09 e 0,12 contro una soglia di 0,30) e tiene lo sleeve fermo: dice di no
  esattamente dove l'occhio direbbe di si', ed e' per questo che esiste.
- prima comparsa della riga [drawdown]: -1,08% dal picco di $2.073,59, con la sua
  avvertenza attaccata (letture ORARIE, non minimo intra-giorno: e' un pavimento).

Campo `nota` lasciato vuoto: e' dell'operatore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 06:51:22 +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 2beb11b764 fetch IB: client in readonly — via due righe d'errore da 63 notti su 63
`fetch_ib_equities.py` si connetteva senza `readonly`, e ogni notte il log del
cron si prendeva

    open orders request timed out
    completed orders request timed out

126 righe in 63 giri. Due errori innocui ripetuti per sempre sono il modo in cui
un errore VERO smette di farsi notare (P14): su `cron_daily.log`, 126 dei 146
match di "error" erano questi.

CAUSA, letta nel sorgente di ib_async e non indovinata: in `IB.connectAsync` le
richieste "open orders" e "completed orders" esistono SOLO se il client non e'
readonly (`if not readonly: reqs[...]`), e sul gateway paper non rispondono.
Questo client scarica storico e non manda ordini mai: `readonly=True` e' insieme
la cura del rumore e la dichiarazione corretta di cosa fa. Tolta la CAUSA, non
filtrato il messaggio — filtrarlo avrebbe nascosto anche il giorno in cui quel
timeout significasse qualcosa.

VERIFICATO con un A/B sul solo flag, contro il gateway vero:
  · readonly=False -> le due righe compaiono, e si apre sul gateway il dialogo
    modale "API client needs write access action confirmation" (visto nei log del
    container, resta su ~75s);
  · readonly=True  -> nessuna delle due righe, nessun dialogo.

⚠️ CIO' CHE NON E' STATO VERIFICATO, e va detto: in nessuna delle quattro prove
fra le 13:05 e le 15:35 UTC il gateway ha servito storico — 0 barre con ENTRAMBI
i flag, quindi la causa non e' questa modifica, ma non ho potuto confermare
end-to-end che il fetch continui a riportare barre. La conferma e' il log del
cron di stanotte: se SPY/QQQ/IWM/TLT/GLD/HYG tornano con le loro barre e senza
le due righe di timeout, e' a posto; se tornano tutti a 0, si revoca il flag.
Il fallimento e' comunque innocuo: con 0 barre lo script NON sovrascrive i
parquet (verificato: eq_spy/eq_qqq intatti dopo i tentativi falliti).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:31:22 +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 21fe289383 research(gtaa): cosa cambia togliendo GTAA01 — +0.11 di Sharpe a iso-rischio, sul filo
Misura chiesta prima di decidere del gate (A): se togliere lo sleeve non
cambiasse niente, la domanda sul gate sarebbe accademica. Portafoglio di
RICERCA a 5 sleeve (33/15/12/20/20), NON il book live (dove GTAA01 non c'e').

Due lenti, ed e' la seconda che decide (M6: un diversificatore a basso CAGR si
giudica a iso-rischio, mai a iso-nozionale; M5: "meno drawdown" si testa a
iso-rischio o si sta comprando de-levering):
  · iso-nozionale: CON Sh 2.28 CAGR +19.2% DD 6.1% vol 7.8%
                   SENZA Sh 2.16 CAGR +23.8% DD 7.8% vol 10.1%
    -> togliendolo si guadagna DRIFT e si compra VOLATILITA'.
  · iso-rischio (×0.77): SENZA Sh 2.16 CAGR +18.0% DD 6.0%
    -> Δ Sharpe +0.121, Δ maxDD +0.02pp.
Hold-out 2025+: Δ +0.247. Per anno: GTAA01 aiuta in 6/8. Correlazione col resto
del portafoglio +0.087 — e' davvero altro. Standalone Sh 1.06, CAGR +5.8%.

⚠️ E LA BANDA DI FASE, che e' la ragione per cui questo numero va citato con la
sua incertezza: il Δ sulle 5 fasi va da +0.095 a +0.124 e supera la soglia
dichiarata (0.12) in 2 fasi su 5. Il SEGNO e' stabile — GTAA01 aiuta in ogni
fase — ma il verdetto BINARIO dipende dalla notte in cui lo si legge. Sanity:
la fase 0 riproduce lo sleeve di produzione bit-exact (max|Δ| = 0.00e+00).

Lettura: il contributo e' reale e sempre positivo, e vale ~+0.11 di Sharpe, cioe'
ESATTAMENTE quanto lo spread fra le tre baseline che il progetto gia' si porta
dietro (0.12, §2). Non e' "GTAA01 e' inutile": e' "sta al limite di cio' che
questi dati risolvono".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:34:44 +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 c21a0d4058 research(gtaa): criterio (C) — la mediana delle 5 fasi regge come strumento, e sceglie il 60%
Analisi richiesta prima di decidere che fare del gate (A). Il criterio: a cadenza
di produzione, la banda si sceglie sulla MEDIANA delle 5 fasi di ribilanciamento
invece che sulla fase capitata (M7: su ancore appaiate la statistica e' la
mediana). Toglie la componente di FASE; resta quella di DATO.

⚠️ DICHIARATO IN TESTA ALLO SCRIPT: (C) e' stato scelto DOPO aver visto la
tabella delle fasi di r0828_gtaa_band_phase. Sceglierne uno nuovo guardando
l'esito del vecchio e' selezione. Quindi (C) misura lo STRUMENTO — risoluzione
e potenza — e NON valida la proposta del 27/07. Pavimento tenuto a 0.01, quello
che il test si diede il 07/08: il metro non si ritocca sul risultato.

ESITO, coi tre criteri calcolati a runtime:
  (i)   scelta stabile su 10 notti : SI — ['60%'] in tutte e dieci
  (ii)  margine sempre >= 0.01     : SI — minimo 0.0197 (fase singola: 0.0026,
        e sotto il pavimento in 4 notti su 10)
  (iii) potenza (in-sample ≠ hold-out) : SI — al buio 60%, sull'hold-out 40%
Lo strumento funziona: l'escursione dello Sharpe in-sample su 10 notti cala del
74-99% per ogni banda (60%: da 0.1120 a 0.0006).

MA LA CELLA CHE SCEGLIE NON E' LA PROPOSTA. Al buio esce il **60%**; il 25%
vince **0 notti su 10**. Da tenere accanto: sull'hold-out il 60% e' penultimo
(0.7430 contro 0.9315 del 40%), coerente con lo Spearman IS/OOS ~0 misurato il
07/08 — la scelta in-sample non predice, e non va letta come "la banda giusta".

CONTORNO che vale piu' del verdetto: le 5 serie di fase correlano **0.988**,
quindi N_eff = 1.01. La mediana di 5 fasi e' UNA osservazione: toglie
l'artefatto, non compra precisione. Va citata come robustezza alla fase, mai
come campione (§2: «positivo in N/N ancore NON e' N osservazioni»).

Nessuna decisione presa qui: il gate (A) non e' toccato e i due test restano
rossi in attesa della scelta dell'operatore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:51:43 +00:00
Adriano Dal Pastro 31f82e1730 research(gtaa): il gate (A) della banda e' una moneta — la finestra "congelata" rotola ogni notte
Il 28/08 falliscono `test_la_banda_proposta_e_quella_scelta_al_buio` e
`test_il_margine_del_blind_non_e_un_arrotondamento`, a codice fermo dal 07/08
(nessun commit su src/portfolio/gtaa.py ne' su r0727_gtaa_band_gate.py). Al buio
esce il 60% invece del 25%, con margine 0.0074 — sotto il pavimento di 0.01 che
il test si era dato. Questo script chiede, per la terza volta sullo stesso
parametro, se il criterio misura cio' che dichiara. Replica bit-exact della
produzione verificata a fase 0 / taglio 0 (max|Δ| = 0.00e+00 su 7.544 barre).

(0) LA FINESTRA IN-SAMPLE NON E' FERMA. IB serve una finestra ROTOLANTE di 30
    anni. SPY e' l'unica gamba al muro (30.0 anni), e nel cron log la sua data
    d'inizio avanza di un giorno di borsa ogni notte: 1996-07-02 il 24/06,
    1996-09-04 oggi. Il pre-2015, che tutto il progetto tratta come finestra
    congelata, perde il giorno piu' vecchio ogni notte. QQQ e IWM arriveranno
    allo stesso muro fra 2,5 e 3,7 anni.

(1) L'AMPLIFICATORE E' LA FASE. `_gated_returns` ribilancia su `i % every == 0`,
    indice di POSIZIONE nell'array: se la prima barra scivola, si ri-fasa ogni
    decisione di trent'anni. Il progetto sapeva che la fase conta
    (`r0726_loo_deluck.gtaa01_at(ph)`, 5 ancore) ma la assumeva fissa alla
    canonica 0. Non lo e': la fase canonica cambia da sola ogni notte.

MISURE. Sulla finestra CHIUSA pre-2015, che non puo' acquisire dati nuovi, lo
Sharpe si e' mosso fino a 0.0760 fra il 07/08 e oggi. Su 10 notti consecutive
la banda scelta al buio e' 25% / 40% / 60% — la proposta vince il 40% delle
notti — e il margine sta sotto il pavimento in 4 notti su 10 (minimo 0.0026).
A dato FISSO, muovendo la sola fase, il verdetto cambia lo stesso (25% su 3
fasi, 60% su 2): l'imputato e' la fase, non le barre perse.

VERDETTO calcolato a runtime coi criteri dichiarati in testa (M13): il gate (A)
NON ha risoluzione. Il verdetto non e' una proprieta' della banda, e' una
proprieta' della notte in cui lo si legge. La banda al 25% non e' ne' confermata
ne' smentita: non e' decidibile cosi'.

Lo script misura e basta. Ritirare il criterio, come si fece il 07/08 col
confronto fra ranghi, e' una decisione dell'operatore e non e' presa qui.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:44:25 +00:00
Adriano Dal Pastro cb40ab3e20 journal: recuperata l'analisi del 27/08, saltata dal guasto di autenticazione
Rigenerata con `analista.py --giorno 2026-08-27 --no-telegram`. Le sezioni
misurate escono IDENTICHE (ricostruzione deterministica da trades.db e dal
feed): cambiano solo l'ora di scrittura in testata e la sezione `Analisi`,
che ora c'e'. Controllo sui numeri: ok.

`--no-telegram` di proposito: la notifica delle 00:37:02Z era partita e diceva
«analisi non disponibile (errore)». Quel record e' la prova che l'allarme del
guasto e' uscito, e riscriverlo con un invio di oggi la cancellerebbe.

L'analisi legge lo storico com'e' OGGI, non com'era stanotte: la testata porta
l'ora vera di scrittura (08:29:00Z), quindi la pagina non si spaccia per una
scritta a ridosso del giorno chiuso.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:32:41 +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 a6b5756cc0 journal: voci automatiche del 26-27/08 — rischio tutto su TP01, SKH01 flat
Due voci scritte dal cron delle 00:37Z (27/08 e 28/08). Numeri come registrati,
nessuna riscrittura a mano.

- 26/08: equity $2.065,45, giorno $+8,86, 4 fill / 2 round-trip, 24/24 giri.
  L'analisi dell'agente segnala il denominatore cambiato il 25/08 (conversione
  USDE): stessa esposizione ($582 lordi), leva 0,28x non confrontabile coi
  giorni precedenti.
- 27/08: equity $2.070,23, giorno $+4,78, 1 fill / 1 round-trip, 24/24 giri.
  Manca la sezione "Analisi (agente)" — il passo dell'analista nel cron e'
  a `|| true`, quindi un suo fallimento non lascia traccia nella voce.

Cumulato dall'arming $+1.472,17 di equity, di cui $+1.399,39 versati:
trading **$+72,78** su 65 giorni e 23 round-trip — taglia a cui il P&L non
distingue l'edge dalla fortuna, e con l'82% del cumulato negli ultimi 7 giorni
(la settimana in cui BTC ha fatto +9,94% e il libro era lungo su entrambe le
gambe).

SKH01 flat su BTC e ETH in entrambe le voci: l'esposizione e' interamente TP01.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:19:09 +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 562e95338b ricerca: USDE come collaterale a rendimento — analisi da candidato + test di eligibilita' pre-registrato
Verificato sul venue: apr 4.0 (netto fee), spot USDE_USDC spread ~3bps fee zero,
haircut 10% (non morde al nostro profilo di leva), indice usde_usd multi-exchange
con mediana+clamp (la differenza strutturale dal caso Binance 10/10/2025).
Rischi dichiarati R1-R4, p non stimabile -> la leva di controllo e' la QUOTA (N4).
Aritmetica: a $5k/quota 50% ~$101/anno; -100% = 25 anni di resa, non si recupera.
Pre-registrato il test di eligibilita' (~$500, 3 giorni, regola dichiarata prima).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:44:58 +00:00
Adriano Dal Pastro c4c82a8fbd diario: USDC rewards — verdetto: Italia esclusa per MiCA, pista chiusa + episodio scam in chat
Coinbase (chi paga i reward del programma Deribit) ha cessato i reward USDC
nell'EEA dal 2024-12-01 per il divieto MiCA di remunerare gli EMT; l'espansione
Deribit del 2026-08-01 aggiunge 80 paesi, nessuno EEA. Nessun ticket necessario.
Registrato l'episodio dei finti agenti in chat ("Yes, Italy is supported" =
falso) con la regola permanente sul canale di supporto.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:37:30 +00:00
Adriano Dal Pastro e7a5fee2fd diario: USDC Rewards Deribit — prodotto verificato sul venue (apr 3.4), il conto NON li riceve
Verifica empirica sulla serie equity oraria: nelle finestre di pagamento
(1-14 lug, 1-14 ago) il libro era flat e nessun accredito da ~$0,65-2,00
compare (0-1 salti >=$0,40, tutti spiegati dai fill). Resta il ticket al
supporto sull'idoneita' dell'Italia. Vale ~$170/anno a $5k.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:15:47 +00:00
Adriano Dal Pastro 3034bfdc58 gate XSR01: riscrittura DICHIARATA (opzione A dell'operatore) + haircut con script
Decisione operatore 26/08, a 58 giorni dall'esito, in direzione che stringe:
(1) capitale deploy $5k -> $20k — riconcilia il gate (25/07) con la decisione
vincolante "100% Deribit fino a $20k" (26/07), posteriore, che governa (M28);
deploy XSR01 e scelta del venue ora coincidono in un punto solo.
(2) gamba haircut: numero decisivo da r0826_xsr_haircut.py (N11) a pavimento
$10 (il vero, HL-EXEC), citato con la frazione di ordini eseguiti (P7).
Misurato: FULL 968 barre floor $10 -> haircut -1,1% con 22% di eseguiti (la
guardia da sola era vacua: un libro fermo ha haircut piccolo); ticket mediano
$3,34/gamba, 84% sotto $10 — sostituisce il "$14,41" senza script.
(3) contesto 1.82 -> 1.79 (lente dei gate). Soglie numeriche INVARIATE.

Chiude il debito S5.3. Diario 2026-08-26-xsr01-gate-riscritto.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:04:57 +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 f10d847816 ricerca: XSR01 sotto la lente RENDITA (filone 70) + cosa compra un versamento da $3k
XSR-RENDITA (r0825_xsr_rendita.py): prima valutazione di XSR01 sul criterio della
perpetua. A iso-nozionale alza il muro; a iso-rischio lo abbassa del 20,6% MA il null
mostra che il meccanismo vale 0,8% (mescolare i rendimenti non cambia nulla) e un
conto remunerato allo stesso tasso lo eguaglia a vol zero senza secondo venue.
A drift zero il muro SALE: si compra un drift scorrelato, non la scorrelazione.
L'haircut non pareggia un conto al 4% nemmeno a zero. Vincolo binding: capitale
($60k per un 25% sopra C*). Corretta in CLAUDE.md la riga Sharpe 1,82 (terza lente;
la lente dei gate da' 1,79 alla scoperta / 1,56-1,63 a oggi).

VERSAMENTO-3K (r0825_versamento_3k.py): $2.065 -> $5.065 appaiato sugli stessi path
del piano = 5,5 mesi di versamenti anticipati; 10a $114.929 -> $122.491 (+6,6%);
$15k in 1,3a e $20k in 1,9a. P(cap >= $5k al gate XSR01 del 23/10): 0% -> 100% --
il lump rende il gate leggibile senza rendere XSR01 comprabile: la decisione sulle
soglie (S5.3) va presa PRIMA che il lump atterri.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 06:56:40 +00:00
Adriano Dal Pastro 4f91b25b72 journal: voce automatica completa del 25/08 (riscritta dal cron delle 00:37Z)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 06:56:40 +00:00
Adriano Dal Pastro ee5c6ed539 ricerca: il piano a 10 anni dal conto vero, l'ETF-quando-flat SCARTATO, slippage rifatto
Giornata partita da "stato trades" e finita sul disegno del sistema. Versamento di
1.400 USDC atterrato alle 11:03:35Z (equity $667,88 -> $2.066,88); il giro delle 11:47
ha ribilanciato correttamente e ha ripiazzato i disaster-SL alla taglia nuova -- prima
volta che il ramo riparato stamattina gira sul serio.

(1) PIANO A 10 ANNI DAL CONTO VERO -- r0825_piano_10a_500.py (nuovo)
Le tabelle pubblicate partono da $600/$635: rifatte su $2.067, lente L3 CONGIUNTA.
Replica superata: chiede EUR 1.718/m dove la tabella da $635 chiedeva EUR 1.733.
EUR 500/mese per 10 anni -> mediana $114.934, rendita 18,35 EUR/g, P(>=50 EUR/g) = 0,0%
su 3.000 traiettorie. Il bersaglio con EUR 500/m arriva al 17o anno.

  L'EQUIVALENZA CHE ORDINA IL PIANO: EUR 100/mese in piu' == +4,07%/anno di drift,
  cioe' +27% su TUTTO il drift del libro. A 10 anni i bonifici fanno il 59%.
  Tutta la leva autorizzabile vale quanto EUR 100-150/mese: k=1,25 (+15,6%) vale MENO
  di EUR 100/mese in piu' (+19,1%), e si porta dietro il peggior giorno al 21,48%.

  E il libro a k=1 rende MENO dell'S&P (15,19% vs 17,40%): il vantaggio sta nello
  Sharpe (1,35 vs 0,89) e senza leva NON si converte in rendimento. Senza leva il libro
  non si giustifica come veicolo di ACCUMULO -- si giustifica come veicolo di RENDITA,
  dove serve 2,5x meno capitale ($254k contro $646k) perche' la perpetua vive sul DD.

(2) "ETF QUANDO IL LIBRO E' FLAT" -- SCARTATO, r0825_capitale_fermo.py (nuovo)
Il libro e' flat il 28,0% dei giorni (2,7% nel 2021, 77,0% nel 2022, 75,6% nel 2026);
live, esposto 14 giorni su 64, leva lorda mediana 0,00x e max 0,52x su un tetto di 1,0x
-- il cap non ha mai morso, il vincolo e' il segnale.
A ISO-RISCHIO il dinamico PERDE: Sharpe 1,01 contro 1,40 del 50/50 e 1,35 del libro. E
il null a maschera casuale (400 estrazioni, stessa quota, blocchi 20g) lo mette al 30o
percentile: fa PEGGIO di commutare a caso.
A iso-nozionale sembrava vincere (drift 17,09%, il piu' alto) perche' aveva la vol piu'
alta: e' la trappola di M6, il de-levering e' il PRIMO test.

  E IL MECCANISMO CHE SEMBRAVA OVVIO NON ESISTE. Aggregato: SPY 4,91% nei giorni flat
  contro 21,48% negli altri (-16,57%), e la storia si scrive da sola. FALSA: scomposta
  per anno il segno ALTERNA (3 su, 4 giu') e il 2022 -- l'anno che doveva reggerla --
  ha il segno OPPOSTO. Artefatto di composizione: i giorni flat stanno negli ANNI brutti
  per l'azionario, non nei GIORNI brutti. M9 ha fatto il suo lavoro su di me.

(3) SLIPPAGE RIFATTO ALLA TAGLIA VERA -- r0822_slip_audit.py riparato
26 fill (erano 18), $6-$319. I due piu' grandi mai eseguiti sono di oggi e hanno preso
1,01% e 0,54% della loro barra 5m, con il print a meta' del range (q=0,50). Il caso
peggiore resta un fill da $74 del 18/07 al 21,9%: un sabato, nastro inesistente.
L'attrito non e' funzione della TAGLIA ma di taglia/volume-della-barra -- l'estrapolazione
lineare che prevedeva ~71% a questo capitale e' refutata dalla misura diretta.
NB non e' "assente", e' "non ancora testato": manca un fill grande in una barra sottile,
e il weekend e' dove TP01 fa il 38% del proprio gross.

  DIFETTO P1 RIPARATO: l'equity era CABLATA a 636.0 con un commento che diceva di
  leggerla dal watermark. Il giorno del versamento avrebbe stampato $636 sbagliando di
  3,3x proprio la sezione che esiste per dire QUANDO la misura scade. Riparata leggendo
  il watermark -- e poi riparata di nuovo, perche' i fill del campione sono stati
  eseguiti a conti diversi ($597-$2.067) e una base sola e' sbagliata comunque la si
  scelga. Ora la normalizzazione e' PER FILL, e a $600 riproduce il 22,0% originale.

DUE ERRORI MIEI, CATTURATI PRIMA DI PUBBLICARLI
- maschera VUOTA vestita da risultato: la prima stesura di r0825_capitale_fermo prendeva
  i giorni flat dalla serie DE-LUCKATA, ma `deluck` sottrae una costante e lo zero esatto
  sparisce -> maschera vuota, dinamico identico al book, e lo script ha stampato tabelle
  piene e un p-value. Lo ha rivelato solo la riga "0 = 0.0%".
  REGOLA: stampare la CARDINALITA' di una maschera prima di usarla.
- il meccanismo falso della (2), demolito dalla scomposizione per anno.

Suite: 730 passati, 1 fallito -- quello gia' noto di 5.9 (deriva dati, non codice).
Watermark del libro live sopravvissuto intatto alla suite (fixture autouse di stamattina).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 18:13:15 +00:00
Adriano Dal Pastro 14e1567125 docs: il cap per-asset non ha tetto assoluto — CLAUDE.md dichiarava la formula del fallback
CLAUDE.md 1 descriveva il guardrail live come `min($3.000, equity_osservata x 0.5)`.
Il codice dice altro (src/live/book._cap):

    if trusted:                      # equity reale leggibile
        return float(equity) * float(frac)          # <-- nessun min() con `fixed`
    return min(fixed, wm * float(frac)) ...         # <-- il $3.000 vive SOLO qui

Cioe' `max_notional_per_asset_usd` NON morde mai sul percorso normale: e' il tetto del
ramo di FALLBACK (equity illeggibile), e la riga lo spacciava per quello vivo. Stessa
classe del difetto 5.7 — una descrizione puntata su una configurazione diversa da quella
che gira.

Conseguenza da sapere, emersa da "cosa succede se arrivo a 3.000 USDC": nessun livello
di capitale cambia il profilo di rischio RELATIVO. Il book scala indefinitamente a leva
lorda massima 1,0x (0,40x al segnale corrente), e $3.000 non e' una soglia — il numero
compare in tre posti del progetto e nessuno scatta li':
  - max_notional_per_asset_usd: cap sul nozionale, non soglia di equity, non morde;
  - "la soglia $3k" di 3: decisione CHIUSA il 26/07, si riapre a $20k;
  - C* ~$3.000 del monitor XSR01: difetto noto (5.3), il pavimento vero e' $15-20k.

CODICE NON TOCCATO: il comportamento e' intenzionale e documentato nel docstring di
_cap (la "frontiera" del 03/07 esiste apposta perche' un deposito non resti strozzato).
Era sbagliata la descrizione, non la scelta. Verificato anche che il tetto sul PRODOTTO
del GATE SCALA-01 (n_asset x frac x scala x disaster_sl_pct = 0,30 <= 0,50) non dipende
dall'equity, quindi regge identico a ogni capitale.

Contesto: versamento di 1.400 USDC atterrato alle 11:03:35Z, equity $667,88 -> $2.066,96.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 11:07:11 +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 11a2370027 journal: voci automatiche del 23-25/08
Giri notturni del cron. Il 23/08 e' stato rigenerato alle 00:36 del 24 col
giorno COMPLETO (24 giri invece di 20, equity $637.58, cumulato $+39.52):
la voce precedente era stata scritta alle 19:44 a giornata in corso.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:50:02 +00:00
Adriano Dal Pastro b237ad2e8b docs: compattazione di CLAUDE.md — 3458 -> 424 righe, memoria in docs/memory/
CLAUDE.md era arrivato a 310 KB (~80k token caricati a OGNI sessione) e la
sua funzione si era sdoppiata: era insieme il manuale operativo e l'archivio
di 69 filoni di ricerca. Le due cose hanno lettori diversi.

I 65 bullet-blocco sono stati spostati VERBATIM in docs/memory/ (nulla
riscritto). Verifica meccanica riga per riga prima del commit: 3272 righe
non vuote, 0 mancanti, 0 aggiunte, zero buchi e zero sovrapposizioni nella
copertura delle regioni estratte.

  10-sleeve-e-candidati.md    30 KB  TP01 XS01 VRP01 SKH01 GTAA01 XSR01
  20-ondate-e-scartati.md    126 KB  69 filoni, ogni scartato col suo perche'
  30-piano-capitale-fisco.md  59 KB  muri, versamenti, venue risk, fisco, prop
  40-produzione-e-deploy.md   66 KB  esecutore, tripwire, monitor, PRIIPs/UCITS
  50-dati-e-feed.md           14 KB  difetti del dato, catena opzioni
  60-metodo-e-gate.md          4 KB  i gate di altlib.py

In CLAUDE.md resta solo cio' che serve a non sbagliare una decisione: stato,
book live vs book di ricerca, i numeri da citare e quelli da NON citare,
7 decisioni vincolanti dell'operatore con "cosa le riapre", 6 gate
pre-registrati con la data, 9 debiti aperti non riparati, le regole di
prim'ordine (D/M/C/P/N, distillate dalle 113 righe che contenevano REGOLA),
IL DATO, metodologia, stack/struttura/comandi.

Tre fatti che erano sepolti in 3400 righe e ora stanno in testa: le TRE
baseline diverse che girano sotto il nome "libro 75/25" (spread piu' grande
di quasi tutti gli effetti misurati), il funding non modellato in nessun
backtest (-2,16%/anno), e che «N/N ancore» vale ~2 osservazioni.

Verificato prima del commit: 36/36 percorsi citati esistono su disco,
708 test collezionati, code fence bilanciati. Nessun file di codice toccato.

Convenzione aggiunta (§14) perche' il file non torni a crescere: quando un
risultato CAMBIA UNA DECISIONE si aggiorna CLAUDE.md; quando aggiunge
racconto, va in docs/memory/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:50:02 +00:00
Adriano Dal Pastro 214599e0a8 docs: libro di bordo in CLAUDE.md + diario del 23/08
CLAUDE.md: bullet del libro di bordo (il difetto dell'ora dei fill, il DB a
tre fonti incrociate, i quattro livelli della pagina, l'analista e i suoi
limiti, le due riparazioni al notifier), piu' i file nuovi nella Struttura e
i quattro comandi nella sezione Comandi.

Diario `2026-08-23-libro-di-bordo.md`: la storia per esteso, i numeri del
libro live dall'arming (+$37,50 in 64 giorni, ma l'80% delle giornate a
equity invariata e tutto il P&L in sei giorni), i cinque difetti trovati dai
test e il ciclo di retroazione dell'agente.

Le due cose che un lettore futuro deve trovare scritte: che l'analisi in
prosa NON e' parte del registro (una guardia sui numeri non copre il
ragionamento — due errori su due giri con sonnet-5, nessuno con una cifra
nuova), e che il modello e' stato cambiato su un campione di due
osservazioni, quindi e' un tentativo di abbassare un tasso e non una
garanzia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:50:56 +00:00
Adriano Dal Pastro 12dc04c969 analista: modello di default a opus-5
Sonnet-5 ha prodotto due errori di ragionamento in due giri: una frase su un
merge di cui nessuno gli aveva parlato, e un round-trip corretto sulla pagina
dichiarato inesistente, con una spiegazione inventata per il proprio dubbio.
Nessuno dei due contiene una cifra nuova, quindi numeri_non_supportati() non
li vede: e' il buco dichiarato quando la guardia e' stata scritta.

Primo giro con opus-5 sulla stessa giornata: nessuna affermazione inventata,
e le affermazioni numeriche verificate a mano contro il DB tornano tutte
(fill 1 contro 2/5/4/3 dei giorni precedenti, equity ferma a $597.12 dal 13
al 18/08, target BTC 189 -> 115). Resta un'imprecisione di nome: chiama
"target" un valore che nella fonte era la POSIZIONE. Il numero e' della
fonte, la classe di errore e' cambiata.

E ha prodotto una riformulazione che le regole non possono dare: la
concentrazione del P&L in 7 giorni ha una lettura alternativa altrettanto
compatibile — quei sette giorni sono anche gli UNICI in cui il libro e'
stato a mercato, quindi la finestra non separa l'edge dal beta a un rialzo
del 22-29%.

⚠️ Il campione e' di due osservazioni contro una: e' un tentativo di
abbassare un tasso, non una garanzia, ed e' scritto cosi' nel sorgente.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:47:11 +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 7456be1ce5 merge: ondata di ricerca 0822 + libro di bordo del book live
114 commit. Due cose diverse dentro lo stesso ramo.

RICERCA (scripts/research/, docs/) — sei ondate, §21-69, 0 candidati promossi.
Il valore e' difensivo e reale: quattro monitor forward rotti che avrebbero
fatto decidere un gate al contrario, un costo gia' in essere mai contato (il
funding dei perpetual, -2,16%/anno di drift), un punto singolo di guasto nel
trasporto degli allarmi, quattro soglie pubblicate falsificate. Il finding di
prim'ordine e' §58: l'obiettivo del progetto ha DUE definizioni operative in
uso che danno 33,9% contro 0,33% sulla stessa domanda.

PRODUZIONE (src/live/, scripts/live/, cron) — il libro di bordo:
- data/live/trades.db, i trade allineati col tempo. Erano salvati ma datati
  alla BARRA DI SEGNALE: 19 righe su 19 a 00:00:00, e un trade registrato sei
  giorni prima di essere eseguito. L'ora vera viveva solo in cron_book.log,
  gitignored e fuori dal backup.
- book_execute.py: ts_utc = ora vera del fill, bar_ts = barra, con test di
  regressione sulla sorgente.
- docs/journal/: una voce al giorno, quattro livelli separati per
  provenienza — numeri misurati, Lettura a regole tracciabili, Analisi di un
  modello, Nota dell'operatore.
- sync orario in cron_book, giornale e analista in cron_daily.

Strategia, pesi e config del libro INVARIATI su tutto il ramo. Nessun ordine.
695 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 17:48:24 +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 0cd0747e95 CLAUDE.md: bullet della sesta ondata (§58-69) + tre correzioni inline
0 candidati su 69 filoni cumulativi. Il finding di prim'ordine e' §58:
l'obiettivo del progetto ha DUE definizioni operative in uso (flusso e
ricchezza sostenibile) che danno 33,9% contro 0,33% sulla stessa domanda, e
per cinque ondate i due corpi di lavoro sono stati confrontati come se
parlassero della stessa cosa.

Tre marcatori inline dove l'ondata contraddice numeri gia' scritti, perche'
questa memoria non deve contraddirsi da sola:
- il vincitore MISTO del 25/07 e' superato da MISTO-A (§60)
- il gate XSR01 del 23/10 legge un monitor tarato sul pavimento del venue
  sbagliato (§67); soglie NON toccate, decisione dell'operatore
- la ragione per raccogliere la catena USDC e' caduta: le due superfici sono
  la stessa superficie a strike appaiati (§64)

Registrata anche la provenienza anomala dei verdetti (riesecuzione degli
script, non messaggi degli agenti) e la previsione verificabile che la 70a
ondata dara' la stessa risposta.

Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:51:58 +00:00
Adriano Dal Pastro 8c0b5f97ee registro: chiusi §58-69 — dodici verdetti, 0 candidati, e due appoggi tolti a decisioni gia' prese
I dodici filoni della sesta ondata erano rimasti `_in corso_`: la sessione si e'
chiusa dopo che gli agenti avevano scritto gli script e prima che i verdetti
fossero consolidati, e i loro messaggi finali sono persi. I numeri qui NON
vengono da quei messaggi: vengono dalla riesecuzione dei dodici script
(07:38-08:06 UTC, sequenziale, log in logs/r0823b/ che e' gitignored).
E' il motivo per cui l'ondata non e' andata persa: ogni script calcola il
proprio verdetto a runtime.

Cosa tocca decisioni gia' prese:
- §67 il gate pre-registrato XSR01 del 23/10 legge un monitor tarato sul
  pavimento del venue sbagliato (C* $15-20k, non ~$3k)
- §64 la raccomandazione di §51 (raccogliere la catena USDC) non e'
  giustificata dalla ragione che porta: le due superfici sono la stessa
- §60 la politica MISTO scelta il 25/07 non e' piu' l'ottimo (oggi MISTO-A)
- §63 domanda fiscale NUOVA, diversa da quella aperta il 07/08

Il risultato piu' grande e' di §58: l'obiettivo del progetto ha DUE definizioni
operative in uso che danno 33,9% contro 0,33% sulla stessa domanda, e non era
mai stato detto quale si stesse ottimizzando.

r0823b_quasi_passati.py (§68) terminava con IndexError: Griglia.combo()
indicizzava con self.idx (2720 giorni) un sottoinsieme di 958 righe. Corretto
col parametro idx esplicito piu' un controllo di lunghezza; la
rinormalizzazione e' riga per riga, quindi i valori sono quelli dell'intento
dell'autore. La correzione e' del coordinatore, non dell'autore, ed e'
dichiarata nel registro.

Libro, pesi, cron, config INVARIATI. Nessun ordine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:40:30 +00:00
Adriano Dal Pastro cdec81c5bc registro: aperti §58-69 — sei filoni sulla conversione del libro in 50 EUR/g, cinque sullo spazio-strategie non toccato, uno scettico 2026-08-23 04:24:59 +00:00
Adriano Dal Pastro e48de7fcc7 CLAUDE.md: rimando al diario di chiusura 2026-08-23 04:17:25 +00:00
Adriano Dal Pastro 273a43ad6a diario 23/08: ondate 7-8 e critico di chiusura — 17 filoni, 0 candidati, 3 numeri di testa riscritti e 5 errori miei 2026-08-23 04:17:12 +00:00
Adriano Dal Pastro ab4590c326 CLAUDE.md: bullet della quinta ondata (§46-57) — 0 candidati su 57 filoni, PREVDAY girava senza gate, 1,50x bocciato, e la somma di tutti i lead vale +0,036 EUR/giorno 2026-08-23 04:12:06 +00:00
Adriano Dal Pastro 80ca982f64 CLAUDE.md: correzioni del critico — il muro e' una mediana con banda esplosiva, «N/N ancore» vale ~2 osservazioni, il 1,50x e' bocciato, il soffitto ~1,3 e' refutato due volte, i bonifici fanno il 61% non il 73% 2026-08-23 04:10:34 +00:00
Adriano Dal Pastro 00f55fd753 registro §57: il critico di chiusura — repliche 6/6, ma il muro e' una mediana con banda esplosiva e «N/N ancore» vale ~2 osservazioni; somma di tutti i lead = +0,036 EUR/giorno 2026-08-23 04:09:26 +00:00
Adriano Dal Pastro 37c83c11c9 critico di chiusura: il muro $313k e' una mediana con banda [$187k, $1,14M], e «N/N ancore» vale ~2 osservazioni
Ultimo agente dell'ondata 2026-08-22/23. Sola lettura, nessun file di produzione toccato.
Attese a priori dichiarate nel docstring: A1/A4/A5/A6 confermate, A2 e A3 REFUTATE.

REPLICHE (prima di ogni accusa, tutte riuscite):
  - libro 75/25 path live: drift 19,23%/17,07%, Sharpe 1,692/1,513, funding -2,1597%/anno
  - i quattro muri L0/L1/L2/L3 riprodotti al dollaro: $278.033 / $264.373 / $327.617 /
    $313.143, e il muro E' esattamente `prelievo / perpetua`
  - §42 dShFULL(floor=-1) all'ancora 0 = -0,4502 (pubblicato -0,450)
  - TP01 canonico ShFULL 1,305; XS01 fase 0 == sleeve di produzione a max|diff| 0,0
  - funding ri-misurato da implementazione indipendente: TP01 2,138%/anno, rapporto
    condizionale 1,93x (BTC) / 2,58x (ETH) contro il pubblicato 1,86-2,55x

TROVATO:
1. Il muro $313k non ha mai avuto una banda. Propagando SOLO la SE del drift (5,151%/anno,
   block bootstrap; §53 la misura 5,09 su altra lente) va da $204k (+1 SE) a $707k (-1 SE),
   p10-p90 [$187k, $1,14M], e a -2 SE il traguardo NON esiste a nessun capitale. La riga
   «EUR500/mese -> P(20a) 85%» diventa ~0% a -1 SE. L'ondata ha pubblicato la risoluzione
   Monte Carlo del muro (0,7%) e mai quella del suo input, che e' 100x piu' grande.
2. «positivo in N/N ancore/fasi» non e' N osservazioni: N_eff misurato 1,6-2,1 (24 ancore
   TP01, corr 0,63) e 1,2-1,5 (10 fasi XS01, corr 0,79), con controllo positivo 24,5 / 1,00.
   La componente comune NON si cancella nella differenza appaiata (corr 0,59) -> A3 refutata.
   E la banda d'ancora non e' un IC: per la stessa grandezza l'IC95 bootstrap e' 4,3x piu'
   largo e contiene lo zero. I verdetti reggono, la precisione dei numeri no.
3. Tre baseline diverse sotto lo stesso nome «libro 75/25»: 1,68 (hourly, tutti i muri),
   1,80 (canonical, §41/42/49/50/54), 1,63 (mediana d'ancora, §8/25) — spread 0,12 di Sharpe
   e 1,7pp di maxDD, piu' grande di quasi tutti gli effetti misurati.
4. «Soffitto direzionale ~1,15» contro 1,639 (§23) e 1,621 (§54) nella stessa ondata: seconda
   refutazione indipendente dell'argomento aritmetico di §12.
5. «EUR X/mese» versa ogni 30 GIORNI (12,17 versamenti/anno, +0,8-1,4%); e il contatore
   `versato` non si ferma al traguardo -> a 10 anni i bonifici fanno il 61%, non il 73%.
6. MDE: la catena opzioni misurata da me da' 77 giorni di superficie (registro 74-75, ok)
   = MDE 4,3 di Sharpe -> ogni SCARTATO di §4/§5/§7/§11 che poggia su uno Sharpe e' un
   non-risultato su quell'asse. §21 XS01-OOS, pilastro del canale funded, ha effetto +1,12
   contro un MDE di 1,13.
7. Errore mio catturato in sessione: la prima stesura de-luckava una serie gia' de-luckata
   (0,89^2) e stampava un finto +31,5% sul muro; il valore vero della scelta di modello e'
   +4,0%.

RISPOSTA AL MANDATO: no. La somma di TUTTI i lead positivi dell'ondata, se fossero
autorizzati e additivi (non lo sono), vale +0,036 EUR/giorno a $635. EUR250 -> EUR500 al mese
porta P(20a) dal 14% all'85%. Il valore dell'ondata e' difensivo ed e' reale; il mandato
«arrivare ai 50 giornalieri velocemente» ha risposta negativa.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 04:06:28 +00:00
Adriano Dal Pastro 8c57274bac registro §54 addendum: serie PREVDAY intatta 1512/1512 ma MDE 4,72 sulla finestra forward — il gate non puo' appoggiarsi al numero forward (e un mio meccanismo era falso) 2026-08-23 03:36:22 +00:00
Adriano Dal Pastro c97f221c62 registro §55: COSTO-CAPITALE — il costo endogeno non morde, e alla taglia di oggi il costo mancante ha segno negativo 2026-08-23 03:29:41 +00:00
Adriano Dal Pastro 73207f79b9 research(costo-capitale): il costo d'esecuzione e' una funzione del capitale, e il muro non si muove — a $635 il vincolo e' il pavimento min_order, di segno opposto
§55 COSTO-CAPITALE. Tutti i muri pubblicati ($272k/$278k/$313k/$325k, traiettorie,
versamenti) sono calcolati con un costo d'esecuzione COSTANTE, mentre un muro che si
raggiunge accumulando attraversa tutte le taglie. Qui il costo diventa una funzione,
misurata camminando il libro Deribit vero.

[VENUE] 50 istantanee di BTC_USDC-PERPETUAL / ETH_USDC-PERPETUAL in 35 minuti (domenica
notte UTC = la finestra piu' sottile della settimana, quindi conservativa). Mezzo spread
0,0065 / 0,0207 bps = UN TICK; costo sotto ~2 bps fino a $500k per ordine; il libro
visibile finisce a $2,8M (BTC) / $1,2M (ETH).

[CALC] Muro L3 congiunta $313.143 -> $315.080 col costo endogeno (+0,6%, DENTRO la
risoluzione Monte Carlo del muro stesso, punto fisso convergente in una iterazione).
La traiettoria EUR500/mese non si muove (P(20a) 85,1% -> 84,7%). Saturazione a ~$9,5M
per argmax di C x drift(C) e a $10M per il primo 1% di nozionale non eseguibile in un
istante: due definizioni indipendenti nella stessa decade, oltre un ordine di grandezza
sopra il muro. Il gradino di leva sopravvive (k* 12,50x -> 12,25x alla taglia del muro;
morde solo a $5M, dove crolla a 1,75x).

Le due riserve degli scettici sono misurate e non mordono qui: il costo che si annullava
in §52 e' quello dello SPOT (spread 100-500x piu' largo), e la partecipazione del 21,9%
di §53 e' la quota di una barra 5m a volume basso — l'ordine di oggi e' lo 0,13% (BTC) /
0,43% (ETH) della profondita' a 1 bps.

Trovato per strada, ed e' il fatto piu' utile: alla taglia di OGGI il costo che le tabelle
non contengono ha segno NEGATIVO. Il drift a $635 e' 13 bps/anno PIU' BASSO che a $5.000
per il pavimento min_order, ~2x cio' che lo slippage costa fra $313k e $1M.

Repliche 8/8 (TP01/SKH01/libro bit-exact; $272.061 e $258.338 al dollaro; accumula
bit-exact; walk_cost_bps identica a §52) + R9 k* = 12,25x come FD.k_star, e due controlli
POSITIVI obbligatori. Due errori miei catturati e pubblicati: banda p10/p50/p90 che si
incrociava oltre il libro visibile (tre oggetti-curva separati), e un controllo positivo
DEGENERE per costruzione (un costo costante sparisce da un drag differenziale).

Sola lettura, nessun ordine, solo GET pubbliche. Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 03:28:10 +00:00
Adriano Dal Pastro 4a849f3f74 registro §56: XS-AMPIEZZA — la caduta non era ampiezza ma IC, e k=5 non e' invariante di scala 2026-08-23 03:04:32 +00:00
Adriano Dal Pastro bf617b75ff research(xs-ampiezza): NO — la caduta di XS01 su 11 gambe non era ampiezza, e' selettivita' piu' un IC che li' vale zero
L'ampiezza effettiva (participation ratio) scende solo da 9,34 a 7,23 (-23%) mentre lo
Sharpe scende dell'86%: sotto IR = IC*sqrt(ampiezza) la sola ampiezza spiega il 14% del
divario, e NESSUNA delle costruzioni dichiarate la muove (7,13-8,47). Il demeaning — la
mossa che creo' XSR01 — e' un NO-OP ALGEBRICO su XS01, perche' i pesi sommano gia' a zero
per costruzione (max|sum w| = 2,8e-17, serie identiche a 2,2e-16): non e' un risultato
debole, e' un'identita' che vale a ogni universo e per sempre.

Il divario sta altrove, ed e' due cose. (a) SELETTIVITA': k=5 su 11 gambe tiene 10
posizioni su 11 e non seleziona niente; k=5 non e' un parametro invariante di scala, fu
tarato su A=19. Congelando il QUANTILE invece del numero la mediana delle 10 fasi passa
da -0,04 a +0,69 (delta appaiato +0,83, positivo in 10/10 fasi, plateau su k in {1,2,3},
mentre su 19 gambe k non conta) contro +1,15 dell'universo pieno. (b) IC: -0,027 (t -0,88)
sulle 11 contro +0,057 (t +2,29) sulle 19, sotto TUTTI i 40 sottoinsiemi casuali da 11 —
e sui 9 alt maturi presi da soli e' NEGATIVO (-0,065, t -2,07) mentre le 8 mancanti da
sole non ce l'hanno (+0,008). L'informazione vive nel CONTRASTO fra le fasce: XS01 e' in
buona parte una rotazione major-maturi contro alt-recenti, non una selezione dentro una
fascia. §50 lo chiamava "sfortuna di listino" al 9° pctl dello Sharpe: sull'IC il
sottoinsieme di Deribit e' fuori dalla banda, per una ragione strutturale.

E tutto il recupero sta sotto la risoluzione del campione, per quattro strade: MDE
dell'hold-out ~2,3 di Sharpe su 1,64 anni attivi; lo spread di coda che dovrebbe pagarlo
ha t 0,2-0,6 contro 1,91 dell'universo pieno; il null di permutazione a fee zero (p
de-luckato sulle 10 fasi: mediana 0,130, sotto 0,05 solo nel 40%) separa il candidato dal
rumore su 19 gambe e non su 11; il deflated-Sharpe sulle 80 celle dichiarate FALLISCE
(0,158, massimo atteso dal rumore 1,065 contro candidato 0,459).

Due errori catturati su me stesso. (1) La selezione in-sample-only NON e' stabile alla
dichiarazione della griglia: con k in {2,3,4,5} la cella al buio era resid k=2 (HOLD
+1,33), aggiungendo k=1 diventa white k=1 (HOLD -0,53) — con ~1 anno di in-sample
(SE(Sharpe) 1,7) la procedura onesta e' una monetina. (2) La prima misura di
eseguibilita' usava |dW| invece di |d(W*scale)| e dava "100% eseguito": la posizione in
dollari e' W*scale e il vol-target muove il nozionale ogni giorno anche a pesi fermi.
Corretta, riproduce le due popolazioni di §45 per via indipendente (11,9% degli ordini =
62,5% del nozionale). A $635 passa l'83% del nozionale: il muro non e' il capitale.

Venue letto ora: 14/19 quotate (SUI 18/08, APT 21/08 senza NESSUNA quota, AAVE 15/08),
11 da >=1 anno, lotti $0,01-$7,72. Solo 2 delle 11 gambe netterebbero col libro live.

Replica bit-exact contro sleeves._xsec_returns (max|dif| = 0,0); controlli positivi su
tutti e tre i rilevatori (ampiezza su matrici note, IC con un segnale che bara = +1,000,
null di permutazione che separa 19 da 11). Sola lettura, nessun ordine, output
riproducibile a meno del timestamp.

Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 03:02:41 +00:00
Adriano Dal Pastro 8694da31bc registro §54: GATE PREVDAY-01 scritto — la cella che gira non e' quella che la selezione onesta sceglie, e quella onesta butta la gamba short 2026-08-23 02:57:26 +00:00
Adriano Dal Pastro aaddd2c93c research(prevday): §54 GATE PREVDAY-01 scritto — il lead piu' forte gira la cella SBAGLIATA
Chiude un buco di PROCESSO: PREVDAY sta in forward-monitor dal 2026-06-21 senza gate
pre-registrato e senza deflated-Sharpe, mentre XSR01/DVOLSPREAD/STATARB ne hanno uno.

FAMIGLIA DICHIARATA PRIMA E CONTATA AL RIALZO: anchor{1,2,3,5} x k{0..1.00, 7} x
short{T,F} x min_hold{0,24,72} x tf{1h,4h} = 336 celle (le 11 gia' spese in giugno da
prevday_turnover e le >=8 della scoperta sono tutte DENTRO). Screen dichiarato: i 16
agenti dell'onda intraday + le 104 ipotesi del 20/06.

IL RISULTATO PRINCIPALE — la cella scelta AL BUIO (in-sample-only) NON e' quella che
gira: e' 4h LONG-FLAT (short=False), mentre il monitor gira 1h LONG-SHORT, che sta al
rango 186/336 in-sample e FALLISCE il DSR (0.905 contro 0.993 della cella al buio).
La gamba SHORT — l'intera ragione per cui PREVDAY fu promosso a LEAD — e' esattamente
cio' che la selezione onesta non compra. E il rovescio: la cella al buio sta a corr
0.641 da TP01 contro 0.152 della congelata (diversifica di meno).

BANDA D'ANCORA: PREVDAY UN'ANCORA CE L'HA (l'ora del confine-giorno) e §50 l'ha tenuta
FERMA. De-luckata sullo spazio congiunto (TP01 x24 · SKH01 x23 · PREVDAY x24, 300
estrazioni, differenze APPAIATE): dShFULL +0.191 -> +0.100, dShHOLD +0.362 -> +0.246 al
peso 15% — meta'. Il SEGNO regge al 100% delle estrazioni; la TAGLIA no. Replica
indipendente di §50 a candidato fermo: +0.191/+0.362 contro i +0.192/+0.363 pubblicati.
Standalone: canonica al 96o pctl delle 24 ancore (ShFULL 1.236 contro mediana 0.963).

MDE: 63 giorni = 0.17 anni -> SE(Sharpe) 2.41 naive / 4.23 Lo, t 0.85 / 0.48, IC95 largo
16.6 punti. Per distinguere uno Sharpe vero di 1.2 dal nulla all'80% di potenza servono
9.4 anni. Il forward serve a UCCIDERE, non a promuovere. E il "+2,04" pubblicato e' su
lente ORARIA: sulla lente giornaliera del progetto e' +1.56.

DSR: attesa a priori REFUTATA. Non si ribalta col conteggio (11 -> 560 celle costa 0.009);
si ribalterebbe solo con sd(trial) >= 0.363 contro 0.267 misurata. Su famiglia OMOGENEA il
deflated-Sharpe e' cieco sul conteggio ma NON vacuo: la cella mediana della stessa
famiglia fallisce (0.863).

INTEGRITA' (sola lettura provata con md5+mtime): 1512 barre su 1512 ore, 95.6%
ricostruibili bit-a-bit; le 67 divergenti sono 1.06/giorno all'ora del cron = ~32
min/giorno non registrati (contro i 4 min/GIORNO REGISTRATI di paper_statarb, §32).
paper_prevday e' sano, ma non al 100%.

FUNDING (mai in nessun backtest): -1.37%/anno di sleeve. La gamba short NON compensa —
incassa solo 0.26-0.46x l'incondizionato mentre la lunga paga 1.25-1.69x.

weights_tilt_null PASS a ogni peso, ma frac_random_beat_hold = 0.91: "migliora
l'hold-out" e' un claim generico su questo libro.

GATE PREVDAY-01: decisione 2027-06-21, 7 condizioni (DSR>=0.95 sulla famiglia
ri-dichiarata + sensibilita' alla partizione pubblicata; cella al buio == congelata,
altrimenti si ri-congela e il forward RIPARTE DA ZERO; delta di libro appaiato > +0.05
positivo al >=90%; weights_tilt_null; ADDS non-hedge sulla cella al buio;
day_boundary_robust != ARTIFACT-RISK; Sharpe forward > 0, soglia debole di proposito),
veto d'integrita' >=80% di barre ricostruibili, kill a Sharpe < -0.50 su >=180 giorni
attivi. Oggi 8/10 condizioni; le 2 che mancano sono la stessa cosa.

Nessun file di produzione toccato, nessuna proposta di cambio al libro live.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 02:55:39 +00:00
Adriano Dal Pastro 9d23ea2ef0 registro: ondata 8, lotto finale — tre filoni nati da cio' che l'ondata ha appena trovato 2026-08-23 02:23:35 +00:00
Adriano Dal Pastro e428659851 registro §52: SKEPTIC-SPOT — il lead regge a $600 e si annulla a $272k, esattamente al muro che pretendeva di spostare 2026-08-23 02:20:52 +00:00
Adriano Dal Pastro f5ebe689da skeptic(spot): il lead REGGE a $600 e si ANNULLA alla taglia del muro che sposta
§52 SKEPTIC-SPOT — attacco deliberato a §39/§45 (spot al posto del perpetual per
la gamba TP01). Sei attacchi, replica bit-exact prima di ognuno (max|dif| = 0.0 su
tp01_realistic; +2,106% di sleeve e +1,580% di libro protetti da assert).

Esiti: 1 allineamento REGGE · 2 controfattuale INCRINA · 3 tetto 1,0x REGGE ·
4 spread/profondita' INCRINA · 5 haircut REGGE · 6 disaster-SL REGGE.

Il risultato che cambia una conclusione e non una presentazione: il differenziale
di cammino spot-vs-perp e' +0,72 bps a $600 (-0,04%/anno) e +25,66 bps a $272k
(-1,54%/anno = il 97% del lead lordo). Il +1,55% e' misurato a una taglia a cui
l'esecuzione e' gratis e speso dentro un muro da $290k, dove non lo e': il muro
NON si sposta del 10,9% pubblicato.

Trovato invece che la storia dello spot ESISTE (get_tradingview_chart_data serve
BTC_USDC/ETH_USDC dal 2023-04-24, 29.196 barre orarie, 0 gap): §39 la dichiarava
assente. TP01 girato sul prezzo spot VERO contro il perp, 24 ancore appaiate, da'
+0,166%/anno di sleeve con la banda che contiene lo zero (16/24) -> il
controfattuale sul PREZZO e' innocuo. Ma lo strumento non esisteva per il 55,3%
del campione e nel 2023 aveva ~9% di ore senza scambi: il lordo passa da +1,580%
(7,4 anni) a +1,450% (era spot) a +1,180% (era liquida, 2024+).

Attacchi falliti, e vanno detti: il tetto 1,0x non morde (3 giorni su BTC, tutti
nel 2018-11 e in PERDITA: troncare avrebbe fatto guadagnare); nessun haircut <=100%
rende binding il margine (copertura 50,0x replicata al decimo); il disaster-SL tolto
a TP01 vale 0,15%/anno ammortizzato allo scenario operativo.

Tre errori miei, catturati e dichiarati nello script: (a) confrontavo il costo di
SPREAD dello spot con la banda NETTA di §45 — mele contro pere, nel verso che mi
conveniva: like-with-like le due bande si sovrappongono; (b) l'aritmetica del
margine metteva SKH01 a 1,0x su ciascun asset invece che sul proprio sleeve
(25,0x invece di 50,0x: §45 aveva ragione); (c) ammortizzavo su 7,4 anni la coda
di un blackout da 30 giorni preso come argmax, ottenendo 1,97%/anno = il 127% del
lead da un evento mai accaduto.

Squalificato dal proprio controllo positivo: gli stimatori di spread da OHLC
(Roll, Corwin-Schultz) attribuiscono 4-16 bps al perpetual, che e' a un tick ->
numeri cancellati, non riportati.

Correzione a §45: «lo spot non si liquida» e' falso — BTC/ETH hanno
in_cross_collateral_pool: true, quindi sono collaterale liquidabile (non binding).

Numero onesto rivisto: [+1,38%, +1,58%]/anno a $600, -0,11%/anno a $272k.
Sola lettura provata (git status -- src/ config/ scripts/live/ tests/ data/ vuoto),
0 ordini, solo GET pubbliche con pacing e astensione nei minuti :05-:10 e :24-:30.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 02:19:33 +00:00
Adriano Dal Pastro 892ca6e214 CLAUDE.md: il lotto minimo di VRP01 era misurato sugli inverse — sui lineari USDC e' 7,5x piu' piccolo, cade il lotto non la regola 2026-08-23 02:18:08 +00:00
Adriano Dal Pastro ab497cc028 registro §50: BOOK-3RD — nessun terzo sleeve ammissibile, e PREVDAY e' in monitor da giugno senza gate 2026-08-23 02:17:55 +00:00
Adriano Dal Pastro caa7cc4020 research(book-3rd): nessun terzo sleeve ammissibile oggi, e per sette candidati ci sono sette muri diversi — nessuno dei quali e' il capitale
§50 BOOK-3RD. Domanda: con ~$635 su Deribit, qual e' il MIGLIOR terzo sleeve realmente
eseguibile del LIBRO LIVE a 2 sleeve (`deribit_book_sleeves`, TP01 75 / SKH01 25) — e se la
risposta e' "nessuno", a quale capitale cambia? Un solo script, nessun file di produzione
toccato, nessun ordine.

REPLICA DI CONTROLLO PRIMA DI OGNI DELTA: ShFULL 1,813 / ShHOLD 1,437 / maxDD 9,42%
riprodotti al terzo decimale; replica ancorata (h=0, off=0) bit-exact contro lo sleeve di
produzione (max|dif| = 0,0), idem XS01, VRP01 e STATARB (0,746 contro il motore originale).

IL VINCOLO MAI MESSO IN TABELLA — IL NETTING. Letto dal sorgente: `book_net_target` somma i
due sleeve in UN numero per asset e `build_book_order` manda UN ordine, quindi un terzo
sleeve DIREZIONALE su BTC/ETH non paga un min-order proprio (misurato: 163 -> 344 ordini/anno
a $635, ma il turnover sale solo del 14%; e per disuguaglianza triangolare le fee modellate
per-sleeve sono un LIMITE SUPERIORE). Il rovescio: non puo' avere un proprio stop. Un terzo
sleeve su ALTRI strumenti richiede una riga in `_CONTRACT` = codice su un percorso con soldi veri.

LA MISURA (1000 estrazioni congiunte TP01 x24 · SKH01 x23 · candidato, mediana delle
DIFFERENZE APPAIATE, funding dentro, peso 15%):
  PREVDAY    +0,192 ShFULL / +0,363 ShHOLD / +1,31pp drift — eseguibile, netta, ADDS, e SENZA
             gate pre-registrato: e' il piu' forte ed e' il meno disciplinato.
  STATARB    +0,159 / +0,081 / -0,12pp — gate aperto 27/09; NEUTRAL, robust_oos FALSE.
  VRP01      +0,121 / +0,067 / +0,19pp — fermo per REGOLA, non per lotto (sotto).
  XS01(19)   +0,110 / +0,378 / +0,79pp — NON eseguibile: Deribit non quota 5 delle 19 gambe.
  DVOLSPREAD +0,073 / +0,062 / -1,12pp — gate aperto 24/10; il maxDD PEGGIORA sopra il 15%.
  XS01-D(11) -0,024 / -0,128 / -0,73pp — l'unica versione eseguibile oggi PEGGIORA il libro.

DUE FATTI DI VENUE, LETTI DALL'API E NON DALLA MEMORIA:
  (a) il muro del LOTTO di VRP01 era misurato sulla famiglia INVERSE, che un conto USDC non
      puo' marginare: sulla USDC-lineare il lotto ETH e' $242 (non $1.832) e il BTC $772 (non
      $6.210) -> 1 lotto ETH = peso 12% gia' da ~$2.000. Cade il lotto, NON la regola
      "niente short-vol da modello in deploy". 5a occorrenza dello schema `fee_watch`.
  (b) Deribit quota 14 dei 19 major di XS01, ma 3 sono listati fra il 15 e il 21 agosto (APT
      non ha nemmeno una quota). Sulle 11 con >=1 anno di listino il meccanismo collassa, e il
      null dei sottoinsiemi (100 estrazioni da 11 fra le 19) separa le due cause: il
      sottoinsieme MEDIANO fa gia' 0,548 contro 1,265 (62% della caduta = AMPIEZZA, non
      riparabile col capitale) e quello di Deribit sta al 9° percentile (il resto = QUALI
      gambe mancano). Aspettare 2-3 listing non basta.

`weights_tilt_null`: 25/28 PASS — e il numero da leggere non e' quello ma `frac_random_beat_hold`,
che arriva a 0,94: dove vale cosi', "questo candidato migliora l'hold-out" e' un claim GENERICO.
Il gate ha potenza (fallisce su XS01-D a 10/15/20%), ma resta necessario e non sufficiente.

LA SCALA: non esiste una soglia di capitale che ammette un terzo sleeve. Il capitale sposta
solo VRP01 (~$2.000 gamba ETH, ~$6.440 gamba BTC), che e' fermo per una regola. Le due date
che contano sono un GATE (27/09, gratis) e la DECISIONE DI VENUE ($20k), che e' cio' che
riapre XS01 sulle 19 gambe.

ONESTA': attesa a priori dichiarata prima di misurare, esito A1 confermata, A2 meta' giusta,
A3 e A4 REFUTATE, A5 confermata al rovescio. Caveat pubblicato: sono 7 candidati x 4 pesi = 28
configurazioni sullo stesso hold-out, nessuna passata per un deflated-Sharpe DI SCREEN — il
modo giusto di usare la tabella e' scegliere un candidato per una ragione dichiarata PRIMA.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 02:16:18 +00:00
Adriano Dal Pastro f4551090f5 CLAUDE.md: il guadagno in anni del gradino di leva dipende da una convenzione mai dichiarata (muro mobile vs congelato, 1,2 anni di differenza) 2026-08-23 02:07:52 +00:00
Adriano Dal Pastro 8c2fa6e46c registro §53: SKEPTIC-LEVA regge 5/6 — k max 1,40, il 1,50x cade, e nel ramo eq_fallback la scala moltiplica un buco esistente 2026-08-23 02:07:24 +00:00
Adriano Dal Pastro a4c9fca77a registro §47: ANCHOR-ENSEMBLE — su TP01 il drift non puo' cambiare per algebra, il segnale sta su SKH01, e la premessa del 02/07 era sbagliata 2026-08-23 02:06:01 +00:00
Adriano Dal Pastro e7ee0738a3 scettico(leva): il gradino 1,25x REGGE 5 attacchi su 6 — k max difendibile 1,40
Filone §53 SKEPTIC-LEVA. Sei attacchi con soglie dichiarate PRIMA, 10 numeri
pubblicati riprodotti prima di attaccarli. Sola lettura, zero rete, 127 s.

A1 DRIFT   REGGE   — il gradino diventa dannoso solo sotto +1,42%/anno di drift
                     (-2,70 SE, 0,25° pctl bootstrap a blocchi): fuori da IC95
                     [+4,78%] E da IC99 [+2,36%]. Il libro puo' perdere il 90,6%
                     del suo drift e il gradino resta non dannoso; il PEGGIOR
                     triennio mai realizzato (+5,35%) ci sta 3,8x sopra.
A2 SINISTRO REGGE  — Delta g(1,25) > 0 in 5/5 finestre giudicabili (2020-21 tolto
                     compreso). QUALIFICA misurata: nel biennio MOBILE peggiore
                     (dal 2021-10, drift -0,45%) il gradino COSTA -0,31%/anno =
                     -0,62% cumulato. Non falsifica per il criterio (li' perde il
                     LIBRO), ma il numero e' quello. Rapporto guadagno/costo 13:1.
A3 CODA    REGGE   — con Hill xi=0,43 (piu' severo del +0,34 pubblicato) il peggior
                     giorno strutturale a 1,25x e' 17,90% (<50%) e P(dimezzamento
                     10a) 0,100% contro 0,000%. CORREZIONE a §33: la coda muove k*
                     di 4,6 unita', non "1-2" — la conclusione regge (il drift ne
                     muove 6,2) ma il numero pubblicato e' ottimista ~3x.
A4 LENTE   REGGE   — sotto la lente accoppiata il ricarico del maxDD CALA con k
                     (1,2358 -> 1,2297 -> 1,2237): moltiplicativo, verso favorevole.
                     E la frequenza del disaster-SL e' invariante a k PER
                     COSTRUZIONE (innesco sul MARK, test di ri-piazzamento
                     RELATIVO): il numero di §40 va moltiplicato, non rifatto.
A5 INVARIANTE INCRINA — completo sul percorso FIDATO (0 violazioni su 576 combo:
                     il vero e' n_asset*min(WEIGHT*(W_TP01*lev+W_SKH), frac)*scala,
                     quindi l'invariante e' un LIMITE SUPERIORE). Ma nel ramo di
                     FALLBACK il denominatore del rapporto e' il WATERMARK, non
                     l'equity: leva vera fino a 5,00x GIA' a k=1,00 e 6,25x a 1,25.
                     La scala non apre il buco, lo MOLTIPLICA -> la guardia G3
                     della SPEC non e' una raffinatezza ed e' NON OPZIONALE, ma non
                     e' una chiusura. E il fattore 0,30 non e' un tetto di perdita
                     (§40: stop rotolante, passano -60% dall'ingresso).
A6 FUNDING REGGE   — rifatto col funding DENTRO e proporzionale a k (r_k = k*(r-f),
                     lineare per costruzione): il gradino vale +3,49a (muro mobile)
                     / +2,10a (muro congelato) contro +2,98a / +1,82a sulla lente
                     pubblicata. Il funding NON riduce il gradino: lo AUMENTA in
                     anni, perche' peggiora il caso base (17,28a contro 14,81a).
                     Ma il livello peggiora su tutta la colonna: k=1,25 col funding
                     (13,78a) resta peggio di k=1,00 senza (14,81a) -> il gradino
                     non ripaga il funding, lo attenua.

RICONCILIAZIONE: il «+1,8a / +EUR164» pubblicato NON era una discrepanza, era una
CONVENZIONE non dichiarata — e' la lettura a MURO CONGELATO (de-leva al traguardo),
riprodotta a 0,02a (+1,82a). Col muro che si muove con k il gradino vale +2,98a. La
differenza fra le due letture (1,2 anni) e' piu' grande di quasi tutti gli effetti
che questo progetto misura: va dichiarata. Il +EUR164 e' invece +EUR144 misurato
direttamente — la differenza E' l'ipotesi di linearita' dell'interpolazione.

K MASSIMO DIFENDIBILE = 1,40 (morde il peggior giorno strutturale <= 20%, soglia
AGGIUNTA da questo scettico); coi soli vincoli gia' dichiarati dal progetto sarebbe
1,67 (G6, il disaster-SL). Il 1,50x NON sopravvive: sfonda il 20% (21,48%) e sta al
90% del tetto G6. La scaletta SCALA_LADDER a 1,25 resta giusta: e' l'unico gate che
il progetto ha contro un parametro che nessun altro gate vede.

NON PORTATI: banda d'ancora del guadagno in ANNI (23x24 congiunte, fuori budget);
slippage a taglia crescente (la partecipazione 21,9% di una barra 5m diventa 27,4%
SUBITO, non a $5.000: va misurata PRIMA del gradino); costo di margine sopra 1x
(non esiste su perp lineare marginato); coda di venue (vive sul suo asse).

Nessun file di produzione toccato: git diff sui tracciati e' vuoto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 02:05:22 +00:00
Adriano Dal Pastro 58395a594e research(§47): l'ensemble d'ancora e' ESEGUIBILE a ogni capitale — ma su TP01 vale +0,014 di Sharpe, e il segnale sta su SKH01
VERDETTO: ESEGUIBILE MA INUTILE SU TP01 — nessun cambio al libro.

La domanda mai chiusa: invece di de-luckare il NUMERO, si puo' de-luckare
l'ESECUZIONE (N tranche, N ore, 1/N di size)? Tre risposte:

(i)  batte l'ancora MEDIANA: si', di +0,014 di Sharpe FULL. E l'algebra dice
     che non puo' fare di piu': la posizione dell'ensemble e' la MEDIA delle
     posizioni, il lordo orario e' lineare -> lordo_ens == media dei lordi
     (max|dif| 1.4e-17, verificato). Tutto il guadagno e' vol (-1,1%); il
     drift si muove di +0,013% = solo fee-netting. Cio' che compra davvero
     non e' nella colonna Sharpe: sd(ShFULL) 0,061 -> 0, sd(ShHOLD) 0,112 -> 0.
(ii) batte la CANONICA che gira oggi: NO sull'hold-out (-0,223), SI su FULL
     (+0,024) e IS (+0,071). I due numeri non sono due stime della stessa
     cosa: +0,44 e' un'estrazione gia' avvenuta (98 pctl di 24), +0,21 e' cio'
     che si ottiene senza estrarre. La stima onesta del futuro e' +0,21.
(iii) eseguibile da quale capitale: da TUTTI, gia' a $635.

PREMESSA DEL 02/07 REFUTATA, CONCLUSIONE INTATTA. Il 02/07 boccio' il
tranching perche' "i delta per-ancora (~$1-2) sono sotto il min-order $5".
Ma `book.build_book_order` banda la posizione NETTA e manda UN ordine per
asset per giro: un delta per-ancora non e' mai un ordine. Il tranching non
moltiplica gli ordini per K, e la degenerazione non avviene (retention
0,88-1,06 a $635; a K=24 il path eseguito segue l'ideale MEGLIO che a K=1,
corr 0,9986 vs 0,9954). Cio' che lo boccia e' la taglia dell'effetto, non
l'esecuzione — e la ragione conta, perche' quella vecchia cadrebbe al primo
esecutore che mandasse un ordine per tranche.

FUNDING: canale chiuso per ALGEBRA, non per piccolezza. funding = pos*f e'
lineare in pos -> funding_ens == media esatta (max|dif| = 0). Il rapporto
condizionale 2,25x non si attenua (2,25 -> 2,26 da K=1 a K=24): la
correlazione esposizione-funding vive alla scala del regime, non dell'ora.

DOVE STA IL SEGNALE: SKH01, l'unica ancora a cui il 02/07 non porto' mai
questa domanda. Sulla lente del path che gira, mediana delle 23 fasi ShFULL
0,974 -> ensemble 1,286 (+0,312), maxDD 23,3% -> 16,6%: 20x TP01, perche' i
suoi trade sono DISCRETI (spostare la griglia cambia QUALI trade esistono).
Dentro il libro pesa il 25% e li' non si distingue da zero. 23 e' PRIMO ->
sulla griglia 30m non esiste sotto-ensemble simmetrico.

Contro-intuitivo misurato: tranciando entrambi gli sleeve gli ORDINI salgono
6,5x (197 -> 1283/anno) ma le FEE SCENDONO ($5,76 -> $5,29/anno) — su un
venue a fee proporzionale si paga il nozionale, e mediare 23 fasi trasforma
un +-1,0x che sbatte in una posizione frazionaria. Su un venue a pavimento
fisso il segno si ribalterebbe.

BARRIERA (canale funded): [A7] refutata sulla regola misurabile e con un
meccanismo — il lato binding non e' la barriera (-6%, P(breach) 0-7%) ma il
BERSAGLIO (+10%): meno vol allontana dal traguardo quanto dalla barriera, e
l'ensemble sta al 31 pctl su P(pass). MA la regola che il 22/08 ha misurato
uccidere e' la daily-loss a UN giorno, che close-only non puo' vedere
(cieca, non conservativa). Sul p1 giornaliero — cio' che quella regola legge
— l'ensemble batte il 66% delle configurazioni. Dichiarato come indizio.

COSTO VERO, e non e' negli ordini: 23 ancore su 24 di TP01 richiedono barre
di oggi, cioe' `fresh_5m` — il path che il 26/07 ricade in silenzio sul
certificato e che il 29/07 ha fallito 6 giri su 8. E' l'unica delle tre
obiezioni del 02/07 che sopravvive intatta.

Repliche prima di ogni delta: h=0 == tp01_baseline_daily; guardie di
causalita' su tutte le ancore; `banded()` == `r07.smallcap_net` bit-exact
(0.0e+00, stessi ordini); K=4 == EW di 4 book (2.2e-16 sul daily);
offset 0 == `sleeves._skyhook_returns()` (0.0e+00). I livelli del 02/07 sono
derivati col dato: dichiarato, non nascosto.

Due errori miei catturati e congelati in commento: (a) confrontavo
`turnover_per_year`, che eval_weights ARROTONDA, accanto a una
disuguaglianza stretta -> sembrava violata; (b) i percentili di coda usavano
un solo segno per tre colonne di cui due sono ritorni e una una frequenza ->
stampavo 34 dove il valore vero e' 66, cioe' "peggio della mediana" per un
numero migliore della mediana. E il criterio N_max SATURA (6/6 celle a ogni
capitale): un gate che passa sempre non misura niente, e lo dice il codice.

Book, pesi, ancore, cron, config INVARIATI. Nessuna proposta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 02:03:55 +00:00
Adriano Dal Pastro 89ab19aed5 CLAUDE.md: rimosso il frammento di riga lasciato dalla correzione precedente 2026-08-23 02:00:43 +00:00
Adriano Dal Pastro c4514fc2c7 CLAUDE.md: il muro delle opzioni valeva per VENDERE — comprare costa il premio, e il muro vero e' il tick da 5 USDC 2026-08-23 02:00:33 +00:00
Adriano Dal Pastro d84471e6f7 registro §46: TAIL-HEDGE REFUTATO — il maxDD sale in 162/162, e comprare un'opzione costa il premio non il nozionale 2026-08-23 01:59:43 +00:00
Adriano Dal Pastro 5700280f65 research(tail-hedge): REFUTATO — la copertura di coda ALZA il maxDD del libro, 0/162 celle
§46. Prima misura del progetto sull'acquisto di put deep-OTM come assicurazione statica
sul libro (TP01 75 / SKH01 25), senza delta-hedge e senza pretendere alpha. Motore prezzi
RIUSATO da VRP01 (_bs_put/_strike_from_delta su DVOL reale). Griglia dichiarata prima:
3 delta x 3 tenori x 3 budget x 2 roll = 54 celle per lente di f (162 in tutto).

VERDETTO: il null del de-levering non arriva nemmeno a essere il gate che decide — la
premessa cade prima. Il maxDD SCENDE in 0/54 celle a OGNI lente di f (compresa f=1.00,
cioe' regalando alla copertura il prezzo di modello): 9,42% -> 9,53-10,37%. Meccanismo:
il bleed del premio cade DENTRO i drawdown, che su questo libro sono lunghi e poco
profondi, mentre il payoff cade su singoli giorni di crollo che NON sono il fondo del
drawdown. Beta del libro al sottostante +0,076 (il 19/05/2021 il mercato ha fatto -21,1%
e il libro -2,0%): la put protegge una perdita gia' ridotta di ~10x dalla strategia
stessa, quindi coprirla costerebbe ~1/beta volte il budget.

ATTESA A PRIORI, riportata anche dove sbagliata: (c) REFUTATA nella forma scritta — 15/20
dei peggiori giorni SONO crolli, e lo short-squeeze che avevo in mente sta fuori finestra;
(b) e (a) confermate, e (b) e' il meccanismo operativo.

f MISURATO OGGI sulle quote vere (420 put con bid E ask, catena USDC): 1,89 / 1,27 / 1,06
a delta -0,05 / -0,10 / -0,15 — piu' mite del 2,23-5,85 del 30/07, e il verdetto non
cambia. Struttura del modello che vale come risultato: f si paga solo sulla parte di
valore che converge a INTRINSECO, quindi un roll anticipato non lo paga (sensitivita' con
f asimmetrico riportata).

ESEGUIBILITA': corregge un muro ereditato. Comprare un'opzione costa il PREMIO, non il
NOZIONALE — i "lotti da migliaia di dollari" del 22/08 sono il collaterale per VENDERE.
Il lotto minimo BTC_USDC (0,01) costa $1,79-7,93; la copertura diventa comprabile a ogni
roll da ~$9,2k (30g, delta -0,05) a ~$38,8k (7g, delta -0,15). Secondo muro, STRUTTURALE:
il tick da 5 USDC — piu' la copertura e' deep-OTM (cioe' economica) piu' il tick domina.

CANALE FUNDED: sull'unica regola binding (max-loss 6% statico) la copertura va nel verso
sbagliato — alza il maxDD e quindi abbassa la leva ammessa (k 0,629 -> 0,594-0,620).

DUE ERRORI MIEI CATTURATI PRIMA DI PUBBLICARE, entrambi dal controllo e non a occhio:
(1) il controllo positivo "payoff gratis" FALLIVA perche' non accreditavo il valore
    dell'asset regalato, mentre il MTM successivo ne addebitava il decadimento -> il free
    lunch costava quanto il premio. Un controllo positivo rotto dichiara guasto l'apparato.
(2) la prova di causalita' dava 1,28e-04 ("DIVERGE"): confrontavo fino al taglio, ma il
    prefisso si ferma un roll prima -> differiva per ASSENZA di un roll, non per
    look-ahead. Finestra corretta: 0,00e+00 esatto.
(3) e un errore di CRITERIO: contavo "vittoria" anche dove il maxDD PEGGIORA, dove il null
    del de-levering e' degenere (k=1) e un Δdrift>0 risponde a una domanda di alpha, non a
    questa. Col criterio corretto le "3/54 vittorie" a f=1 diventano 0/54.

Controlli 3/3 OK (free lunch e f=0,1 riconosciuti, f=10 rifiutato). Causalita' esatta.
Lente wick accoppiata riusata da r0725_prop_coupled, copertura 100% del pannello.
Distorsioni dichiarate: finestra 2021-03+ (il DVOL non esiste prima, quindi marzo 2020 e'
FUORI CAMPIONE); spread misurato sui soli strumenti con bid E ask = pavimento che favorisce
la copertura; 3-5 breach in 5,4 anni non distinguono le varianti.

Libro, pesi, cron, config INVARIATI. Nessun ordine.
2026-08-23 01:57:56 +00:00
Adriano Dal Pastro c7ec178499 registro §49: TP01-TWIN REFUTED — l'ensemble protegge peggio nei 4 anni recenti a 0/24 ancore, e i meccanismi non erano ridondanti 2026-08-23 01:51:01 +00:00
Adriano Dal Pastro af19892c20 CLAUDE.md: il costo della catena USDC era +90% e sono +18% — il 587 non contava il filtro OI che il collettore applica 2026-08-23 01:49:37 +00:00
Adriano Dal Pastro 7d4f0c328e research(§49 TP01-TWIN): un ENSEMBLE di 5 meccanismi di trend NON protegge piu' di TP01 — REFUTED
Domanda: TP01 e' il 75% del libro live e dipende da UNA definizione di trend (TSMOM
30/90/180). Sostituirlo con un ensemble di meccanismi diversi ma tutti long-flat (Donchian,
incrocio EWMA, canale di Keltner, Kaufman/KAMA) migliora la PROTEZIONE — che e' il suo
compito — a pari drift e a pari costo? NON e' la domanda `marginal_vs_tp01` (secondo sleeve):
e' la STESSA quota di libro espressa da piu' meccanismi, quindi `weights_tilt_null` non si
applica (il vettore dei pesi e' identico nei due bracci).

Esito: REFUTED. Libro, pesi, cron, config INVARIATI.

Entrambe le attese a priori, scritte prima di misurare, sono REFUTATE:
 (A1) "correlano 0,85-0,95, l'ensemble e' TP01 con piu' fee" -> 0,795 sui rendimenti e 0,608
      sulle POSIZIONI; KEL/KAU stanno a 0,51-0,53 da TSMOM. Meccanismi genuinamente diversi:
      il filone non si chiude sulla matrice, va misurato fino in fondo.
 (A2) "meno DD sara' de-levering" -> k_isovol 0,990: NON C'E' NIENTE DA DE-LEVERE. Vol
      identica (12,1 vs 12,0%), esposizione media PIU' ALTA (0,152 vs 0,141), tempo a mercato
      70% vs 55%. Il null non e' "superato", e' SENZA POTENZA, e va detto cosi'.

Muore invece sulla DISTRIBUZIONE della protezione (criterio (B) di edge_watch importato dal
sorgente di produzione) e sul costo al libro:
 - per anno x 24 ancore: l'ensemble protegge PEGGIO in 2022, 2024, 2025 e 2026 a 0/24 ancore
   (degradazione UNANIME, non fortuna d'ancora) e meglio in 2019-2021 e 2023. I quattro anni
   in cui perde sono i quattro PIU' RECENTI. Nel 2022 (DD buy&hold 68%, il sinistro maggiore)
   il rapporto passa 0,04 -> 0,13 = 3,2x peggio.
 - 73/192 celle ancora-x-anno a favore dell'ensemble (TSMOM meglio nel 62%); rapporto MEDIO
   0,18 -> 0,21 (peggiora, 0/24 ancore favorevoli).
 - costo sul LIBRO 75/25: Sharpe hold-out delta appaiato -0,127, favorevole 3/24.
 - 0/30 delle 31 composizioni possibili batte TSMOM da solo su protezione E hold-out insieme:
   il compromesso non e' di questo ensemble, e' della famiglia.
 - e il criterio che si voleva migliorare NON E' BINDING: TSMOM ha rapporto peggiore 0,635
   contro la soglia 0,75 in 192 celle su 192.

ERRORE MIO catturato in sessione e riportato nello script: la prima stesura decideva sul CASO
PEGGIORE (max degli 8 rapporti), che migliora 0,56 -> 0,49, e avrebbe stampato "PROMOSSO A
LEAD". Il massimo di 8 numeri non e' una statistica: si era mosso perche' era migliorato UN
anno (il 2023, che deteneva il massimo) mentre 4 su 8 peggioravano. Secondo errore corretto:
il tempo a mercato era calcolato sulla serie 50/50 (non-zero se lo e' UNO dei due asset) e
dava 66,8/79,4% contro i 55,4/70,3% di eval_weights nella stessa pagina.

Onesta' verso l'ensemble: l'ancora canonica h=0 e' la MIGLIORE delle 24 per lo Sharpe hold-out
di TSMOM (100 pctl, replica indipendente della fortuna d'ancora del 02/07 e 26/07), quindi il
divario a h=0 (-0,37) e' gonfiato: il numero da citare e' la mediana appaiata, -0,067.

Fatto trasferibile: mediare meccanismi di trend NON diversifica il rischio di trend. Cinque
segnali guidati dallo stesso prezzo divergono solo ai BORDI del trend — cioe' nei ribassi — e
la media li tiene mezzi-lunghi mentre il singolo e' gia' flat. Piu' meccanismi = ingresso e
uscita piu' morbidi, non piu' assicurazione. Cio' che NON si conclude: che la monocultura sia
sicura — servirebbe un regime in cui il TSMOM fallisce, e in 7,4 anni non c'e'.

Controlli: replica bit-exact vs sleeves._tp01_returns (max|diff| = 0,0); criterio (B) 8/8 su
TP01 come pubblicato e 0/8 su buy&hold; stimatore di correlazione validato su corr(TP01,SKH01)
= +0,095 contro +0,09 pubblicato; il null del de-levering DEVE scattare e scatta su un
de-levering vero (target_vol 10%); causality_ok max_tail_diff 0,0 su 5/5 + ensemble.
DSR di famiglia 0,999 PASS ma dichiarato NON decisivo (famiglia omogenea -> sr0 piccolo per
costruzione); trial contati al rialzo 22 + 31 composizioni = 53.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:49:29 +00:00
Adriano Dal Pastro 4e1dae5c09 registro §51 e §48: cosa raccogliere (2 su 10, e il +90% era +18%) e il quinto lato del DVOL chiuso 2026-08-23 01:48:56 +00:00
Adriano Dal Pastro 9cb3465374 research(volvol): la vol-of-vol e' una variabile NUOVA che guarda INDIETRO — SCARTATA, quinto lato del filone DVOL chiuso
§48 VOLVOL. Il DVOL era stato usato in quattro modi, tutti sul LIVELLO o su una differenza
di livelli (VRP01 gate IV-rank, DVOLSPREAD, TP01xDVOL, DVOL-direzionale). Mai il secondo
momento. Qui si apre e si chiude.

ORTOGONALITA' (il gate, misurato PRIMA di costruire qualsiasi strategia): PASS con margine.
Max |corr| = 0.396 su 6 referenze x 6 celle; contro il LIVELLO del DVOL sta a 0.13-0.21 e
contro l'IV-rank di VRP01 a 0.01-0.24. **La meta' "ridondante" dell'attesa a priori e'
REFUTATA**: e' davvero una quinta variabile, non una quarta riscritta.

LEAD-LAG: e' un termometro, e peggio di quanto l'attesa dicesse. Il picco di
corr(VoV_t, |r|_{t+k}) non e' a lag 0 ma a lag **-5/-10**, con la curva monotona da +0.17
a lag -10 fino a +0.02 a lag +10: non accompagna il movimento, lo INSEGUE. E al netto di
RV_t e DVOL_t la correlazione con la vol futura a 10g e' **NEGATIVA** (-0.069 BTC /
-0.090 ETH). Controllo positivo del rilevatore superato 2/2 nei due versi.

GRIGLIA dichiarata prima e contata al rialzo: 3 finestre x 3 soglie x 4 usi = 36 celle
(27 direzionali + 9 sull'arm VRP). Tenuta piccola di proposito: su 168 trial il massimo
atteso dal puro rumore e' Sharpe 1.572, sopra il soffitto direzionale.
- study_family_honest: cella scelta in-sample-only SIZE w=10 p=0.50, marginal NEUTRAL,
  **DSR 0.448 FAIL** (0.441/0.381/0.228 a N=36/72/168) -> earns_slot_honest=False.
- La spia T1 in chiaro: la cella scelta ha **corr->TP01 0.995 SULL'HOLD-OUT** (0.667 sul
  pieno). E' TP01 con un nome diverso. Per uso: RISKOFF/SIZE ereditano lo Sharpe del trend
  (mediana IS 0.40/0.66), **DIR — l'unico uso in cui la variabile decide da sola — ha
  mediana IS -0.24 e 5 celle su 9 con FULL negativo**.
- Arm VRP01, replica del sleeve **bit-exact 2/2** prima di ogni delta: 5/9 celle battono il
  canonico (moneta), maxDD giu' in **9/9** = de-levering puro, e contro gate CASUALI che
  saltano lo stesso numero di settimane la mediana e' 0.71/0.72 con **0/9 celle al 95° pctl**.
  5° fallimento consecutivo di un gate nuovo su VRP01 dopo i 4 del 03/07.

IL NUMERO CHE CHIUDE, e non e' quello della griglia: il candidato migliore batte TP01 nudo
di **+0.034 di Sharpe su una finestra il cui MDE e' 1.51 — fattore 44**. Su questo dato la
domanda non e' rispondibile in positivo nemmeno in linea di principio. A chiudere sono le
due misure che hanno potenza e non dipendono da nessuna cella scelta: la parziale negativa
e il **controllo NON CAUSALE** (stessa cella con vol-of-vol che sbircia: **-0.292** sotto
TP01) -> non e' che la si stima male, e' che la variabile non contiene l'informazione.

Errori catturati su me stesso: (a) la lettura di §1 era CABLATA e diceva "il legame piu'
forte e' con la vol realizzata" mentre la tabella diceva SPREAD -> ora e' calcolata;
(b) il null del gate casuale estraeva le settimane INDIPENDENTEMENTE per gamba mentre il
gate vero e' guidato da due DVOL correlati -> bracciato coi due estremi, e la differenza
e' risultata immateriale (0.71 vs 0.72, sovrapposizione vera 0.29), ma andava misurata e
non assunta (nel 25/07 lo stesso errore valeva 2-3x); (c) un conteggio off-by-one su DIR.

Eseguibilita' a $635 NON e' il vincolo (haircut -0.002, turnover 4-5/anno): 8ª volta
nell'ondata che muore sull'edge e non sulla taglia del conto. causality_ok OK, oracolo OK.

Book, pesi, cron, config INVARIATI. Nessuna scrittura, nessuna rete, 20s di corsa.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:46:53 +00:00
Adriano Dal Pastro e2aee5730b research(newdata): raccogliere 2 fonti su 10 — il criterio di ricostruibilita' ne uccide 4 da solo
§51 NEWDATA-SCOUT. La scorta di dati e' esaurita (§43), quindi la domanda cambia: non "cosa
abbiamo e non guardiamo" ma "cosa NON abbiamo che vada iniziato OGGI". Ogni riga della colonna
ricostruibilita' e' PROVATA con una GET pubblica + controllo positivo, non dedotta.

VERDETTO: raccogliere la catena opzioni USDC-lineare (+117 chiamate/giro = +18%, non +90%);
il book depth L2 come CAMPAGNA A TERMINE, non come collettore. Tutto il resto: no.

- tape/liquidazioni Deribit: muro di ritenzione misurato fra -24h e -26h (non ricostruibile),
  ma il MDE lo manda al 2032 come segnale -> non raccogliere. E il campo `liquidation` non si e'
  fatto vedere in 1000 trade: non si accende una raccolta su un campo che non si sa se scatta.
- §10 proponeva un collettore di OI perpetual "perche' oggi ripartirebbe da zero": MISURATO,
  non riparte da zero — Bybit serve >=800 giorni di OI perpetual gratis (timestamp verificati
  dentro la finestra chiesta), e la famiglia funding e' chiusa su 4 lati -> testare prima.
- Binance OI/taker/long-short: muro vero a 30 giorni (l'API RIFIUTA, non risponde vuoto), ma MDE
  6 anni + venue USDT -> no.
- funding, DVOL, macro: ricostruibili E famiglie chiuse -> doppia eliminazione.

Correzione a un numero pubblicato: la catena USDC con gli STESSI filtri del collettore vivo
(<=95g, OI>=100) sono 113 strumenti, non ~587; l'origine del 587 resta ignota e lo dico.
Il +117 e' un numero di OGGI e cresce con la liquidita' USDC: va ri-misurato prima di accendere.

Bug catturato in sessione: urlopen solleva su HTTP 400, quindi il RIFIUTO di Binance veniva
ingoiato come guasto di rete e il muro si ribaltava in silenzio in "RICOSTRUIBILE" — stessa
conflazione error/no_quote gia' codificata in collect_chain. Guardia sulle finestre di cron
verificata in entrambi i versi; MDE replica la convenzione §43 (1,40 a -> 1,66).

Sola lettura sul disco, nessun ordine, nessuna chiave. Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:46:16 +00:00
Adriano Dal Pastro fd8d5441af registro: ondata 8, secondo lotto — due scettici adversariali sui due lead che valgono soldi veri 2026-08-23 01:34:15 +00:00
Adriano Dal Pastro 5f6aa90180 registro: ondata 8, primo lotto — sei filoni (assicurazione di coda, ensemble d'ancora, vol-of-vol, ensemble di trend, terzo sleeve, cosa raccogliere) 2026-08-23 01:32:11 +00:00
Adriano Dal Pastro ca1e766069 CLAUDE.md: ondata 23/08 — 0 candidati, la scorta di dati esaurita, il timing dei bonifici refutato e il lead spot ridotto al solo funding 2026-08-23 01:24:20 +00:00
Adriano Dal Pastro 33c24b14b2 registro §45: SPOT-NETTING — il lead regge ma vale solo il funding; T1 sbloccato e' un declassamento e il netting perso risparmia commissioni 2026-08-23 01:22:54 +00:00
Adriano Dal Pastro 279c70222b research(§45): il percorso --no-net non deve crollare — apr assente si DICHIARA, non si formatta
Trovato dallo smoke test a cache fredda: senza get_currencies la sezione 1f cadeva su
TypeError formattando None. Un'analisi che non puo' girare offline non e' riproducibile.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:20:19 +00:00
Adriano Dal Pastro 13daccf6de research(§45): SPOT-NETTING — il margine non uccide il lead, il CODICE si'; e separare le gambe non aggiunge niente
Filone §45: quanto vale, e quanto costa, spostare TP01 sullo SPOT Deribit separandolo
da SKH01 (oggi nettati su un unico strumento). Solo misura, nessun file di produzione
toccato, nessun ordine.

Q1 MARGINE — il venue NON blocca: BTC/ETH sono `in_cross_collateral_pool: true`
[VENUE], lo spot ha `max_leverage: 10` (vive dentro il conto marginato, non in un
wallet a parte) [VENUE], e il margine iniziale misurato sul conto reale e' il 2,00%
del nozionale [CONTO: equity-available su 2 posizioni] -> nel caso peggiore la gamba
SKH01 resterebbe marginata 50x dal solo USDC libero, a QUALUNQUE capitale (il
rapporto e' invariante in E). L'haircut non e' leggibile e non e' binding.
A bloccare e' il CODICE: `shadow._equity` legge solo `account_summary('USDC')` e
`position_usd` matcha per instrument_name -> comprando spot il libro leggerebbe il
25% del conto vero e non vedrebbe la gamba. Non e' un cambio di strumento, e' un
cambio del percorso di sizing del live.

Q2 VALORE — T1 riprodotto (+0,051/+0,057 contro `hourly`, pubblicato +0,054/+0,061)
MA contro `fastdetect`, che il 26/07 stabili' essere il path del live vero, vale
-0,048 FULL (6/23 offset): sbloccarlo e' un DECLASSAMENTO. Il netting perso non
costa commissioni (-0,216% di equity/anno: e' un risparmio) ne' ordini (-6,3/anno):
costa tracking (+12%) e spread ([0,139%,0,250%]/anno). I due si compensano quasi.
Il valore vero e' il funding e basta: +1,58%/anno lordo di drift di libro.

Q3 — `fee_watch` DERIVA i suoi strumenti da `src.live.book.INSTRUMENT`: una gamba
spot sarebbe invisibile (stesso difetto corretto il 21/08 sugli inverse). Riga
dichiarata, non scritta. `convenzione('BTC_USDC')` = 'ignota' -> servirebbe anche
una terza famiglia o il cross-check sui fill resta muto.

Q4 — la liquidazione MIGLIORA (il 75% del libro esce dal perimetro; uno spot non si
liquida) ma la gamba TP01 resterebbe senza disaster-SL; il fisco PEGGIORA di
0,83%/anno se i derivati sono `c-quater`, e i comparti si SEPARANO (le minusvalenze
del perp smetterebbero di compensare le plusvalenze spot): costo nuovo, mai contato.

IPOTESI MIA NATA E REFUTATA: «convertire USDC in spot rinuncia all'interesse». Il
venue dichiara USDC `apr` 3,40; sul log del cron, 6 run flat (il piu' lungo 257 giri
= 10,7 giorni) mostrano equity INVARIATA al centesimo contro i +$0,59 attesi ->
limite superiore su qualsiasi interesse < 0,029%/anno. L'obiezione e' morta.

⚠️ Due istantanee del libro a 4 minuti danno differenziali di spread 2,27 e 4,08 bps
(+79%) e il contributo netto dell'esecuzione CAMBIA SEGNO fra le due: e' dichiarato
come banda, non come punto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:19:04 +00:00
Adriano Dal Pastro 7264a8fe90 registro §43: DATA-UNUSED SCARTATO — la scorta di dati e' esaurita, e il candidato sta sotto il massimo atteso dal rumore 2026-08-23 01:13:21 +00:00
Adriano Dal Pastro 696f2e5bdd research(§43 DATA-UNUSED): inventario dei dati mai letti + l'unica ipotesi che ne esce, misurata
FASE 1 — censimento di data/ e di CHI lo legge (indice di 647 .py, Old/ escluso).
Colonne MAI lette: 26 su 31 di CoinMetrics (fra cui FlowIn/FlowOutExNtv, 2018-2026 al 100%),
`fetch_errors_json`, `iv_90d`. Tutto il resto con storia vera e' gia' stato analizzato: cio'
che resta non letto e' telemetria a finestra corta (catena opzioni 113 g, 0DTE 30 g, vol_term
58 righe). Corretti in sessione due difetti dell'inventario stesso: la ricerca a SOTTOSTRINGA
dava `iv` in 571 file, e le chiavi derivate dall'etichetta producevano due falsi "NESSUNO"
su famiglie realmente lette (eqx_, fut_deribit/fund_).

FASE 2 — EXFLOW: il turnover LORDO sugli exchange. SCARTATO.
La famiglia exchange-flow fu uccisa il 24/07 sullo STOCK (SplyExNtv). Misurato prima di
riaprirla: `In-Out` e' la derivata dello stock (corr +0.999 BTC / +0.752 ETH) mentre `In+Out`
e' ortogonale (+0.035 / +0.080) — il 94% del flusso si cancella, quindi il lordo e'
algebricamente assente da cio' che era stato provato. Griglia dichiarata prima: 3 variabili x
3 finestre x 2 modi x 2 segni = 36 celle, +4 gia' spese su EXS = 40 trial.
(1) La cella scelta al buio fa Sharpe FULL 0.951 contro un massimo atteso dal PURO RUMORE di
1.009: sotto la soglia che una griglia di monete raggiunge da sola (DSR 0.437 a N=36, 0.411 a
N=40). (2) La selezione in-sample torna sul CONTROLLO NEGATIVO messo apposta nella griglia
(NETCTL = l'informazione gia' uccisa): il lordo non e' selezionabile, hold-out -0.42, DILUTES.
(3) Zero informazione direzionale (|t|<1 su 2 asset x 2 variabili). Il legame col |ritorno| su
ETH (Pearson incrementale t +2.70) non sopravvive al rango (Spearman p=0.46) e cambia segno per
anno; su BTC e' "significativo" nel verso sbagliato.
Sottoprodotti: corr->TP01 0.50-0.65 = replica indipendente del "l'on-chain e' prezzo travestito"
del 24/07 su colonne che quell'ondata non aveva letto; haircut 0.000 a $635.

Corretti prima di pubblicare due errori miei: il pool "N=12" del deflated-Sharpe erano le 12
celle MIGLIORI (rows e' ordinata) e faceva PASSARE il candidato a 0.975 — con la partizione
legittima fa 0.678; e il residuo di vol calcolato a mano invece che per OLS ribaltava il segno
su ETH.

Solo ricerca: nessuna scrittura, nessun ordine, book/pesi/cron/config INVARIATI.
2026-08-23 01:10:52 +00:00
Adriano Dal Pastro 824531b5ba registro §44: DEPOSIT-TIMING SCARTATO 0/12 — il buy-the-dip compra il 51% piu' in basso e arriva nel 6,3% dei casi 2026-08-23 01:06:34 +00:00
Adriano Dal Pastro fc55698096 research(deposit-timing): il timing dei bonifici non paga — 0/12 celle, e il segnale compra davvero il 51% piu' in basso
§44. Prima misura di un calendario di versamento CONDIZIONALE (le 5 leve del piano
misurate finora confrontano solo calendari deterministici).

12 celle dichiarate prima: buy-the-dip x4 soglie, risk-off (TP01 a 0x), valore-medio
x3, anti-dip x4. Stesso flusso di cassa per tutte (EUR X/mese sul conto corrente);
cio' che cambia e' quando entrano nel libro, con la liquidita' in attesa a 0% reale.
Lente L3 CONGIUNTA (funding + fisco), muro $313k, block bootstrap 3000 percorsi.

Replica 4/4 prima di ogni delta: muro $313.143, riga EUR250/m 23,4a / P(20a) 14,4%,
riga EUR500/m 17,3a / 85,4%, e P0 del motore col buffer di cassa BIT-EXACT contro
PN.accumula.

SCARTATO. 0/12 in ogni lente (mercato vero, IID, drift dimezzato, EUR250, EUR500);
migliore -0,03% appaiato contro una risoluzione MC della differenza appaiata di 2,0pp,
e su una cella che aspetta 1 giorno = P0 travestito.

Il meccanismo, misurato invece che assunto: buy-the-dip 20% compra davvero al 0,494
del livello medio del piatto (51% piu' in basso) e arriva al capitale-rendita nel 6,3%
dei casi contro l'85,4%. Comprare meglio e comprare tardi sono la stessa mossa.
Sotto la soglia bassa si ribalta: dip 5% compra a 1,009, cioe' PIU' IN ALTO — una
condizione poco profonda non compra il calo, ritarda dentro la salita.

Due errori catturati su me stesso da un controllo: (i) il ritardo-gemello dava
"informazione" +11,5% sul mercato vero e mi avrebbe fatto scrivere che il dip predice
— sotto IID, dove non c'e' niente da prevedere, la stessa colonna vale +14,9%, quindi
e' meccanica (attesa variabile contro fissa); (ii) senza la colonna dell'attesa avrei
letto P4 anti-dip come "stesso segno => rumore": e' piatto perche' in un mercato che
sale la sua condizione e' quasi sempre gia' vera (16 giorni contro 3682).

Rischio di venue separato dal timing: la cassa fuori dall'exchange riduce la penalita'
di +2,4pp a p=1% e +3,8pp a p=2% su dip 10%, contro una penalita' di timing di -15,7pp,
e P(libro azzerato) e' identica per tutte le politiche.

Ordine di grandezza: la migliore politica di timing vale -0,1pp di P(20a); passare da
EUR250 a EUR500 al mese vale +71pp.

Solo script di ricerca. Book/pesi/cron/config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:05:11 +00:00
Adriano Dal Pastro 6f74dcb843 registro §41: TP01-SIZE SCARTATO — Spearman IS/HOLD −0,527, e la premessa del coordinatore sui bucket di convinzione era falsa 2026-08-23 01:04:43 +00:00
Adriano Dal Pastro 96d37c7013 research(tp01): sizing conviction-aware SCARTATO — l'ottimo del knob sta ai due estremi opposti nelle due meta' del campione
§41 TP01-SIZE. Domanda: esiste una size che risponde alla CONVINZIONE (invece che
solo alla vol realizzata) e che, A ISO-VOL, alzi il drift di TP01? Sarebbe un
miglioramento k-indipendente sul 75% del libro live. Risposta: NO.

Griglia dichiarata PRIMA di guardare: 60 celle (rho = g(1/3)/g(1) x q = esponente
del vol-targeting), TF 1d, 24 ancore, segnale CONGELATO. Replica bit-exact del
canonico max|diff| = 0.0 su target_series E sui rendimenti di sleeve.

- FATTO STRUTTURALE che corregge la premessa: la convinzione NON vale {1/3,2/3,1}.
  La media di 3 segni sta in {-1,-1/3,0,+1/3,+1} -> il bucket 2/3 e' ARITMETICAMENTE
  IMPOSSIBILE. La famiglia ha UN grado di liberta' (rho), non tre: potenza/floor/
  soglia sono la stessa cella riparametrizzata.
- NULL DEL RE-LEVERING misurato in forma pura: togliere il vol-targeting (q=0) porta
  il CAGR da 16,32% a 46,75% (+186%) e a ISO-VOL fa -2,40pp. Era TUTTA leva.
- Il meglio dell'intera griglia e' +0,30pp di CAGR iso-vol. La cella scelta AL BUIO
  (rho=0,25 q=1,25) peggiora l'hold-out del LIBRO in 0/24 ancore e il suo maxDD in
  24/24, contro +0,19pp di CAGR.
- Spearman(ShIS, ShHOLD) = -0,527 sulle 60 celle: qui scegliere in-sample e' PEGGIO
  di una moneta. Meccanismo misurato: Spearman(rho, ShHOLD) = +1,000 a TUTTI e sei i
  q (monotono), mentre in-sample e' a gobba -> la convinzione e' informativa
  in-sample e ANTI-informativa in hold-out. Nessuna cella e' proponibile.
- L'unica con guadagno hold-out robusto e' il BINARIO rho=1 (dShHOLD +0,243, 24/24),
  che perde FULL e drift iso-vol e si potrebbe scegliere solo guardando l'hold-out.
- deflated-Sharpe 0,999 PASS ma QUASI VACUO (famiglia omogenea, sr0 0,197):
  sensibilita' pubblicata, FALLISCE a sr0 >= 0,9. Conferma §10 dell'ondata 22/08.
- Controlli positivi 3/3 (de-levering puro, oracolo look-ahead con causality_ok=False,
  anti-controllo rho=3). Eseguibilita' a $635: haircut 0,001 -> non e' il vincolo.
- Sottoprodotti: banda d'ancora del canonico ricalcolata su dati odierni (hold-out
  canonico 0,441 = 96° pctl, mediana onesta 0,219) e altlib.tp01_baseline_daily NON
  e' bit-exact col sleeve (1 ulp su 68,5% dei giorni: _to_daily fa (1+r).prod()-1).

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 01:02:07 +00:00
Adriano Dal Pastro 8e7d181171 registro §42: TP01-LS SCARTATO — la short toglie drift in 0/24 ancore e senza il 2022 il divario raddoppia 2026-08-23 00:56:10 +00:00
Adriano Dal Pastro 790849cb54 CLAUDE.md: il trasporto degli allarmi non e' mai stato validato — un tentativo, nessun registro, stato marcato prima dell'invio 2026-08-23 00:54:35 +00:00
Adriano Dal Pastro 3e3b41d842 research(tp01-ls): la gamba SHORT del trend a 1d e' SCARTATA — toglie drift a 0/24 ancore
§42 TP01-LS. Meccanismo TP01 di produzione CONGELATO, un solo grado di liberta': il
pavimento della direzione TSMOM (floor 0 / -1/3 / -2/3 / -1, 4 trial dichiarati prima).
Replica bit-exact 3/3 a 0.0 (floor=0 == CANONICAL long_only=True, floor=-1 == long_only=
False, sleeve 50/50 == src/portfolio/sleeves._tp01_returns) + 4a replica candidate_daily
vs tp01_baseline_daily a 0.0. Controlli positivi 4/4 (causality_ok su variante leaky,
implausible_sharpe su serie senza perdite, gate iso-vol su leva pura, anchor_luck_delta
A-vs-A).

Esito: la short NON paga il proprio costo. dDRIFT appaiato -1.91%/anno positivo in 0/24
ancore, dShFULL -0.354 (0/24), maxDD +8.80pp (24/24); gate iso-volatilita' FAIL (dCAGR
-6.19% a pari vol); senza il 2022 il divario RADDOPPIA (dShFULL -0.406, 0/24); anni
positivi 2/8 (2022 +1.84, 2025 +0.27) e non compensano gli altri sei; marginal_vs_tp01
= NEUTRAL su tutte e tre le celle (multicut False, corr 0.79-0.93, alpha -2.6%/anno);
la cella scelta AL BUIO in-sample e' IL CANONICO mentre quella scelta sull'hold-out e'
floor=-1/3 = firma di selezione-sull-hold-out. Non e' morte-per-fee: a fee ZERO 1.338
contro 0.904. Attesa a priori del coordinatore CONFERMATA e superata.

Unica metrica nel verso della short: dShHOLD +0.292 in 23/24 ancore — ma l'hold-out e'
1.6 anni, non e' selezionabile in-sample, e all'ancora canonica non si vede (-0.008:
caso speculare della lezione 26/07). Libro 75/25 con SKH01: dSh -0.356 in 0/24, e la
gamba short isolata ha Sharpe -0.335 con corr +0.10 a SKH01 (non ridondante, solo
perdente). Trovato per strada: src/live/book.py clippa gia' TP01 con max(tp_frac, 0.0)
-> il long-flat e' cablato anche nell'esecutore, non solo in CANONICAL.

Nessun file di produzione toccato. Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
2026-08-23 00:54:17 +00:00
Adriano Dal Pastro 0ff03babae audit: il trasporto degli allarmi e' un punto singolo di guasto — un tentativo, nessun registro, stato marcato prima dell'invio (6,9% misurato) 2026-08-23 00:50:21 +00:00
Adriano Dal Pastro 09bae3b9ea registro: ondata 7 — cinque filoni su angoli mai toccati (sizing per convinzione, short del trend, dati inutilizzati, timing dei bonifici, separazione spot/perp) 2026-08-23 00:46:51 +00:00
Adriano Dal Pastro 3a4592bdfc CLAUDE.md: nodo del disaster-SL sciolto — rotolante ma scatta MENO; e il docstring della cadenza in book_execute e' una trappola viva 2026-08-23 00:38:16 +00:00
Adriano Dal Pastro 9973b04bc1 research(wave-0822): SL-ANCHOR — il nodo sciolto dal LOG (la SPEC lo diceva non misurabile); rotolante ma il timore e' refutato, e il docstring della cadenza e' una trappola 2026-08-23 00:37:46 +00:00
Adriano Dal Pastro 0f64eb4720 CLAUDE.md: evitare il funding — datati scartati, spot lead subordinato alla domanda fiscale, e il muro USDC di ieri falsificato 2026-08-23 00:19:05 +00:00
Adriano Dal Pastro f5d88f10bb research(wave-0822): FUNDING-AVOID — datati scartati, SPOT e' lead (+1,55%/anno a iso-vol) ma la domanda fiscale vale piu' del risparmio; corretto il muro USDC di §34 2026-08-23 00:18:27 +00:00
Adriano Dal Pastro db9d844351 CLAUDE.md: la chiave di scala specificata — tetto sul prodotto, il test di guardia smette di controllare, e il nodo del disaster-SL rotolante 2026-08-22 23:58:19 +00:00
Adriano Dal Pastro ef30c20af5 research(wave-0822): SCALE-SPEC — chiave specificata, il tetto va sul PRODOTTO, e il test di guardia non si rompe ma smette di controllare; corretto un mio numero conflato 2026-08-22 23:57:48 +00:00
Adriano Dal Pastro 1d513632c7 CLAUDE.md: GATE PROP-01 chiuso 3/3 senza date; P(50/g) onesto 2,6%; XS01 paga funding; il biglietto batte il versare solo perche' il piano esiste 2026-08-22 23:37:14 +00:00
Adriano Dal Pastro df08460af0 research(wave-0822): GATE-C — gate riformulato senza date, PASS 2/2; XS01 PAGA funding; il biglietto batte il versare solo perche' il piano esiste 2026-08-22 23:36:38 +00:00
Adriano Dal Pastro 2da765bcbb CLAUDE.md: il piano al netto di TUTTO — EUR250/mese fa P(20a) 14-26%, non 92%; e le correzioni si sommano invece di compensarsi 2026-08-22 23:13:37 +00:00
Adriano Dal Pastro 758bcce97f research(wave-0822): PIANO-VERO — la tabella congiunta fisco+funding; EUR250/mese passa da P(20a) 92% a 14-26%, e le correzioni si sommano invece di compensarsi 2026-08-22 23:13:05 +00:00
Adriano Dal Pastro fc0c0a2923 CLAUDE.md: il funding misurato — 2,16%/anno, muri +17,5%, e l'avvertenza che fisco e funding si sommano senza che nessuna tabella li contenga entrambi 2026-08-22 22:43:56 +00:00
Adriano Dal Pastro ee5cbb2c08 research(wave-0822): FUNDING misurato — 2,16%/anno di drift, muri +17,5%; esposizione e funding sono correlati e la stima ingenua sottostima di 2x 2026-08-22 22:43:24 +00:00
Adriano Dal Pastro d930492d47 research(wave-0822): CC01 riaperto col 2022 dentro — resta scartato, ma la liscezza era una proprieta' della COLONNA (HL 4,2 bps vs Deribit 106,2) 2026-08-22 22:38:38 +00:00
Adriano Dal Pastro 8eaf7aa730 CLAUDE.md: terza ondata — due gate d'attesa eliminati, il cap e' un clamp non un moltiplicatore, e il funding non e' in nessun backtest 2026-08-22 22:12:01 +00:00
Adriano Dal Pastro 73ae21c955 research(wave-0822): WORST-DAY — la riserva sulla leva e' mal tarata di 2-4 ordini di grandezza, ma il knob di scala NON ESISTE; e il funding non e' in nessun backtest 2026-08-22 22:10:43 +00:00
Adriano Dal Pastro ebc8cf7d7c research(wave-0822): GATE PROP-01 gamba (b) PASS 23/23 — e la distorsione su SKH01 dichiarata due volte e' refutata; P(50/g) 7,8% -> 4,4% 2026-08-22 22:02:26 +00:00
Adriano Dal Pastro dd4391b55b research(wave-0822): GATE-RECON — il difetto ribalta STATARB (+1,96 -> -2,02), la premessa della rigenerazione e' confermata per via diretta 2026-08-22 21:54:59 +00:00
Adriano Dal Pastro bcffcc01af research(wave-0822): GATE PROP-01 gamba (a) CHIUSA — 13/13 sul venue; e la quota d'ingresso e' un deposito rimborsabile, non una fee 2026-08-22 21:40:12 +00:00
Adriano Dal Pastro a1407874cb CLAUDE.md: seconda ondata — XS01 regge fuori finestra, il canale funded scende a 7,8%, e il deflated-Sharpe non ha regione utile in mezzo 2026-08-22 21:35:40 +00:00
Adriano Dal Pastro 89af0554d5 diary(2026-08-22): seconda ondata — XS01 fuori finestra regge, il canale funded si ridimensiona di 5x, il deflated-Sharpe non ha regione utile 2026-08-22 21:33:55 +00:00
Adriano Dal Pastro e460caf667 research(wave-0822): PROP-RECAL — il 42% del numero funded stava in 6 gambe che fuori campione non esistono; P(50/g) 42% -> 7,8% 2026-08-22 21:32:25 +00:00
Adriano Dal Pastro fd37add518 research(wave-0822): BIN-FREQ — direzione reale (0/72 sul segno inverso), taglia = selezione; e due premesse del briefing refutate 2026-08-22 21:22:43 +00:00
Adriano Dal Pastro 74539db8b8 research(wave-0822): DEPEG — XS01-OOS sopravvive al falsificatore di venue; il caso peggiore non e' il depeg ma il 2025-10-10 2026-08-22 21:17:36 +00:00
Adriano Dal Pastro aaa32daff7 CLAUDE.md: buco di colonna nell'archivio catena (underlying 100% None pre-30/07) e come chiuderlo con la parita' put-call 2026-08-22 21:08:57 +00:00
Adriano Dal Pastro 1b5ddd1ba1 research(wave-0822): SURFACE-RV — la superficie e' arbitrage-free sui prezzi eseguibili; l'incoerenza al mid E' la larghezza del mercato 2026-08-22 21:08:36 +00:00
Adriano Dal Pastro 409de063f6 research(wave-0822): registro — TP01-SINISTRO, l'allarme falsificato nel verso 2026-08-22 21:08:02 +00:00
Adriano Dal Pastro 82ccff2553 research(wave-0822): TP01-SINISTRO — l'allarme e' falsificato nel verso; il rischio dell'ottimo funded e' XS01, non TP01 2026-08-22 21:07:19 +00:00
Adriano Dal Pastro 93ce12931a CLAUDE.md: ritiro una regola mia — dealer_net_gamma non e' il GEX invertito, e' una convenzione dichiarata nel sorgente su questa VPS 2026-08-22 20:54:29 +00:00
Adriano Dal Pastro 1ec928cf09 research(wave-0822): XS01-OOS — l'edge esiste FUORI dalla finestra di scoperta ed e' piu' grande li'; il gate del prop-alloc si sostituisce, non si aspetta 2026-08-22 20:52:40 +00:00
Adriano Dal Pastro 0f2e195674 research(wave-0822): MAKER scartato (il segno dipende da < contro <=) + CRITICO — la cucitura dell'ondata, non i filoni 2026-08-22 20:51:47 +00:00
Adriano Dal Pastro 103dd7bce5 research(wave-0822): BOCPD — il falsificatore eseguito con potenza, 0/68 celle adattive; l'adattivita' spiega il -7% del vantaggio 2026-08-22 20:50:03 +00:00
Adriano Dal Pastro 0bcc5bc5d0 research(wave-0822): apre il registro della seconda ondata — 7 filoni sui buchi della prima 2026-08-22 20:34:08 +00:00
Adriano Dal Pastro 827ae54dc1 CLAUDE.md: ondata 2026-08-22 — difetto dei monitor forward, tre soglie falsificate, la leva invisibile ai gate, e una regola ritirata 2026-08-22 18:04:52 +00:00
Adriano Dal Pastro 272622b6e8 research(wave-0822): PROP-ALLOC — riallocare per la barriera vale il 4%, diversificare vale tutto, e la banda va da 42% a 0,7% 2026-08-22 18:03:12 +00:00
Adriano Dal Pastro 93147a95c8 diary(2026-08-22): ondata multi-agente — 20 filoni, 0 candidati, 1 difetto di produzione, 3 soglie falsificate 2026-08-22 18:02:22 +00:00
Adriano Dal Pastro fbb6e75e67 research(wave-0822): MONITOR-AUDIT — 4 monitor su 6 rotti, il gate STATARB si ribalta, ma la finestra e' rigenerabile e nessuna data si sposta 2026-08-22 17:52:53 +00:00
Adriano Dal Pastro cef559b350 research(wave-0822): ritirato anche il sottoprodotto sull'universo USDC 'piu' liquido' — piu' OI e meno quote 2026-08-22 17:46:33 +00:00
Adriano Dal Pastro 987569c5a3 research(wave-0822): corretta la mia inferenza su BTC_USDC — l'OI non misura la negoziabilita' 2026-08-22 17:46:22 +00:00
Adriano Dal Pastro fe6ad97225 research(wave-0822): ALT-OPT — l'open interest e la negoziabilita' sono anti-correlati (rho −0,77); corretta la mia inferenza su BTC_USDC 2026-08-22 17:46:13 +00:00
Adriano Dal Pastro 1750b5a93b research(wave-0822): lo scettico RITIRA il difetto di contabilita' (non esiste, bit-exact) e chiude oggi il gate del 22/12 — il meccanismo e' un filtro di frequenza 2026-08-22 17:43:33 +00:00
Adriano Dal Pastro b6c0deb866 research(wave-0822): BASIS-CALENDAR scartato — il basis dei datati E' il funding del perp; ma in regalo 240k barre di futures scaduti col 2022 dentro 2026-08-22 17:39:55 +00:00
Adriano Dal Pastro 32ed18222e research(wave-0822): lo scettico conferma il gradino di leva ma corregge due contorni — e la lente close-only e' cieca solo sulle regole a UN giorno 2026-08-22 17:36:45 +00:00
Adriano Dal Pastro 5fe931e00d research(wave-0822): SLIP-AUDIT — nessun costo nascosto a questa taglia, ma la misura scade (22% del nastro a 600 diventa 687% a 20k) 2026-08-22 17:34:51 +00:00
Adriano Dal Pastro 090129359b research(wave-0822): HL-EXEC refuta il muro dei 20k di XS01 e lo slippage come rischio #1 — e il 20k di venue e' un'altra cosa 2026-08-22 17:33:55 +00:00
Adriano Dal Pastro ea22a0e20c research(wave-0822): XSR-REPRO trova un difetto di produzione (i monitor forward registrano ~41 min/giorno); SKEW scompone il f di VRP01 — il 42% e' struttura a termine 2026-08-22 17:29:19 +00:00
Adriano Dal Pastro f0122d97a1 research(wave-0822): VOL-SIZE — il null di permutazione si cita col segno, non col decimale (gira su 3 ancore su 23) 2026-08-22 17:24:23 +00:00
Adriano Dal Pastro f975272ec8 research(wave-0822): VOL-SIZE — il p-value del null di permutazione si cita col segno, non col decimale (3 ancore su 23) 2026-08-22 17:24:10 +00:00
Adriano Dal Pastro e8bbb92f8a research(wave-0822): VOL-SIZE e' un LEAD — e un overlay giornaliero su equity a gradino e' look-ahead che nessun causality check vede 2026-08-22 17:23:22 +00:00
Adriano Dal Pastro aa72e0c9ed research(wave-0822): versione finale di r0822_term_structure (sezione 7 + tre fix dell'agente) 2026-08-22 17:21:24 +00:00
Adriano Dal Pastro 110f894bdf research(wave-0822): TERM-STRUCTURE e OI-PIN scartati — la catena ereditata ha 74 giorni utili, non 3,7 mesi 2026-08-22 17:19:45 +00:00
Adriano Dal Pastro 75606d0f44 research(wave-0822): VRP-QUOTE-VERE scartato — e collect_chain raccoglie la famiglia di contratti che il conto non puo' marginare 2026-08-22 17:19:07 +00:00
Adriano Dal Pastro f4b14f305b research(wave-0822): FLOW-SQUEEZE scartato — e il filone funding si chiude sul QUARTO lato (affollamento) 2026-08-22 17:12:42 +00:00
Adriano Dal Pastro bd5b634209 research(wave-0822): ORTHO-SCREEN 7/7 scartato (e uno screen largo non puo' passare il proprio DSR); XS-LITE falsifica il muro dei 20k di XS01 2026-08-22 17:12:15 +00:00
Adriano Dal Pastro 14c1a75a7e research(wave-0822): GROWTH-POLICY — il libro gira al 7% di Kelly, e ogni gate del progetto e' cieco alla scala 2026-08-22 17:10:03 +00:00
Adriano Dal Pastro 3b206c8e6d research(wave-0822): DEALER-GAMMA scartato — e dealer_net_gamma e' il GEX col segno invertito 2026-08-22 17:08:20 +00:00
Adriano Dal Pastro ff4aa94528 research(wave-0822): ledger degli esiti — ADAPTIVE-HORIZON scartato 2026-08-22 17:03:07 +00:00
Adriano Dal Pastro fa86a7b089 research(wave-0822): brief condiviso per l'ondata multi-agente 2026-08-22 16:43:06 +00:00
Adriano Dal Pastro cb8d9e2a0e docs: SOL escluso — decisione dell'operatore, con la condizione di riapertura
L'analisi del 22/08 (eec7642) concludeva "scartato"; qui la conclusione diventa una
DECISIONE registrata, con la stessa disciplina usata per la decisione di venue del
26/07: cosa NON si ri-discute, cosa la riaprirebbe, e una nota per il futuro-me.

Nessun cambio di codice: l'universo direzionale era gia' BTC/ETH ed e' presidiato da
test_l_universo_direzionale_resta_BTC_ETH.

Riapertura: ~3 anni di storia SOL certificata (dal 2024) tali da rifare la misura
SENZA la finestra 2022-23 che la certificazione segnala — quindi non prima del 2028 —
oppure un meccanismo che non sia TP01/SKH01 congelati. I parquet alt_sol_* restano su
disco per quel giorno (precedente: i 51 HL tenuti dopo il rifiuto dell'espansione
XS01), fuori dal feed attivo e non rinfrescati dal cron.

La nota per il futuro-me c'e' perche' l'argomento piu' probabile per riproporre SOL
("e' eseguibile su Deribit") e' proprio quello che l'analisi ha gia' escluso:
l'eseguibilita' non e' mai stata il problema, l'hold-out lo e' a 24 ancore su 24.

Book, pesi, config, cron: INVARIATI. Suite 631 verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 08:46:35 +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 b1c3ff1bb8 docs(fisco): quadro fiscale verificato sulle fonti — la citazione normativa era sbagliata
Verificato sulle fonti (Fisco Oggi dell'Agenzia, Eutekne, Fiscomania, Circolare AdE 30/E
del 27/10/2023, guide professionali) cio' che il progetto assumeva senza averlo mai
controllato. NON e' un parere fiscale.

CONFERMATO, e nessun numero del piano cambia: 33% sulle plusvalenze cripto realizzate dal
1/1/2026 (art. 67 c.1 lett. c-sexies TUIR); franchigia EUR 2.000 abolita dal 2025;
minusvalenze riportabili 4 periodi ma solo contro plusvalenze cripto (art. 68 c. 9-bis);
patrimoniale 2 per mille sul valore al 31/12; regime dichiarativo per gli exchange esteri.

CORRETTO: il progetto citava «L.199/2025» come origine del 33% in 5 punti (r0725_capcurve,
r0725_ib10k x2, r0727_tasse, r0807_asset_compare, diario 24/07). E' falso. Il 33% dal 2026
e l'abolizione della franchigia vengono dalla L. 207/2024 art. 1 c. 23-29. La L. 199/2025
art. 1 c. 28 ritaglia il 26% per i soli token e-money denominati in EURO: BTC/ETH e le
stablecoin in dollari restano al 33%.

RESTA APERTA la domanda che vale $22k di muro: la Circolare 30/E non tratta i derivati, e
le fonti professionali collocano i derivati su cripto fuori dalle cripto-attivita'
(c-quater, RT Sez. II, 26%) — ma parlando di CFD di broker UE regolati in euro, non di
contratti inverse marginati e regolati IN CRIPTO su sede extra-UE. Registrata la domanda
da porre al commercialista nei termini esatti.

Trovata per strada una conseguenza modellistica: se i derivati sono c-quater, sono un
comparto di compensazione separato → il buffer di carry UNICO di r0807_piano_netto e
r0727_tasse e' ottimistico sulla coda (non sull'aliquota).

REGOLA: una fonte normativa citata in un commento di codice si verifica come un numero —
questa era sbagliata da settimane in 5 file e nessun test poteva accorgersene.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 19:51:50 +00:00
Adriano Dal Pastro 3bc620e914 docs: memoria — gate GTAA corretto, storia troncata di TLT, tabelle del piano al netto
Tre aggiornamenti alla memoria operativa:

1. Il bullet "BANDA GTAA01 AL 25%" registrava «proposta 4/30 in-sample, 5/30 hold-out →
   il rango NON migliora» come evidenza. Non lo era: quel criterio lo passa il 47% della
   griglia per costruzione. Sostituito col criterio decidibile (la banda scelta al buio
   in-sample E' la proposta, quella scelta sull'hold-out no), che e' piu' forte del
   precedente. Registrata la storia troncata di TLT e la guardia cablata.

2. Il bullet "IL FISCO DURANTE L'ACCUMULO" dichiarava che tutte le tabelle a 15-20 anni
   erano al lordo. Ora ci sono le versioni nette (muro, traiettorie, versamenti, rendita)
   con il controllo di replica.

3. Le due tabelle lorde piu' citate (traiettoria da $600 e "quanto versare per un
   orizzonte dato") portano un rimando esplicito alla versione netta: restano perche'
   sono la replica di controllo del fattore d'ancora, non perche' siano il piano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 19:31:02 +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 ba5ea2f5c3 docs: diario 07/08 e memoria — e un gate di GTAA01 che ORA FALLISCE
Diario 2026-08-07-crescita-fisco-etf-scelta.md + i bullet corrispondenti in
CLAUDE.md (fisco d'accumulo, confronto book/ETF, scelta 50/50, simulatore web).

Registra anche un buco trovato ricostruendo il piano: i QUATTRO risultati del
27/07 sera (r0727_3k_vs_5k, r0727_orizzonte10, r0727_tasse) non erano ne' in
CLAUDE.md ne' in un diario — vivevano solo nei messaggi di commit, e uno di essi
cambia il numero di testa del piano.

GATE GTAA01 CHE FALLISCE (test_gtaa_band_gate::test_la_proposta_non_e_selezionata
_sull_hold_out): la proposta e' 9a/30 in-sample e 8a/30 sull'hold-out contro il
4/30 e 5/30 registrato il 27/07 — cioe' migliora dove non doveva essere guardata.
Caratterizzato prima di riportarlo: i due ranghi distano 0.00116 di Sharpe su
un'ampiezza di griglia di 0.3124 (0.4%), quindi il criterio non ha mai avuto
margine; il calcolo e' deterministico (2 corse, max|diff| = 0.0) e il codice e'
invariato dal 27/07 -> e' cambiato il DATO, perche' data/raw/ e' gitignored e i
parquet equity sono riscritti ogni giorno dal cron con ADJUSTED_LAST di IB, che
e' retroattivo.

REGOLA NUOVA: un gate validato su dati sovrascritti ogni giorno non e'
ri-verificabile. Il lato cripto non ha il problema (rebuild_history.py ricostruisce
da sorgente deterministica), il lato equity si'.

Il test NON e' stato toccato: allentare una soglia perche' ha smesso di passare e'
proprio cio' che questo progetto vieta, e un xfail silenzierebbe il segnale.
Niente di operativo dipende da questo (GTAA01 non e' deployabile per il blocco
PRIIPs e non e' nel book live), ma l'affermazione "il rango NON migliora
sull'hold-out" oggi e' falsa e la decisione su cosa farne e' dell'operatore.

Book, pesi, cron, config/live.json e i gate pre-registrati: INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 18:44:36 +00:00
Adriano Dal Pastro ed2532b991 feat(web): simulatore di accumulo nel browser, verificato contro il Python
scripts/web/ — motore in JavaScript (engine.js) sui ritorni VERI del book
esportati da export_series.py, pagine assemblate da build.py. Da "sistema
dinamico dove imposti valore iniziale, mensile e durata, e calcola la best curva
fissando il tempo": la simulazione gira nel browser, quindi il motore va
riscritto e VA PROVATO che dia la stessa risposta.

test_engine.js confronta mediane e probabilita' con r0807_growth_yearly.py su due
configurazioni, esige che il versato (deterministico) coincida al centesimo, e
include un controllo positivo — un motore col fisco spento DEVE risultare fuori
tolleranza, perche' un test che non sa fallire non e' un test. Il risolutore e'
validato contro dep_necessario di r0727_tasse.py: -0.4 / -0.6 / -1.1%.

smoke.js ESEGUE le pagine con un DOM finto. Serve perche' node --check valida solo
la sintassi: ho pubblicato una pagina che lo passava e moriva alla prima riga
utile (chiavi Python "0.0" ricostruite in JS come String(0) = "0"; i pesi
intermedi funzionavano per caso).

Altri due errori che questi strumenti hanno intercettato:
- due anni di dati di un grafico scritti A MEMORIA perche' tail aveva troncato
  l'output -> ora i dati si INIETTANO da JSON (build.py), il passaggio manuale
  non esiste piu';
- una "distorsione sistematica" del motore JS (+0.75%, 8 semi tutti positivi) che
  erano 8 estrazioni contro UN punto Python rumoroso. Misurato bene, 8 semi per
  parte: -0.01%, t = -0.04; ed entrambi i campionatori cadono entro 1.7 SE
  dall'atteso ANALITICO della media di blocco.

Scelta guidata da una misura: la banda del versamento suggerito resta +-1% da
1.200 a 3.000 percorsi -> non domina il Monte Carlo ma la granularita' della
bisezione (~5 EUR). Percorsi tenuti bassi e incertezza dichiarata, invece di
pagare tempo per una precisione che non arriva.

Nessun impatto sulla produzione: non tocca book, pesi, cron o config.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 18:44:13 +00:00
Adriano Dal Pastro 56141b0ffe research(portafoglio): book vs ETF — le due lenti si contraddicono, la scelta robusta e' 50/50
r0807_asset_compare.py (book / S&P 500 / MSCI World sullo stesso piano) e
r0807_best_strategy.py (quale peso scegliere a 12 anni). Da "e se mettessi in
MSCI World o ETF SP500?" e "quale e' la miglior strategia?".

Tre cose rese comparabili: la GRIGLIA (azioni su calendario con 0.0 a borsa
chiusa = convenzione GTAA01; senza, Sharpe x1.20), il FISCO (book realizza ogni
anno al 33%, UCITS ad accumulazione paga il 26% alla vendita -> le curve ETF sono
valori di liquidazione: il differimento e' un vantaggio strutturale dell'ETF e
va nel modello), il BERSAGLIO (272.061$ vale per la rendita perpetua DEL BOOK e
per il 33% -> ricalcolato per ciascuno).

Il risultato non e' chi vince, e' che le due lenti si contraddicono: sulla storia
piena il book arriva al 115% del proprio bersaglio e l'S&P al 32%; sulla stessa
finestra 118% e 110%, e l'S&P ACCUMULA PIU' del book. Il divario e' tutto nei
crolli 2000/2008 che la strategia non ha mai vissuto.

E sulla stessa finestra il rendimento e' quasi identico (17.4% vs 16.8%): la
differenza e' tutta nel rischio (vol 11.0 vs 19.6%, maxDD 10.5 vs 33.7%). Il book
non guadagna di piu', perde di meno — conferma indipendente di cio' che il
progetto scrive di TP01 dal 19/06, contro un'alternativa vera.

Difetto corretto in sessione: un MIX esiste solo dove esistono ENTRAMBE le serie.
La prima stesura confrontava "storia piena" contro "stessa finestra" ma calcolava
i bersagli del mix sull'intersezione in tutti e due i casi -> dichiarava 30 anni e
ne usava 7 (per l'ETF puro: rendita 8.63% invece del 4.16% vero). Rifatto su una
finestra sola con gli scenari come spostamento del drift, simmetrico sui due lati.

A 12 anni vince 50/50 sul RIMPIANTO massimo (20% contro 52% del book puro e 53%
dell'ETF puro); il criterio del solo caso peggiore non distingue 25% da 50%
(27.09 vs 26.99% = pareggio nel rumore). L'asimmetria fra i due stress e' il
risultato: quello sull'equity e' misurato (30 anni esistono), quello sul book e'
giudiziale (7.4 anni sono tutta la sua storia).

MSCI World e' un PROXY 70% SPY + 30% EFA: URTH/ACWI/VT non sono
nell'abbonamento dati del conto IB, e la nota lo dichiara invece di nasconderlo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 18:43:57 +00:00
Adriano Dal Pastro 68c6894d85 research(capitale): il fisco durante l'ACCUMULO non era mai stato contato
r0807_growth_yearly.py: crescita anno per anno separando versamenti e guadagno,
con e senza l'imposta d'accumulo. Nasce da "grafico della crescita per anno con
versamento e con guadagno".

TAX_RATE compariva in UN SOLO punto del progetto: la lordizzazione del bersaglio
in fase di PRELIEVO. L'accumulo componeva al lordo per dieci o vent'anni.
Costo (lump 5k + 500/mese): -15.7% a 5 anni, -29.8% a 10, -42.6% a 15 — replica
coerente col 27/07 su lump 10k (-16.8/-31/-44%). L'errore e' COMPOSTO.

Conseguenza: tutte le tabelle a 15-20 anni pubblicate in CLAUDE.md sono al lordo.

Contro-intuitivo e misurato: versare di piu' RITARDA il sorpasso (l'anno in cui
il guadagno cumulato supera il versato) — 7o anno a 500/mese, 8o a 800 — perche'
alza l'asticella. I 300 in piu' comprano il traguardo (12o anno invece del 15o,
P(bersaglio) a 15a da 73.2% a 99.0%), non il sorpasso.

Riusa senza riscriverle la contabilita' fiscale di r0727_tasse.accumula e il
block bootstrap di r0725_capcurve.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 18:43:38 +00:00
Adriano Dal Pastro f81c783ea7 fix(sicurezza): dashboard 8787 solo su 127.0.0.1, era raggiungibile da internet
La riga era "8787:8787", cioe' pubblicata su tutte le interfacce. ufw non la
fermava: il DNAT che Docker installa in nat/PREROUTING devia il pacchetto prima
della catena INPUT su cui ufw lavora, e in FORWARD la catena DOCKER lo accetta
prima delle catene ufw-*-forward (DOCKER-USER era vuota). Verificato: da IP
pubblico la dashboard rispondeva HTTP 200.

Dietro c'erano conto e posizioni reali (monta .env.mainnet per lo Shadow live),
senza autenticazione, su http.server della stdlib, processo root.

Svista e non scelta: la riga sotto lega gia' il gateway IB a 127.0.0.1 con il
commento "raggiungibile solo da localhost dell'host".

Dopo il fix: DNAT con -d 127.0.0.1/32, listener solo su 127.0.0.1:8787, da IP
pubblico connessione rifiutata. pythagoras-ibgw non toccato.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 09:35:49 +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 a2f28153d8 docs(bite): verificato il primo giro post-eliminazione, e come NON leggere quote_status
Il giro delle 21:25 (primo con bite gia' cancellato): 576 chiamate, 0 risposte
429, 0 errori. E' il controllo che conta, perche' il guasto del 29/07 era la
raffica di bite che saturava il rate limit per-IP.

Aggiunta la tabella dei 5 giri della giornata, che mostra invarianza prima/dopo.

⚠️ E una precisazione sul nostro stesso strumento: 'ok' significa ALMENO UN LATO
del book, non quota completa. Con ok=572 le righe a due lati sono 432 (75.5%).
Che sia strutturale (opzioni molto OTM) e non un degrado si vede dall'invarianza
fra i giri, non dal fatto che il numero sembri alto.

E' 'una riga presente non e' un dato presente' un livello piu' in giu', applicata
allo strumento costruito per quella lezione: la battuta di cuore vedrebbe il
guasto del 29/07 (quote vuote) ma non una deriva verso book a un lato solo.
Nessuna soglia cablata: con 5 giri di storia sarebbe inventata, e una soglia
inventata e' peggio di nessuna soglia. La colonna da guardare e' 'due lati %'.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 21:33:46 +00:00
Adriano Dal Pastro 933ccff057 docs(bite): cerbero-bite ELIMINATO — cosa e' stato verificato prima di cancellare
Container, volume, immagine e cartella rimossi il 2026-07-30 (12 GB liberati).
Book, pesi, cron, config INVARIATI: la raccolta era gia' passata al successore
e la sovrapposizione fra le due ha coperto la consegna senza buchi.

Le quattro verifiche, nessuna delle quali era 'il backup esiste':

1. Snapshot COMPLETO, non solo integro: SHA256 OK su entrambi i file, ma
   soprattutto conteggi confrontati tabella per tabella fra volume vivo e
   snapshot (1.232.212 / 17.406 / 59 / 0), identici anche ai parquet importati.
   Un hash prova che il file non e' corrotto, non che contenga tutto.

2. I 10,6 GB di backup interni al volume non contenevano dati unici. La domanda
   giusta non era la loro dimensione ma se bite potasse lo storico: tutti e tre
   i campioni controllati hanno la STESSA riga piu' vecchia (2026-05-01T20:53:49)
   e conteggi monotoni crescenti -> nessuna potatura, sottoinsiemi stretti.

3. Zero dipendenze a runtime: ne' cron, ne' systemd, ne' route traefik, ne'
   altri progetti. I riferimenti rimasti sono documentazione, che resta.

4. cerbero-mcp e' un progetto DIVERSO e serve a PythagorasGoal (Hyperliquid,
   percorso del conto). Progetto compose separato; la rete traefik condivisa e'
   external: nel compose di bite, quindi down -v non la tocca. Verificato dopo:
   Up 41 hours (healthy). Due servizi con lo stesso prefisso sono un incidente
   che aspetta.

Il codice non e' stato perso: era su Gitea (Adriano/Cerbero-Bite) e l'unica
modifica pendente e' stata committata la' come commit di dismissione.

REGOLA: prima di cancellare una sorgente si verifica che la copia sia COMPLETA,
non che esista.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 21:24:39 +00:00
Adriano Dal Pastro e9a4538054 chore(gitignore): la battuta di cuore del collettore e' stato runtime, non sorgente
data/chain_collect/runs.jsonl era finito tracciato nel commit d55eb13: e' lo
stato del collettore (una riga per giro, oraria), della stessa famiglia di
data/paper_*, data/live, data/venue_watch, data/fee_watch — tutti gia'
gitignored. Tracciato avrebbe sporcato ogni commit futuro con una riga di
heartbeat e messo in git un file che il monitor riscrive da solo.

Rimosso dall'indice (il file su disco resta: e' la serie che monitor_health
sorveglia) e la cartella aggiunta a .gitignore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 20:34:08 +00:00
Adriano Dal Pastro 444b804415 ops(backup): PythagorasGoal nel backup rotativo, solo il dato non ricostruibile
data/raw/ e' gitignored e /opt/docker/scripts/backup.sh non copriva questo
progetto: dopo lo spegnimento di cerbero-bite la catena opzioni esisteva in
due copie SULLO STESSO DISCO.

Aggiunta do_pythagoras con criterio dichiarato — si salva cio' che non si
puo' riscaricare:
  dentro (28 MB): catena + contesto, data/paper_* e data/chain_collect
    (serie forward-only che alimentano i gate pre-registrati: non sono
    ricalcolabili, sono un registro di cosa si sapeva e quando),
    options_daily, live, venue_watch, fee_watch, config/live.json
  fuori (~110 MB): quanto si riscarica dai venue (rebuild_history, fetch_dvol,
    fetch_hyperliquid, fetch_ib_equities) + cache

Due guardie provate nei DUE versi: fallisce se la catena e' assente o vuota
invece di produrre un archivio che sembra a posto, e verifica che il tar
contenga davvero la catena (caso negativo: 0 file prodotti). La radice e'
sovrascrivibile via PYG_ROOT solo per poter far scattare la guardia.

Verificato che dopo un riavvio la raccolta riprenda da sola: cron enabled +
active, nessuna dipendenza da docker o cerbero-mcp; giro provato con env -i
(574 chiamate, 0 errori). Finestra scoperta fino al :25 successivo, senza
catch-up.

/opt/docker/scripts NON e' un repo git: la modifica vive solo su disco, il
diario e' l'unico posto in cui e' scritta.

Book, pesi, config, strategia INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 20:25:08 +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 0a77290636 research(capitale): il fisco durante l'ACCUMULO non era mai stato contato — vale il 31% a 10 anni
r0727_tasse.py. TAX_RATE=0.33 compare in tutto il progetto in UN SOLO punto: la lordizzazione
del bersaglio (fase di RENDITA). L'accumulo compone al lordo per dieci o vent'anni.

10.000 EUR + 500/mese, 10 anni, capitale mediano:
  nessuna imposta (modello pubblicato)  229.638$   P(entro 10a) 34.5%
  plus 26%                              173.284$                 8.5%
  plus 33% + patrimoniale 0.2%          158.401$                 3.8%   = -31%

Versamento necessario a 10 anni (lump 10k): P=50% da 602 a 880 EUR/m; P=75% da 790 a 1.051.
Cioe' +33%: il numero dato stamattina (790-870 EUR/m) era al lordo del fisco.

L'errore e' COMPOSTO, non una tantum: -16.8% a 5 anni, -31% a 10, -44% a 15, -55% a 20.

Assunzioni dichiarate (NON un parere fiscale): 33% cripto da L.199/2025 (misurato anche a 26%,
perche' e' aperto se i derivati di sede estera seguano quel regime), minusvalenze riportabili
4 anni, 0.2% annuo sul valore. Il modello tassa la variazione ANNUA di valore, quindi anche la
parte non realizzata a cavallo del 31/12: e' un LIMITE SUPERIORE rispetto alla pura
realizzazione, ma il turnover del book lo rende stretto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:51:42 +00:00
Adriano Dal Pastro 067c89fc16 research(capitale): aggiunta la riga 10k al filone orizzonte-10
10.000 EUR + 500/mese: P(entro 10 anni) 33.9% (contro 19.7% con 5k), mediana 10.7 anni,
rendita a 10 anni 42.25 EUR/g. Raddoppia quasi la probabilita' ma resta fuori dal vincolo.

Versamento richiesto con lump 10k: P=50% -> 604 EUR/m, P=75% -> 793, P=90% -> 975.
Cioe' 5.000 EUR in piu' oggi valgono 77 EUR/mese per 10 anni (~9.240): meno del 2.45x
misurato su 20 anni, perche' a orizzonte corto il lump compone meno.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:37:34 +00:00
Adriano Dal Pastro fa18621eb3 research(capitale): 50 EUR/g in 10 anni costa ~870 EUR/mese, non 500
Vincolo nuovo dell'operatore (49 anni, non oltre 10 anni). r0727_orizzonte10.py.

Il piano attuale NON regge il vincolo: 5.000 EUR + 500/mese danno P(entro 10a) = 19.7%
(mediana incondizionata ~11.4 anni).

Quanto serve al mese per 10 anni, con lump 5.000:
  P=50% -> 689 EUR   P=75% -> 870 EUR   P=90% -> 1.047 EUR
A P=75% si versano $119.273 per arrivare a $272.061: e' la frase del 26/07 col prezzo
attaccato (a orizzonte corto non fai lavorare la strategia, compri il capitale coi bonifici).

Tabella inversa (lump 5k), cio' che si compra in 10 anni:
  500/m -> 36.90 EUR/g    800/m -> 55.57    1.000/m -> 72.66    1.500/m -> 105.94

Due difetti miei corretti prima di pubblicare:
- la colonna "anni mediani" era CONDIZIONATA ai percorsi che arrivano: mostrava 9.4 anni
  accanto a P=15%, che e' contraddittorio. Ora e' etichettata "mediana SE ce la fa".
- il muro stampato (254.524$, ricalcolato dalle serie di questo script) non era quello usato
  nelle simulazioni (272.061$ pubblicato). Le due costruzioni del book live danno rendite
  perpetue 10.91% e 11.67%; si tiene la conservativa e si dichiara la differenza.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:29:37 +00:00
Adriano Dal Pastro 1aa5a0616a research(capitale): 3k o 5k -> ~3.7 mesi su 11.5 anni, non e' una decisione importante
r0727_3k_vs_5k.py. Domanda dell'operatore, poi ristretta a "fregatene del fuori": quanto
versare su Deribit dei 6.043 EUR fermi in XEON.

Tutto su Deribit, 500 EUR/mese, bersaglio 272.061$:
  3.000 EUR -> 11.73 anni    4.000 -> 11.58    5.000 -> 11.42    6.043 -> 11.28
Ogni 1.000 EUR in piu' all'inizio vale ~1.8 MESI. P(entro 20a) 100% in tutti i casi.

Il motivo strutturale: fino al traguardo entrano ~69.000 EUR di versamenti, quindi il
versamento iniziale e' il 4-9% del flusso totale. La decisione che conta e' la SOSTENIBILITA'
dei 500/mese (26/07: smettere al 5o anno porta P(muro) dal 90% al 53% = venti volte l'effetto
misurato qui).

Aggiunto anche il taglio con il venue dentro (quota fuori 46% vs 16%) e il fatto che con i
versamenti su Deribit quella quota si DILUISCE: 4.0 anni di copertura versando 3k, 0.7 anni
versando 5k -> la differenza fra i due e' temporanea, non una postura permanente.

simulate() accetta dep_to (dove vanno i versamenti); replica del 26/07 preservata.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:17:59 +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 d0c804ebfc research(gtaa): l'assenza di API DEGIRO vale -0.02 di Sharpe, non e' squalificante
Domanda dell'operatore: "degiro ha api?". Fatto: no, non ufficiale; Revolut nemmeno
(la sua e' per pagamenti); IB si'. I wrapper non ufficiali girano su credenziali +
seed 2FA e si rompono IN SILENZIO a ogni cambio di front-end — e il progetto ha gia'
pagato quel prezzo con fresh_5m il 26/07. Un esecutore che puo' rompersi senza dirlo
e' peggio dell'esecuzione manuale.

Misurato il costo di NON automatizzare invece di discuterlo:
  carico operativo: 15 settimane/anno con >=1 ordine (29% dei controlli, 1.4 per volta)
  ritardo 1g  -0.02 Sharpe (peggiora in 6/11 anni = moneta)
  ritardo 3g  -0.13
  ritardo 10g -0.27

Il costo non e' il ritardo tipico ma la coda: il rischio dell'operativita' manuale e'
la dimenticanza, e si copre con un allarme, non con una API (gtaa_rebalance_plan esiste
gia' in produzione ed e' nato per un esecutore).

Nota di metodo: sulla finestra UCITS di 3.2 anni la curva del ritardo NON e' monotona
(5g -0.26, 10g -0.13) -> il campione corto non risolve differenze di questa taglia,
quindi il numero si legge sulla finestra lunga a 10 anni, dove lo e'.

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp
2026-07-27 11:05:33 +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 6664575e1c ❌ GTAA01 NON deployabile: blocco PRIIPs CONFERMATO sul conto reale
Il rischio sollevato poche ore fa e' stato verificato tentando l'ordine. Il broker rifiuta:
"Trading limitato — Questo prodotto non dispone di un KID in inglese o in una lingua
approvata per il vostro Paese. I clienti retail possono negoziare prodotti retail
preconfezionati solo se e' disponibile un KID appropriato."

Non e' piu' un'ipotesi regolatoria: e' un rifiuto d'ordine documentato.
SPY/QQQ/IWM/TLT/GLD/HYG sono ETF domiciliati USA, gli emittenti non pubblicano il KID e i
broker UE ne vietano l'ACQUISTO al retail. ⚠️ Le QUOTAZIONI restano visibili — l'operatore
vedeva tutti e sei i prezzi in piattaforma, ed e' esattamente cio' che rendeva invisibile
l'assunzione.

COSA CADE: lo sleeve cosi' com'e' non e' deployabile, e con esso il piano di attivarlo a
~$13k. Restano valide come RICERCA e nulle come DEPLOY: validazione a 30 anni (22/06), fix
costi IB (25/07), GTAA_MIN_CAPITAL, e il LOO del 26/07 che lo indicava come l'unico sleeve
positivo nel 100% delle estrazioni su tutte e tre le metriche.

COSA NON CADE: tutte le traiettorie, i muri e le tabelle di rendita usano
book_series(with_gtaa=0) = solo TP01+SKH01 su Deribit -> nessun numero del piano va
rifatto. E il book live non lo include.

VIA D'USCITA (non percorsa): equivalenti UCITS. NON e' una sostituzione di ticker —
storia piu' corta (si perde la validazione a 30 anni, cioe' cio' che lo rendeva credibile),
ritenuta/TER/replica diversi (decine di bps su un CAGR del 3.65%), quotazione LSE/Xetra con
orari e valuta diversi da uno sleeve che decide sul close USA. Percorso onesto: validare
sull'INDICE e negoziare il VEICOLO, dichiarando tracking error e ritenuta come costi.

REGOLA: la negoziabilita' sul conto REALE va verificata quando lo sleeve entra in RICERCA,
non quando entra nel book. Cinque settimane di misure poggiavano su un'assunzione mai
controllata, e il controllo e' costato un ordine di prova.

Book, pesi, cron, config INVARIATI. 411 test verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 22:10:43 +00:00
Adriano Dal Pastro b3082de9af ⚠️ GTAA01: negoziabilita' degli strumenti MAI VERIFICATA (rischio aperto)
Domanda dell'operatore ("GTAA01 puo' essere in revolut?") che scopre un'assunzione mai
controllata in 5 settimane di lavoro sullo sleeve.

GTAA01 usa SPY, QQQ, IWM, TLT, GLD, HYG = ETF DOMICILIATI NEGLI USA. Sotto il regolamento
PRIIPs un investitore retail residente nell'UE tipicamente NON puo' acquistarli, perche'
gli emittenti USA non pubblicano il KID; i broker UE — Interactive Brokers incluso, che e'
esattamente il venue che lo sleeve assume — li bloccano in acquisto per la clientela
retail.

COSA POGGIA SU QUESTA ASSUNZIONE: i 30 anni di storia, il fix dei costi IB reali del
25/07, la soglia GTAA_MIN_CAPITAL $3.000, il contributo al book, e il risultato del LOO del
26/07 che lo indica come l'UNICO sleeve positivo nel 100% delle estrazioni su tutte e tre
le metriche. Nessuno di questi numeri e' sbagliato come backtest; quello che non e' mai
stato verificato e' se lo sleeve sia ACQUISTABILE dal conto reale dell'operatore.

DA VERIFICARE PRIMA DEL DEPLOY, non dopo. Se il blocco c'e' servono gli equivalenti UCITS
(CSPX/SXR8, EQQQ/SXRV, IUSN/CSUSS, DTLA/IDTL, SGLN/IGLN, IHYU), che sono strumenti DIVERSI
per domicilio, valuta, TER e replica -> rifetch dei dati e rivalidazione, non una
sostituzione di ticker.

SU REVOLUT nello specifico la domanda resta piu' stretta: universo ETF limitato, prodotto
retail leggero, e un ribilanciamento settimanale a 6 gambe con banda $50 non e' cio' per
cui e' pensato. Il confronto va fatto su esistenza degli strumenti e costo per ordine.

Nota permanente nel sorgente sopra EQ_UNIVERSE + bullet in CLAUDE.md.

REGOLA: la negoziabilita' di uno strumento sul conto REALE va verificata quando lo sleeve
entra in RICERCA, non quando entra nel book. E' l'analogo azionario di cio' che il progetto
gia' fa sul crypto (min-order, haircut small-cap, eseguibilita' a $600): la stessa
disciplina non era stata applicata all'equity.

Book, pesi, cron, config INVARIATI (GTAA01 non e' nel book live).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 22:01:26 +00:00
Adriano Dal Pastro dc4135a781 fix: le soglie della tabella anni contraddicevano la decisione venue
L'operatore ha chiesto "GTAA01 e XS01 sono in deribit?". No, e la domanda scopre
un'incoerenza in cio' che avevo presentato.

MAPPA REALE DEI VENUE:
  TP01, SKH01  -> Deribit          (gli unici LIVE)
  VRP01        -> Deribit opzioni  (paper: regola "niente short-vol da modello")
  XS01         -> Hyperliquid      (stat-mode, serve ~$20k sulla gamba)
  GTAA01       -> Interactive Brokers, 6 ETF azionari (paper)

L'INCOERENZA: la tabella anno-per-anno annotava "anno 1: GTAA01 entra nel book" e
"anno 8: XS01 eseguibile", ma attivare GTAA01 E' lo split di venue, e l'operatore ha
deciso il 2026-07-26 di restare 100% Deribit fino a $20k. Le due cose non stanno insieme:
sotto i $20k quelle attivazioni non avvengono.

COSA NON ERA SBAGLIATO: i NUMERI. `book_series(with_gtaa=0)` usa il solo book Deribit a 2
sleeve, quindi tutte le traiettorie, i muri e le rendite pubblicate NON assumono nessuna
delle due attivazioni — sono Deribit-only e coerenti con la decisione. Sbagliata era solo
la colonna di annotazione, che descriveva cio' che sarebbe POSSIBILE come se fosse
pianificato.

Etichette corrette: le soglie ora dicono "sarebbe eseguibile ... ma la decisione venue dice
$20k", e i $20k sono marcati come il punto in cui GTAA01/XS01 diventano una SCELTA.

REGOLA: un'annotazione che descrive una possibilita' accanto a numeri che descrivono un
piano viene letta come parte del piano. Se una decisione registrata la esclude, va detto
nella riga stessa.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:57:59 +00:00
Adriano Dal Pastro 95f7fb30a3 fix: il massimo di una simulazione non e' una statistica della strategia
L'operatore ha contestato un numero che avevo citato io ("anno migliore +184%"). Aveva
ragione, e l'errore era di METODO, non di calcolo.

IL NUMERO E' VERO. Tracciato l'anno estremo: 18 blocchi da 20 giorni, nessuno
significativamente negativo (+20% +15% +12% +10% +8% ... -1%). La popolazione lo consente:
blocchi 20g reali con mediana -0.1%, p95 +8.5%, max +22.4%, skew +2.15 — firma classica di
un trend-follower. E la materia prima esiste: la miglior finestra 365g REALE e' +89.8%.

MA CITARLO ERA SBAGLIATO, perche' il massimo di N estrazioni cresce con N:
  su   1.000 anni simulati -> max  +96.0%
  su   5.000               -> max +135.2%
  su 114.000               -> max +184.3%
Il numero che avevo dato parlava del mio N_PATHS, non del book. Con 1.000 percorsi avrei
scritto +96% per la stessa identica strategia.

I NUMERI CORRETTI SONO I PERCENTILI: p1 -11.9% · p5 -5.5% · MEDIANA +16.0% · p95 +51.2% ·
p99 +71.8%. Vale simmetricamente per il "peggiore -27.4%", anch'esso minimo campionario (a
1.000 percorsi era -19.1%): la coda sinistra onesta e' p1 = -11.9%.

CABLATO: r0726_decadimento.py aveva lo stesso difetto ("drawdown PEGGIORE 44.2%") -> ora
stampa p99 = 26.0% e dichiara che il 44.2% e' un massimo campionario da non citare come
"il caso peggiore".

REGOLA: il massimo (o il minimo) di una simulazione e' una statistica del NUMERO DI
SIMULAZIONI, non della strategia. Si citano i percentili. Stessa famiglia dell'errore gia'
codificato oggi ("un percentile stampato a 0 decimali mente esattamente agli estremi"):
gli estremi sono dove i numeri sembrano piu' informativi e lo sono meno.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:49:45 +00:00
Adriano Dal Pastro 66b4b2b9c0 research: tabella anni parametrizzabile da riga di comando
"E con 1000 al mese?" non deve richiedere di modificare lo script: importo mensile e
versamento iniziale passano come argomenti. Modificarlo ogni volta significherebbe avere
due versioni dei numeri in giro senza sapere quale ha prodotto cosa.

  uv run python scripts/research/r0726_tabella_anni.py            # EUR 500/mese
  uv run python scripts/research/r0726_tabella_anni.py 1000       # altro mensile
  uv run python scripts/research/r0726_tabella_anni.py 1000 10000 # mensile + iniziale

EUR 1.000/mese: traguardo al capitale mediano all'anno 9 (2035) invece del 12; P(traguardo)
80% a 10 anni contro 16%. Il totale versato a 20 anni raddoppia ($270.917 vs $138.482).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:38:09 +00:00
Adriano Dal Pastro bdd9e60355 research: tabella anno per anno del piano (EUR 5.000 + 500/mese)
Mette in forma leggibile le misure di r0726_piano_5k500.py, anno per anno e con gli anni
di calendario, piu' tre colonne che mancavano e che servono a leggerla onestamente:
quanto hai VERSATO fino a quel punto (senza, il capitale sembra rendimento), la banda
p10-p90 (meta' dei percorsi sta fuori dalla mediana) e la soglia attraversata.

Traguardo EUR 50/g al capitale mediano: anno 12 (2038). P(traguardo) 16% a 10 anni,
53% a 12, 92% a 15, 99.9% a 20.

Il pezzo che conta: la quota di capitale che viene dal RENDIMENTO invece che dai
versamenti e' 10% al primo anno, 39% al quinto, 63% al decimo, 88% al ventesimo. I primi
anni si giudicano sui versamenti, non sui risultati — e' il motivo per cui il piano e'
fragile all'interruzione precoce (misurato: i primi 5 anni sono il 25% dei soldi e il 58%
del risultato).

Regola del progetto rispettata: un numero pubblicato deve avere uno script committato che
lo riproduce.

Ipotesi dichiarate in testa allo script: x0.89 misurato, book live TP01+SKH01, fisco 33%,
NESSUN rischio di venue e NESSUN decadimento dell'edge (misurati in r0726_venue_risk.py e
r0726_decadimento.py, da leggere insieme a questa).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:35:37 +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 e320e3c2ba merge: edge watch — criteri di kill pre-registrati per il book live 2026-07-26 21:14:53 +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 1296fa2d96 research: "dai per scontato che non perdiamo mai?" — meta' infondata, meta' e' il punto piu' debole del piano
Obiezione dell'operatore, presa sul serio. Due parti con risposte opposte.

PARTE 1 (infondata): le perdite SONO nel modello. Il block bootstrap ricampiona i ritorni
reali a blocchi di 20 giorni e conserva la forma dei drawdown. Serie reale: 35.6% giorni
in perdita, 27.5% flat, 36.9% in guadagno; giorno peggiore -3.94%, peggior mese -5.76%.
Sui 5.000 percorsi: maxDD mediano 14.4%, p90 19.8%, PEGGIORE 44.2%; anni-calendario in
perdita 5.8% su 95.000 anni simulati.

⚠️ ERRORE MIO CATTURATO PRIMA DI PUBBLICARE: la prima stesura diceva 63.9% di giorni in
perdita. Artefatto — il de-luck sottrae una costante a OGNI giorno (e' cosi' che riduce il
drift lasciando la vol invariata, come prescrive la misura d'ancora), quindi trasforma il
27.5% di giorni FLAT in piccoli negativi. REGOLA: una correzione uniforme sul drift e'
giusta per le domande sul drift e sbagliata per quelle sulla distribuzione — la stessa
serie dice 36% o 64% a seconda di quale si guarda, senza che sia cambiato niente.

PARTE 2 (coglie il punto): l'assunzione ottimista c'e' ed e' che l'EDGE CONTINUI A
ESISTERE per vent'anni. Il bootstrap assume che il futuro sia il passato rimescolato;
nessuna parte del progetto misura il decadimento dell'alpha. Misurato ora:
  edge intatto            -> 11.6a, P(20a) 99.9%
  edge dimezzato          -> 15.8a, P 76.6%
  decade a zero in 20a    -> 14.3a, P 65.5%
  decade a zero in 10a    -> oltre 20a, P 18.4%
  morto dall'anno 10      -> oltre 20a, P 42.0%
  morto dall'anno 5       -> oltre 20a, P 0.0%
Il piano NON e' fragile a un dimezzamento dell'edge, lo e' alla sua morte. E i due casi
non sono distinguibili in anticipo: e' la ragione per cui esistono i gate pre-registrati.

IL LIMITE STRUTTURALE: il peggior BIENNIO dell'intero campione e' +3.0%, cioe' POSITIVO.
Sette anni di storia crypto contengono due tori: un decennio davvero brutto non e' mai
successo, quindi il bootstrap non lo puo' estrarre. Se i 20 anni fossero tutti come quel
biennio, P(traguardo) 2.9% e capitale finale $149.014 contro $136.847 versati — il piano
non fallirebbe, semplicemente non renderebbe. Non e' un parametro da alzare: non si puo'
simulare un regime peggiore di qualunque cosa ci sia nel campione.

Book, pesi, piano INVARIATI. Cambia cosa si sorveglia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 21:06: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 8b21d29e69 fix(dashboard): taglia del book letta dal conto, non cablata
Il cruscotto dichiarava "cap $300/asset · capitale reale ≈ $600" come testo fisso: sarebbe
diventato falso al primo deposito, sulla pagina che si guarda per capire cosa sta girando.
Ora legge equity reale + max_notional_per_asset_frac + disaster_sl_pct dalla config.

Reso dinamico solo il testo di stato del book LIVE. I $600/$2000 restanti in dashboard.py
sono i capitali d'inizio CONGELATI dei libri paper (forward-monitor): quelli devono
restare fissi o le serie perdono continuita'.

Verificato il percorso di ESECUZIONE: nessuna assunzione cablata sulla taglia da $600
(book.py / shadow.py / book_execute.py). Reso: "capitale reale $596.92 · cap $298/asset ·
disaster-SL on-book −30%".

391 test verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:53:57 +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 eb7c3af636 merge: piano 5k+500/mese + strozzatura cap post-deposito 2026-07-26 20:34:00 +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 d1cf44f874 merge: piano versamenti — interruzione, crescita, calendario, domanda inversa 2026-07-26 20:23:46 +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 e8ce60d41c merge: rivalutazione strategia — 75/25 confermato, nessun cambio 2026-07-26 20:06:23 +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 4450321a81 merge: venue watch — tripwire di fallimento exchange (100bps/4h, zero falsi allarmi in 8 anni) 2026-07-26 19:38:19 +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 0ec6f8b761 decision: concentrazione 100% Deribit fino a $20k (decisione dell'operatore)
L'analisi venue-risk di stamattina raccomandava lo split a ~$3k (GTAA01 su IB, 20-25%
fuori dal rischio-exchange). L'operatore ha deciso, DOPO aver visto la tabella della
rovina, di restare concentrato fino a $20k. Registrato con i termini espliciti perche'
non venga ri-litigato alla soglia dei $3k.

ACCETTATO: P(perso TUTTO) resta 10/18/34/64% a p=0.5/1/2/5% invece di 0/0/4/27%.
IN CAMBIO DI: ~EUR 0.08/g di rendita + commissione fissa IB + un secondo venue da
gestire, per proteggere $750 alla soglia dei $3k.

L'argomento dell'operatore REGGE sull'asse su cui ottimizza: sulla probabilita' di
ARRIVARE al capitale-rendita lo split vale +1-3pp (81% -> 83% a p=1%), fatto misurato
nella tabella del §2, non una concessione. L'argomento contro resta scritto: zero e'
ASSORBENTE (andare a zero all'anno 10 di un piano da 16 anni = non arrivarci piu', si
riparte da EUR 0 + versamenti), quindi il valore del non-andare-a-zero non e'
proporzionale alla frazione salvata.

SI RIAPRE a $20k, o PRIMA se cambia il piano (orizzonte/versamenti) o se `p` diventa
stimabile invece che assunto.

CORREZIONE A UN MIO SUGGERIMENTO, verificata nel codice: avevo detto "non lasciare su
Deribit piu' di quanto serve a girare il book". E' inerte — `src/live/book.py:81` fa
`raw = weight * equity * (...)` con equity = saldo reale del conto, quindi prelevare
$100 riduce il nozionale di $100 (1:1), non mette al sicuro $100. Tenere meno saldo a
pari nozionale richiederebbe di scollegare il sizing dal conto e usare il margine =
scambiare rischio-venue con rischio di liquidazione, oggi escluso dal cap a 1.0x.

Agli atti anche: "exchange FDIC" non esiste (FDIC = depositi bancari USD; la
pass-through di alcuni exchange copre solo il contante). Le protezioni reali sono SIPC
(IB: ETF/azioni = GTAA01, non le crypto via Paxos) e segregazione CFTC (CME, taglia
contratti inaccessibile a questa scala).

Book, pesi, cron, config INVARIATI. Nessun cambio di codice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:14:15 +00:00
Adriano Dal Pastro dc60624772 merge: muro come punto fisso — previsione refutata, book deployable a 73.900 2026-07-26 18:58:20 +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 29626210e6 merge: fee Deribit 1 ago — curva misurata, book poco sensibile (-0.017 Sh/bps), nessuna azione
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 18:32:28 +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 0050ac4782 merge: rischio di venue prezzato — con un conto solo, 'un fallimento' = 'perso tutto'
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 17:57:58 +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 ff3ec6795a merge: traiettoria di accumulo col fattore de-luck corretto (€500/m: 19.6a -> 12.4a)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 17:05:53 +00:00
Adriano Dal Pastro 825bf081f4 research: traiettoria di accumulo ricalcolata col fattore de-luck corretto
Il fattore agisce DUE volte e i due effetti pesano quasi uguale: alza il drift (si
accumula prima) E abbassa il bersaglio (il muro scende da $495k a $272k). Le colonne
li separano invece di sommarli alla cieca.

Mediana degli anni da $600 al capitale-rendita (block bootstrap, 3000 path, 25 anni):

  dep./mese   x0.60 muro $495k   x0.89 muro $495k   x0.89 muro $272k
              (25/07)            (solo drift)       (26/07)
     0        mai                mai                mai
     250      22.4a  (8% <20a)   19.6a  (53%)       16.2a  (91%)
     500      19.6a  (48%)       15.7a  (94%)       12.4a  (100%)
     1000     14.8a  (95%)       12.0a  (100%)       9.0a  (100%)
     2000     10.0a  (100%)       8.5a  (100%)       6.0a  (100%)

VALIDAZIONE: la colonna x0.60 riproduce ESATTAMENTE i numeri pubblicati il 25/07
(500/m -> 19.6a, 1000/m -> 14.8a) -> la replica e' fedele e le altre due colonne sono
confrontabili con quelle.

A 500 EUR/mese: dei ~7 anni guadagnati, ~4 vengono dal drift e ~3 dal bersaglio.

CIO' CHE NON CAMBIA: senza depositi il capitale-rendita non si raggiunge MAI (0% dei
path a 20 anni, a ogni fattore). L'accumulo viene dai versamenti, non dal rendimento:
correggere il x0.6 accorcia i tempi, non crea una via che non c'era.

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 17:05:49 +00:00
Adriano Dal Pastro 75713a5ec4 merge: follow-up SKH01 chiuso — de-luck onesto x0.87-0.91 (non x0.6), muro $495k -> $272k
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 16:55:06 +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 5e2b4bd308 merge: leave-one-out del book de-luckato — stima onesta FULL 1.95 / HOLD 1.54 / DD 6.85%
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 13:23:40 +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
Adriano Dal Pastro 7453a29699 merge: ondata 26/07-bis — TP01 barra parziale + gate implausible_sharpe/anchor_luck 2026-07-25 22:36:40 +00:00
Adriano Dal Pastro 37be1df838 research: ondata 26/07-bis — TP01 su barra parziale + i 2 gate mai costruiti
0 sleeve nuovi. Book, pesi, cron, config INVARIATI.

T1 — anche TP01 legge una barra giornaliera PARZIALE nel live, ma non conta.
Stesso fatto strutturale di SKH01: resample_tf non scarta il giorno in corso e
current_target prende [-1]; il feed si ricostruisce alle 00:30 UTC, quindi per
tutta la giornata il book vede oggi come 1 barra oraria su 24 (verificato).
Il docstring "ultima barra CHIUSA" era falso: corretto.

Tre path a un grado di liberta' per volta, 24 ancore, differenze appaiate:
  barra parziale   ΔFULL -0.031 (pos 7/24)  ΔHOLD +0.118 (pos 19/24)
  ritardo 1h       ΔFULL -0.004 (pos 11/24 = moneta)
  leva LIVE/MODEL  1.004
-> trascurabile, nessun cambio al live.

All'ancora canonica sembra peggio del vero: a offset 0 la parziale costa -0.230
di hold-out, che e' il MINIMO della banda (mediana +0.118). Speculare alla
lezione del 26/07: li' l'ancora canonica nascondeva un vantaggio, qui inventa
un danno.

REGOLA: la parzialita' dell'ultima barra conta in proporzione a quanto il
segnale pesa la barra piu' recente. Donchian breakout su 230m (la barra corrente
E' il segnale) -> +0.38; TSMOM 30/90/180g -> ±0.03. Non si trasferisce.

T2 — implausible_sharpe e anchor_luck_band codificati in altlib (debito
raccomandato 3 volte e mai scritto), piu' anchor_luck_delta che codifica
l'errore di stamattina (mediana delle differenze appaiate, non differenza
delle mediane).

Il gate ha segnalato VRP01 e il difetto era MIO: perdite contate su tutte le
barre, ma VRP01 e' settimanale su griglia giornaliera (94.2% di zeri) -> "0.96%,
coda assente" su uno sleeve in produzione. Sulle barre ATTIVE e' 16.5%, la forma
giusta di un credit spread a rischio definito. La lezione era gia' cablata il
giorno prima nel monitor DVOLSPREAD ("barre attive, non giorni di calendario").

Applicazione retroattiva 7/7 tutti ok, con controlli positivi obbligatori
superati (firme CC01 e deep-OTM segnalate, rumore Sh 0.62 no).

Replica indipendente del finding d'ancora del 02/07: il gate applicato alla
cieca a TP01 ritrova canonica +0.237 = 92 pctl delle 24, mediana onesta +0.056,
fortuna +0.182 — contro mediana 0.04 misurata il 02/07 con implementazione
separata. L'hold-out onesto di TP01 e' ~+0.05, non 0.31.

NON fatto: il book ricalcolato sul path live, bloccato da incompatibilita' di
lenti (simulatore per-trade vs sleeve vol-targeted). Follow-up dichiarato.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 22:36:40 +00:00
Adriano Dal Pastro 6d0813a399 merge: misura ingressi SKH01 su barra parziale — non e' un difetto 2026-07-25 22:12:42 +00:00
Adriano Dal Pastro c8d31bc944 research(skh): misura dedicata sugli INGRESSI da barra 230m parziale
Chiude il follow-up dichiarato del 26/07 (misura T1). Il live valuta il segnale
a ogni giro orario del cron su una barra 230m mediamente completa a meta'; il
backtest solo a chiusura di bin. Domanda: di che segno e' il saldo.

Confronto di due path identici in tutto (livelli pct-asimmetrici, uscite
intra-barra, cap max_per_day, fee 0.10% RT) tranne quando si valuta l'ingresso.

  ΔSharpe (live - backtest), 3 offset x 2 asset:
    -0.01 / +0.04 / +0.44 / +0.32 / +0.59 / +0.98  -> 6/6 non negativi, mediana +0.38

Falsi ingressi ~5/anno/asset; cannibalizzano il cap 2-3 volte in 7 anni.
Meccanismo: Donchian breakout — aspettare la chiusura del bin fa pagare il
movimento gia' avvenuto (ingresso 0.25-0.26% peggiore), e su livelli percentuali
quello 0.26% vale il 6-13% della distanza dallo SL contro il 2.6-3.3% da quella
dal TP -> asimmetria a favore della sopravvivenza del trade.

Due attacchi superati:
  - il divario NON e' concentrato: togliendo i 5 giorni migliori si ALLARGA
    (ETH@460 35.6x vs 3.0x); e' il backtest il path concentrato;
  - nessun look-ahead intra-bin: troncando i 5m alle sole barre gia' chiuse la
    risposta e' identica in 289/289 osservazioni (test permanente). Serviva
    perche' il self-check valida solo a CHIUSURA di bin.

Verdetto: non e' un difetto da correggere, il verso e' lasciarlo. Ma live e
backtest girano due strategie diverse e la differenza non e' neutra: sommato
alla misura sulle uscite, il path live di SKH01 e' stato modellato in modo
sistematicamente pessimistico su entrambi i lati.

Book, pesi, cron, config INVARIATI.

Due errori di metodo catturati in sessione e codificati come regole:
  - un self-check su eventi rari si campiona sugli EVENTI (il primo dava
    "80/80 OK" confrontando zeri con zeri, con la ricostruzione rotta);
  - un conteggio su segnale grezzo non e' un conteggio di trade (sovrastima
    ~20x dei falsi ingressi ignorando cap e non-overlap del live).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 22:12:42 +00:00
Adriano Dal Pastro 36d3361075 merge: T1 non implementato (declassamento misurato) + sorveglianza freschezza feed SKH 2026-07-25 20:20:06 +00:00
Adriano Dal Pastro 031b71bf54 ops(live): sorveglianza freschezza feed SKH + correzione dei docstring sulla latenza d'uscita
T1 (TP di SKH01 come limit resting on-book) NON e' stato implementato, per misura.
Leggendo il codice di produzione: TP01 e SKH01 tradano lo stesso strumento con una
sola posizione netta Deribit, quindi un ordine on-book al livello di SKH chiuderebbe
anche quota TP01. Misurati i due ostacoli: (A) segno compatibile nel 97% dei trade
che escono in TP = risolvibile; (B) divergenza modello/live apparentemente bloccante.

Ma (B) non esiste: resample_5m NON scarta il bin 230m in corso (21 barre 5m su 46
nell'ultimo bin) e _skyhook_positions ci itera dentro -> il live rileva gia' SL/TP
intra-barra, entro ~1h dal tocco. I docstring che dicevano "usa solo barre chiuse" e
"latenza fino alla chiusura della barra 230m" erano FALSI e hanno guidato tre analisi
(02/07, 24/07, T1). Corretti sul posto.

Conseguenza: la lente `hourly` sottostima il path live di +0.081 Sharpe FULL di book
(23/23 offset, banda appaiata); il live vero sta sopra il canonical sul FULL, e il fix
richiesto sarebbe un declassamento (+0.054 vs +0.081) in cambio di ordini parziali sul
netto in un percorso con soldi veri.

Cablato invece il problema vero trovato per strada: fresh_5m fallisce in SILENZIO
(fallback al certificato, rigenerato 1x/giorno) -> la latenza d'uscita di SKH01 passa
da ~1h a ~1 giorno senza segnalazione, e nessun controllo esistente scatta (il gate di
staleness guarda il feed di TP01). Stesso schema del feed-freeze del 14/07.

  * livefeed.feed_age_minutes: pura, eta' dalla CHIUSURA della barra, None = non
    misurata, clamp sugli skew d'orologio
  * book_report espone skh_feed_age_min (max fra gli asset)
  * book_execute stampa lo stato e allerta su Telegram sopra skh_feed_max_age_min (30m)

Scelta dichiarata: ALLERTA, NON blocca. Bloccare fermerebbe anche TP01 (nettato sullo
stesso strumento) per un guasto di rete; forzare SKH flat chiuderebbe posizioni buone
su un glitch.

Follow-up dichiarato: la stessa barra parziale tocca gli INGRESSI (ent[n-1] da breakout
non confermato). Disaccordo in 1 bin su 112, ma con 3 entry nel campione la taglia non
e' stimabile. E' un cambio di strategia, non di strumentazione -> misura dedicata prima.

Strategia, pesi e cadenza del cron INVARIATI. Nessun ordine inviato. Suite 266 verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 20:20:01 +00:00
Adriano Dal Pastro 4b2de1ce87 merge: forward-monitor DVOLSPREAD cablato nel cron con gate pre-registrato 2026-07-25 20:05:33 +00:00
Adriano Dal Pastro 841f48c319 ops(live): cabla il forward-monitor DVOLSPREAD nel cron + gate pre-registrato
Chiude la lezione (c) dell'ondata 26/07: "un lead in forward-monitor senza
monitor e senza scadenza e' un lead perso" — DVOLSPREAD era in limbo da 35
giorni. Ora ha config congelata, monitor nel cron e gate con data.

Config congelata = la cella scelta IN-SAMPLE (zwin=180 k=2.0 lw=0.6 zw=1.1
tgt=0.17 svw=60), NON quella pubblicata dall'agente: quella era 83a/729
sull'hold-out ma 471a/729 in-sample e fallisce il deflated-Sharpe (0.947),
la congelata lo passa (0.953). Riusa make_book di r0726_dvolspread_gate,
nessuna reimplementazione.

Strumentazione specifica: il book va flat quando manca il DVOL, quindi un feed
rotto produrrebbe zeri che contati come evidenza direbbero "nessuna perdita"
invece di "nessuna misura". Contabilita' a 3 stati (attive / flat-da-segnale /
flat-senza-dato), finestra misurata in barre ATTIVE, e guardia che esce 1 se
FROZEN diverge dallo stato salvato.

Gate pre-registrato: kill 2026-10-24 se Sharpe < -0.50; decisione 2027-01-24
solo se Sharpe>0 E marginale ADDS E deflated-Sharpe>=0.95 E weights_tilt_null;
veto d'integrita' se barre attive <80% (si estende, non si decide su dati
mancanti). La soglia su Sharpe e' debole di proposito: con ~180 barre
SE(Sharpe)~1.4, una soglia alta sarebbe finta precisione.

Inception 2026-07-25, apertura +0.184 = $111/gamba (cap $300).
Book/pesi INVARIATI. Suite 255 verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 20:05:30 +00:00
Adriano Dal Pastro 444c251e3b merge: ondata 2026-07-26 — degrado SKH01 de-luckato, DVOLSPREAD promosso, XSR01 crypto-specifico 2026-07-25 19:51:58 +00:00
Adriano Dal Pastro 2c3882b60c research(wave): ondata 3 filoni — esecuzione SKH01, DVOLSPREAD, XSR01 fuori dal crypto
Tre questioni che il progetto aveva lasciato aperte e decidibili oggi.

T1 — ESECUZIONE SKH01. Testato l'unico meccanismo che non e' un cron: ordini
resting on-book (TP=limit al livello per costruzione + fee maker, SL=stop-market).
A offset 0 recupera il 94% del degrado, ma l'audit 02/07 aveva de-luckato i
numeri headline di SKH01 e NON il degrado. Sulla banda appaiata dei 23 offset il
degrado recuperabile e' +0.054 Sh di book, non -0.35 di sleeve.

Errore di metodo corretto in sessione: mediana(A)-mediana(B) fra offset confronta
offset diversi; serve la mediana delle DIFFERENZE appaiate. Col fix il verdetto
si ribalta: solo TP a limite = +0.054 FULL / +0.061 HOLD, positivo in 19/23 e
21/23 offset; lo SL on-book PEGGIORA (mediana -0.010, positivo in 11/23) perche'
cristallizza la perdita mentre l'exit ritardata incassa il rimbalzo.
Raccomandazione NON eseguita: TP a limite si, SL strategico on-book no.

T2 — DVOLSPREAD esce dal limbo (fermo dal 21/06). Passato ai due gate che allora
non esistevano. La griglia dichiarata "72 celle" ne contiene 729: valutate tutte.
Plateau reale (729/729 hold-out positivo). Selection-on-holdout confermata ma
mite: cella pubblicata 83a/729 sull'hold-out, 471a/729 in-sample. Cella onesta
FULL 0.68 / HOLD 0.69 (non 0.93) e DSR 0.953 PASS; la pubblicata fallisce 0.947.
Promosso a forward-monitor coi parametri onesti, NON nel book (hold-out attivo
1.6 anni, DSR sul filo, weights_tilt_null mai affrontato).

T3 — XSR01 non generalizza. Meccanismo congelato su 9 settoriali (1998+) e 28 ETF
(30 anni), versione DEMEANATA (il test del 25/07 era a coppie). Lordo +0.24
p=0.193 e -0.14 p=0.747 vs null a fee zero. Il risultato che conta e' l'ampiezza:
il demean fa 4.5->37.4 (8x) sul crypto ma 5.3->6.2 (1.2x) sulle azioni, perche'
sul crypto il residuo-vs-BTC lascia un enorme fattore comune e sulle azioni il
residuo-vs-SPY e' gia' indipendente. XSR01 e' crypto-specifico; NON e' falso.
Soglie del gate 23/10 non toccate.

Book/pesi/cron INVARIATI. Suite 245 verdi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 19:51:52 +00:00
Adriano Dal Pastro 8b4c698ad9 merge: lente wick accoppiata — follow-up 25/07 chiuso, raccomandazione funded 0.50x->0.75x 2026-07-25 19:30:10 +00:00
Adriano Dal Pastro 4cb82dc474 research(prop): lente wick ACCOPPIATA — chiude il follow-up dichiarato del 25/07
La scala di conti funded era giudicata con due lenti a un ordine di grandezza di
distanza su P(>=50 EUR/g): 20.7% close-only vs 1.6-2.5% wick indipendente. Il
difetto era dichiarato (gap estratto indipendente dal rendimento del giorno) ma
il recon accoppiato esisteva solo per il book 75/25.

Qui si generalizza: sleeve TP01/SKH01 separati a risoluzione oraria (minimo
intraday esatto per qualsiasi vettore di pesi) + XS01 accoppiato dagli OHLC
giornalieri HL (recon = sleeve ufficiale a max|delta|=0.0).

FINDING: la calibrazione del wick era giusta, l'errore era l'INDIPENDENZA. Le
marginali coincidono (p50 -0.17pp identico) ma il gap e' ~3x piu' profondo nei
giorni che finiscono BENE (-1.58pp vs -0.48pp), perche' un giorno brutto chiude
sul minimo (m==R nel 26% dei giorni). Il breach si valuta sul minimo -> la lente
indipendente raddoppia i breach da daily-loss (2.0-2.9x, misurato sui giorni
storici). close-only non e' conservativa ma CIECA: 0.00% di breach ovunque.

Verifiche: (1) 1h vs 5m identici (p99 -3.06 vs -3.14pp) -> il caveat di
risoluzione del 24/07 e' trascurabile; (2) riconciliazione col 24/07 RISOLTA
(63.2% vs 58% sulla stessa finestra: non era la finestra, era la lente);
(3) bound severo su XS01 non ribalta config B.

Decisioni: funded 0.75x (non 0.50x — massimizza il payout a 3 anni, $2674 vs
$1230); scala P(>=50/g) ~6% con P(zero) 52-65%; ordine fra politiche invariato
a tutte e 3 le lenti. Book/pesi/cron INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 19:30:03 +00:00
Adriano Dal Pastro 8831c3ff38 merge: fix GTAA01 — costo IB a pavimento fisso + esecuzione a banda 2026-07-25 17:25:06 +00:00
Adriano Dal Pastro 607cd94ecd fix(gtaa): costo IB reale (pavimento fisso) + esecuzione a banda — lo sleeve era cieco al capitale
DIFETTO. src/portfolio/gtaa.py modellava il costo come 2bps PROPORZIONALI e il modulo si
dichiarava "eseguibile a basso capitale, switch mensile/basso turnover". Entrambe false:
il vol-target e' CONTINUO (l'esposizione cambia ogni giorno, su 6 gambe) e IB non ha una
fee proporzionale ma un PAVIMENTO FISSO per ordine, min(max($0.35, $0.0035/az), 1% del
controvalore) = ~$530/anno indipendenti dal capitale.

Il modello vecchio era quindi CIECO AL CAPITALE: dava Sharpe 0.64 sia a $50.000 sia a $600.
Alla taglia grande era sostanzialmente giusto (0.64 vs 0.59-0.66 reali); a $600 la realta'
e' -0.55 di Sharpe e -3.5%/anno di CAGR. L'errore era tutto concentrato dove lo sleeve
verrebbe realmente deployato.

FIX. Il modulo ora:
  * modella la commissione IB reale (ib_commission);
  * esegue a BANDA + CADENZA (settimanale, $50/gamba) — config scelta sul PLATEAU del sweep
    (weekly/monthly x banda 25-100 -> Sh 0.45-0.64 a ogni capitale), non sull'argmax
    in-sample (banda $50 daily a $600 = cella isolata che crolla a banda 100);
  * prende il CAPITALE allocato come parametro: gtaa_returns(capital=...);
  * dichiara la soglia di deployabilita': GTAA_MIN_CAPITAL=$3.000 + gtaa_is_deployable();
  * espone gtaa_rebalance_plan(held, capital) per l'esecutore — salta le gambe il cui
    nozionale non supera la banda (un ordine da $12 costa $0.35 = 2.9%).
sleeves.py dichiara esplicitamente il capitale assunto (GTAA_DEFAULT_CAPITAL=$10.000 allocati
= book ~$50k al peso 20%) invece di nasconderlo.

IMPATTO SUL BOOK (misurato sostituendo la sola gamba GTAA, non citato):
  GTAA01 standalone  Sh 0.64 -> 0.61   CAGR 3.76% -> 3.65%
  book 5 sleeve      FULL 2.22 -> 2.22  HOLD 2.36 -> 2.38  maxDD 6.2% -> 6.0%
Trascurabile alla taglia assunta: il fix conta per il DEPLOY (a $600-2k passa da -3.5%/anno
a +3.0%/anno). PESI INVARIATI -> nessun weights_tilt_null richiesto.

CORREZIONE A UN ERRORE DI ANALISI DELLA SESSIONE. Il diario citava il modello vecchio a
"Sharpe 0.77 / CAGR 5.5%": artefatto di annualizzazione: la serie GTAA grezza ha ~252 barre
/anno (soli giorni di borsa) e metrics() annualizza a 365 con years=n/365.25 -> Sharpe x1.20
e CAGR x1.45. Le righe per-capitale erano gia' su calendario 365, quindi era falsata solo la
riga di riferimento. Corretti diario, CLAUDE.md e r0725_capcurve.py.
LEZIONE: una serie su giorni di borsa non si passa a metrics() senza to_daily().

Test: 221 pass (+4 in tests/test_gtaa_sleeve.py: pavimento non proporzionale, dipendenza dal
capitale + soglia, senza-banda-e-distruttivo, piano che salta le gambe sotto banda).
Smoke: scripts/live/paper_combo.py gira invariato.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 17:25:06 +00:00
Adriano Dal Pastro 3266f3a09a merge: ondata rendita 2026-07-25 — curva capitale, muro della rendita, asimmetria funded, HyroTrader 2026-07-25 17:18:24 +00:00
Adriano Dal Pastro 6f64845aa9 research(hyro): HyroTrader nello specifico — consistency 40% refutata, DD 6% e' il vincolo
Addendum all'ondata rendita, su richiesta dell'operatore ("e hyrotrader").

CONSISTENCY 40%: ipotesi REFUTATA. Avevo previsto una tagliola (SKH01 ha P&L a scalino,
TP01 fa strappi di trend). Misurato: costo ~0pp a ogni leva e in entrambe le lenti,
perche' il book accumula il 10% in 130-300 giorni -> nessun giorno si avvicina al 40%
del cumulato. Prima di dichiararlo ho dovuto PROVARE che il controllo funziona (un
"costo 0" puo' essere un bug): su un book con profitto concentrato in 1-2 giorni la
regola porta P(pass) da >90% a <5%. Due iterazioni di test prima di avere un
discriminante valido (strappi ripetuti si diluiscono; sim_eval fa block-bootstrap,
non replay).

IL VINCOLO VERO E' IL maxDD 6% STATICO. Config A (book live TP01/SKH01) ha maxDD 9.5%
> 6% = strutturalmente incompatibile a leva piena: intraday a 1.0x sopravvive l'1.4%.
Config B (+XS01) ha maxDD 6.2% e Sharpe 1.13.

RACCOMANDAZIONE: config B a leva funded 0.50x (intraday P(vivo) 71% vs 32% a 0.75x;
E[payout] €7.69 vs €8.66/g — la sopravvivenza COMPONE su piu' anni, un conto bustato
smette di produrre per sempre). EV del biglietto $100k positivo in entrambe le lenti
(+$6.789 close-only, +$1.166 intraday), con ~69% di perdere la fee nella lente
pessimista. Cap $200k/trader => ~€15-30/g max: per €50/g servono piu' firm.

DISCREPANZA DICHIARATA col 24/07 (P(vivo) A@0.75x: 58% loro, 10% mio): il mio wick e' a
estrazione indipendente (piu' severo) e la finestra 2024+ e' quella dove A e' debole.
La direzione concorda (meno leva e' meglio); sul LIVELLO il numero del 24/07 (recon MTM
vero) e' piu' affidabile del mio.

Piu' l'addendum "10k su IB" al diario (analisi gia' committata in ea6743d).

Test: 217 pass (+3: consistency morde/non-morde, DD statico binding).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 17:10:26 +00:00
Adriano Dal Pastro ea6743d6b0 research(rendita): curva capitale->book eseguibile, muro della rendita, asimmetria funded
Ondata "rendita passiva" (2° filone del 2026-07-25). Book live, pesi, config e cron
INVARIATI: questa sessione non tocca nulla del path di esecuzione.

1) DIFETTO DI ESEGUIBILITA' su GTAA01 (5° sleeve del book attivo). gtaa.py modella 2bps
   proporzionali e lo sleeve e' documentato "switch mensile/basso turnover": entrambe false.
   Il vol-target ribilancia OGNI GIORNO su 6 gambe e IB ha un pavimento FISSO per ordine
   (min(max($0.35, $0.0035/az), 1% valore)) = ~$530/anno indipendenti dal capitale.
   A $600: CAGR -3.5% / Sharpe -0.55 (vs +5.5%/0.77 modellato); negativo fino a ~$3k.
   Con banda $50 + cadenza settimanale (plateau, non argmax) torna a Sh 0.52 / CAGR 3.0%.
   -> Sharpe onesto di GTAA01 ~0.55-0.64, non 0.77.
   REGOLA NUOVA: il costo di un venue va modellato nella sua FORMA (fisso vs proporzionale),
   non solo nel livello. Controprova su Deribit (proporzionale): TP01 realistico = modellato
   da ~$500 in su.

2) LA RENDITA NON E' capitale x CAGR. Il muro del 24/07 (EUR 122k) ignorava il rischio di
   sequenza. Prelievo perpetuo (P(cap a 20a >= cap iniziale) >= 90%) sul path live
   de-luckato: 5.98% -> $497k; banda onesta $232k-$497k (il de-luck x0.6 sopra il path live
   rischia di contare due volte la degradazione SKH01). Invariante di lente: la rendita
   perpetua vale ~45-55% del CAGR -> ogni muro calcolato come target/CAGR sbaglia di ~2x.

3) DIVERSIFICARE NON CREA REDDITO a pari nozionale (5.98% -> 6.35%); libera BUDGET DI
   RISCHIO: a iso-rischio (vol 15%) 7.51%/$395k -> 9.25%/$321k. L'ipotesi "piu' capitale ->
   piu' sleeve -> CAGR super-lineare" e' REFUTATA nella forma forte (curva Sharpe piatta da
   $600 a $200k).

4) ASIMMETRIA CAPITALE-PROPRIO vs FUNDED. Su conto funded il capitale e' $100k -> gli sleeve
   STAT-MODE per taglia (XS01) diventano eseguibili, e le regole prop passano sul DRAWDOWN,
   non sul CAGR. Aggiungendo XS01: P(pass) HYRO 44.4->54.7%, funded P(vivo 1a) 18.9->57.6%.

5) LA VIA: i 600 euro come BIGLIETTO. Scala di conti funded, 36 mesi. Problema mai studiato:
   N conti sullo STESSO book bustano INSIEME -> serve sleeve diversi su conti diversi.
   Vince il MISTO, non gli estremi; il book live attuale e' la politica PEGGIORE.
   Verdetto in banda: P(arrivare a 50 EUR/g in 3 anni) 2-21%, P(bruciare i 600) 33-78%
   -> scommessa a coda destra, non una rendita.

6) ADDENDUM "10k su IB": allocazione fra venue. 94% su IB piu' che dimezza il reddito
   (EUR 0.93/g vs 2.16/g). La leva che convertirebbe lo Sharpe in reddito e' chiusa dai
   costi (Reg-T 2x + margine 5.5%) -> vince tutto-Deribit a 1.33x. GTAA01 sui 10k rende
   EUR 0.50/g sopra la liquidita' ferma, pagati con un maxDD del 10%.

Bug catturato in sessione: base di prelievo funded aggiornata giornalmente come HWM mobile
-> payout $230/anno invece di ~$7.000; regole vere = max-loss STATICO dal saldo iniziale.
Test di regressione cablato.

Test: 214 pass (200 preesistenti + 14 nuovi in tests/test_capcurve.py).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 17:05:16 +00:00
Adriano Dal Pastro 7b567c8435 merge: staleness-gate bloccante + report Telegram giornaliero
Protezione di capitale su un fallimento gia' materializzato (acquisto ETH del
2026-07-14 su feed fermo da 6 giorni) e fine del silenzio Telegram a libro flat.
Strategie, pesi e sizing INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 10:05:47 +00:00
Adriano Dal Pastro 71b39c2c86 ops(live): staleness-gate bloccante + report Telegram giornaliero
Presa in carico operativa del conto Deribit (delega dell'utente). Nessun cambio a
strategie, pesi o sizing: il libro resta TP01 0.75 + SKH01 0.25.

1) STALENESS-GATE (protezione di capitale, era un follow-up mai cablato)
Il 2026-07-14 alle 14:00 UTC il book ha COMPRATO ETH $75 con l'ultima barra del
feed certificato ferma al 2026-07-08: feed congelato da 6 giorni (diario
2026-07-15-feed-freeze). I due gate esistenti non potevano vederlo — il conto ERA
online e la posizione ERA leggibile: proteggono dai problemi di CONTO, non da un
feed morto. Il diario raccomandava un alert; qui il gate e' BLOCCANTE, coerente
con gli altri due ("non opero a cieco"), col disaster-SL on-book come rete su
eventuali posizioni gia' aperte.
- config/live.json: max_data_age_days = 2;
- book_execute: _data_age_days() + blocco PRIMA di costruire DeribitTrader
  (nessuna sessione autenticata aperta su dati morti) + alert Telegram con il
  comando di sblocco; data illeggibile => trattata come stantia;
- letto con cfg.get(default): una config priva della chiave ricade sulla soglia
  sicura invece di sollevare KeyError dentro il percorso con soldi veri;
- tests/test_book_staleness_gate.py: 8 casi, incluso il funzionale che riproduce
  la situazione del 14/07 (online + posizione leggibile + ordine pronto) e
  verifica che DeribitTrader NON venga costruito.
- tests/test_book_live.py: i 3 report finti avevano last_data="2026-07-01"
  hardcoded -> ora data fresca calcolata. Quei test riguardano skh_error /
  pos_error / eq_fallback, non la staleness: con la data fissa sarebbero marciti
  al superamento della soglia.

2) REPORT TELEGRAM GIORNALIERO (scripts/live/telegram_daily.py, in cron_daily.sh)
Gli alert esistenti scattano solo su ordine o errore: con il libro flat — stato
normale e corretto col trend giu' — significava silenzio per settimane,
indistinguibile da un sistema morto. Il report dice ogni giorno dove sta il conto,
perche' non opera e quanto manca perche' operi (con la convenzione TP01 corretta:
media dei SEGNI, quindi servono 2 orizzonti su 3, non basta il piu' breve).
Sola lettura: un test verifica che il modulo non possa inviare ordini.

Stato al commit: equity $596.92, flat e a target, disaster-SL -30% verificato
(placed @ $1,308.7 sull'ultima posizione). TP01 0.00 su entrambi: accensione a
BTC $78.680 (+22,7%) / ETH $2.370 (+27,2%).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 10:05:47 +00:00
Adriano Dal Pastro 8a2fede2d5 merge: ondata 2026-07-25 — XSR01 in forward-monitor, 2 refutazioni, fix split feed equity
Filone 'trova nuove strategie'. Book e pesi INVARIATI; il conto live non e' toccato.

- fix DATO sul libro live: split non aggiustati IWM/EFA (2005-06-09) che la
  certificazione non vedeva (soglia maxret>50% vs split 2:1 = esattamente -50%).
  GTAA01 FULL Sh 0.61->0.64, IS 0.49->0.54; OOS e maxDD invariati -> il difetto
  sottostimava lo sleeve, nessuna decisione presa va rivista.
- MAT01 (trend su 18 ETF multi-asset) SCARTATO: a pari volatilita' il minor DD si
  inverte -> de-levering. GTAA6 e' gia' al soffitto d'ampiezza.
- STATARB-EQ (12 coppie ETF, 28.5 anni) SCARTATO: il meccanismo non si trasferisce
  alle azioni; il lordo e' -0.17 e il resto e' turnover.
- STATARB-MULTI: ETH/BTC e' al 58° pctl fra le 50 coppie -> per il gate 27/09
  l'ipotesi 'fortuna di una coppia' e' refutata. Addendum pre-registrato al gate.
- XSR01 CANDIDATO NUOVO in forward-monitor (gate 2026-10-23): cross-sectional
  residual dollar-neutral su 50 alt HL, Sharpe netta 1.82, DSR 0.985, corr ~0 a
  tutti e 5 gli sleeve; fuori dal book per storia corta, tilt-null fallito e
  margine di costo sottile.

Da questo merge il cron giornaliero avvia l'accumulo della finestra forward XSR01.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:50:29 +00:00
Adriano Dal Pastro ec1501caa6 docs: diario ondata 2026-07-25 + CLAUDE.md — XSR01, 2 refutazioni, fix split equity
Diario docs/diary/2026-07-25-mat01-statarb-generalization.md (6 sezioni):
MAT01 scartato col null de-levering a pari volatilita'; STATARB-MULTI
(ETH/BTC non e' un outlier: 58° pctl) e STATARB-EQ (non si trasferisce alle
azioni, il lordo e' -0.17 e il resto e' turnover); lo split non aggiustato di
IWM/EFA con impatto quantificato su GTAA01; l'addendum pre-registrato al gate
del 27/09; e XSR01 col suo scettico e le sue tre debolezze dichiarate.

Registrati anche i due errori di metodo miei corretti in sessione (null statico
con look-ahead; null a fee piene contro un segnale permutato ad alto turnover):
entrambi avrebbero prodotto numeri piu' belli e sbagliati.

CLAUDE.md: nuove voci XSR01 (candidato in monitor, gate 2026-10-23), ondata
2026-07-25, e il difetto SPLIT-NON-AGGIUSTATI con la regola nuova — ogni soglia
di certificazione tarata su un valore tondo va controllata contro il difetto che
genera esattamente quel valore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:48:23 +00:00
Adriano Dal Pastro b8c9430bd7 feat(research): XSR01 "Cross-Sectional Residual" — candidato nuovo in forward-monitor
Primo candidato da molte ondate a superare marginale-ADDS, deflated-Sharpe 0.95,
tre null avversariali e il test di lag, con corr ~0 a TUTTI e 5 gli sleeve attivi.

COS'E'. Il meccanismo congelato di STATARB-RESID (W=45, sgn=+1, residuo OLS
causale su BTC, z-score, tanh, vol-target 20%) applicato ai 50 alt HL, con
posizioni DEMEANATE cross-sezionalmente ogni giorno. Il demeaning annulla
ALGEBRICAMENTE la gamba BTC comune — sum(p_i-p̄)(r_i-r_btc) = sum(p_i-p̄)r_i —
quindi non e' un paniere di coppie ma una strategia cross-sectional
dollar-neutral, e l'ampiezza effettiva passa da 4.5 a 37.4.
NB: non e' nato da un'idea nuova ma dalla DIAGNOSI di un fallimento (l'ampiezza
effettiva 4.5 indicava un fattore comune da togliere).

NUMERI (2.6 anni): Sharpe netta 1.82 (lorda 2.70), maxDD -2.6%, vol 2.3%.
GATE: marginale ADDS (robust_oos + beats_noise_null + non-hedge +
has_insample_edge); deflated-Sharpe 0.985 PASS; corr TP01 0.060 / XS01 -0.019 /
VRP01 -0.001 / SKH01 0.001 / GTAA01 0.071; book a w=15% HOLD 2.36 -> 2.51,
DD invariato.
SCETTICO (r0725_statarb_demean_skeptic.py): 3 null A FEE-NEUTRALE (permutazione
cross-sezionale / casuale / temporale a blocchi) centrati a ~0.01, candidato
lordo 2.70 sopra il MASSIMO di 300 estrazioni (p<0.004); lag 1.82/1.19/0.81/0.51
a +0/1/2/3g = decadimento dolce di segnale lento, non firma di look-ahead; non
ridondante con XS-momentum semplice (corr 0.17-0.29).
Nota di metodo: i null vanno confrontati A FEE ZERO — permutare un segnale ne fa
esplodere il turnover, quindi a fee piene il null perderebbe per COSTO invece che
per assenza di informazione (p-value trionfale e falso).

NON NEL BOOK, 3 motivi dichiarati: (a) storia 2.6a monoregime e CRESCENTE
(Sh 2024 1.03 / 2025 1.98 / 2026 3.11) -> edge recente; (b) weights_tilt_null
FALLITO (gate_pass=False a 10% e 15%); (c) margine di costo sottile — 1.82 a
0.05%/gamba, 0.93 a 0.10%, NEGATIVA a 0.20%, turnover 38.5% del lordo/g su 50 alt
anche illiquidi con slippage NON modellato (rischio #1).

ESEGUIBILITA': ticket/gamba $1.73 a $600 (sotto min-order $5 -> STAT-MODE oggi),
$5.76 a $2000, $14.41 a $5000 -> diventa reale a ~$5k, non ai ~$20k di XS01.

CABLATO: scripts/live/paper_xsr.py (config CONGELATA, 3 libri MODELED $2000 /
REAL $600 / REAL $5000 con min-order per gamba, stato append-only) in
cron_daily.sh; gate PRE-REGISTRATO a forward-day 0 (r0725_xsr_deploy_gate.py):
decisione 2026-10-23, deploy solo se Sharpe>=1.0 E haircut di eseguibilita' a
$5000 <=40% (se sfonda -> RITIRO a prescindere dallo Sharpe).
tests/test_paper_xsr.py: 7 casi che bloccano config, dollar-neutralita',
causalita' dello step, min-order e la trappola dei timestamp tz-aware
(astype int64 -> epoche 1970, gemella di quella dell'ondata 2026-07-01).

Book e pesi INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:48:11 +00:00
Adriano Dal Pastro 9af6693e4f research: MAT01 e generalizzazione STATARB — 2 refutazioni pulite + addendum al gate 27/09
MAT01 (r0725_mat01_multiasset_trend.py, r0725_mat01b_regime.py) — SCARTATO.
Allargare il trend difensivo da 6 a 18 ETF multi-asset-class a meccanismo GTAA
CONGELATO: MAT18 perde 3/4 finestre disgiunte e, a PARI VOLATILITA', il suo
minor drawdown si INVERTE (-20.6% vs -15.4%) -> era solo de-levering. Terza
occorrenza del null de-levering dopo VRP-DD e TP01xDVOL. Corr->crypto invariata
(0.110 vs 0.116): zero guadagno di diversificazione.
Risultato positivo conservato: la curva d'ampiezza e' monotona (mediana OOS 0.44
a k=1 -> 0.80 a k=18, DD -16.0% -> -6.9%, satura a k~10-12), ma GTAA6 sta gia' al
95° pctl dei 6-subset casuali — e non e' cherry-picked (contiene TLT, il peggiore
dei 18) -> niente piu' ampiezza da raccogliere su quello sleeve.

STATARB-MULTI (r0725_statarb_multi.py) — il meccanismo congelato (W=45, sgn=+1)
su tutte le 50 coppie alt/BTC, out-of-pair-sample. REGGE: 82% Sharpe>0, 0/50
degeneri (mono 53%), perm p<0.05 nel 18% (atteso 5%). E ETH/BTC e' al rango
22/50 (58° pctl): la coppia scopritrice NON e' un outlier -> per il gate 27/09
l'ipotesi "fortuna di una coppia" e' refutata. NON e' uno sleeve: ampiezza
effettiva ~4.5 (corr media 0.204, gamba BTC condivisa), paniere IC95%
[-0.12, 1.72] con t 1.31.
Errore di metodo corretto in-sessione: il primo null statico usava
sign(mean(segnale)) sull'intero campione = look-ahead; rifatto causale + a priori.

STATARB-EQ (r0725_statarb_eq.py) — SCARTATO. Stesso meccanismo su 12 coppie ETF
a priori, 28.5 anni, ampiezza effettiva 9.9: paniere Sharpe -1.00 (t -5.33),
negativo in 4/4 decadi. Ma la lettura sta nel LORDO (-0.17, non -1.00): due terzi
sono drag di turnover -> non esiste strategia specchio. Il segno lordo dice che
sulle azioni il residuo REVERTE mentre sul crypto CONTINUA: meccanismo
plausibilmente crypto-specifico. Il gate 27/09 non puo' appoggiarsi
all'argomento "fenomeno universale".

r0724_statarb_deploy_gate.py: addendum PRE-REGISTRATO oggi (forward-day 26 di 90,
64 giorni prima della decisione) — riporta anche lo Sharpe della statica
"sempre short ETH vs BTC" a pari vol-target sulla stessa finestra. Le soglie del
2026-07-24 NON sono toccate: e' diagnostica non binding. Lettura odierna
(26 barre): STATARB +5.70 vs benchmark -4.98, posizione corrente LONG lo spread
= opposta alla statica.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:47:47 +00:00
Adriano Dal Pastro 741bbc2c09 fix(data): split non aggiustati nel feed equity — difetto sul libro live, riparato alla fonte
IWM ed EFA avevano uno split NON aggiustato il 2005-06-09 (IWM 2:1 = -49.5%,
EFA 3:1 = -66.5%): IB ADJUSTED_LAST non li aveva aggiustati.

La certificazione non li vedeva per un punto cieco STRUTTURALE: l'unica guardia
sui salti era `maxret > 50% -> SPIKE?` e uno split 2:1 fa esattamente -50%, cioe'
cade sul filo della soglia (IWM passava a 49.5% con status OK).

IWM e' una delle 6 gambe di GTAA01, sleeve in PRODUZIONE. Impatto misurato:
GTAA6 FULL Sharpe 0.61 -> 0.64, IS (<2015) 0.49 -> 0.54; OOS 2015+ e maxDD
INVARIATI (l'artefatto e' nel 2005, fuori hold-out) -> il difetto SOTTOSTIMAVA
lo sleeve: nessuna decisione presa va rivista.

Discriminante split-vs-crollo: NON il rapporto (SLV 2026-01-30 ha rapporto
1.3994, a 4bps da 1.4, ma e' un crollo vero: GLD -10.3% lo stesso giorno) ma il
RANGE INTRADAY — lo split apre gia' al nuovo livello con range normale (IWM:
open 47.00, range 1.7%), il crollo si muove DENTRO la barra (SLV: range 33%).

- src/data/eq_splits.py: detect_unadjusted_splits() a 3 condizioni congiunte
  (|ret|>20% AND rapporto ~ fattore comune AND range intraday <5%) + repair_splits()
  con split multipli componibili;
- riparazione in LETTURA in src/portfolio/gtaa.py::_close (produzione) e
  scripts/research/eqlib.py::load_eq (ricerca);
- fetch_ib_equities.certify(): nuovo status SPLIT-NON-AGG + elenco split rilevati;
- tests/test_eq_splits.py: 8 casi, inclusi il falso positivo SLV e un crollo -50%
  esatto con range grande.

Regola nuova: ogni soglia di certificazione tarata su un valore tondo va
controllata contro il difetto che genera esattamente quel valore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:47:25 +00:00
Adriano Dal Pastro d606cd3548 docs(diary): snapshot stato paper book a chiusura sessione — book +0,94%/35g risk-off, STATARB +4,4% (gate 27/09), promemoria trigger attivi
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 23:37:03 +00:00
Adriano Dal Pastro 05d069f336 chore(cron): cabla i monitor read-only decisi alla merge — cc01_regime_watch + snapshot stablecoin in cron_daily; snapshot opzioni 0DTE 2x/g (07:55+08:05 UTC)
Crontab utente aggiornato (2 righe nuove per cron_opt_snapshot.sh). Tutti read-only:
nessun ordine, book live invariato. Smoke-test OK (0DTE: 160 righe; CC01: QUIET
BTC +8.4%/ETH +7.5% ann. 30g).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 23:19:47 +00:00
Adriano Dal Pastro 636be89b2b research(live): follow-up SKH chiuso — peso 0.25 e cron orario CONFERMATI de-luckati sul path live; + snapshot point-in-time stablecoin (sblocco WATCH a 12 mesi)
- r0724_skh_live_weight.py: sweep w 0-0.50 sul path hourly x 23 offset; w*=0.25
  (argmax mediana-IS di banda, plateau 0.20-0.30); w=0.30 passa weights_tilt_null
  solo a off0 (ancora fortunata), fallisce a offset mediano -> INVARIATO.
  Cadenza 230m = rumore (+0.01/+0.02 Sh med); il degrado live e' il fill-al-livello
  (~+0.35 Sh) che nessun cron recupera. Book e cron INVARIATI.
- r0724_stable_snapshot.py: cattura giornaliera point-in-time supply stablecoin
  (DefiLlama, tokenless, idempotente) -> data/external/stable_snapshots/ (gitignored).
  Criterio di rivisita del lead STABLE: >=12 mesi di serie propria.
- CLAUDE.md: bullet SKH01 aggiornato (follow-up chiuso).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 23:08:23 +00:00
Adriano Dal Pastro 00996640fb research(cases): 3 agenti live sui 3 case — PM<->Deribit SKIP (gap=spec non alpha), HLP SKIP/WATCH (carry ex-evento 0.2%/a), 0DTE capture avviata
PM: 34 binarie riconciliate vs daily options; il gap 11pp si decompone in basis USDT
(+4-5pp ATM), tempo 8h (-+5pp) e replica su book morti; residuo tail 2-3pp sotto costi;
trade coperto reale: lock /bin/bash.1-5, P(conflitto gambe) 2-22%, margine SM domina -> SKIP.
HLP: serie daily trovata (wHLP): Sharpe 0.69 non ~2, +12% 2026 = 1 evento, ex-evento
+0.2%/a, coda JELLY = inventario ereditato troncato da voto discrezionale, Kelly f*=0
-> SKIP/WATCH con trigger meccanici. 0DTE: fee cap binding = drag 2-3x weekly, IV<RV
al front stanotte; snapshot pipeline scritta e primo capture su disco; decisione
pre-registrata a 90g di serie. Book INVARIATO.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 22:46:59 +00:00
Adriano Dal Pastro 4c1961d77b research(hunt-web): sintesi caccia strategie via web — 10 famiglie nuove 0 slot; lead-lag JEDC = reversal travestito (rank-corr -1.000), MAX DSR 0.41
3 agenti web (~50 fonti) + 3 ondate empiriche in una notte. Convergenza indipendente
ricerca<->empirica: il factor zoo crypto si riduce a liquidity/momentum (gia' nel book).
XS su HL: lead-lag all-others e' matematicamente l'inverso del momentum proprio (check
di degenerazione da riusare); MAX segno instabile L7<->L30. HLP probe: crash-long reale
(corr book -0.19, +10.4% nel crash ott-25) ma decay 79->12%/anno + coda JELLY fuori
serie -> ALLOCATION-WATCH. Pista nuova prossima ondata: Polymarket<->Deribit (gap 11pp,
arXiv 2606.19517, spec-mismatch da riconciliare prima di credere). Book INVARIATO.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 22:24:57 +00:00
Adriano Dal Pastro b65f067f69 research(premium): ondata premi cross-venue auto-calcolati — CBPREM morto, KIMCHI d30 ucciso dallo scettico (spike+lag)
CBPREM (Coinbase vs feed cert, 2015->): HEDGE, hold -0.46. KIMCHI (Upbit/ECB, 2017->,
ancora 00:00 UTC verificata): EARNS_SLOT=True al marginal scorer (ADDS, robust_oos,
uplift + ogni anno) ma DSR 0.891 -> scettico obbligatorio: niente plateau
(d15/30/45/60 = 0.44/1.07/0.51/0.24) e lag +1g azzera (hold 0.74->0.14) = parameter
luck. Lezione codificata: EARNS_SLOT con DSR<0.95 -> sempre plateau+lag skeptic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 22:23:16 +00:00
Adriano Dal Pastro 2320fa9cec research(onchain): prima ondata on-chain/sentiment — 0/6 slot; l'on-chain tradabile e' prezzo travestito (corr TP01 0.5-0.8)
6 famiglie mai testate (NET Liu-Tsyvinski, MVRV, exchange-supply, hash ribbons, F&G,
stablecoin-supply-growth) su segnali CoinMetrics community + alternative.me + DefiLlama,
ritorni SOLO dal feed certificato, study_family_honest su 32 celle. EXS hold-out -0.58
(claim outflow=bullish decaduto), HASH=HEDGE, FNG corr 0.82 (trend travestito), MVRV
DILUTES. Unico lead: STABLE thr=10% (DSR 0.998, ADDS persistente) ma robust_oos=False
+ caveat VINTAGE (storia DefiLlama ricostruita) -> WATCH, no paper. Regola nuova:
classificare il rischio-vintage di ogni fonte esterna prima del backtest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 22:15:05 +00:00
Adriano Dal Pastro 5c48a8322a research(goal50): MC prop INTRADAY wick-aware — leva eval 1.5x refutata, funded ottimo a 0.75x, P(perdere fee) ~56%
Recon MTM 1h del book Deribit (TP01 pesi daily + SKH01 230m exit-al-livello SL-first,
fee incluse). Validata: leg TP corr 0.9997 / log-total +0.833 vs 0.827; leg SKH +0.548
vs +0.513; Sharpe MTM 1.62 vs 1.77 sleeve (delta = attribuzione a scalino di SKH).
I wick tagliano 6-37pp di P(pass): de-luck 1.0x HYRO 44.7% / FTMO 59.9% / Breakout 26.6%
(declassata). Funded sweep: leva ottima 0.75x (HYRO P(vivo) 58% vs 20.5% a 1x), atteso
~EUR 14.5/g a 100k. EV biglietto resta positivo ma sottile (de-luck +491/+1048/+2197 USD).
Bug tz-naive/aware nel reindex catturato dalla sanity (TP01 spariva, corr 0.43).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 21:55:23 +00:00
Adriano Dal Pastro 2e7178487d research(goal50): R2 prop-firm + roadmap finale — 50eur/g in mesi NON esiste via legale; stack onesto 18-36 mesi
- MC aggiornato alle regole VERE (HYRO 10/6/4, BREAKOUT 10/6/3, FTMO 10/10/5):
  de-luck P(pass) 55-68% a leva 1-1.5x, mediana 68-137g; funded 100k de-luck
  P(vivo) 69%, atteso blended onesto 250-450 eur/MESE (attriti fuori-MC: carry,
  recycling bust, controparte non regolata, cap industria 200k).
- Roadmap: prop = unico canale che cambia scala in mesi (8-15 eur/g);
  stack 24 mesi top-decile 30-60 eur/g, mediana 10-25; fisco 33% = muro x1.5.
- Book live INVARIATO.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 21:02:45 +00:00
Adriano Dal Pastro acfba63420 fix(test): test_paper_advance bug latente — factor divideva via (1+tail[0]), passava solo con combo[-500]==0
Pre-esistente su main (fallisce anche li'), emerso con l'avanzare dei dati.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 20:58:52 +00:00
Adriano Dal Pastro 870428e559 docs(goal50): diario R3 — monetizzazione track record: 0 in mesi, stack legale 18-36 mesi (Darwinex/eToro/OKX EU); family&friends remunerato = art.166 TUF
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 20:57:48 +00:00
Adriano Dal Pastro 7ebb1b8c37 feat(goal50): CC01 regime watch (funding 30g HL, trigger 10/15% ann.) + diario R1 yield/basis
R1 (web): carry al fondo del ciclo (BTC 0-4%, ETH negativo), Aave 4-5% = pavimento,
0k -> 2.5-4 eur/g; MiCA lascia a IT esattamente Deribit+HL; fisco 33% dal 2026
(muro capitale x1.5). Watcher read-only, oggi: BTC +8.4% / ETH +7.4% 30g = QUIET.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 20:57:13 +00:00
Adriano Dal Pastro ddc980a097 research(goal50): matematica onesta del target 50eur/g + gate deploy pre-registrato statarb
- r0724_goal50_math: muro capitale (73-228k), leva=rovina, Monte Carlo prop-firm
  sui ritorni reali del book (P(pass) 56-86%, funded 100k mediana 31-42eur/g),
  vault TVL 1-2M. Unica via 'da mesi' = moltiplicare nozionale gestito.
- r0724_statarb_deploy_gate: regola di deploy PRE-REGISTRATA a fwd-day 25
  (decisione 2026-09-27, Sh>=0.5, haircut<0.5pp, 1 proroga max) — anti
  selection-on-forward.
- diario roadmap (sezioni web-research da completare).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 20:55:23 +00:00
Adriano Dal Pastro 7534b08be0 research(weekend): ondata ven->lun SCARTATA 4/4 — famiglia calendario SATURA; weekend = 38% del gross TP01 (mai de-esporre)
4 agenti (drift/cond/intra/overlay), 375 trial: il drift weekend e' beta B&H,
i gate condizionali sono TP01 re-timed, l'intraday weekend e' moneta simmetrica
(CME-gap morto anche lordo). Fatto strutturale: TP01-weekend-flat = danno certo
(dSh -0.46, P=1.000) -> ogni proposta "risk-off weekend" parte REFUTED salvo
null de-levering. Chiusa la famiglia calendario su BTC/ETH (SEA+expiry+event-clock
+weekend). Book/pesi INVARIATI. Diario 2026-07-17-weekend-window.md.

gitignore: + data/live/ (log esecuzioni book live, stato runtime del conto reale)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 15:03:44 +00:00
Adriano Dal Pastro 67f7b89e4c chore(live): ritira paper_trend inerte -> Old/ — sostituito da paper_portfolio
Il paper trader standalone TP01 (paper_trend.py) era inerte dal 2026-06-19
(n_bars=0), non in cron, e sostituito da paper_portfolio (TP01+XS01, gira ogni
giorno). Archiviato in Old/scripts/live/ e stato congelato rimosso.

Book live INTATTO: shadow.py legge PAPER_STATE con guardia .exists() -> degrada
a FALLBACK_CAPITAL=2000 (identico allo stato congelato) e paper_pos=None. Dry-run
di book_execute identico prima/dopo (conto online, HOLD su BTC/ETH).

- git mv scripts/live/paper_trend.py -> Old/scripts/live/paper_trend.py
- rm data/paper_trend/ (state inerte, gitignored)
- CLAUDE.md: 3 riferimenti -> paper_portfolio + nota di ritiro
- live_trend.py + shadow.py: hint/commento fallback legacy aggiornati

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 15:42:29 +00:00
Adriano Dal Pastro 9fa3e6a0be fix(feed): backup rebuild non-fatale — copy2→copyfile, il .bak non abortisce piu' il feed live
Il feed BTC/ETH del book era congelato 7 giorni (2026-07-08 -> 07-15): rebuild_history.py
usava shutil.copy2 per il .prebuild.bak; copy2=copyfile+copystat e copystat (os.utime/chmod
con valori espliciti) richiede la PROPRIETA' del file, non basta il group-write. I .bak sono
root:adriano, il cron gira come adriano -> EPERM ogni notte, abortendo PRIMA della scrittura
del feed (data/raw/*.parquet fermo a Jul 8). Il book ha ri-girato ogni ora su barra vecchia
(TP01 1d non ri-valutato); nessuna perdita (segnale fresco == tenuto) ma cieco 7g.

Fix: backup best-effort = shutil.copyfile (solo contenuto, no copystat) in try/except OSError.
Un .bak difensivo non deve mai poter bloccare la scrittura del feed live.

Verificato: rebuild rigirato -> feed a 2026-07-15, audit cross-venue BTC 1.9/ETH 2.0 bps,
file ora adriano:adriano (auto-sana), book dry-run legge ultima barra 2026-07-15 -> HOLD.

Diario: docs/diary/2026-07-15-feed-freeze-rebuild-copystat.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 18:37:42 +00:00
Adriano Dal Pastro b691f48f43 docs(diary): incident 2026-07-09 — "BOOK LIVE conto offline" = cert Traefik di default
Traefik auto-upgrade (latest+Watchtower -> 3.7.7) ha scartato il resolver ACME
per acme.json a 660 (3.x pretende 600) -> cert self-signed su tutto il VPS ->
DeribitRead SSLError -> book online=False. Zero trade persi (target flat, gate
di sicurezza OK). Fix: chmod 600 acme.json + restart; pin traefik:3.7 nel compose.
Diario con diagnosi, verifica end-to-end e runbook.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 20:09:41 +00:00
Adriano Dal Pastro 822aa1307e research(crt): video-claim "CRT top-down 74% win rate" SCARTATO — il 74% e' un knob, non un edge
Meccanizzato e falsificato il claim ICT/SMC top-down (H1 setup CRT -> M15/M5
conferma -> entry, uscita parziale+BE+runner) su BTC/ETH certificati.

- Setup H1 CRT gia' triplo-refutato (onda 2026-07-02); qui testato l'angolo nuovo:
  la gestione d'uscita e il "74% WR".
- WR reale 30-37% a RR 1.5-2, SOTTO il null gambler's-ruin 40% -> il ritest tocca
  il target meno di una moneta (conferma "il ritest e' informazione negativa").
- Il 74% si fabbrica avvicinando il target: sweep rr1 0.5->2.0 = WR sale, expectancy
  R INVARIANTE e negativa (-1.2..-3.3R netto). DSR 0.000; a fee 0 ancora negativa
  -> non morte-per-fee, l'edge lordo non c'e'.
- Non eseguibile pulito a $600 (3-4 ordini/trade, alcuni sub-min-order).
- Regola candidata: convertire ogni claim "WR X%" da schema parziale+BE in
  expectancy R netto fee (WR ~= 1/(1+rr1), non un merito).

Nessuna modifica a src/config/live/tests. Book e pesi INVARIATI.
Diario: docs/diary/2026-07-07-crt-topdown-74winrate.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 06:02:38 +00:00
Adriano Dal Pastro cf7de40dc0 feat(live): cap/asset dinamico = equity/2 — operazionalizza la decisione frontier (inerte a $600)
Il cap notional per-asset non e' piu' fisso a $300: con max_notional_per_asset_frac
in config diventa equity/2, cosi' cresce col capitale e un deposito futuro non resta
strozzato (frontiera 2026-07-03). Guardrail: dinamico SOLO con equity reale fidata;
su fallback/offline si torna al cap fisso (protezione downside quando E e' ignota).
Live dry-run: cap $299 a equity $598 -> inerte oggi. Suite 172 passed (+4 test).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 09:42:13 +00:00
Adriano Dal Pastro eef200cf14 research(frontier): frontiera onesta del book — il 6% e' un miraggio di regime, gira gia' alla vol nativa
Misura (non ricerca segnali) della frontiera CAGR/DD/P-rovina vs
target-vol, pesata per confidenza per-sleeve, a 2k/5k. 7 agenti (3
filoni + refuter fat-tail + scettico), sanity bit-exact dei due book.

Reframe decisivo: il "6% attuale" NON e' un target, e' la vol realizzata
in risk-off; a lambda=1 il book LIVE 2-sleeve gira gia' a ~11% vol/9.4%
DD -> "saltare a 10%" e' assumere non-risk-off, non aggiungere leva.

- Target-vol fidato book LIVE (TP01+SKH01, unico eseguibile <20k):
  ~10% (banda 8-11%, lambda ~0.9). Scale-invariante: stesso % a 2k/5k.
- P(rovina-50%) e' la metrica SBAGLIATA (slack a 22%); il vincolo che
  morde e' P(DD>30%), super-lineare. Muro onesto ~12% (gap-through SKH
  reale non nei rendimenti modellati; 2-sleeve 4x crash-sensibile).
- Vol differenziata-per-confidenza REFUTATA: taglia la diversificazione;
  la bassa fiducia va nel DE-MEAN (haircut media), non nella leva.
- Reward onesto (HOLD<<FULL): ~EUR 0.3-0.7/g@2k, 0.8-1.8/g@5k; warm-up
  vs 6% risk-off = ~+EUR 0.2/g@2k. EUR 50/g resta ~130k (capitale+tempo).
- UNICA azione config (proposta, NON applicata): cap $300 -> equity/2,
  altrimenti a 5k il cap raffredda paradossalmente il book sotto il punto
  fidato (6% vol ceiling).

config/live.json NON toccato. Book invariato. 168 test verdi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:43:59 +00:00
Adriano Dal Pastro 116abf5203 docs(diary): snapshot stato completo del progetto (2026-07-03)
Foto d'insieme dopo il blocco di ricerca 1-3 luglio: book live
(TP01+SKH01 flat, $598), portafoglio research 5-sleeve (de-luckato
HOLD ~2.0), anchor-audit completo 4/4, edge morti da non ri-testare,
~10 gate anti-illusione codificati, mappa capital-scaling 2-5k,
aperti/prossimi passi. Punto di riferimento unico dello stato.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:16:17 +00:00
Adriano Dal Pastro 26f8d27a61 research(wave-0703): migliora+proteggi VRP01 — 7 filoni, 0 miglioramenti, anchor-audit VRP01 chiuso (4/4 sleeve)
Goal: migliorare la strategia short-vol (famiglia Albimarini/VRP01) e
proteggerla dai DD. Workflow 26 agenti (7 filoni + 2 lenti avversariali
+ scettico incrociato). Esito: NON migliorabile; la protezione DD si
compra SOLO con la size.

- Griglia 288 strutture: nessuna batte VRP01 (DSR 0.000; meta' griglia
  = 3a occorrenza "0-perdite/Sharpe implausibile" dopo CC01/ALB-A).
- 4 overlay DD (exit-spike/SL-MTM/ala-coda/cooldown): 4/4 REFUTED dal
  null de-levering — la protezione crash vive gia' nel gate IV-rank.
- Gate nuovi: 4o fallimento su 4 (l'alpha e' il binario IV-rank>0.30).
- Sizing: 12% deploy ~ 0.27 Kelly onesto (anti-rovina); disambiguazione
  unita' obbligatoria vs 12% peso book (0.014 Kelly, fattore 19x).
- Gate term-structure VIX/VXV su SPX (dSh +0.90, DSR 0.992) = confound
  di modello al 100% -> nuova regola: riprezzare term-structure-consistent
  prima di credere a un gate vol su strutture BS-flat.
- ANCHOR-AUDIT VRP01 CHIUSO: primo sleeve SENZA luck (fase canonica =
  peggiore delle 7 -> numeri di ammissione conservativi). Audit anchor
  ora completo su 4/4 sleeve ancorati.

Book/pesi INVARIATI. Nessun nuovo sleeve. 168 test verdi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:05:19 +00:00
Adriano Dal Pastro 76120b59c2 research(wave-0702bis): ondata video-claims — Elliott 3/3 e Albimarini 2/2 scartati, mappa capital scaling 2-5k
Sei agenti, nessun sopravvissuto:
- ELL-A range-cycle: rumore (0/24 Bonferroni; nessuna cella weekly regge
  a tutte le 7 ancore). Lezione pandas: resample("7D", origin) IGNORA
  origin -> usare "168h" per le bande d'ancora weekly.
- ELL-B Fibonacci: l'edge apparente e' la POSIZIONE dei livelli, non i
  numeri (null location-matched: pctl 0.39-0.68); confluenza FAIL 4/4.
- ELL-C canale: Donchian travestito (non batte il Donchian equivalente,
  DSR 0.685, IS 1.40 -> HOLD -0.87; target 1.618 = caso; anchor-luck 4h).
- ALB-A diagonale: il condor stessa-scadenza la batte a ogni f; senza
  gate IV-rank tutte le strutture perdono (3a conferma: l'alpha del VRP
  e' il gate); fee-negativa su Deribit a qualsiasi size; 2o caso
  "0-perdite = Sharpe implausibile" dopo CC01.
- ALB-B claims: 82%/PF 5.16/"420%" consistente con zero skill (P=20-45%,
  78.6% delle finestre 6-mesi lo produce); replay con code reali =
  rovina 1998/2002/2020; la diagonale passa il 12-40% della perdita naked.
- Capital scaling 600->2-5k: unico vincolo binding = cap $300/asset
  (a 5k book al 49% del target) -> AL DEPOSITO alzare a equity/2;
  min_order $5 lasciare; XS01 ~20k confermata; aspettativa onesta
  de-luckata 2k ~EUR 0.6-0.8/g, 5k ~EUR 1.4-2/g.

Nessun nuovo sleeve, book live invariato. 168 test verdi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 23:31:38 +00:00
Adriano Dal Pastro a74cc69583 research(anchor-audit): timing-luck confermato su XS01 e SKH01 — 3/3 sleeve ancorati, book de-luckato HOLD ~2.0
Chiude il pendente dell'ondata timing 2026-07-02. Due audit indipendenti
(sanity replica bit-exact, ancore a priori, zero tuning per-fase, bootstrap):

- XS01 (10 fasi ciclo H=10): fortuna nel DD (15° pctl: 10.8% vs 15.5% tipico,
  29% peggiore) e FULL (85°), non nell'hold-out (65°); P(spike)~0.91-0.94.
  Lens onesta = ensemble di fase FULL 1.25 / HOLD 1.31 / DD 11%. Ammissione
  @15% regge, i numeri 1.50/1.71/11% no.
- SKH01 (23 offset griglia 230m/690m): canonico = 93-98° pctl di OGNI metrica,
  minHold/blend/book-HOLD = massimo dei 23; il gate DD<30% (criterio di
  selezione V2-DD) fallisce in 15/23 offset. Regge: uplift blend positivo a
  tutte le 23 fasi (min +0.18) + corr ~0.08 -> ADDS ridimensionato. Path live
  reale (cron orario + exit software): book FULL 1.46->1.19 / HOLD 1.64->1.15 /
  DD 18->25%, gap-through-stop nei crash (sl2% -> -11/-23%).
- Book 5-sleeve: HOLD 2.46 eredita ~+0.10/+0.17/+0.5 di fortuna d'ancora
  (TP01/XS01/SKH01) -> stima de-luckata HOLD ~1.9-2.1, FULL ~2.0-2.2, DD ~6%.

Nessun cambio operativo (pesi/book live invariati; ogni cambio passa
weights_tilt_null). Narrativa aggiornata (CLAUDE.md, docstring skyhook).
Follow-up: anchor_luck_band() in altlib, cadenza 230m, peso SKH live.
168 test verdi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:34:35 +00:00
Adriano Dal Pastro 73d74c5e53 research(wave-0702): ondata timing + CRT — 8 filoni, 0 nuovi sleeve, finding anchor timing-luck TP01
Goal: "altre strategie su Deribit con timing differenti". 8 filoni multi-agente + scettico:
- event-clock bars, expiry calendar Deribit, clock lenti/bande, regime-speed: SCARTATI
- CRT (Candle Range Theory) base/multi-TF/contesto: SCARTATA 3/3 (DSR~0, ritest =
  informazione negativa; sottoprodotto: FOLLOW>FADE sui livelli prior-day ogni anno,
  conferma il lead prevday)
- FINDING (confermato da scettico indipendente): hold-out 0.31 di TP01 = migliore delle
  24 ancore orarie (mediana 0.04, banda [-0.13,+0.30]) -> narrativa corretta in CLAUDE.md
  e docstring: l'hold-out non risolve l'edge di ritorno, regge il taglio DD a ogni ancora.
  Tranching K=2/4 = solo varianza della stima, no deploy a $600. Audit d'ancora pendente
  su XS01/SKH01. Book live e portafoglio INVARIATI. Test 168/168.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:12:22 +00:00
Adriano Dal Pastro e6657fcb16 feat(portfolio): GTAA01 promosso a 5° sleeve @20% — FULL 2.12→2.24, HOLD 2.21→2.46, DD 7.8→6.2%
Il diversificatore strutturale validato il 2026-06-22 (trend difensivo equity
6-ETF su IB, 30y storia, OOS 2015+ indipendente dall'hold-out crypto, corr al
book ~+0.10) era rimasto in paper_combo senza mai essere valutato come sleeve.
Valutazione onesta (r0701_gtaa_5th_sleeve): uplift positivo in-sample e su
TUTTE le finestre disgiunte (+0.05/+0.19/+0.25), multi-cut +0.21..+0.25,
plateau monotono w10-30% — passa dove EW-STR era morto. Ingresso @20% (IS-best
30%, scelta strutturale dichiarata). Convenzioni: weekend equity=0 (capitale
IB fermo, non riciclato), attivazione all'era book 2019-03. Il book live
Deribit (TP01+SKH01) NON cambia. Suite 168/168.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-01 23:31:38 +00:00
Adriano Dal Pastro 491411ac77 research(wave-0701): 6 filoni multi-agente — 0 nuovi sleeve, pesi confermati, gate weights_tilt_null
Ondata onesta su angoli non coperti: funding-TS (chiude il filone funding su 3
lati), breadth alt (non-ridondante ma DSR 0.43, rivisitabile con storia),
XS-residmom (REDUNDANT), pesi+guardia-DD (EW-STR refutato dallo scettico come
selezione-sull'hold-out di 2° ordine, firma best-of-15), VRP-refine (filone
esaurito), stagionalità-XS (morta allo step statistico).

Lezione codificata: weights_tilt_null + combine_outer in src/portfolio
(ogni cambio-pesi vs null di tilt casuali cap-respecting + delta in-sample>=0);
5 test nuovi, suite 165/165.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-01 23:21:59 +00:00
Adriano Dal Pastro ccf5e38101 feat(dashboard): banner alert operativi del book live (SKH/posizione/equity)
Il dashboard non mostrava nessuno dei tre segnali di health introdotti nei
commit 31369b3 (skh_error) e 5670469 (pos_error/eq_fallback): finivano solo su
Telegram + log cron, invisibili a chi guarda il monitor. pos_error/eq_fallback
erano gia' in shadow_report (usato dal dashboard) ma ignorati dal template;
skh_error non era nemmeno recuperato (il dashboard usa shadow_report, non
book_report).

Fix:
- _alerts_banner(): helper puro (verde "nessun alert" se pulito, rosso con una
  riga per errore) che rispecchia i tre alert di book_execute.
- build(): raccoglie pos_error/eq_fallback dallo shadow gia' fetchato + skh_error
  da book_report(offline=True) (feed certificato, nessuna rete extra).
- html(): renderizza il banner in cima alla sezione ① LIVE.
- tests/test_dashboard.py: +4 (verde, 3 alert, parziale, chiave-ignota).

Suite 160/160. Render end-to-end verde (conto sano $598.06 flat). Chiude la
copertura: i 3 pattern di errore silenzioso ora visibili su log + Telegram + dashboard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:47:35 +00:00
Adriano Dal Pastro 567046953d fix(book): gate fail-safe posizione + diagnostica equity — niente errori silenziosi nel path live
Terza+quarta chiusura del pattern "eccezione ingoiata -> stato safe silenzioso"
in src/live, dopo skh_error (31369b3). Emerse durante la verifica del gate SKH01.

Opzione A (gate fail-safe posizione):
- shadow._positions: se la read della posizione reale Deribit lancia, assume flat
  MA ora ritorna un pos_error esplicito (prima solo una note mai propagata).
- Propagato shadow_report -> book_report -> book_execute: se ONLINE ma posizione
  IGNOTA, l'esecutore NON opera a cieco (return + alert), come gia' per 'online'.

Opzione B (diagnostica equity, no halt):
- shadow._equity/shadow_report: se ONLINE ma equity reale non leggibile, il book
  ripiega su paper_cap (~$2000) invece del conto reale (~$598) -> sovradimensiona
  ~33%, ma l'hard-cap $300/asset limita il downside. Nuovo flag eq_fallback ->
  book_execute stampa warning + alert Telegram MA prosegue (niente gate: la scelta
  e' solo diagnostica, l'hard-cap gia' protegge).

Test: +8 (4 gate A, 4 diagnostica B). Suite 156/156. Path live pulito
(skh_error/pos_error/eq_fallback = None). Diario 2026-07-01-book-live-error-surfacing.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:39:59 +00:00
Adriano Dal Pastro 31369b358c fix(book): esponi skh_error nel book live — niente flat SKH silenzioso
book_report scriveva skh_error in un dict locale MAI incluso nel return ->
r.get("skh_error") era sempre None. E book_execute non lo leggeva comunque.
Risultato: se il feed SKH (fresh_5m) fallisse, il book forzava SKH a flat in
silenzio, indistinguibile da un flat legittimo -> entry SKH reale mancato,
nessun alert.

Fix:
- src/live/book.py: skh_error come variabile esplicita, esposta nel dict di
  ritorno (None normalmente). Il fail-safe (SKH->flat, TP01 indipendente sul
  suo feed certificato) resta invariato.
- scripts/live/book_execute.py: emette la riga di log + alert Telegram quando
  skh_error e' presente.
- tests: book_report cattura-e-flagga l'errore; book_execute lo fa emergere
  (log + notify). Suite 148/148.

Contesto: verifica del gate SKH01 dopo 193 run flat dal 06-23 (gate SANO —
335/341 entry storici, shorta i crash; flat legittimo: ultimo entry 06-06
chiuso ~06-08 pre-arming). Questo chiude il rischio latente scoperto durante
la verifica.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:26:02 +00:00
Adriano Dal Pastro 88f5f5a02a docs(memory): CLAUDE.md — completa il log dei filoni 2026-06-29 (1ª ondata A/C/D)
Aggiunge il bullet riassuntivo dei filoni della prima ondata del 29-06 (gia' nei diari
ma mancanti dal log curato in CLAUDE.md): A DVOL-direzionale=HEDGE, B intraday ERM=falso
positivo (gia' coperto dal gate), C xsec-v2 low-vol=debole/STAT-MODE, D macro-gate=ridondante.
Memoria curata ora completa per la sessione 2026-06-29.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:29:37 +00:00
Adriano Dal Pastro ee82e0a056 feat(dashboard): box forward-monitor STATARB-RESID (lead ortogonale+eseguibile)
Aggiunge il forward-monitor STATARB-RESID al dashboard accanto a PREVDAY (sezione
③·c FORWARD-MONITOR): carica data/paper_statarb/state.json, mostra doppio libro
MODELED/REAL-$600, ret/maxDD/fill-haircut, posizione spread corrente e giorni forward.
Warn aggiornato: LEAD sotto deflated-Sharpe -> forward per confermare l'edge, non deploy.

Smoke-test html() OK (box presente, dati live). Test 146/146.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:20:56 +00:00
Adriano Dal Pastro c52e0ab3f8 feat(forward): cabla STATARB-RESID nel forward-monitor PAPER (lead ortogonale ETH/BTC)
Forward-monitor del LEAD dello sweep 2026-06-29 (relative-value ETH/BTC, dollar-neutral 2 gambe),
il primo stream insieme ORTOGONALE (corr->book 0.027, beta-mkt 0.013) ED eseguibile a $600.

- scripts/live/paper_statarb.py: forward-only, doppio libro MODELED($2000)/REAL-$600 (haircut fill),
  riusa il segnale ESATTO di orthogonal_signals.py (niente reimplementazione). Config CONGELATA
  W=45 sgn=+1.
- Cablato in scripts/cron_daily.sh accanto a paper_prevday. Stato runtime in data/paper_statarb/
  (gitignored).
- test tests/test_paper_statarb.py (frozen config + advance forward/idempotente + haircut $600 basso).

Correzione di etichetta (verificata): la cella vincente e' sgn=+1 -> NON mean-reversion ma
relative-MOMENTUM sul residuo (dislocazioni ETH-vs-BTC continuano a 1d; sgn=-1 perde -1.4 IS).
Diario + CLAUDE.md aggiornati. Test 146/146. Nessun deploy, forward-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:58:29 +00:00
Adriano Dal Pastro cff5fa2bf5 research(sweep): 5 thread paralleli — 0 nuovi sleeve, STATARB-RESID LEAD ortogonale+eseguibile
Ricerca onesta su aree inesplorate (harness altlib+xsec_v2_nonmom, tutti i gate incl.
study_family_honest anti-selection-on-holdout). Branch main, nessun impatto live, test 143/143.

1 XSEC low-risk cousins (MAX/idio-vol/Amihud) -> 1 LEAD (IVOL), STAT-MODE, DSR 0.37<0.95
2 XSEC momentum-structure vs XS01            -> tutto REDUNDANT (sostituire XS01 distrugge hold)
3 Meta-allocazione dinamica (4 sleeve)       -> pesi fissi vincono (gia quasi risk-parity)
4 Segnali ortogonali ETH/BTC (2 gambe)       -> STATARB-RESID + DVOLSPREAD LEAD
5 1-gamba a segnale (MACD/RSI/Supertrend/...) -> 0/12 earns_slot (trend=TP01, MR morta, hedge)

LEAD principale STATARB-RESID (mean-rev residuo ETH-b*BTC, OLS rolling, 2 gambe): primo stream
INSIEME ortogonale (corr->book 0.027, beta-mkt 0.013) ED eseguibile a $600 (haircut ~0, NON
STAT-MODE) -> cadono i 2 muri di XS01/opzioni. Resta solo il muro dell'edge (Sharpe 0.84,
DSR 0.929 same-sign <0.95). Causalita+fee verificate dal coordinatore. Forward-monitor, non sleeve.

Soffitto direzionale ~1.3 riconfermato. Diario 2026-06-29-strategy-search-5threads.md, CLAUDE.md agg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:50:33 +00:00
Adriano Dal Pastro 02d875b07b merge(research): equity IB screeners + 4 filoni crypto 2026-06-29 + gate selection-on-holdout
Ricerca onesta, branch separato (nessun impatto sul book live). Test 119/119 verdi.

Equity (IB/Yahoo):
- scalping 'sottoquotate' su IB + check dati dalla rete (forward, edge non provato)
- screener short 'fond/news neg ma prezzo su' (forward, edge non provato)

Crypto BTC/ETH + universo HL (harness altlib, causale, fee 0.10% RT, marginal vs TP01):
- A DVOL direzionale  -> LEAD hedge/DD-dampener, NON sleeve
- B Intraday ERM      -> falso positivo: earns_slot da selezione-sull'hold-out + coda 2026
- C Cross-sectional non-mom (low-vol HL) -> DEBOLE/forward-monitor (deflated-Sh 0.13) STAT-MODE
- D Macro regime-gate -> RIDONDANTE col trend (corr->TP01 0.989), SCARTATO

Harness indurito (LESSON 4 in altlib): deflated_sharpe + select_cell_insample +
study_family_honest -> chiude il punto cieco "selection-on-holdout".
2026-06-29 20:09:18 +00:00
Adriano Dal Pastro b4ec92734c research(intraday): de-bias del lead ERM (filone B) — falso positivo + gate selection-on-holdout
L'analisi di robustezza affonda lo "earns_slot=True" di ERM: era prodotto da
selezione-sull'hold-out + coda 2026 + multiple-testing non corretto.
  A) deflated-Sharpe FAIL: 0.00 (tutti 122 trial) / 0.16 (no-TOD) / 0.24 (solo-ERM) << 0.95
  B) selezione in-sample-only -> ALTRA cella (long-flat, corr->TP01 0.53) = NEUTRAL, no slot
  C) ensemble del plateau (no cherry-pick) -> ADDS ma robust_oos=False -> no slot
  D) uplift FULL solo +0.10, negativo 2021/2022; uplift HOLD +0.30 concentrato nel 2026
=> ERM SCARTATO come sleeve. Conferma ennesima del soffitto BTC/ETH-direzionale ~1.3.

Lezione CODIFICATA in altlib (LESSON 4, test in tests/test_harness_realism.py):
  - deflated_sharpe()       Bailey & Lopez de Prado, PASS >= 0.95
  - select_cell_insample()  scelta cella col solo Sharpe pre-HOLDOUT (no peeking)
  - study_family_honest()   gate combinato: earns_slot[cella in-sample] AND DSR>=0.95
Regola: una strategia direzionale grid-searched si giudica con study_family_honest,
non chiamando study_marginal sulla cella a max hold-out. Verificato end-to-end su ERM
(earns_slot_honest=False). Chiude il punto cieco gemello di CC01.

Diario aggiornato (verdetto downgrade), CLAUDE.md aggiornato. Test 119/119 verdi.
Nessun impatto live (branch separato).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:04:36 +00:00
Adriano Dal Pastro aad69f9790 research(crypto): 4 filoni 2026-06-29 — ERM lead sub-daily (forward), 3 scartati/deboli
Ricerca onesta su BTC/ETH + universo HL, branch separato (nessun impatto live).
Harness condiviso altlib (causale, fee 0.10% RT, marginal vs TP01, day-boundary,
haircut $600). Test 19/19 verdi.

- A DVOL direzionale  -> LEAD hedge/DD-dampener, NON sleeve (buy-the-fear; is_hedge).
- B Intraday ERM 8h   -> LEAD forte / forward-monitor: earns_slot=True, ADDS oltre
                         SKH01 (TP01+SKH+ERM 60/25/15 FULL 1.88/HOLD 1.46/DD 8.9%).
                         Caveat: plateau hold-out single-row, multiple-testing non
                         deflazionato, exec 8h. Controllo TOD = FAIL atteso.
- C Cross-sectional non-mom (low-vol HL) -> DEBOLE/forward-monitor (deflated-Sh 0.13,
                         storia 2.5a, non eseguibile $600) STAT-MODE.
- D Macro regime-gate -> RIDONDANTE col trend (corr->TP01 0.989), SCARTATO.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:48:36 +00:00
Adriano Dal Pastro a158d0e2ae research(equity): screener short 'fond/news neg ma prezzo su' (forward, edge non provato)
Goal chiarito: short su titoli con fondamentali/notizie negativi ma prezzo in salita.

Gate dati (v2.0.0): NON backtestabile -> fondamentali da rete = snapshot correnti,
applicarli a prezzi passati = look-ahead. Come la term-structure: solo screener forward.

Costruito screener da dati di rete tokenless: fondamentali strutturati Yahoo
(quoteSummary via crumb: recommendationMean/surprise/revGrowth/sell-skew) + sentiment
headline + momentum 1m/3m. SHORT cand = (fond/news neg) AND prezzo su. Run live oggi:
nessun candidato (mercato in flessione ampia -> gamba 'prezzo su' non scatta).

Intuizione chiave: shortare la FORZA combatte momentum + PEAD; il rialzo 'malgrado'
brutte notizie spesso prezza info che i fondamentali trailing non hanno -> e' la
versione contrarian/rischiosa dell'anomalia. La versione pulita = short su fondamentali
deboli quando il prezzo CONFERMA (scende), non quando diverge.

Eseguibilita': borrow/squeeze/perdita illimitata/PDT 5k/IB instabile/00 -> non deployabile.

- scripts/research/eq_fundnews_short.py (+ forward log data/raw/fundnews_short_screen.parquet)
- tests/test_eq_fundnews_short.py (scoring puro offline)
- docs/diary/2026-06-26-equity-fundnews-short.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 19:51:22 +00:00
Adriano Dal Pastro e28176efef research(equity): scalping 'sottoquotate' su IB + check dati dalla rete
Goal: comprare azioni IB quando sottoquotate, con verifica incrociata dei dati.

1) CHECK DATI DALLA RETE (il pezzo richiesto): IB certificato (eq_*, ADJUSTED) vs
   Yahoo adjclose (sorgente rete indipendente, tokenless). Tutti CONCORDE <=1.2bps
   sui rendimenti. Teaching: un confronto naif (adjusted vs grezzo) falso-allarmava
   4/6 ticker a 30-52bps = TUTTO stacco dividendo -> ogni divergenza va SPIEGATA
   prima di gridare 'feed sporco' (v2.0.0). Strumento riutilizzabile (validatore feed
   / pre-trade price-check).

2) Scalping 'sottoquotate': NON testabile (no dati intraday) ne' eseguibile (PDT rule
   5k blocca il day-trading; IB instabile). Versione testabile = swing MR (Connors
   RSI2<10 + MA200, exit MA5): Sharpe modesto (SPY 0.75/0.70) ma NON batte il buy&hold
   (B&H hold 0.81), expo 13%, CAGR 2-5%, fee-sensitive. Niente edge schierabile.

- scripts/research/eq_meanrev_ib.py
- tests/test_eq_meanrev.py (incl. network check)
- docs/diary/2026-06-26-equity-meanrev-network-check.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 19:42:14 +00:00
Adriano Dal Pastro 8d559c6f33 merge(research): gamma-scalp + cash-carry + TP01×DVOL + vol-termstructure
Analisi onesta di 5 angoli (tutti su dati certificati, leak-free, netto fee,
scoring marginale vs TP01, vincoli eseguibilita' a $600):
- gamma scalping (scalp+opzioni)  -> SCARTATO (specchio del VRP, perde ogni freq)
- funding cross-sectional (FC01)  -> gia' morto (DILUTES)
- cash-and-carry (CC01)           -> premio reale ma Sharpe artefatto, STAT-MODE -> lead
- TP01 x DVOL vol-targeting       -> non migliora (de-levering, non timing)
- calendar-vol / term-structure   -> dato storico non pubblico -> forward logger (gia' su main)

Zero impatto sul codice live: solo script di ricerca + test + diari + note CLAUDE.md.
Il forward logger era gia' stato cablato in cron su main (555977d).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 19:28:54 +00:00
Adriano Dal Pastro 555977d987 feat(research): forward logger della vol term-structure + cron giornaliero
La storia per-scadenza non e' pubblica su Deribit -> calendar-vol non backtestabile
ora (data-first gate). Unica via: costruire il dato in avanti. Aggiunto logger
idempotente (interpola ATM IV a tenor fissi {7,30,60,90,180}g -> data/raw/vol_term_*)
+ wrapper cron giornaliero. SOLO ricerca forward: non tocca il book live ne' i dati
certificati. Analisi completa (gamma scalp/cash-carry/dvol/feasibility) sul branch
research/gamma-scalp-options.

- scripts/research/log_vol_termstructure.py + probe_vol_termstructure.py
- scripts/cron_vol_term.sh
- tests/test_vol_termstructure.py

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 19:27:15 +00:00
Adriano Dal Pastro 8c3868cb31 research(vol): calendar-vol non backtestabile — data-first gate + forward logger
Angolo term-structure DVOL / calendar-vol. Scan di fattibilita' PRIMA del backtest:
la storia per-scadenza NON e' pubblica su Deribit (DVOL solo 30g; trade-history IV
solo per strumenti vivi; il front rotola/espira -> serie continua front-vs-back
irricostruibile). Per la metodologia (niente edge senza OOS su dati certi) -> STOP,
niente backtest su uno snapshot.

Unica via legittima: costruire il dato IN AVANTI. Aggiunto logger forward idempotente
che interpola l'ATM IV a tenor fissi {7,30,60,90,180}g e accumula data/raw/vol_term_*.
Seminati i primi snapshot (oggi: contango lieve su BTC/ETH). Non auto-cablato in cron.

- scripts/research/probe_vol_termstructure.py (scan fattibilita')
- scripts/research/log_vol_termstructure.py (forward dataset builder)
- tests/test_vol_termstructure.py (interpolazione offline)
- docs/diary/2026-06-26-vol-termstructure-feasibility.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 19:18:59 +00:00
Adriano Dal Pastro 9d586eeb58 research(tp01): DVOL vol-targeting non migliora TP01 (de-levering, non timing)
Angolo ESEGUIBILE (tocca il book live): DVOL (vol implicita forward-looking) come
denominatore del vol-target invece della realizzata. Finestra comune 2021-2026.

Le varianti DVOL abbassano DD (12.3->9.2%) ma anche Sharpe FULL (0.75->0.70) e CAGR.
Controllo decisivo: realized @ vol-tgt 15% eguaglia quel DD (9.4%) a Sharpe piu' alto
(0.75) -> il taglio di DD del DVOL e' solo DE-LEVERING, replicabile meglio con un
target_vol piu' basso. Hold-out +0.06 = single-window (storia DVOL <5y), sotto la
soglia multi-cut. Gate DVOL-spike ridondante col trend (TP01 gia' flat nei crash).

Lezione: per meno DD sul live la leva e' target_vol, non un overlay DVOL.

- scripts/research/tp01_dvol_overlay.py (realized/dvol/blend/max/derisk + controllo target_vol)
- tests/test_tp01_dvol_overlay.py
- docs/diary/2026-06-26-tp01-dvol-overlay.md
- CLAUDE.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 18:56:56 +00:00
Adriano Dal Pastro 69e3517f1b research(carry): cash-and-carry CC01 — premio reale, Sharpe artefatto, non deployabile
Provato l'angolo basis/cash-and-carry (l'altro proposto; il funding cross-sectional
FC01 era gia' SCARTATO 2026-06-22). Delta-neutral long-spot/short-perp -> r=funding,
zero esposizione prezzo.

Premio di funding REALE (~+8-14%/anno aggregato, positivo ogni anno in-sample,
ortogonale a TP01). MA Sharpe modellato 11-13 = ARTEFATTO: rischi di coda fuori
dal dataset (manca il 2022; procyclico +23% 2024 -> +1.7% 2026; liquidazione/slippage
non modellati). Il mark-to-market della base (premium col) sgonfia solo 13->11 ->
il basis-from-data non e' il rischio vero. NON eseguibile a $600 (spot+perp, funding
HL non Deribit) -> STAT-MODE. LEAD da rivedere a scala, non uno sleeve.

Sottoprodotto: CC01 passa ogni gate del marginal scorer -> punto cieco (manca un
gate 'Sharpe implausibile -> rischio nascosto').

- scripts/research/cash_carry_hl.py (CC-static/gated, BTC-ETH + 19-major, basis MtM, reality-check)
- tests/test_cash_carry.py (lock del fatto economico, non dello Sharpe)
- docs/diary/2026-06-26-cash-carry-hl.md
- CLAUDE.md: riga nella sintesi di ricerca

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 18:46:14 +00:00
Adriano Dal Pastro cf72e395d3 research(options): gamma scalping (long-vol) — SCARTATO
"Scalping BTC/ETH con copertura in opzioni" = gamma scalping, lo specchio
esatto del VRP01 (long straddle ATM + delta-hedge -> incassa RV-IV).

Esito: perde ogni anno / ogni variante / ogni frequenza (Sharpe -3 a -6).
Diagnostica strutturale: a 1d IV>=RV (paghi il VRP); a 1h RV>IV gross ma il
rehedge orario paga 24x la fee di hedge -> variante peggiore. Marginale vs TP01
= DILUTES, non e' nemmeno un hedge. Muro eseguibilita': opzione BTC min $5968 >> $600.

Schiacciato tra due muri: rehedge lento = premio, veloce = fee -> nessuna
frequenza vince. Il VRP01 (lato short, gated) resta l'unico edge opzioni.

- scripts/research/options_gamma_scalp.py (harness: naked/cheap/rich, 1d+1h, diagnostica RV-IV)
- tests/test_gamma_scalp.py (lock della conclusione)
- docs/diary/2026-06-26-gamma-scalp-options.md
- CLAUDE.md: riga nella sintesi di ricerca

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 18:36:48 +00:00
Adriano Dal Pastro db738bce3b feat(live): arma il BOOK DERIBIT (TP01+SKH01 nettati in software)
Estende l'esecuzione live da TP01-only al book Deribit-only completo. TP01 e SKH01
tradano lo STESSO strumento (una sola posizione netta per conto su Deribit) -> netting
in software: un solo ordine/asset verso il target netto.

- src/live/book.py: target NETTO per asset = clamp(0.5*E*(0.75*tp_frac + 0.25*skh_sign), ±cap).
  Riusa current_target (TP01, causale) + _skyhook_positions (segno L/S, book 230m) + conto reale.
- src/live/execution.py: rebalance_signed() — reconcile CON SEGNO (long/short, flip via close+open,
  reduce reduce_only). La close resta sempre permessa (si esce da qualunque posizione).
- src/live/livefeed.py: fresh_5m() — feed 5m certificato + coda recente EFFIMERA da Deribit pubblico
  (stesso simbolo inverse, in-memory, NON scrive su disco -> dati certificati intatti; fallback al
  certificato su errore). Solo SKH01 ne ha bisogno (e' a 230m); TP01 e' giornaliero.
- scripts/live/book_execute.py: executor doppio-gate (config + --execute), disaster-SL on-book sulla
  posizione netta, log in data/live/book_executions.jsonl. Feed SKH fresco (live_feed=True).
- scripts/cron_book.sh + crontab ORARIO: book idempotente ogni ora (riconcilia al netto corrente);
  rimossa la riga live_execute.py (TP01-only) dal cron daily per non far collidere i due.
- config/live.json: ARMATO (execution_enabled=true). cap/asset $300 split 75/25, disaster-SL -30%.
  Tutto flat all'arming -> nessun ordine finche' un segnale non arma.
- tests/test_book_live.py: 20 test (sizing 75/25, cap, flip/close/reduce, parita' pesi backtest,
  gate-safety, reconcile con trader fittizio, merge/dedup feed + fallback, loader onorato). 76/76 pass.

CAVEAT: exit SKH SOFTWARE (latenza fino a fine barra 230m; solo disaster-SL on-book); TP01 scende a
peso 0.75 (max $225/asset); SKH01 resta research-grade (equity daily-step, margine DD ETH sottile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 21:43:27 +00:00
Adriano Dal Pastro 25a22fc7c1 feat(dashboard): riordino LIVE→trades→storico + trade/anno contati
- dashboard riorganizzata in 3 sezioni: ① LIVE (mainnet sola lettura) in
  alto, ② TRADES ESEGUITI (reali) + frequenza operativa al centro,
  ③ STORICO (backtest/forward simulato) in fondo (COMBO/BOOK/FORWARD come ③·a/b/c).
- book_trade_frequency() in sleeves.py: trade/anno CONTATI sui dati certificati
  (cache di modulo, una volta per processo). SKH01 round-trip BTC ~37 / ETH ~43
  -> ~75/anno combinato; TP01 turnover ~7x/anno. Card "trade/anno" + blocco freq.
- fix: collisione var `pos` nel ramo shadow-online (-> shpos) che avrebbe rotto
  la tabella posizioni se il conto fosse leggibile dal container.
- fix: turnover TP01 nan (disallineamento groupby) -> groupby posizionale, 7.2x/anno.
- 56 test pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 21:18:52 +00:00
Adriano Dal Pastro eeac97dde4 feat(dashboard): Deribit-only book panel (TP01+SKH01) + accumulation forecast
New section showing the executable Deribit-only book (TP01 75% + SKH01 25%): combined
FULL/HOLD Sharpe+DD, plus the reinvest-winnings accumulation projection (historical &
conservative CAGR, €5k→5y/10y, conservative €/day run-rate). Reuses the already-computed
sleeve daily series (no extra heavy compute). Honest caveats (bull sample, no leverage,
SKH01 not live, ~€177k for €50/day).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 20:43:47 +00:00
Adriano Dal Pastro c8a390d6b7 feat(portfolio): reproducible accumulation forecast for the Deribit book
scripts/portfolio/forecast_deribit_book.py — projects the Deribit-only book (TP01+SKH01)
forward by pure compounding (reinvest winnings), monthly-aligned, NO external contributions
(not a PAC). Deterministic @historical & @conservative CAGR + Monte-Carlo block-bootstrap
(median/p10/p90), plus €/day run-rate @conservative. Parametric (--capital/--years/--cons-frac).
Honest caveats baked in (bull-crypto sample, no leverage, SKH01 not live, conditional projection).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 20:42:14 +00:00
Adriano Dal Pastro 384b9cb0af feat(skyhook): pos_fn introspection for SKH01 sleeve (current open trade / flat)
_skyhook_positions(): replays the non-overlap entry+exit logic (TP/SL/max_bars) to the last
closed 230m bar and reports, per asset, the current OPEN trade (dir/entry/sl/tp/bars_in) or
'flat'. Wired into skyhook_sleeve(pos_fn=...) so the Deribit book report & web dashboard show
Skyhook's live position. Causal (closed bars only). +1 test. Currently flat/flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 20:32:14 +00:00
Adriano Dal Pastro 160ad300be feat(portfolio): Deribit-only executable book (TP01+SKH01) + periodic rebalancing
- deribit_book_sleeves(): TP01 75% + SKH01 25% — the two directional BTC/ETH legs on
  ONE venue (Deribit), both since 2019. Excludes XS01 (Hyperliquid/stat-mode) & VRP01
  (modeled options). FULL Sharpe 1.78 / HOLD 1.17 / DD 9.4% (research).
- rebalance_sim(): realistic PERIODIC rebalancing (drift between dates, turnover cost at
  Deribit-taker ~5bps/side) vs the idealized continuous rebalance of combined_daily.
  period=1 + cost=0 reduces to continuous (tested).
- run_deribit_book.py: report — continuous vs weekly/biweekly/monthly rebal, per-year,
  accumulation €2k & $600-real, min-order $5 note. Finding: turnover is LOW (0.2-0.4x/yr),
  so monthly rebal (€7,919) ~= continuous (€7,938) — cost is negligible; daily would be
  sub-min-order fiction at $600 -> use >= weekly.
- +2 tests (rebalance_sim continuity & cost). Full suite green.

TP01 is the only live-armed leg; SKH01 is the candidate 2nd leg (validate execution code first).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 20:26:53 +00:00
Adriano Dal Pastro 50e2adf837 merge(skyhook): SKH01-V2-DD strategy + 4-sleeve portfolio + dashboard
Brings the Skyhook line into main:
- SKH01 dual-TF regime+breakout engine (BTC/ETH, causal, honest harness)
- 2 multi-agent research waves -> SKH01-V2-DD (asymmetric %-exits, standalone
  maxDD <30%, minHold +1.26, marginal ADDS vs TP01)
- wired as 4th portfolio sleeve @25% effective: FULL Sharpe 1.68->2.13, DD 14->8%
- dashboard shows the 4-sleeve view; tests 25 pass

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:42:15 +00:00
Adriano Dal Pastro 7eb0f67956 feat(dashboard): show SKH01 sleeve in 4-sleeve portfolio view
active_sleeves() already feeds the per-sleeve table & combined metrics, so SKH01
appears automatically. Manual touch-ups: title/docstring -> +SKH01; position label
is now sleeve-aware (the None fallback used to mislabel every pos-fn-less sleeve as
XS01's "book 19 gambe" — now XS01/SKH01/VRP01 get correct labels); footer note adds
SKH01 (quasi-orthogonal @25%, FULL Sharpe 1.68->2.13, DD 14->8%, research/forward-monitor).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:41:52 +00:00
Adriano Dal Pastro 8d1fe173f7 feat(portfolio): wire SKH01-V2-DD sleeve @25% effective -> 4-sleeve book
Add Skyhook (SKH01_V2_DD) as a portfolio sleeve. Effective weight 25%: the three
existing sleeves scaled into the remaining 0.75 keeping their 55:25:20 ratio
(TP01 41.25% / XS01 18.75% / VRP01 15% / SKH01 25%).

_skyhook_returns(): 50/50 BTC+ETH daily series of the dual-TF regime+breakout engine
(causal, net 0.10% RT), same convention as the marginal lens.

Portfolio impact (run_portfolio.py), 3-sleeve -> 4-sleeve:
  FULL Sharpe 1.68 -> 2.13 (+0.45), FULL maxDD 14.3% -> 7.8% (halved)
  HOLD-OUT Sharpe 1.63 -> 2.30 (+0.67), HOLD-OUT maxDD ~3.5% (flat)
  Positive every year 2019-26 (annual DD <=7.8%) vs buy&hold 50/50 FULL Sh 0.93 / DD 76%.

Skyhook is quasi-orthogonal (corr ~0.09 to TP01) so it lifts Sharpe AND cuts DD.
Research portfolio (fixed weights, no real rebalancing cost at $600; Skyhook daily
Sharpe is the step-marked lens convention) -> forward-monitor, not deploy.
Tests: 25 pass (skyhook 8 + portfolio 7 + vrp 4 + trend 6). Diary + CLAUDE.md updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:22:15 +00:00
Adriano Dal Pastro de72e3ce1f feat(skyhook): SKH01-V2-DD — asymmetric %-exits cut standalone DD <30% (2-wave agent research)
Second agent wave (skyhook-improve-v2, 14 DD-reduction families, each adversarially
verified by 2 skeptics) beats the prior winner on the only unmet goal (DD<30%).

Winner = ASYM_LS -> promoted to engine as SKH01_V2_DD:
  same signal (ptn_n=45, vola[35,95], vol_lo=0, exit-bars 24/16) but exits switched
  from ATR to FIXED-PCT ASYMMETRIC — long sl4%/tp10%, short sl2%(tighter)/tp8%.
  The tight short %-SL caps the per-trade loss that forms the maxDD in vol spikes.

Verified (sk.study, independent re-run): standalone maxDD BTC 21.4% / ETH 27.4% (<30%),
minFull +0.99, minHold +1.26, causality 0/400 both assets, fee-surviving to 0.40%RT,
marginal vs TP01 ADDS (corr 0.09, in-sample edge, robust_oos, multicut, clean-year +0.57),
blend 0.75*TP01+0.25*SKH uplift_hold +0.87; blend 50/50 full 1.84/hold 1.59/DD 10.7%.
Plateau (not knife-edge); both skeptics holds_up=high, killer=null.

Engine: per-direction short exit overrides (exit_mode_short/sl_*_short/tp_*_short),
backward-compatible (None -> symmetric, V1/intermediate-winner unchanged). +3 tests (8/8 pass).

Lessons: DD is cut by changing the exit MECHANISM (%-SL, L/S asymmetry, ensembles), NOT by
entry-only kill-switch / vol-target / cadence. PATTERN_CONF killed as overfit (knife-edge).
PCTL_DD unverified (rate-limit) and ENS_PARAM/TPSL_DD recency/hedge-loaded -> forward-monitor.
NOT yet wired to live sleeves: re-verify blend@0.25 + causality on execution code before deploy.

Includes both waves' research scripts (runs/SKH_* wave 1, runs/SKH2_* wave 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:10:38 +00:00
Adriano Dal Pastro 8e46a62e67 docs(skyhook): diario porting SKH01 + V1 (sintesi onda agenti in aggiornamento)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:47:41 +00:00
Adriano Dal Pastro c7c07f4c35 test(skyhook): demo anchors + dual-TF alignment + causality + V1 robustness (5 pass)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:46:47 +00:00
Adriano Dal Pastro 2d8faf3896 research(skyhook): inline lever-scout -> shorts essential, regime gate matters, ptn_n=55/vol_lo=40/wider-stops lift hold-out
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:35:35 +00:00
Adriano Dal Pastro 64d98a070d feat(skyhook): SKH01 dual-TF regime+breakout engine + honest eval harness
Porting onesto del sistema ES Skyhook su BTC/ETH certificati:
- src/strategies/skyhook.py: 690m(segnale)+230m(exec) da 5m; BuzVola/BuzVolume
  Chande 0-100 (ancore demo verificate); Donchian breakout HTF; regime gate;
  composer; entries asimmetrici (uscitalong/short + stop/profit ATR) per backtest_signals.
- scripts/research/skyhook/skyhooklib.py: study (FULL/HOLD/fee-sweep/per-anno BTC&ETH),
  causality guard (0 mismatch), marginal-vs-TP01.
Baseline: BTC FULL Sh +0.91/+581%, ETH +0.64/+255%, fee-surviving, ma HOLD-OUT debole -> da migliorare.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:33:54 +00:00
Adriano Dal Pastro 237ca8da13 research(report): resoconto PROTETTO (soft-guard DD -4%) anno-per-anno -> combo + TP01 + GTAA singoli
Report che mette combo (TP01+GTAA 50/50), TP01 e GTAA sulla stessa griglia giorni-di-borsa
(esposizione 1x, come dentro al combo), applica la guardia-DD -4% a ciascuna serie e tira fuori
per anno: NL (net liquidation da $2000), DD intra-anno, rendimento, Sharpe + riga TOT con CAGR.
Combo protetto: CAGR +9.1% / DD 5.8% / Sh 1.38 (2022 -1.8%); baseline +11.3% / 8.4% / 1.48.
Aggiunto data/paper_combo/ al .gitignore (stato paper runtime, come gli altri paper dir).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:16:59 +00:00
Adriano Dal Pastro 856a02fcc5 research(stops): SL classici vs soft-guard -> il soft-guard vince (lo SL duro whippa nel grind)
Goal 'prova anche SL'. Test equo (trigger/re-entry sul NAV mercato). soft-guard -4% Sh 1.38/DD 5.8%
resta il migliore; trail-stop -6% valido ma inferiore (1.34/6.6%); -4% whipsaw (1.07, inMkt 42%);
stop mensile/vol inutili. Per un DD da grind, de-risk parziale > uscita totale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 13:09:43 +00:00
Adriano Dal Pastro 010d1f0733 feat(combo): paper combo NUDO vs PROTETTO (guardia-DD -4%) affiancati + dashboard
paper_combo traccia forward entrambe le versioni; dashboard mostra nudo + protetto. Guardia-DD:
de-risk 0.4x a DD>-4%, ri-rischia a -1.6% (backtest MaxDD 8.4->5.8%, 2022 -4.4->-1.8%). Opzioni
escluse (non aiutano il grind). Container ricostruito.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:59:07 +00:00
Adriano Dal Pastro 1c15c3c1be research(tail-hedge): protezione DD combo (incl. opzioni) -> vince la guardia-drawdown
Goal: sleeve/overlay protettivo per il combo (TP01+GTAA), anni tipo 2022, valutare opzioni.
Diagnosi: DD combo 8.4% e' grind-lento (2022 -4.4%), non crash -> il doppio trend gia' taglia i crash.

Test (tail_hedge_lab.py): guardia-DD -4% -> MaxDD 8.4->5.8%, 2022 -4.4->-1.8%, Sharpe 1.48->1.38,
CAGR 9.2%. Vol-target NON aiuta (2022 non e' vol-spike). OPZIONI (put/put-spread LONG su BTC/ETH,
premio BS su DVOL): sempre-on ~50%/anno -> con budget 3%/y effetto ~nullo, e nel grind 2022 sanguinano;
pagano solo nei crash secchi (stress -30%: put +25% netto). -> black-swan insurance cara, fuori
bersaglio per il 2022. A leva: guard rende il 2x sopportabile (2022 -10.9%), il 3x resta margin-call.

RACCOMANDAZIONE: aggiungere guardia-drawdown di portafoglio (no premio); opzioni solo eventuale
micro-hedge black-swan. Costo onesto del guard: -2.1pp CAGR per dimezzare il MaxDD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:55:14 +00:00
Adriano Dal Pastro 3a3bdd5c7b research(report): sim leva 1x/2x/3x combo vs TP01 (DD reale + margin-call), da 2k/5k
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:44:54 +00:00
Adriano Dal Pastro f983cc2447 research(report): resoconto anno-per-anno combo/TP01/GTAA da $2k (PnL/MaxDD/NumTrades)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:37:23 +00:00
Adriano Dal Pastro 389573e517 feat(dashboard): pannello COMBO cross-venue (TP01 Deribit + GTAA IB)
Aggiunge alla dashboard la sezione "COMBO DEPLOYABLE — cross-venue (paper)": equity paper forward
del blend 50/50 TP01+GTAA (da data/paper_combo/state.json) + posizioni azionabili IB correnti
(gtaa_weights: peso ETF + cash, asof). Nota onesta: paper rischio-zero, Sharpe ~1.5 ottimistico, il
robusto e' la diversificazione (corr 0.21, DD dimezzato); XS01/VRP01 esclusi (STAT-MODE).
Container ricostruito (codice baked nell'immagine).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:32:19 +00:00
Adriano Dal Pastro 3b552a92da feat(combo): paper-trade cross-venue TP01 (Deribit) + GTAA (IB), forward-only
L'unica cosa vera/deployabile della ricerca: diversificazione TP01+GTAA (corr 0.21, blend Sharpe ~1.5,
DD dimezzato). Si va in PAPER cross-venue.

- src/portfolio/gtaa.py: GTAA sleeve di prima classe (trend difensivo TSMOM vol-target 12% su
  SPY/QQQ/IWM/TLT/GLD/HYG). gtaa_returns() Sharpe 0.64; gtaa_weights() = pesi ETF correnti azionabili.
- scripts/live/paper_combo.py: tracker forward-only blend 50/50 TP01+GTAA (crypto compoundato su grid
  giorni-di-borsa), mostra posizioni azionabili su entrambi i venue. Solo gambe eseguibili.
- fetch_ib_equities.py --only: refresh mirato dei 6 ETF GTAA per il cron.
- cron_daily.sh: up gateway IB + refresh ETF GTAA + avanza paper_combo (dipendenza cross-venue gestita).

Init 2026-06-23: TP01 flat (risk-off), GTAA SPY13/QQQ8/IWM9/TLT17/GLD2/HYG17/cash34. Catena
gateway->refresh->paper testata end-to-end. PAPER (rischio zero), valida l'operativita' cross-venue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:26:51 +00:00
Adriano Dal Pastro 09c8bb7de8 research(cross-market): oltre SP500 (bond/commodity/indici esteri) -> niente, artefatto di confine UTC
Esteso il test crypto-lead a ZN(bond), ESTX50/DAX(Europa), NKD(Nikkei) via futures orari IB
(commodity GC/CL/HG bloccate da subscription). Test non-sovrapposto crypto[T-8h->T]->future[T->T+6h].

ES/NQ/RTY niente (gia'); ZN negativo; NKD debole (~overnight drift). ESTX50/DAX SEMBRANO fortissimi
(t_crypto 7.8, Sharpe 2.5, 3/3 anni) MA e' artefatto di confine UTC: picco a coltello a T=00:00,
morto a T=1h; GAP di 1h uccide l'effetto (Sharpe 2.45->-0.52); tutto l'edge nella singola barra
00:00->01:00 (Sh +2.93) vs ora dopo (-1.02). Firma esatta di day_boundary_robust (CLAUDE.md).

VERDETTO: nessuna anticipazione crypto->mercato sfruttabile, ne' SP500 ne' altro. Sempre co-movimento
contemporaneo (risk-beta) o artefatto di confine. Resta valido solo il diversificatore TP01+GTAA.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:12:16 +00:00
Adriano Dal Pastro c4bc336a53 research(cross-market): futures overnight non-sovrapposto -> edge ~0 su SP500, soffio su small-cap
Test ONESTO dell'idea "monitor Deribit/trade IB": entra mid-notte sul future indice, cattura il moto
SUCCESSIVO (finestre non sovrapposte, no look-ahead). Dati: ES/NQ/RTY orari da IB (fut_*_1h, ~3y).

RISULTATO: ES (S&P500) nessun edge (Sharpe ~0/neg, t_crypto 0-1.5); NQ momentum del future non crypto;
RTY (small-cap) unico con t_crypto incrementale 2.0-2.7 e crypto che aggiunge oltre il moto proprio del
future, ma Sharpe 0.4-0.5, 24 config (multiple-testing), 2.3y, per-anno incoerente (2026 negativo).

VERDETTO: l'idea NON da' edge tradabile, men che meno su SP500. Il forte crypto<->equity e' co-movimento
contemporaneo (risk-beta), non anticipazione: imposta una finestra causale non-sovrapposta e svanisce.
Il "Sharpe 5" del gap era look-ahead. RTY -> forward-monitor al piu'. Coerente col soffitto del progetto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 11:51:15 +00:00
Adriano Dal Pastro 55c337144e research(cross-market): "monitor Deribit/trade IB" gap = LOOK-AHEAD, edge tradabile ~0
L'idea (segnale crypto overnight -> trade indice IB) sembrava Sharpe 3.6-5.9 ma e' look-ahead:
la finestra segnale crypto [P21:00->D13:00] e il gap equity [Pclose->Dopen] coprono le stesse ore.
All'entrata (D13:00, pre-open) il gap e' gia' avvenuto -> non catturabile con l'ETF.
Decomposizione (net 2bps, sqrt252): OVERLAP gap Sh ~3.6-4.0 (artefatto) vs TRADABILE intraday
Sh -0.03..0.25 (reale, ~0, muore a costi). Conferma/rafforza "non deployabile" del workflow.
Resta possibile solo la versione futures mid-overnight (finestre non sovrapposte) -> serve dato
intraday ES/NQ, non in cache.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 11:23:18 +00:00
Adriano Dal Pastro d916520f2c research(cross-market): sweep 65-agenti crypto->mercati IB -> fenomeno gap robustissimo ma NON edge
Goal: >=50 agenti, migliore soluzione, diversi mercati e timing, su piu' anni.
Setup: 26 ETF certificati (IB) + BTC/ETH 1h; harness parametrizzato (lead overnight crypto ->
gap/intraday equity, t-incrementale, Sharpe IS/OOS, hit per-anno); workflow 416 config = 52 sweep +
12 verifica avversariale + 1 sintesi = 65 agenti.

RISULTATO: cluster fortissimo crypto-overnight -> GAP apertura equity (tutti i target risk-on).
Migliori: ETH->IWM/QQQ/XLK gap (Sh OOS 2.4-2.5, t 17), BTC->QQQ gap (Sh OOS 2.31, t 15, 9/9 ANNI).
Regge stress 10bps e OOS recente. MA due killer (verificatori concordi):
  1. NON tradabile via ETF (gap gia' all'open) -> serve future overnight (MNQ/MES), fuori dal
     capitale $0.5-2k (margin/liquidazione);
  2. e' RISK-BETA non alpha: finestra-lead ~contemporanea al gap (stesso shock macro), forza solo
     negli anni alta-vol (2022), beta implicito ~37%.
Unico ETF-tradabile (ETH->XLE intraday) crolla a 10bps (0.48->0.15), t 2.38 sotto Bonferroni/416.

VERDETTO: nessun edge proprietario deployabile a basso capitale. Migliore FENOMENO da forward-monitor
= BTC->QQQ gap overnight (9/9 anni). Coerente col soffitto del progetto. Valore: aver classificato il
fenomeno (risk-beta overnight) invece di scambiarlo per alpha.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 22:32:28 +00:00
Adriano Dal Pastro d2d535cf6a research(cross-market): crypto x mercati IB -> trovata ANTICIPAZIONE weekend-crypto -> lunedi' equity
Goal: cercare correlazioni/anticipazioni crypto<->IB. Dati cache (BTC/ETH Deribit 1h->1d; ETF eq_*).

(1) Correlazione contemporanea: crypto = risk-on (BTC ~0.32 SPY/QQQ/IWM, 0.25 HYG, 0.13 GLD, ~0 TLT).
(2) Lead-lag GIORNALIERO: NIENTE (picco k=0, rumore a |k|>=1) -> nessuno anticipa l'altro al daily.
(3) EFFETTO WEEKEND (anticipazione pulita): crypto Sab+Dom (equity chiuso) anticipa il lunedi'.
    GAP lunedi' corr +0.22/0.24 (SPY/QQQ/IWM/HYG), hit 59-62%, si RAFFORZA OOS22+ (+0.30/0.36).

Validazione avversariale:
  (A) INCREMENTALE vs venerdi': beta weekend-crypto significativo (QQQ gap t=+4.7, intr +2.9; SPY
      +4.4/+2.0; IWM +4.7/+2.7), friday_eq NON signif. -> info crypto-specifica, non momentum equity.
  (B) TRADABILE (entro Mon open, esco close, net 4bps): QQQ hit 60%, Sharpe 1.46 (OOS 1.33), long-flat
      OOS 1.91 ~+9%/yr; SPY/IWM piu' deboli ma OOS positivi.

VERDETTO: prima anticipazione cross-mercato reale. Crypto = proxy 24/7 risk-sentiment; lunedi' equity
recupera la direzione del weekend. Caveat: capacita' bassa (~52 lun/anno), tattico non cornerstone;
gap catturabile via futures IB (MNQ domenica sera) da validare. Coerente su 3 ETF (no cherry-pick).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:55:01 +00:00
Adriano Dal Pastro 67850b0dd8 research(equities): valida combo DEPLOYABLE TP01+GTAA (le due gambe eseguibili)
Combo onesto/eseguibile a basso capitale: TP01 (Deribit, gia' armato) + GTAA vt12 (IB), senza
XS01/VRP01 STAT-MODE. Finestra 2019-2026, TP01 compoundato sui giorni di borsa.

RISULTATO: corr TP01<->GTAA +0.21; blend 50/50 Sharpe 1.48 (40/60 e risk-parity 1.52) > best solo
1.25, maxDD 14%->8%. DIVERSIFICA anche da deployable.
CAVEAT: 2022 negativo (-2.64, trend whipsaw su entrambe), anni boom gonfiano l'assoluto (recenti
~0.95) -> il dato robusto e' il +0.27 di diversificazione, non il livello. Costo deployability:
crypto-pieno+GTAA 1.81 vs 1.48 (i ~0.33 persi = XS01/VRP01 non eseguibili). Cross-venue Deribit+IB.

Migliore config rischio-aggiustata EFFETTIVAMENTE eseguibile trovata post-reset. Non risolve EUR50/g
(capitale). Prossimo: paper-trade GTAA su IB (forward-only) per validare l'esecuzione cross-venue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:48:35 +00:00
Adriano Dal Pastro 437cf11199 research(equities): EQ-GTAA01 trend multi-asset + COMBO cross-mercato (diversifica il crypto)
(1) GTAA: trend difensivo long-flat su SPY/QQQ/IWM/TLT/GLD/HYG (EW sugli asset disponibili).
  GTAA lf vt12%: Sharpe 0.64 (OOS 0.89), maxDD 15% (8% sui 6-asset 2016+), corr SPY 0.64.
  Migliore sleeve equity: rischio-aggiustato > mono-SPY, DD bassissimo, diversificatore migliore.
  Difensiva (CAGR basso). Bear DD: GFC 14% vs 55%, COVID 10% vs 34%.

(2) COMBO cross-mercato: crypto (TP01+XS01+VRP01) x equity (GTAA vt12), finestra 2019-2026.
  corr crypto<->equity = +0.17 (bassissima). blend 50/50 Sharpe 1.81 > crypto solo 1.60 >
  equity 1.12; maxDD dimezzato 14%->7%. DIVERSIFICA: primo miglioramento STRUTTURALE del
  rischio-aggiustato complessivo della ricerca post-reset (diversificazione vera, non alpha).

CAVEAT: finestra crypto corta/favorevole (Sharpe assoluti ottimistici), cross-venue Deribit+IB,
XS01/VRP01 STAT-MODE -> il combo deployable reale e' ~TP01+GTAA. Non risolve EUR50/g (capitale).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:42:42 +00:00
Adriano Dal Pastro c9b89739c1 research(equities): EQ-TREND01 trend difensivo su SPY = edge difensivo REALE (analogo TP01)
Il cross-section e' morto (EQ-MOM01), ma il trend DIFENSIVO time-series su SPY regge — stesso
tipo di TP01 nel crypto. TSMOM multi-orizzonte / SMA-200 long-flat, causale, netto fee, OOS 2015+.

RISULTATO: Sharpe 0.54->0.62/0.65, maxDD DIMEZZATO (55%->~27%; nei bear lenti piu': GFC 19% vs
55%, dot-com 26% vs 49%, COVID 17% vs 34%). Plateau robusto (0.56-0.65), fee-robusto (0.48 a
0.10%/lato), basso turnover, eseguibile a $0.5-2k (switch mensile SPY/cash). SMA-200 = piu'
semplice E migliore.

CAVEAT: e' risk-management non alpha (CAGR -2/3pp); i tagli grossi sono in-sample (OOS 2015-26
quasi tutto toro -> ha seguito SPY a beta minore, ma COVID dimezzato). long-bonds TLT non convince.

Lezione cross-mercato confermata: il valore robusto e' ridurre il rischio (trend long-flat), non
battere il buy&hold. Prossimo: trend multi-asset/GTAA + diversifica la sleeve crypto?

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:37:37 +00:00
Adriano Dal Pastro 03267b8fc3 research(equities): EQ-MOM01 momentum settoriale -> NON batte SPY
Primo backtest del fronte equity. Momentum cross-sectional settoriale (9 SPDR, 1998-2026),
causale, netto fee, OOS 2015+, giudicato marginale vs SPY buy&hold (il baseline equity).

VERDETTO: nessun edge. Long-short Sharpe -0.08 (alpha cross-sectional MORTO su 27y,
decadimento post-2000 noto). Long-only ~= SPY (corr 0.85, uplift marginale ~0.00) = SPY a
beta piu' basso. Plateau stabile ~0.50 vs SPY 0.51; sugli 11 settori (2018+) peggio (0.69
vs 0.82). L'unico beneficio (maxDD 55->39%) e' del vol-target, non del momentum.

Coerente col progetto: il relative-value momentum e' morto anche in equity (come ortho wave
nel crypto). Prossimo angolo: TS-trend difensivo su SPY (analogo equity di TP01) per tagliare
il drawdown, non per battere il CAGR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:33:38 +00:00
Adriano Dal Pastro 1c0b5f1869 research(equities): apre il fronte azioni/ETF via IB — dati certificati + cache su disco
Branch dedicato. Disciplina v2.0.0: prima il dato certificato, poi la strategia.
IB paper (gnzsnz/ib-gateway) da' storia daily ADJUSTED_LAST (div+split) profonda.

- ib_equities_probe.py: sonda fattibilita' dati (profondita', adjusted, subscription).
- fetch_ib_equities.py: FETCH+CERTIFY universo -> data/raw/eq_<sym>_1d.parquet (ms epoch,
  namespace dedicato). RIPARTIBILE (salta i parquet gia' scritti) -> niente refetch da IB.
  Certifica: integrita', gap lunghi, sanita' ritorni, sanita' adjustment.
- eqlib.py: harness ricerca equity. Legge la CACHE su disco (lru_cache) MAI da IB; universi
  (11 settori SPDR + 9 classici 1998+ + broad), panel allineato, riusa lo scorer indurito altlib.

UNIVERSO CERTIFICATO (17, data/raw/eq_* gitignored = cache locale):
  9 settori classici dal 1998-12-22 (27.5y) + XLRE(2015)/XLC(2018) + SPY(1996,30y)/QQQ/IWM/
  GLD(2004)/HYG(2007)/TLT(2016). Tutti integri (monotoni, no dup, no spike>50%, gap-lunghi 0).
  Start comune: 9 classici 1998, 11 settori 2018.

Prossimo passo: prima ricerca = momentum cross-sectional settoriale, gauntlet onesto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 21:29:11 +00:00
Adriano Dal Pastro 61180637eb research(funding-carry): FC01 cross-sectional su HL -> fragile, NON regge + infra IB paper
Onda "nuova ricerca mirata". Unico meccanismo non coperto dalle 2 ondate: carry da
funding (cashflow perp, delta-neutral). Scan dati: price-clock gia' FAIL (intraday),
Deribit ccxt 0 righe, Cerbero solo candele -> fonte = API pubblica Hyperliquid.

- fetch_hl_funding.py: 19 major, funding orario reale dal 2023-05, certificato
  (0 gap, cov 98-100%, ann +1.0% APT .. +21.6% NEAR). backoff anti-429.
- funding_carry_hl.py: book dollar-neutral short-alto-funding/long-basso, causale come
  XS01, vol-target 20%, fee 0.05%/lato. Giudizio: marginal_vs_tp01 indurito + overlap XS01.

VERDETTO: il premio esiste (carry >> anti) ma il book NON regge il gauntlet.
  FULL -0.12, HOLD -0.50, DILUTES vs TP01, in-sample edge <0.5, no multicut.
  Jackknife universo: FULL oscilla [-0.39,+0.30] togliendo UN asset -> FRAGILE/overfit.
  (preview a 17 asset era +0.62 ADDS: fortuna, mancavano NEAR/AAVE). corr XS01 -0.19
  (ortogonale, non re-skin). Meccanismo: carry-vs-momentum, gli alto-funding pompano.
  -> NON entra in portafoglio, fetcher NON in cron. Diario completo.

Infra IB (thread parallelo): gateway paper gnzsnz/ib-gateway (127.0.0.1:4002, READ_ONLY)
in docker-compose + ib_probe.py. Esito dati basis CME micro: backtest NON fattibile
(ContFuture back-adjusted, scaduti=1 barra). IB ok per esecuzione/forward, non ricerca.
.env.ibgw gitignored (credenziali paper), template in .env.ibgw.example.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 20:56:18 +00:00
Adriano Dal Pastro 745ba7d066 research(portfolio): simula PREVDAY come overlay tail-hedge su TP01+XS01+VRP01 (NON deploy)
Simulazione d'impatto (registry di produzione invariato): riscala i 3 sleeve attivi a (1-W) e
aggiunge PREVDAY a peso W; sweep W {0,5,10,15,20%}. A 10%:
 - FULL Sharpe 1.68->1.88 (+0.20), maxDD 14.3%->9.9% (-31%): la gamba short ammortizza i crash storici.
 - HOLD-OUT Sharpe 1.66->1.97 (+0.31), ret +16.7->+19.0% (DD gia' bassissimo 3.4%).
 - 10% ~ ottimo di DD: oltre, lo Sharpe sale ma il maxDD smette di scendere (solo piu' rischio short).
 - per-anno: migliora/pareggia quasi ovunque; costa solo nel toro 2021 (premio hedge), paga nel bear 2022.

Caveat: tutto IN-SAMPLE (i guadagni assumono che l'edge persista -> e' cio' che il forward-monitor
verifica); outer-join gonfia il peso effettivo 2019-20 -> l'hold-out e' il read pulito a 10%. PREVDAY
resta FORWARD-MONITOR. Lo script e' il riferimento per ri-valutare l'overlay a forward maturo.

Diario: 2026-06-21-prevday-overlay-portfolio.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 20:01:20 +00:00
Adriano Dal Pastro 043f141bf1 research(intraday): PREVDAY block-bootstrap -> coda-fortuna vs persistente (blocker #2/#3)
Chiarimento: il "top-5 giorni = 76-83%" del diario era sulle gambe REVERT scartate, non su PREVDAY
(breakout). Test su PREVDAY stesso + gamba short (= tutto il valore). Block bootstrap circolare 20g B=3000.

[A] Concentrazione: PREVDAY-full NON e' piu' coda-fortuna di TP01 (top5 22% vs 19%; 14.3% dei giorni
per il 50% del gain vs 8.0% -> piu' distribuito). MA la gamba short e' tail-dipendente (top5=130% del
netto: togliendo i 5 giorni migliori va in perdita; sono i giorni-crash).

[B] Bootstrap: full robustissimo (uplift mediana +0.28, 99% dei resample >0); hold-out regge con coda
piu' larga (uplift mediana +0.53, 93% >0, 5deg pctl appena negativo per hold-out corto + short
tail-dipendente).

Verdetto: #3 tail-luck DECLASSATO per PREVDAY-full, CONFERMATO per la gamba short (payoff grumoso, su
<10 giorni-crash/anno); #2 null-corr-zero RIDIMENSIONATO (uplift genuinamente positivo, era efficienza
relativa). Sintesi trilogia: PREVDAY = tail-hedge legittimo e bootstrap-robusto, eseguibile a taglia
reale, payoff concentrato sui crash -> candidato overlay tail-hedge, non sleeve-alpha. Forward-monitor.

Diario: 2026-06-21-prevday-bootstrap.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:56:11 +00:00
Adriano Dal Pastro b388c462e8 research(intraday): PREVDAY turnover-reduction (no free lunch) + long-only probe (e' un HEDGE)
La fee (~2.6%/anno) viene dai ~70 flip/anno, non dal churn sub-dollaro (da fill_haircut). Sweep
delle leve che riducono i flip a livello di segnale (buffer k, anchor multi-giorno, min-hold):
 - allargare buffer/anchor taglia fee e turnover ma l'uplift hold-out del blend cala monotono
   (k0.30->0.50->0.75 = upl 0.56->0.40->0.00); anchor multi-giorno tutto peggio (conferma anchor=1).
 - min_hold=24h e' l'unico ritocco quasi-gratis (upl 0.56->0.60) ma peggiora il DD -27%->-32%.
 - la config congelata e' gia' sulla frontiera efficiente turnover<->edge -> nessun cambio.

Bonus blocker #1: long-only vs long-short. long-only ha Sharpe standalone PIU' ALTO (1.55 vs 1.23)
ma corr a TP01 +0.64 e blend uplift solo +0.09. TUTTO il valore di portafoglio e' la gamba SHORT
(decorrelazione 0.64->0.15, uplift 0.09->0.56). PREVDAY non e' alpha: e' un HEDGE di regime-down
(costa nel toro, paga nell'orso 2022/2025-26), additivo alla flat-stance di TP01. Restano i blocker
null-corr-zero e tail-luck. Forward-monitor invariato; eventuale ruolo = overlay di tail-hedge.

Diario: 2026-06-21-prevday-turnover-and-hedge.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:45:54 +00:00
Adriano Dal Pastro 8514c096ea research(intraday): fill-haircut PREVDAY a basso capitale -> blocker d'esecuzione BENIGNO
Stima SUBITO (invece di aspettare il forward-monitor) quanto il fill reale a $600 erode il lead
PREVDAY, replicando i due libri di paper_prevday.py su tutto il path 1h (2019-03 -> 2026-06):
 - MODELED (continuo) vs REAL-$C (skip ribilanciamenti < $5 min-order), sweep C {600,2k,20k}.
 - HAIRCUT $600 = +0.01 Sharpe (FULL e HOLD): saltare il 98.4% dei micro-ribilanciamenti del
   vol-target non costa nulla (trade infinitesimi: fee risparmiata e tracking-error entrambi
   trascurabili; fee-drag 2.49% -> 2.39%). L'uplift hold-out del blend 80/20 regge +0.56 -> +0.55.

Conseguenza: dei 4 blocker no-deploy, il #4 (fill a basso capitale) e' SMONTATO. Restano i 3
strutturali (hedge-shaped, fallisce il null a corr-zero, tail-luck). PREVDAY resta forward-monitor.
Lezione: eseguire eval_weights_smallcap PRIMA di scartare un lead per 'fill irreale'.

Diario: 2026-06-21-prevday-fill-haircut.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:41:20 +00:00
Adriano Dal Pastro b5db59bea9 feat(dashboard): mostra il forward-monitor PREVDAY (lead ortogonale a TP01)
Nuova sezione "FORWARD-MONITOR — lead paper (non deploy)" nel dashboard, tra PAPER e LIVE:
legge data/paper_prevday/state.json e mostra i due libri (modeled €2k nominale vs real-$600
con min-order $5), ret/maxDD di entrambi, il fill-haircut, le posizioni correnti BTC/ETH e
i giorni/flip forward. Nota esplicita: LEAD in osservazione, NON deployato.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:27:27 +00:00
Adriano Dal Pastro 5cce7acfe1 live(monitor): prevday-breakout in FORWARD-MONITOR (paper, non deploy)
Il lead ortogonale a TP01 sopravvissuto all'onda intraday entra in forward-monitor (stesso
trattamento di XS01 STAT-MODE / STA05), NON in esecuzione reale.

- src/strategies/prevday_breakout.py: segnale CONGELATO (params fissi anchor=1, k=0.30, simmetrico,
  vol-target 0.20/30/2.0), self-contained. Bit-identico all'agent di ricerca (max diff 0.0):
  BTC full Sh 1.18/hold 0.92, ETH 1.09/1.42; marginal ADDS, earns_slot, corr_hold -0.01, non-hedge.
- scripts/live/paper_prevday.py: forward-only paper, traccia DUE libri — MODELED ($2000 continuo)
  e REAL-$600 (salta i ribilanciamenti < min-order $5) -> il gap = haircut di fill reale che lo
  scettico aveva segnalato. Inizializzato forward-only da oggi.
- cron_daily.sh: avanza il monitor ogni giorno.
- test: param congelati + causale + bounded + long-short. Suite intera verde.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:37:41 +00:00
676 changed files with 173569 additions and 736 deletions
+7
View File
@@ -0,0 +1,7 @@
# Credenziali IB Gateway PAPER per la ricerca dati (account paper, es. DUQ513966).
# COPIA questo file in .env.ibgw (gitignored) e riempi i valori REALI.
# cp .env.ibgw.example .env.ibgw && chmod 600 .env.ibgw && nano .env.ibgw
# NON committare mai .env.ibgw. Sono credenziali del CONTO PAPER (nessun denaro reale),
# l'API e' comunque READ_ONLY (solo dati storici, nessun ordine).
TWS_USERID=il_tuo_username_paper
TWS_PASSWORD=la_tua_password_paper
+36
View File
@@ -6,6 +6,8 @@ build/
.venv/ .venv/
.env .env
!.env.example !.env.example
.env.ibgw
!.env.ibgw.example
.vscode/ .vscode/
.idea/ .idea/
.DS_Store .DS_Store
@@ -29,6 +31,7 @@ data/funds_watch.json
# dati regime (DVOL/funding/feature cache, rigenerabili) # dati regime (DVOL/funding/feature cache, rigenerabili)
data/regime/ data/regime/
data/venue_watch/
_disp_scratch/ _disp_scratch/
data/regime/dispersion_features.parquet data/regime/dispersion_features.parquet
@@ -46,6 +49,10 @@ Old/**/__pycache__/
# run logs (rigenerabili dagli script) # run logs (rigenerabili dagli script)
logs/ logs/
# cache di ricerca rigenerabile (serie d'ancora, tabelle di segnale intra-bin SKH01):
# 22MB, ~2.4h a ricostruirla, ma e' DERIVATA dai parquet certificati -> non si versiona.
data/_cache/
# cache della ricerca trackE (rigenerabile) # cache della ricerca trackE (rigenerabile)
.cache_trackE_*.npy .cache_trackE_*.npy
@@ -60,3 +67,32 @@ scripts/research/xsec/runs/out/
# blind-signal derived data (regenerable via make_blind.py) # blind-signal derived data (regenerable via make_blind.py)
data/blind/ data/blind/
scripts/research/blind/leaderboard.json scripts/research/blind/leaderboard.json
# forward-monitor runtime state (regenerable, forward-only)
data/paper_prevday/
data/paper_combo/
data/paper_statarb/
data/paper_xsr/
data/paper_dvolspread/
# stato della sorveglianza fee (ultima lettura del tier Deribit, per rilevarne i cambiamenti)
data/fee_watch/
# battuta di cuore del collettore catena (stato runtime, come gli altri monitor)
data/chain_collect/
data/vrp_f_watch/
# giri misurati del trigger di regime CC01 (letti da monitor_health, #12)
data/cc01_regime/
# giri misurati dei sorveglianti generalizzati da cc01 (#16), letti da monitor_health
data/edge_watch/
data/scale_watch/
data/venue_news/
# log esecuzioni del book live (stato runtime, contiene fill/fee del conto reale)
data/live/
# dati esterni di ricerca (on-chain CoinMetrics community, F&G) — non certificati, non in git
data/external/
data/options_daily/
# libro di bordo: il DB e' dato operativo (coperto dal backup), non codice
data/live/trades.db
data/cache_regime_capitale.json
+717 -244
View File
@@ -1,278 +1,751 @@
# PythagorasGoal — Istruzioni per agenti # PythagorasGoal — Istruzioni per agenti
## Stato del progetto — v2.0.0 RESET (2026-06-19) **Come si usa questo file.** Qui sta solo cio' che serve per **non sbagliare una decisione**:
stato, book, numeri citabili, decisioni vincolanti, gate con la loro data, debiti aperti, regole.
Il racconto completo — 69 filoni di ricerca, le misure, i controesempi, gli errori corretti — sta
in `docs/memory/`, estratto **verbatim** da questo file il 2026-08-25 (nulla riscritto, nulla perso).
**LEGGERE PRIMA DI TUTTO.** Il progetto è stato resettato dopo aver scoperto che l'intera ⚠️ **Prima di riaprire un tema, apri il file di memoria che lo copre.** Quasi tutto e' gia' stato
libreria di strategie "validata OOS" (FADE, PAIRS, DIP01, TR01, ROT02, TSM01, XS01, SH01) era misurato, e **il motivo per cui una cosa e' morta vale piu' dell'esperimento che l'ha uccisa**:
**artefatto di uno storico contaminato** — print fantasma del feed Cerbero **testnet** + storico chi la riapre deve battere il motivo, non ripetere la misura.
**Binance/USDT**. Ri-testate sul feed reale, tutte perdono ogni anno (vedi
`docs/diary/2026-06-19-deribit-history.md`, il documento di fondazione).
Cosa è cambiato: | file | contiene | aprilo quando |
- Lo storico è stato **ricostruito da Deribit mainnet** e **certificato**. Universo affidabile = |---|---|---|
**solo BTC/ETH** (tutti i TF). Gli alt sono esclusi (illiquidi/divergenti/non certificabili). | `docs/memory/10-sleeve-e-candidati.md` | TP01 · XS01 · VRP01 · SKH01 · GTAA01 · XSR01, portafoglio | tocchi uno sleeve o i pesi |
- Tutto il codice vecchio (strategie, stack live, ~100 script di ricerca/gate, dati non | `docs/memory/20-ondate-e-scartati.md` | 69 filoni, ogni scartato col suo perche' | hai un'idea "nuova" |
certificati, 60+ diari) è **archiviato in `Old/`** (preservato in git, non cancellato). | `docs/memory/30-piano-capitale-fisco.md` | muri, versamenti, rischio venue, fisco, prop firm | parli di soldi, rendita, orizzonti |
- ~~L'esecuzione è DISABILITATA, il conto mainnet è flat. Non c'è trading live attivo.~~ | `docs/memory/40-produzione-e-deploy.md` | esecutore, tripwire, monitor, libro di bordo, PRIIPs/UCITS | tocchi cio' che gira con soldi veri |
**AGGIORNATO 2026-06-20: l'esecuzione di TP01 è ARMATA e LIVE su Deribit mainnet** — | `docs/memory/50-dati-e-feed.md` | difetti del dato trovati e riparati, catena opzioni | tocchi i feed |
`config/live.json` `execution_enabled=true` + cron giornaliero `live_execute.py --execute` | `docs/memory/60-metodo-e-gate.md` | i gate codificati in `altlib.py` | valuti un candidato |
(cablato in `scripts/cron_daily.sh`). Guardrail: cap **$300 notional/asset**, min order $5, | `docs/research/RESULTS-0822.md` | registro per filone §1-77 | vuoi il dettaglio di un filone |
**disaster-SL on-book −30%**, alert Telegram su esecuzione/errori. **Capitale reale ≈ $600** | `docs/diary/` (146 voci) | la sessione originale, per data | vuoi il contesto completo |
(NON i €2000 nominali del paper trader). Stato corrente: **flat** (target TSMOM risk-off →
BTC/ETH 0.0x, nessun ordine). Solo TP01 è eseguito; XS01/VRP01 restano paper/STAT-MODE.
- Si riparte dalla ricerca di strategie NUOVE, su dati certi, con la metodologia qui sotto.
### Ricerca post-reset (2026-06-19) — esito ---
Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condiviso ## 0. Stato — v2.0.0 RESET (2026-06-19)
`src/backtest/harness.py`). Sintesi in `docs/diary/2026-06-19-research-synthesis.md`.
- **TP01 Trend Portfolio — strategia DIFENSIVA robusta (non alpha)** — **LEGGERE PRIMA DI TUTTO.** Il progetto fu resettato dopo aver scoperto che l'intera libreria di
`src/strategies/trend_portfolio.py`. TSMOM multi-orizzonte (1-3-6 mesi) vol-targeted, long-flat, strategie "validata OOS" era **artefatto di uno storico contaminato** (print fantasma del feed
50/50 BTC+ETH. Config canonica **PORT LF1d** (**>=12h, 1d raccomandato**, vol-target 20%, leva cap 2x): Cerbero **testnet** + storico **Binance/USDT**). Ri-testate sul feed reale, tutte perdono ogni anno.
**FULL Sharpe ~1.30, maxDD ~14%; HOLD-OUT 2025-26 Sharpe ~0.31 / +3.5%** mentre il buy&hold 50/50 Documento di fondazione: `docs/diary/2026-06-19-deribit-history.md`.
faceva −39%/DD60%. Verificata indipendentemente col gauntlet onesto (hold-out + cross-asset +
plateau + deflated-Sharpe 0.999): **regge**. **Valore = taglio del drawdown ~6× vs buy&hold**, NON
generazione di ritorno (CAGR ~16% vs ~48% del buy&hold sul toro).
⚠️ **LOOK-AHEAD (2026-06-19):** un ffill MIXED-TIMEFRAME su barre open-labeled gonfiava il 4h
(~1.60 → reale ~1.1). Il calcolo per-singolo-TF è leak-free, ma **NON scendere sotto le 12h**:
costi+overfitting dominano senza vantaggio (FULL Sh piatto ~1.3 da 12h a 4h; hold-out migliore a 1d).
Deploy/paper a **1d**. Diari `2026-06-19-tp01-verification.md` / `-tp01-lookahead-fix-lf.md`.
Paper trader: `scripts/live/paper_trend.py` (1d). Test: `tests/test_trend_portfolio.py`.
Ri-verifica: `scripts/analysis/{verify_tp01,stress_tp01,tp01_lowfreq}.py`.
- **XS01 Cross-Sectional Momentum (Hyperliquid) — DIVERSIFICATORE che migliora il portafoglio** —
`src/portfolio/sleeves.py:_xsec_returns`. Market-neutral su **19 alt liquidi major** Hyperliquid (1d,
dal 2024): ogni 10g long i 5 più forti / short i 5 più deboli, vol-target 20%. **Scorrelato a TP01
(~−0.12).** Affinato (2026-06-19): **(a) blend di lookback [30,90]** (z-score cross-sectional mediato,
come il multi-orizzonte di TP01); **(b) gate di dispersione p30** (entra solo se la dispersione
cross-section del momentum supera il percentile espandente causale, altrimenti flat — XS è rumore in
regime compatto). Standalone FULL Sh **1.50** / HOLD 1.71 / DD 11%, plateau robusto (lookback, gate
p15-35). **Caveat:** storia ~2.5 anni; STAT-MODE (book a 19 gambe non eseguibile a 2k, serve ~20k) →
monitor forward. NB il gate concentra XS nei regimi dispersi (2025-26 = hold-out alta-dispersione).
Ricerca `scripts/portfolio/{xsec_research,xsec_blend,xsec_dispgate}.py`. Diari `2026-06-19-hyperliquid-xsec`
/ `-xsec-blend` / `-xsec-dispgate` / `-xsec-universe-expansion` / `-trend-multiasset`.
- **PORTAFOGLIO ATTIVO = TP01 (55%) + XS01 (25%) + VRP01 (20%)** (`src/portfolio/sleeves.active_sleeves`):
TP01+XS01 combinato **FULL Sharpe 1.55, HOLD-OUT 1.55, DD 4.4%**. Aggiunto **VRP01** (options
short-vol, sotto): TP01+VRP01 da solo fa FULL Sh 1.30→1.44 / HOLD 0.31→0.40 a peso 20% (3-way da
validare locale con dati HL). Report `scripts/portfolio/run_portfolio.py`. Sleeve a date d'inizio
diverse → outer-join con pesi rinormalizzati (TP01 da solo 2019-20, VRP dal 2021, blend pieno dal 2024).
- **VRP01 Options Short-Vol — DIVERSIFICATORE da FinanceOld/OptionsAgent** — `src/portfolio/sleeves._vrp_combo_returns`.
Put credit spread settimanale (vendi put -0.28, compra put -0.10) gated su IV-rank. Idee portate da
`../FinanceOld/OptionsAgent` (Bear Call Spread + gate d'ingresso). Migliora il lead VRP nudo
(options_vrp_lab): **(a) defined-risk** taglia la coda (worst-week -16.6%→-7.4%, DD 33%→14%);
**(b) gate IV-rank>0.30** = vendi vol solo ricca → ribalta HOLD-OUT da -0.25 a +0.28 (l'alpha è il
filtro di regime). Standalone **FULL Sh 1.10, HOLD 0.60, DD 12%**, positivo/piatto ogni anno (2022
crash incluso). Scorrelato a TP01 (~+0.01-0.07). **CAVEAT:** premio MODELLATO su DVOL ATM (skew non
esplicito), book a 1d, f di stress reale non catturato → LEAD robusto, non deploy pieno. Ricerca
`scripts/research/options_vrp_v2.py` (vs baseline `options_vrp_lab.py`). Test `tests/test_vrp_sleeve.py`.
Diario `2026-06-20-financeold-analysis-vrp-v2.md`.
- **Universo Hyperliquid: ESPANDERLO NON aiuta XS01** (provato): 52-asset / top-liquidità dinamico /
trend-multi-asset → tutti peggiori (small-cap/memecoin diluiscono il momentum relativo; il trend
multi-asset è ridondante con TP01, corr 0.74). I margini su XS sono nella STRUTTURA DEL SEGNALE
(blend + gate), non nel numero di asset. I **51** parquet certificati restano per ricerca futura.
⚠️ Il test "52-asset = negativo" era in parte inquinato dal backfill sintetico (AXS 83%, ALGO/SAND
37% di barre vol=0) poi rimosso — vedi correzione estrazione 2026-06-20 sotto; resta comunque vero
che il long-tail diluisce XS01, ma il numero netto post-fix è 51.
- **Lead OPZIONI VRP (income short-vol) — quantificato, NON deploy** — `scripts/research/options_vrp_*.py`.
Vendita put settimanali che incassa il volatility risk premium (IV>RV), scorrelato al trend (~0.07).
Premio prezzato BS su DVOL reale (`fetch_dvol.py`) + calibrato su quote REALI cerbero-bite mainnet
(`options_vrp_calibrate.py`): **f reale ≈ 1.0** (non 1.29) → Sharpe ~0.71, DD 33%, coda severa
(settimane −15..−26% su LUNA/FTX). Diversificatore DEBOLE a premio reale, e short-vol da modello.
**Regola: niente short-vol da modello in deploy.** Rivalutare quando cerbero-bite cattura un crash
(per il f di stress reale). Diari `2026-06-19-options-vrp-lab` / `-eval-crypto-backtest-options`.
- **Edge deboli/scartati:** ML walk-forward BTC (Sh ~0.57), trend 1h L/S (~1.0), RV ETH/BTC (Sh 0.27,
regime-luck), calendar/seasonality (buy&hold travestito), volume/vol e momentum-reversal (negativi).
- **MORTO/confermato artefatto:** mean-reversion / fade (negativo anche a fee zero — la vecchia
libreria +201%/+1238% era contaminazione); trend 5m/15m (fee).
- **Soffitto strutturale BTC/ETH-direzionale ~1.3** superato SOLO espandendo a un meccanismo diverso:
cross-sectional su universo Hyperliquid certificato (XS01) → portafoglio Sharpe ~1.55.
- **Sweep "strategie alternative" (2026-06-20) — 104 ipotesi / 153 agenti / NIENTE di nuovo regge.**
Ricerca onesta a largo spettro su BTC/ETH+DVOL (harness condiviso vettoriale leak-free
`scripts/research/alt/altlib.py`, 104 script in `scripts/research/alt/runs/`): 11 famiglie
(breakout, trend non-TSMOM, mean-rev gated, DVOL/vol, cross-asset pairs, stagionalità, overlay
rischio, opzioni modellate, microstruttura, ML walk-forward, combo). 16 promettenti, **1 sola**
sopravvissuta alla verifica avversariale (3 scettici) e comunque NON deployabile. Conferma forte
del soffitto ~1.3: ogni PASS era hold-out-fitting o **TP01/TSMOM travestito** (trend-beta del
toro). Unico LEAD: **STA05** (EWMA-cross ensemble, **long-short**) — leak-free, plateau, corr
hold-out **0.53** a TP01, il blend 0.75·TP01+0.25·STA05 alza l'hold-out 0.31→0.59 (full 1.30→1.24,
DD 14→16%); MA hold-out corto (536g) → **forward-monitor, non sleeve.** Lezione harness: valutare
lo Sharpe **MARGINALE vs baseline TP01** (non assoluto) + esigere plateau e jackknife
drop-one-month sull'hold-out prima di PASS (hanno ucciso 13/14 falsi positivi). Diario
`2026-06-20-alt-strategies-100agent-sweep.md`.
- **MARGINAL SCORER (implementato 2026-06-20)** — la lezione "Sharpe marginale, non assoluto" è
ora codice in `scripts/research/alt/altlib.py`: `study_marginal(name, target_fn)` valuta un
candidato direzionale BTC/ETH **sia** in assoluto **sia** rispetto al baseline `tp01_baseline_daily()`
(corr, uplift del blend OOS, beta+alpha residua) e ritorna `earns_slot = (abs!=FAIL) AND
(marginal==ADDS)`. **Regola: una nuova strategia direzionale si giudica su `earns_slot`, non sullo
Sharpe assoluto** (gli overlay-su-TSMOM ereditano lo Sharpe di trend e prendono PASS fasulli —
es. CMB04 PASS assoluto → NEUTRAL marginale). Demo `marginal_demo.py`, test `tests/test_marginal_scorer.py`.
⚠️ **INDURITO 2026-06-21 (onda ortho):** la versione fisso-HOLDOUT + jackknife-mese era
ingannabile — 17/18 book relative-value "ADDS" su una sola finestra 2025 (ETH-bleed dove TP01 è
debole). Tre gate nuovi in `marginal_vs_tp01`: **(1) persistenza multi-cut** (uplift positivo a più
date di taglio, non solo 2025); **(2) edge in-sample** (`has_insample_edge`: lo Sharpe standalone
PRE-holdout dev'essere ≥0.5 — un low-corr a Sharpe ~0.3 "aggiunge" solo matematica di
diversificazione, riportata via `null_pctl_*` vs un asset-rumore a corr-zero); **(3) hedge vs
alpha** (`is_hedge`: un low-corr che paga SOLO quando TP01 è debole — `corr(Sharpe-TP01, uplift
annuo)` molto negativa — è un hedge, non alpha). Verdetti nuovi: HEDGE, NOISE. Sull'onda ortho lo
scorer indurito collassa 17/18 → **1** (`dvol_spread`, unico con edge in-sample reale; comunque
forward-monitor per multiple-testing/storia DVOL corta). Lezione: un nuovo sleeve si giudica su
edge-in-sample + persistenza multi-cut + non-hedge, non sull'uplift di una finestra fortunata.
- **HARNESS REALISM (codificato 2026-06-21, onda intraday)** — due gate nuovi in `altlib.py`,
test `tests/test_harness_realism.py`:
- **`day_boundary_robust(target_fn, tf)`** — un effetto ora/sessione/giorno il cui uplift
marginale **si inverte** spostando il confine del giorno UTC di poche ore è un **artefatto di
etichettatura calendario** (ha ucciso `open_drive`: +0.23 a 00:00 → −0.33 a +8h → ARTIFACT-RISK).
Un segnale di prezzo è INVARIANT (spread 0); un effetto calendario vero è ROBUST (resta positivo;
es. `prevday_range_breakout`). **Regola: ogni segnale calendar/session/hour passa questo test
prima di crederci.**
- **`eval_weights_smallcap(df, target, capital=600, min_order=5)`** — a ~$600 un ribilanciamento
di nozionale < min_order **non si esegue**; la fee proporzionale che `eval_weights` applica a
migliaia di micro-trade sub-dollaro (tipici di un overlay vol-target) è **finzione**. Salta i
sub-min_order e riporta lo **Sharpe haircut** reale vs modellato. **Vale per OGNI sleeve a questo
capitale, TP01 incluso** — lo Sharpe netto onesto a $600 è quello small-cap, non quello modellato.
- **Onestà sul target €50/giorno:** NON raggiungibile su 2000 in 1-2 anni (servono ~130k di
capitale o un DD da rovina). La leva non è la scorciatoia; la via è target-vol + capitale +
tempo. La strategia che *guadagna* esiste, ma a ~+€1.5/giorno su 2000.
Script ricerca: `scripts/research/track{A,B,C,D,E}_*.py` + `trackD_timing.py`. - Lo storico e' **ricostruito da Deribit mainnet e certificato**. Universo affidabile = **solo
BTC/ETH** (tutti i TF); gli alt sono esclusi (illiquidi/divergenti/non certificabili).
- Tutto il codice pre-reset e' archiviato in `Old/` (preservato in git, non cancellato).
- 🚨 **Il README e' rimasto fermo al 2026-06-04 fino al 2026-09-02**, cioe' *quindici giorni prima*
del reset: per 75 giorni la prima pagina del repo ha pubblicato la libreria pre-reset e i suoi
numeri (PORT06 Sharpe 7,84/10,06, CAGR ~79%) come risultati correnti, mentre il progetto li aveva
gia' dichiarati artefatti. Riscritto contro lo stato vero. **La lezione non e' "aggiornare il
README": e' che un reset invalida anche i documenti che nessuno rilegge** — l'inventario di cosa
cita numeri morti va fatto il giorno del reset, non quando qualcuno ci inciampa.
- **L'esecuzione e' ARMATA e LIVE** su Deribit mainnet: **TP01 da solo dal 2026-06-20** (commit `4650aa7`), **il BOOK TP01+SKH01 dal 2026-06-23** (commit `db738bc`, prima lettura di equity 23/06 22:00Z — e' la data d'arming che il TWR e `config/live.json` usano). Capitale reale **~$4.495** dal 04/09 (era ~$635 fino al 25/08, ~$2.060 fino al 04/09)
(NON i €2.000 nominali del paper trader).
- Si riparte dalla ricerca di strategie NUOVE, su dati certi, con la metodologia della §8.
## Obiettivo 📌 **La riga che chiude sei ondate e 69 filoni:** *la ricerca ha smesso di essere il vincolo binding
il 2026-07-26, e sei ondate lo hanno **confermato** invece che ribaltarlo.* I vincoli binding sono
**il capitale che entra** e **il conto che non sparisce**. Il miglior lead misurato vale
**+0,046 €/giorno**; versare €500/mese invece di €250 porta P(traguardo a 20 anni) dal 14% all'85%.
---
## 1. Il book
**LIVE (soldi veri).** Deribit mainnet, **TP01 + SKH01 a 75/25**, nettati in software su **una sola
posizione per asset** (`src/live/book.py`: `W_TP01=0.75`, `W_SKH=0.25`, `WEIGHT=0.5` → 50/50 BTC/ETH).
Esecutore `scripts/live/book_execute.py`, cron **orario** `scripts/cron_book.sh` (minuto **:47**
dal 2026-08-25; era `:07`). Due vincoli, entrambi misurati: fuori dai ~26s del minuto tondo
(rate-limit per-IP) **e** fuori dallo slot di release Deribit (**martedi' 09:00 UTC**, 15-30 min
annunciati), che il `:07` beccava — 4 volte in 63 giorni. **GTAA01, XS01, VRP01, XSR01 NON sono
nel book live.**
**OMBRA (non e' questo repo, ma gira sullo stesso conto).** Dal 2026-09-13 la crontab ha anche
`44 * * * * /opt/AI-OS/automations/TradingBook/scripts/cron_ombra.sh`: il **book traslocato**
(`Adriano/TradingBook`, stesso codice di questo repo al 13/09) calcola ogni ora il target e lo
scrive in un registro, **senza inviare**. Finestra dichiarata fino al **30/09/2026**; confronto col
`:47` di qui con `TradingBook/scripts/confronta_giornata.py`. Verificato il 16/09 (issue #11):
- **cosa legge**: il conto Deribit tramite il gateway interno di TradingBook, con
`TradingBook/secrets/deribit.json`, il cui `client_id` **coincide** (confronto per hash) con
`DERIBIT_CLIENT_ID_LIVE` di cerbero-mcp, cioe' **la chiave con cui questo libro manda gli ordini**;
il feed tramite `TradingBook/data/raw`, un **collegamento** a `data/raw` di qui (sola lettura).
- **dove scrive**: solo nel suo albero, `logs/cron_ombra.log`, `data/live/ombra.jsonl` e
`data/live/equity_seen.json`. Sui giri delle 18:17, 19:17 e 20:44 del 16/09 **nessun file** di
`data/` o `logs/` di questo progetto e' cambiato: il watermark di qui non lo tocca (P16).
- **perche' non invia**: `book_ombra.py` non contiene il percorso d'invio, e
`TradingBook/tests/test_ombra_non_invia.py` lo verifica sul sorgente. ✅ **Dal 21/09 anche il
PERMESSO** (TradingBook#19): il gateway chiede a Deribit un token con scope
`account:read trade:read wallet:none block_trade:none block_rfq:none custody:none` e rifiuta il token
se lo scope concesso contiene un `:read_write`. Misurato il 21/09: senza scope la chiave dava
**tutto in read_write, anche `wallet` e `custody`**; con lo scope ridotto Deribit concede
`trade:read account:read` e risponde `13021 forbidden` a un `private/cancel`. 🚨 **Il segreto resta
quello pieno**: chi legge `TradingBook/secrets/deribit.json` puo' chiedere un token senza scope. Una
chiave Deribit di **sola lettura** per l'ombra la crea solo l'operatore.
- **orario**: `:44` con `timeout -k 10 150`, quindi finisce entro le `:46:40`, prima del giro di qui.
Era `:17` fino al 16/09 e cadeva nello slot di release del martedi' (15/09 09:17: manutenzione
11051, due BUY calcolati sul paper capital nel registro d'ombra); da TradingBook#16 un conto o una
posizione illeggibile danno un giro **saltato**, come qui danno lo stop.
**RICERCA (paper).** Portafoglio a 5 sleeve `src/portfolio/sleeves.active_sleeves`:
TP01 33 / XS01 15 / VRP01 12 / SKH01 20 / GTAA01 20. **Non e' il book live** — quasi tutti i numeri
di portafoglio del progetto sono su questa serie, non su quella che gira.
**Guardrail live** (`config/live.json`, unica autorita' — **non ridichiararli nel codice**):
cap per-asset **`equity × 0.5`, SENZA tetto assoluto**, quando l'equity reale e' leggibile;
`min($3.000, watermark × 0.5)` **solo nel fallback** a equity illeggibile (watermark
`data/live/equity_seen.json`). ⚠️ Fino al 2026-08-25 questa riga dichiarava `min($3.000, …)`
come se valesse sempre: **falso** — `max_notional_per_asset_usd` non morde mai sul percorso
normale (verificato in `src/live/book._cap`). Conseguenza: **il book scala all'infinito a leva
lorda massima 1,0x**, e nessun livello di capitale cambia il profilo di rischio relativo. ·
`min_order_usd` 5 · `disaster_sl_pct` 0.30 on-book sulla posizione **netta** · staleness-gate feed
2 giorni (blocca) · `skh_feed_max_age_min` 30 (allerta, **non** blocca) · alert Telegram.
📌 **Modello di margine: `Cross: Standard Margin` (X:SM) dal 2026-08-31**, cambiato dall'operatore. Prima era **Segregated** (S:SM), e sotto quello l'USDE **non faceva margine**: e' il motivo per cui la misura dell'haircut trovava $0,0000 accantonati — si cercava un parametro non in vigore. Il passaggio e' verificabile dal gateway: `available_funds` USDC e' passato da ~$1.400 a **$2.011,09**, contro $2.010,90 attesi con haircut 5% (scarto **$0,19** — seconda conferma indipendente del 5%). ⚠️ **Cosa ha comprato, misurato**: **$611** di margine utilizzabile — inutile a 0,28x di leva, serve solo sopra ~1,4x che non e' autorizzata — e **+11 USDE (~$11)** di capienza sul tetto. **Cosa e' costato**: sotto segregato l'USDE era **ring-fenced** dalle perdite del libro (solo il silo USDC rispondeva delle posizioni); sotto cross **l'intero conto risponde**. Non morde oggi (perdita massima plausibile ~$617 col disaster-SL, dentro il solo USDC), ma il rischio strutturale e' cambiato verso: **se un giorno il cross non servisse piu', tornare a S:SM ri-recinta l'USDE**. 📌 **X:PM valutato e SCARTATO il 31/08 senza provarlo** — la risposta era gia' nella pagina margini: **Available Balance $1.935,14 contro $2.011,73** di X:SM (−$76,59) e margini piu' alti su entrambe le misure, **MM 3,43% contro 0,37% (~9×)**. Il PM e' basato su scenari e premia il rischio che si **compensa**: due long direzionali nudi sono il suo caso peggiore, e paga lo scenario di stress invece dell'aliquota piatta. **Cosa lo riapre**: il deploy di VRP01 o di un altro sleeve di opzioni — allora il rischio inizia a compensarsi e il confronto cambia di segno. ✅ **Confermato il 31/08 a X:SM attivo** e su misure pulite: la KB da' l'USDe al 5% sotto entrambi i modelli, quindi l'haircut si cancella e l'inversa della riga CROSS da' il margine di POSIZIONE — **$88,23 sotto PM contro $11,64 sotto SM, 7,6×**, e 9,3× la MM. La riga X:SM era una **proiezione di un modello inattivo** e oggi si riproduce al centesimo ⇒ anche la riga X:PM era affidabile: decidere senza provare era corretto. 🚨 **L'«IM %» della pagina margini NON e' il margine delle posizioni**: e' `(margin_balance − available)/margin_balance`, e da noi e' **74% haircut** (e' salita da 2,13% a 2,15% *perche' abbiamo comprato USDE*, non perche' sia salito il rischio). La **MM** e' pulita e ha base diversa. 📌 **La pagina margini non serve piu' come schermata**: la riga CROSS **e'** `available_funds` del gateway (scarto $0,01) e `r0831_margini_conto.live()` la ricostruisce, haircut compreso. 📌 **L'equity che il book somma e' la RICCHEZZA, non la capacita' di margine** — giusta per accorgersi di un'uscita di fondi (il difetto del 26/08), sbagliata se la si usasse per dire quanto margine c'e'.
📌 **Dal 2026-08-26 l'equity del book somma USDC + USDE** (valutato
all'indice pubblico `usde_usdc`): il conto tiene **2.851,9 USDE, quota 64,0%** dal 10/09 14:16Z (allineato al bersaglio di `cuscino_watch` su ordine dell'operatore: 238 USDE venduti in 3 ordini a 1,0000, slack +$266 = OK; era 3.088,7 / 68,7% dal 06/09) (**IDONEO** dal 28/08;
500 → 644 il 30/08 → **3.088,7 il 06/09** su autorizzazione dell'operatore *«usa piu' USDE»* e *«cerca la %
massima raggiungibile»*, dopo che il versamento di **$2.410,14 del 04/09** aveva dimezzato la quota a 14,6%).
🚨 **Il TETTO del venue del 30-31/08 (~31,2-31,9%) il 06/09 NON C'ERA**: sonda a saldo crescente
(`r0906_usde_tetto_sonda.py`, passi 100→20→4→1, stesso metodo del 31/08) da 31,8% a **68,7% senza un solo
rifiuto**, 2.434 USDE in 39 ordini @ 1,0005 (~$1,2 di spread); si e' fermata al **cuscino di regolamento**
(70% = `2 × 0,5 × disaster_sl_pct`, derivato da config), cioe' al NOSTRO limite, non al venue. **«Il 70% non
e' raggiungibile ne' ora ne' mai» (31/08) e' falsificato**; il tetto e' **sparito, non scalato** — e alle
20:58 dello stesso giorno avevo scritto qui «terza conferma della frazione» sulla base di *nessun rifiuto
fino al 31,8%*, che dimostra ≥, non =. Non spiegato (D5): puo' tornare. `venue_cap_frac` → **null**,
`quota_max_frac` → **0,85** (il valore che l'operatore aveva scelto il 30/08 per questo scenario).
✅ **Il cuscino USDC e' sorvegliato dal 10/09** (`cuscino_watch`, §5.17): una perdita del libro (che si regola in USDC)
fa salire la quota da sola, e sotto zero di slack il sorvegliante vende USDE; prima nessuno lo guardava — a −$58 di USDC
il cuscino era gia' scoperto. GATE USDE-01 in §4). ⚠️ **Ogni versamento abbassa la quota**: dopo un bonifico va riportata al bersaglio, e
**dal 10/09 lo fa `cuscino_watch` da solo** (stato ECCEDENTE: slack > 40% del cuscino ⇒ ricompra USDE fino a quota **0,64**, issue #7); prima si rilanciava `usde_convert --quota 0.70` a mano, e il 04/09 nessuno l'aveva fatto. Autorita' dei parametri: sezione `usde` di `config/live.json`
(haircut **5%** — ✅ divergenza chiusa il 31/08, la config diceva 10% ed era sbagliato (`r0831_margini_conto.py`); oggi comunque **non si applica**, vedi sopra — tetto ALLERTA `quota_max_frac` **0,85** (era 50% fino al 06/09; 0,50 resta solo come default di codice in `src/live/usde.py`, la config lo sovrascrive), soglie depeg 0,99/0,95 coi criteri in `_nota_usde`), letta
da `src/live/usde.py` — shadow (sizing orario) e `usde_watch` (sorveglianza 12:35 UTC, cron
proprio, sotto `monitor_health`) derivano entrambi da li'. ⚠️ Il difetto d'origine: `shadow._equity`
leggeva SOLO il conto USDC — la prima conversione avrebbe causato un falso "USCITA DI FONDI −24%"
e vendite indesiderate. Chi aggiunge una valuta di collaterale DEVE passare da `usde.py`/shadow.
🚨 **Una capacita' PUBBLICATA dal venue non e' una capacita' del CONTO: si verifica sul conto, prima che entri in un piano — e costa un ordine da $1.** Due affermazioni di Deribit smentite dal conto in due giorni: la **APR USDC 3,40%** (l'Italia e' nella lista delle giurisdizioni escluse → i nostri $1.412 di USDC rendono **zero**) e «**all Deribit users are permitted to buy and sell BUIDL**» (11 ordini rifiutati, fino a **1 unita' a limite 1,0100 contro ask 1,0004 con 10.730 di profondita'**, tenendo zero BUIDL e $1.412 disponibili → **GATE BUIDL-01 chiuso: NON ENTRABILE**, costo $0, diario `2026-08-31-buidl-test-eligibilita`). ⇒ **L'USDE e' l'unico collaterale a rendimento che il conto puo' usare**, ed e' al suo tetto: le altre tre vie sono chiuse per **giurisdizione** (USDC), **permesso** (BUIDL) e perche' **non e' un dollaro** (stETH 2,23%, che e' ETH: coprirlo e' CC01, gia' parcheggiato a scala ~$20k+). 📌 **`not_enough_funds_in_currency` e' il messaggio GENERICO di Deribit per "non puoi acquisire altra di questa valuta"** — permesso o tetto, mai i fondi. Chi lo incontra salti subito a *questa valuta la posso acquisire, e fino a quanto?* invece di inseguire taglia, cadenza e prezzo come il 30/08.
⚠️ **Il nome "disaster-SL −30%" inganna:** e' **rotolante e simmetrico**, non un massimo di perdita
per trade. Su cicli a ingresso proprio lascia passare perdite oltre −30% senza scattare, e il
peggior DD dall'ingresso misurato e' **−60,6% BTC / −61,5% ETH**. Dettaglio in `40-produzione`.
📌 **Soldi fermi (01-02/09):** on-venue **chiuso con l'elenco intero** — Deribit remunera 4 valute su 50,
le quattro gia' chiuse il 31/08. L'USDC sul conto **non e' fermo** (base di sizing + cuscino). Il fermo
vero sta fuori (~€6k in XEON = lo split-cassa): le opzioni sicure valgono **+€52-62/anno** (BOT 12,5% /
conto deposito 26%), sUSDe rende 2x ma e' **lo stesso emittente dell'USDE** e distrugge lo split.
✅ **L'operatore ha scelto di VERSARE** (piano 27/07: **€5.000 dentro, ~€1.000 fuori** — la protezione
venue satura a qualunque quota > 0). ✅ **VERSATO il 04/09: $2.414,68 di USDC** (dal balance, fra 13:42Z e
14:42Z), **dichiarato il 10/09** in `movimenti_dichiarati.jsonl` — e **l'operatore ha detto che e' l'INTERO
versamento previsto: il piano €5.000 e' chiuso qui**, non resta nulla «in attesa». Per sei giorni era stato solo
*rilevato* (+$2.410,14 dal salto di equity, col mercato dell'ora dentro): la regola di §2 dice il giorno stesso.
`r0901d_soldi_fermi.py`.
**Candidati in forward-monitor** (nessuno nel book): XSR01 · DVOLSPREAD · STATARB · PREVDAY.
📌 **Revisione SETTIMANALE in sola lettura (dal 2026-09-09).** Lunedi' 06:15 UTC `scripts/cron_review.sh` →
`scripts/live/revisione.py` → `src/live/revisione.py`: un revisore **diverso dall'autore** (`claude-fable-5-1`)
rilegge CLAUDE.md, config, crontab, commit, `monitor_health`, 7 giorni di giornale e di diari, stato dei sorveglianti
(~195k caratteri), e scrive `docs/revisioni/<data>.md` **firmato** + la Sintesi su Telegram. **Propone, non esegue:**
l'unico file che scrive e' il rapporto; le decisioni vincolanti (§3) non le ripropone; un'idea «nuova» la propone solo
citando la memoria che ha ucciso la simile. Il rapporto e' opinione di un lettore fallibile (P13): guardia sui numeri
come `analista`. Un modello muto produce un rapporto che lo dice, e un 🚨 (P5). Deciso dall'operatore il 09/09 sera
(«fai») dopo aver **scartato** autoregolazione dei parametri e generazione automatica di strategie: la ricerca non e'
il vincolo binding dal 26/07, e un generatore e' una grid search senza fondo (M3).
---
## 2. I numeri da citare — e quelli da NON citare
Ogni numero di questo progetto va scritto **con la sua lente e la sua banda**. Le stime canoniche
sono all'ancora fortunata; le stime oneste sono la **mediana della banda d'ancora**.
| grandezza | ❌ non citare | ✅ citare |
|---|---|---|
| Sharpe FULL book 5-sleeve | 2,222 (canonico, 97° pctl) | **1,95** [1,81 – 2,12] |
| Sharpe HOLD-OUT book | 2,364 (canonico, **99,6°** pctl) | **1,54** [1,11 – 1,91] |
| maxDD FULL book | 6,07% | **6,85%** [5,99 – 7,94] |
| TP01 hold-out | 0,31 | **~+0,05** — il valore di TP01 e' il **taglio del DD ~6× vs buy&hold**, non il ritorno |
| XS01 standalone | 1,50 / 1,71 / DD 11% | ensemble di fase **1,25 / 1,31 / 10,9%**; maxDD fuori campione **21%** |
| SKH01 | i numeri di ammissione | de-luckato e' **il meno affidabile dei cinque** (l'ancora regala 2/3 del FULL) |
| VRP01 | f = 1,00 | **f = 0,73** misurato sulle quote reali (IC95 [0,698; 0,780], 30/07); **0,71 [0,680; 0,756]** rigirando lo stesso `r0730` con `cblib` causale (09/09 sera, n=27, 0/27 ≥ 1) |
| muro capitale-rendita | $272k (lordo) | **$313k** al netto di fisco **e** funding — banda **[$187k – $1,14M]** |
| P(≥50 €/g), canale funded, 36 mesi | 42% | **2,6%** [1,5 – 4,7], P(zero) 40,3% |
| XSR01 | Sharpe 1,82 (e' una **terza** lente, divisore fisso 50) | **1,79** alla scoperta / **1,56-1,63** a oggi — lente dei gate, sole barre chiuse. Citare sempre la coppia (lente, ultima barra chiusa) |
| soffitto direzionale BTC/ETH | ~1,3 | **~1,15** col funding dentro |
| performance del libro LIVE | «+243%» di equity (e' **96,3% un bonifico**) · e **+11,98%** (lettura 06/09 20:47Z, PRIMA della dichiarazione del versamento di prova) | **TWR +6,66%** spezzato sui TRE movimenti in QUATTRO tratti — +8,14% fino al 25/08 08:00, −0,62% / −0,12% / **−0,63%** dopo (lettura 10/09 13:04Z, dopo la dichiarazione del versamento del 04/09 a **$2.414,68** dal balance); trading da arming **+$13,82**. Era +7,83% / +$62,45 il 06/09: la coda e' la marcatura delle due long dal picco del 06/09, non trade chiusi. Dal 02/09 lo stampa `trades_db.py --report` (debito 14 chiuso). 🚨 **Il 06/09 l'operatore ha dichiarato un versamento di PROVA di €25 il 25/08 alle 08:00Z**, ~$24,9: +3,3% su $647, **sotto la soglia del 10%** del rilevatore, quindi per 12 giorni e' stato contato come trading (un terzo del «trading da arming» e 4 punti di TWR). Ora sta in `data/live/movimenti_dichiarati.jsonl`, letto da `journal.movimenti_capitale` (fonte `dichiarato`, importo dell'operatore, il mercato dell'ora resta nel rendimento). **Regola: ogni versamento, anche di prova, va dichiarato li' il giorno stesso** — il rilevatore vede solo i salti ≥10% |
📌 **Il libro a k=1 rende MENO dell'S&P 500** (15,19% contro 17,40%, stessa finestra): il vantaggio
sta nello **Sharpe** (1,35 vs 0,89), e **senza leva non si converte in rendimento**. A iso-rischio
farebbe +9,0 punti sopra l'indice; a k=1,40 (max difendibile) +3,9 con meno vol. ⇒ **senza leva il
libro non si giustifica come veicolo di ACCUMULO, si giustifica come veicolo di RENDITA** — dove
serve **2,5× meno capitale** ($254k contro $646k) perche' la perpetua vive sul drawdown (misura
2026-08-25, `r0825_piano_10a_500.py`). E **tutta la leva autorizzabile vale quanto €100-150/mese**:
k=1,25 (+15,6% a 10 anni) vale **meno** di €100/mese in piu' (+19,1%).
📌 **L'equivalenza che ordina il piano:** **€100/mese in piu' == +4,07%/anno di drift** (+27% su
tutto il drift del libro). A 10 anni i bonifici fanno il **59%** del risultato.
📌 **Il libro e' FLAT il 28,0% dei giorni** sull'intera storia (2,7% nel 2021, 77,0% nel 2022,
75,6% nel 2026); live, esposto **14 giorni su 64**, leva lorda mediana **0,00x** e **max 0,52x** su
un tetto di 1,0x. **Il cap non ha mai morso: il vincolo e' il segnale.** Riempire quel vuoto con
l'ETF e' stato **misurato e SCARTATO** il 25/08 (`20-ondate`).
📌 **Il libro nei crolli (misurato 09/09, `r0909_libro_nei_crolli.py`): nel GIORNO del crollo PERDE**
(−0,48%/g sui 160 giorni ≤ −5%, positivo nel 18%); per finestra di 20 giorni e' immune-o-positivo e
**dal 2022 chiude > 0 in 8/8 peggiori finestre**, tutto dalla gamba **short di SKH01** (108% dei
guadagni; marcata all'USCITA del trade, quindi arriva *dopo* il giorno). Le 2 finestre perse (2019,
maggio 2021) sono TP01 long dentro un trend non ancora girato. Beta +0,0769 (riproduce §46). ⚠️ Un
solo aggettivo ("guadagna"/"immune") e' l'ordine delle regole: la prima stesura diceva 8/12 GUADAGNA,
con le classi nell'ordine dichiarato sono 4 + 6 immune. **La leva che aumenterebbe il guadagno e' il
peso di SKH01** (37,5/62,5 batte 12/12 episodi ma maxDD 12,1% vs 9,4%): vincolato (§3), gate
`weights_tilt_null` fallisce su una condizione **in-sample** (delta −0,0026, 26/07; cache segnali ferma
al 25/07). **Crollo CATTURATO a quote vere (1-5/06/2026, archivio bite, `r0909_crash_catturato.py`)**:
f_net del put credit spread **0,76 [0,71-0,86] = 0,712 del rally** (rimisurato la sera del 09/09 con spot e DVOL
causali, debito 18; era 0,74 = 0,714); put δ−0,10 costa **1,98×** il modello all'ask ma paga come il modello nel
crollo (0,99-1,04); f al peggior MTM 1,08 (il 2,58 della prima stesura era un
artefatto di quote oltre la larghezza). **NON e' il f di stress della regola del 19/06**: crollo a vol
BASSA (picco DVOL al 29°/46° percentile), gate IV-rank di VRP01 CHIUSO, famiglia INVERSE, 4 strutture.
Diario `2026-09-09-crolli-opzioni-monete.md`.
🚨 **Tre baseline diverse girano sotto lo stesso nome "libro 75/25"**, e lo spread fra loro (0,12 di
Sharpe, 1,7pp di maxDD) e' **piu' grande di quasi tutti gli effetti che il progetto misura**:
`hourly` **1,683 / 11,22%** (la lente di **ogni muro e ogni traiettoria**) · `canonical` 1,800 / 9,56%
· mediana d'ancora 1,626 / 10,4%. **Un Δ accostato al baseline sbagliato cambia piu' del Δ stesso.**
🚨 **«Positivo in N/N ancore» NON e' N osservazioni.** Correlazione media fra le 24 ancore di TP01
0,631 → **N_eff 1,55**; fra le 10 fasi di XS01 0,790 → **N_eff 1,23**. E non si salva sulla differenza
appaiata (N_eff 1,64-2,24). La **banda d'ancora e' ~4× piu' stretta dell'IC95 bootstrap, che CONTIENE
LO ZERO**. Si cita come *robustezza alla scelta dell'ancora* (~2 osservazioni), **mai** come N prove,
**mai** come intervallo di confidenza, e **mai** con un p-value attaccato a un conteggio di ancore.
*Cade la precisione dei numeri, non la direzione delle decisioni.*
🚨 **Il funding dei perpetual non e' modellato in NESSUN backtest** (verificato: zero occorrenze in
`harness.py`, `trend_portfolio.py`, `sleeves.py`, `portfolio.py`, `src/live/`). Costo misurato:
**−2,16%/anno di drift** (2019-2026), −1,39% sulla finestra dello strumento vero, −0,55% sul 2025+.
Esposizione e funding sono **positivamente correlati** → il prodotto ingenuo *esposizione media ×
tasso medio* **sottostima di ~2×**. E' una tassa sul **drift**, quindi colpisce i **muri** molto piu'
dello Sharpe.
---
## 3. Decisioni vincolanti dell'operatore
Prese **con l'informazione completa**, non sviste da correggere. Se qualcuno le ripropone "come da
CLAUDE.md", la risposta e' la colonna *cosa la riapre*.
| decisione | data | non si ri-discute | cosa la riapre |
|---|---|---|---|
| **100% Deribit fino a $20k** — accettato P(perso tutto) 10/18/34/64% a p=0,5/1/2/5% invece di 0/0/4/27% | 26/07 | la soglia $3k | **$20k**, o un cambio di piano, o `p` che diventa stimabile invece che assunto |
| **SOL escluso** — universo direzionale resta BTC/ETH (presidiato da un test) | 22/08 | SOL su un book a 2 gambe con questi dati | ~3 anni di storia SOL certificata (**non prima del 2028**), o un meccanismo che non sia TP01/SKH01 congelati. **XRP misurato il 09/09 con lo stesso harness: diluisce uguale** (hold-out −0,169 in 0/24, un anno buono, 5m flat 27-61%); su Deribit i perp liquidi (≥$10M/g) sono SOLO BTC/ETH/XRP/SOL — `r0909_deribit_universo.py` |
| **Niente short-vol da modello in deploy** — e niente long-vol scalp da modello | 19/06 | — | un `f` di stress reale misurato su un crash catturato **con IV-rank > 0,30 e sulla famiglia USDC-lineare** — il crollo del 1-5/06/2026 (misurato 09/09) e' catturato ma a vol bassa, sotto il gate e inverse: soddisfa la forma, non la sostanza |
| **Non de-esporre il weekend** (porta il 38% del gross di TP01 nel 31% del tempo) | 17/07 | — | ogni proposta "risk-off weekend" parte **REFUTED** salvo null de-levering superato |
| **Peso 75/25 confermato 3 volte** (24/07, 26/07, 24/07-follow-up) | 26/07 | — | `weights_tilt_null` superato, che finora **fallisce** |
| **Fee Deribit: ≤5 bps/lato → non si tocca nulla; >10 bps → rivedere il peso SKH01** (regola decisa *prima* di vedere il numero) | 26/07 | — | il sorvegliante `fee_watch` allerta da solo |
| **GTAA01: decisione tenere/bloccare RINVIATA a $15k di book** — sotto quella soglia lo sleeve **non e' deployabile** (`GTAA_MIN_CAPITAL` $3.000 allocati al peso 20%), quindi finora e' manutenzione senza beneficio incassabile. Contributo misurato a iso-rischio **+0,095 / +0,124** di Sharpe secondo la fase: **reale e sempre positivo**, e delle stesse dimensioni dello spread fra le baseline (0,12) | 28/08 | «GTAA01 non contribuisce» — la misura dice il contrario | **il book a $15k**, che il giornale sorveglia da solo (`journal.SOGLIE_CAPITALE`) |
| **Gradino di leva NON autorizzato oggi.** 1,25x autorizzabile *a condizione*; **1,50x BOCCIATO** (peggior giorno strutturale 21,48% > 20%); **k max difendibile 1,40** | 23/08 | il 1,50x | ✅ la **chiave di scala e' costruita** (01/09, inerte a 1,00): restano **GATE SCALA-01** (§4) e il rifacimento di `r0726_fee_sensitivity` al nuovo lordo — la sua conclusione *"liquidation fee 1% irrilevante"* era condizionata a lordo ≤1x, a 1,25x costerebbe **1,25%** |
| **Quota USDE = 0,64, DERIVATA dal cuscino, con isteresi automatica** — bersaglio unico `1 − frazione_cuscino × (1 + cuscino_margine_frac 0,20)`; vende sotto zero di slack, ricompra sopra il 40% del cuscino (`cuscino_watch`, cron :53). Sostituisce il **0,70 del 30/08**, che lasciava slack zero per costruzione. Costa ~$10/anno di resa rispetto a 0,70; accettato | 10/09 | «portare la quota al massimo» — il massimo e' 0,70 e vende alla prima ora in perdita | un cambio di `cuscino_margine_frac` in config (0,10 ⇒ 0,67, al prezzo di un ⚠️ dopo ogni vendita), o un cambio di `disaster_sl_pct`/`WEIGHT` che sposta il cuscino stesso |
✅ **La chiave di scala ESISTE dal 2026-09-01** (era il debito che rendeva la regola *"ogni cambio di
scala passa dal cap di config"* non implementabile). `book_scale_k`, letta da `src/live/book._scala`
e applicata **DOPO il clamp** in `book_net_target` — l'ordine non e' di comodo: applicandola PRIMA il
cap se la mangerebbe proprio nei giorni di massima convinzione (k_eff tornerebbe a 1,00 a ogni k),
cioe' sarebbe un cambio di **FORMA** travestito da cambio di taglia, che la curva `g(k)` con cui il
gradino viene autorizzato **non descrive**. 🚨 **La chiave e' INERTE: assente = 1,00 = il libro di
sempre, bit-exact** (T7, `max|diff| = 0.0`) — `config/live.json` **non e' stato toccato**. Guardie:
`LEVA_LORDA_MAX` 1,25 e `SCALA_LADDER` (1,00 · 1,25) sono **costanti di CODICE, non di config** (un
tetto nello stesso file della chiave sarebbe un lucchetto con la chiave attaccata: il gradino a 1,50
richiede una modifica di codice, quindi una review); il tetto e' **sul PRODOTTO**
`n_asset · frac · scala` e l'invariante del disaster-SL e' `n_asset · frac · scala · disaster_sl_pct
≤ 0,50` (la guardia che morde per **prima**: da' scala ≤ 1,67x e scatta se qualcuno allarga lo stop —
🚨 e **`disaster_sl_pct` NON si sostituisce con la distanza di un pavimento di put**: darebbe 2,28x
sulla carta, ma la put limita UNA finestra e i drawdown di BTC sono grind di 290-818 giorni, su 8
finestre −33,6% → 77% dell'equity a 2,28x. Misurato in §72, scritto qui prima che sia comodo);
una scala fuori scaletta o fuori tetto **NON viene tagliata** — `book_execute` si ferma, non invia e
allerta (`ScalaNonAutorizzata`); e **la scala vive solo sul percorso fidato** (equity reale
illeggibile ⇒ 1,00, cosi' "il fallback non e' piu' permissivo" e' vero per costruzione).
Sorvegliante `src/live/scale_watch.py` (giornaliero in `cron_daily`, 3 domande / 3 azioni / 3 stati,
una allerta per streak, marcatore scritto solo dopo invio riuscito), giornale append-only
`data/live/scale_history.jsonl`. Test **T1-T11 in `tests/test_book_scale.py` (18, tutti verdi)**.
📌 **Cio' che il sorvegliante NON puo' fare: impedire la modifica** — la rende visibile entro 24h e
attribuibile. Come `venue_watch`: non protegge il saldo, compra tempo.
---
## 4. Gate pre-registrati — con la loro data
Un gate si decide **alla data**, coi criteri scritti **prima**. Anticiparlo e' selezione
sull'hold-out; cambiarne le soglie guardando l'esito, pure.
| gate | data | criterio | stato |
|---|---|---|---|
| **USDE-01 (eligibilita' reward)** | 2026-08-29 | ≥1 reward entro il 29/08 → IDONEO e si apre la decisione di QUOTA (dell'operatore; tetto allerta 50%, mai 100% — R1 emittente non recuperabile); zero → si riconverte e la pista si chiude | ✅ **CHIUSO IDONEO** il 2026-08-28 12:35Z: primo reward **+0,052055 USDE** rilevato per delta al netto dei trade, coi criteri pre-registrati il 26/08 PRIMA dell'esito. **QUOTA DECISA il 30/08** (l'operatore ha anticipato il rinvio: *"porta in usde tutto il capitale che non viene usato"*): bersaglio **70%**, `usde.quota_target` in config (📌 **dal 10/09 la quota decisa e' 0,64, derivata dalle bande del cuscino: §3 e §5.17**). Tasso a 4 finestre (30/08): **3,26% annuo, banda bootstrap [1,13% – 4,51%]** — 3/4 hanno pagato (0,00 · 3,80 · 4,51 · 4,51%), e la banda larga 3,4 punti **e' il risultato**: a n=4 il tasso non e' misurato. `usde_watch.rendimento()` lo stampa **col suo n**; `quota_da_decidere()` lo chiede ogni giorno da lunedi'. 🚨 **L'EV non puo' scegliere la quota** — e' lineare in q, quindi il suo argmax e' sempre un angolo (0% o 100%): ogni quota interna nasce da un criterio sulla **coda**, dichiarato non ottimizzato (M8). Il resto e' misurato (`r0830_usde_quota.py`, diario 30/08): **hazard di pareggio = l'APR** (EV-positiva sse Ethena sta sotto il 3,3%/anno, numero **assunto** come il `p` di Deribit) · l'haircut **non morde a nessuna quota** fino al 90%, nemmeno a leva 1,50x con USDE marcato a 0,95 (29× di cuscino): **il vincolo non e' il margine** · la resa di oggi vale **$16/anno**, meno di UN mese di versamento ⇒ la leva binding resta il **bonifico** · gia' a 24,2% l'evento emittente vale **3,1× il maxDD dell'intero libro**. 📌 **Aspettare costa $1,33**: alzare a 50% fra 4 settimane invece che subito lascia sul tavolo $1,33 di resa (conversione reversibile a ~6 bps) e porta il campione da **4 a 32 finestre**, stringendo la banda ~2,8×. 🚨 **DUE FATTI DEL 30/08 CHE CAMBIANO IL GATE** (diario `2026-08-30-usde-quota-tetto-venue`). **(a) TETTO DEL VENUE ≈31-32% dell'equity — e' una FRAZIONE, non un livello.** 🚨 **SUPERATO IL 06/09: il
tetto non c'era piu'** — quota portata al **68,7%** con 39 ordini senza rifiuti, fermata dal cuscino di
regolamento (§1). Quanto segue e' la misura del 30-31/08, vera allora, tenuta perche' il tetto puo' tornare. Ogni acquisto oltre il tetto e' rifiutato con `not_enough_funds_in_currency` pur avendo **$1.400 disponibili**: messaggio **fuorviante**, che ha fatto inseguire tre ipotesi sbagliate (taglia, cadenza, prezzo). Che sia un tetto e non un problema d'ordine e' provato a saldo neutro (BUY rifiutato → SELL OK → BUY riaccettato → BUY rifiutato); che sia una **frazione** e' provato il 31/08 lasciando scendere l'equity di $8: **il tetto e' sceso con lei** — 30/08 in [644,18·645,18) con equity $2.063,79 = **31,21-31,26%**, 31/08 in [643,18·644,18) con equity $2.055,56 = **31,29-31,34%** (0,05pp di scarto, dentro il rumore dell'equity che oscilla ±$2-8/ora). ⚠️ **Ri-sondato il 31/08 dopo il passaggio a X:SM** (l'ipotesi era che il tetto dipendesse dal modello segregato): **[654,18-655,18) con equity $2.054,90 = 31,84-31,88%**. Il modello ENTRA nel tetto ma **non lo spiega** — ha comprato **+0,55pp = +11 USDE (~$11)**, non le centinaia che servirebbero. ⇒ **il tetto SCALA col conto**: la quota resta ~31% e il valore in dollari cresce col capitale, ma **il 70% non e' raggiungibile ne' ora ne' mai**. 🚨 **Deribit non lo documenta**: l'articolo ufficiale *Yield/reward bearing coins* descrive un **Cap ETHENA** che diluisce il **TASSO** a livello di exchange (`User APR = min(bal_exchange, cap)/bal_exchange × Ethena APR`) e **nessun limite sulle quantita' detenibili** da un conto. Ora e' in config (`usde.venue_cap_frac` 0.312, bordo basso dei bracket) e `usde_convert` **rifiuta il piano prima di sparare** invece di scoprirlo dal venue. **(b) L'USDC NON frutta SUL NOSTRO CONTO — misurato, e la premessa del gate e' RESTAURATA.** `public/get_currencies` dice USDC 3,4000% (USDE 4,1071%) e per qualche ora quel numero e' stato scritto qui come se fosse nostro: **era un listino del venue, non un accredito**. Deribit paga i reward USDC **una volta al MESE** («paid out as a single monthly payment early in the following month», accrual 00:00 UTC sulla **minima equity**) — non ogni giorno come l'USDE, ed e' per questo che una sorveglianza giornaliera non poteva vederli. Verificato sui **due confini di mese a libro FLAT**, dove `equity == balance == USDC` e ogni scalino sarebbe un accredito: **29/06→08/07 equity 598,06 costante, 237/237 ore ferme, 0 scalini** (attesi $0,45) e **31/07→03/08 equity 596,92 costante per 4 giorni** (attesi **$1,72 contro una risoluzione di $0,01, 172×**). **Zero misurato, non zero sotto soglia.** ⇒ il guadagno di tenere USDE e' il **tasso pieno ~4,1%**, non uno spread: **~$26/anno** sui $644. 🚨 **Il motivo ora e' DOCUMENTATO, e non e' MiCA come avevo ipotizzato**: l'articolo ufficiale elenca le giurisdizioni escluse dai reward USDC e **l'ITALIA c'e'** (con Canada e Giappone: non e' una lista MiCA, e' policy di giurisdizione Deribit). ⚠️ **E la finestra di pagamento e' piu' larga di quella che avevo controllato**: «within the **first two weeks** of the following month». Rifatta la verifica sulle due settimane vere: **luglio e' conclusivo** (atteso $1,72 contro un'escursione TOTALE dell'equity di **$0,48** in 1-16/08, zero scalini compatibili), **giugno NO** (il libro ha iniziato a operare a meta' mese e il rumore e' della taglia del segnale). Quindi: **una finestra conclusiva piu' la lista ufficiale**, non due finestre — il «172× la risoluzione» del 30/08 era sovra-affermato. 📌 **Un tasso pubblicato non e' un tasso incassato: si verifica sul CONTO** — ed e' costato una query su una serie che avevamo gia'. Strumento: **`scripts/live/balance_watch.py`** + `cron_balance.sh` (orario :42, sola lettura) registra il **balance a 8 decimali**, la serie che mancava. 📌 **Il vincolo che l'analisi del margine non aveva guardato**: P&L e funding dei perp USDC-lineari **si regolano in USDC**, quindi la quota massima difendibile non e' data dall'haircut ma dal **cuscino di regolamento** = disaster-SL sulla massima esposizione lorda (`n_asset × frac × disaster_sl_pct` = **30% dell'equity**), che lascia esattamente il **70%** — coincidenza per costruzione, zero slack (M8: non e' un argmax). 📌 **Il costo del NON averlo e' ora documentato e vale il criterio**: un'equity negativa in una valuta paga una *collateral fee* dello **0,05% AL GIORNO** — **18,25%/anno**, addebitata al secondo, **4,3× la resa USDE che si starebbe comprando** (fonte: KB *Cross collateral specifications*). Il ribilanciamento automatico NON salva: scatta solo a **$1M** assoluti o al **100% della cross equity**, soglie che a $2k non si toccano mai — si sanguina la fee e basta. Il 30/08 avevo scritto «Deribit lo finanzia a interesse» **senza il numero**: il numero e' questo, e rende il cuscino piu' giustificato, non meno. Attrezzo: **`scripts/live/usde_convert.py`** (dry-run di default, guardie proprie; NON passa da `execution.ALLOWED`, che resta ai soli due perp) |
| **STATARB** | 2026-09-27 | soglie 24/07 (non toccate), **copiate verbatim** da `scripts/research/r0724_statarb_deploy_gate.py` (docstring e costanti; diario `2026-07-24-goal-50eur-roadmap.md` §Migliorie 1). Metrica: «Sharpe annualizzato di net_modeled su TUTTA la finestra forward (nessuna sottofinestra), da data/paper_statarb/returns.jsonl». «Sharpe >= 0.5 -> CANDIDATO AL DEPLOY: proporre peso {10,15,20}% del book Deribit, giudicato con weights_tilt_null + stima maxDD combinata < 15%. Deploy solo se il tilt-null passa.» · «0 <= Sh < 0.5 -> ESTENDI una sola volta di altri 90g (decisione 2026-12-26). Alla seconda scadenza: o >=0.5 o RITIRO. Niente terza proroga.» · «Sharpe < 0 -> RITIRO dal forward-monitor». Guardie «tutte richieste per il deploy»: «fill-haircut cumulato \|MODELED - REAL\| < 0.5 pp» · «config invariata (W=45, sgn=+1)» · «maxDD forward < 10%». Addendum 25/07: Sharpe della **statica sempre-short** a pari vol-target sulla stessa finestra — «Non e' una soglia binding», diagnostica obbligatoria; renderla binding spetta all'operatore. La lettura si fa lanciando lo script (`uv run python scripts/research/r0724_statarb_deploy_gate.py`), che applica la regola dal 27/09 | ✅ monitor riparato e rigenerato il 26/08: la serie vera da' Sharpe **−1,61** a oggi → coi criteri invariati punta al **RITIRO**. Si legge il 27/09, non prima |
| **XSR01** | 2026-10-23 | Sharpe ≥1,0 **E** haircut ≤40% — dal 26/08 il numero decisivo e' `r0826_xsr_haircut.py` a **pavimento $10**, citato con la frazione di ordini eseguiti — poi `weights_tilt_null` e **capitale ≥$20k** | ✅ **riscritto il 26/08 su decisione dell'operatore** (dichiarato prima dell'esito, stringe: diario `2026-08-26-xsr01-gate-riscritto`): capitale allineato a "100% Deribit fino a $20k"; serie forward rigenerata (31 barre vere, Sharpe −2,72). Sotto la lente RENDITA il sleeve resta **eguagliato da un conto remunerato** (📌 sotto) |
| **DVOLSPREAD** | kill 2026-10-24 se Sh<−0,50; decisione 2027-01-24 | (a) Sharpe>0 (b) marginale ADDS+robust_oos+insample_edge (c) **DSR ≥0,95** (d) `weights_tilt_null`; **veto** se barre attive <80% → si estende, non si decide | ✅ serie rigenerata il 26/08 (−4,41 a oggi, era −14,73 sulla serie rotta); il veto barre-attive ora conta barre VERE e la guardia PREMATURO sorveglia il monitor |
| **GATE PROP-01** | chiuso 22-23/08 | (a) listino 13/13 ✅ (b) ancora SKH01 23/23 ✅ (c) economica+sopravvivenza 2/2 ✅ | **chiuso 3/3** — ma il numero operativo e' sceso 42% → 7,8% → 4,4% → 2,6% |
| **GATE PREVDAY-01** | decisione **2027-06-21** (scritto 23/08, `RESULTS-0822` §54); kill leggibile da ~18/12/2026 | 7 condizioni (a)-(g) tutte necessarie + **veto d'integrita'** (≥80% barre ricostruibili, divergenze non crescenti) + **kill** Sharpe forward **giornaliero** < −0,50 su ≥180 giorni attivi, senza ri-ottimizzare | **5/7** (= l'«8/10» di §54 e di `20-ondate`, contato su una base a 10 voci: stessa sostanza, base diversa): la cella che GIRA non e' quella che la selezione onesta sceglie, e quella viva **fallisce il DSR** (0,905) — (a) e (b) sono STRUTTURALI, nessun giorno di forward le cambia. ✅ **Kill e veto cablati il 10/09** in `paper_prevday.py` (issue #4; fino ad allora esistevano solo nel testo e la revisione del 09/09 lesse «senza data»): al 10/09 Sharpe giornaliero +0,95 su 81 giorni (MDE ±4,25), 1942/1943 barre ricostruibili, kill NON MATURO. Decisione dell'operatore (10/09): si tiene la data — verso i 50 €/g PREVDAY vale centesimi, non si spende altro |
| **GATE SCALA-01** (portare `book_scale_k` da 1,00 a 1,25) | non prima del **2027-02-28** (= 180 giorni dal **01/09**, primo giorno di `scale_watch`: A2 conta da quando il criterio e' MISURATO, non dall'arming — decisione dell'operatore 10/09, issue #5. «Non prima del 2026-10-01», scritto il 01/09, era incompatibile con A2 per costruzione) | 9 condizioni **tutte necessarie** (`SPEC-scale-key` §6.2): A1 gradino di `SCALA_LADDER` · A2 k0 in produzione ≥180g col criterio passato ogni giorno · A3 **C1-C5 di WORST-DAY ricalcolati OGGI**, non ereditati · A4 invariante disaster-SL · A5 tetto sul prodotto · **A6 ANTI-RECENCY** (il criterio deve passare anche **escludendo gli ultimi 90 giorni**) · A7 `r0726_fee_sensitivity` rifatto · A8 la modifica e' **una riga di config + una di giornale, zero codice** · A9 T1-T11 verdi | ◐ **A8/A9 FATTI il 01/09** (chiave inerte + 18 test); **A2 non maturo** — la specifica impone ≥30 giorni a 1,00 col sorvegliante attivo *prima* di eseguire il gate: «l'unico modo di scoprire che il sorvegliante e' rotto mentre la leva e' ancora 1,00». 📌 **A6 oggi NON morde** (k ammesso ~3,5x contro un gradino di 1,25x): il vincolo che morde e' il **disaster-SL**. E' scritto ora **perche' non e' comodo per nessuno**, non quando servira' |
| **`edge_watch`** (kill del book live) | continuo | **(A)** Sharpe rolling 36m < −0,5 → si riapre `weights_tilt_null`+DSR, il book **non si spegne da solo**; **(B)** in un anno con DD buy&hold >10%, il DD di TP01 deve restare <75% di quello | stato 27/07: Sharpe 36m +1,51, protezione **8/8** |
📌 **XSR01 sotto la lente RENDITA (25/08): il meccanismo vale ~0.** Mescolarne i rendimenti da' lo
stesso muro ($476-484k contro $478,7k), e un **conto remunerato** allo stesso tasso (3,72%, vol 0, corr 0,
nessun secondo venue) da' **$477,6k** — identico dentro la risoluzione MC, e **meglio** al 4,0%. Cio' che
si compra e' un **drift scorrelato**, non la scorrelazione (a drift zero il muro SALE). E l'haircut lo
mangia: **non pareggia un conto al 4% nemmeno a haircut ZERO**; pareggia il 2% solo sotto il 46%.
Per un 25% sopra il C\* vero servono **$60.000** di conto. `r0825_xsr_rendita.py`.
📌 **Un gate superato non e' un numero confermato:** differenze e livelli ereditano la fortuna
d'ancora in modo diverso (nella differenza si cancella in parte, nel livello per niente).
---
## 5. Debiti aperti — difetti noti NON riparati
1. ✅ **RIPARATO E RIGENERATO (2026-08-26).** `advance()` consumava la barra del giorno in corso:
ora tutti e 6 i monitor filtrano con `src/live/paper_guard.nuove_chiuse` (barra chiusa =
`ts + cadenza ≤ adesso`), le 4 serie rotte sono **rigenerate dallo stesso `start_ts`**
(`scripts/live/paper_regen.py`, vecchi file in `*.pre_regen_20260826.*`): statarb
**+1,95 → −1,61**, dvolspread −14,73 → −4,41, xsr −4,98 → −2,72, prevday +0,39 → +0,40.
**Nessuna data di gate si sposta.** La guardia e' cablata: `monitor_health` stato **PREMATURO**
(ultima barra che chiude dopo l'mtime, grazia 5 min; `open_labeled=False` per collect_chain).
`paper_portfolio` NON rigenerato (GTAA su ADJUSTED_LAST: replay ≠ serie registrata, P12) —
storia pre-fix dichiarata corrotta, coda non chiusa tolta. ⚠️ Nel fix, D6 pagata di nuovo:
`asi8` in pandas 3 e' in `us`, non `ns` — blindato con test su tre risoluzioni.
2. ✅ **RISOLTO (2026-08-28, decisione dell'operatore).** Il trasporto degli allarmi era un punto
singolo di guasto — 6,9% di invii falliti (2/29) e `alerted=True` marcato **prima** dell'invio,
quindi un 🚨 perso era perso per l'**episodio intero** (200-2.324 ore). Ora `venue_watch.run_once`
riceve il **sender iniettato** e il marcatore «gia' detto» si scrive **solo dopo un invio
riuscito**; su fallimento si disfano i soli marcatori — non le misure — e per il lock **le ore
continuano a correre**, cosi' una manutenzione che sfora la grazia sale ad ALERT anche col
trasporto giu'. `notify()` accetta `tentativi` (venue_watch: 3) e l'esito finisce nel log.
⚠️ Resta scoperto **ogni altro chiamante di `notify()`**: la disciplina «commit dopo l'invio»
e' oggi solo in `venue_watch`.
3. ✅ **RISOLTO (2026-08-26, decisione dell'operatore: opzione "riscrivere adesso").** Gate
XSR01 riscritto in modo dichiarato, prima dell'esito, in direzione che stringe: capitale
$5k → **$20k** (riconcilia con la decisione 26/07, che e' posteriore e governa), gamba haircut
letta da `r0826_xsr_haircut.py` a pavimento $10 con la frazione di ordini eseguiti accanto
(misurata: haircut FULL −1,1% con **22% di eseguiti** — la guardia da sola era vacua), soglie
numeriche INVARIATE. Diario `2026-08-26-xsr01-gate-riscritto.md`.
4. ◐ **(a) RISPOSTA TROVATA ALLA FONTE (2026-08-28), (b) resta aperta.** *Non sono pareri fiscali.*
**(a) I derivati stanno in `c-quater` → 26%, non in `c-sexies` → 33%.** Circolare AdE **30/E del
27/10/2023**, §2.3.2 e §3, verbatim: «In generale, i redditi derivanti da **contratti derivati,
ancorche' aventi come sottostante cripto-attivita'**, costituiscono redditi diversi ai sensi
dell'articolo 67, comma 1, **lettera c-quater)**» e «qualora le cripto-attivita' costituiscano il
sottostante di un contratto derivato (ad es. contract for difference o **future**) i redditi
derivanti da tali strumenti finanziari costituiscono redditi diversi ai sensi dell'articolo
c-quater)». La circolare conferma esplicitamente che la riforma 2023 non sposta nulla: «tali
contratti **non rientrano** nell'ambito di applicazione della lettera c-sexies». ⚠️ Conseguenza:
**le minusvalenze su derivati NON si compensano con le plusvalenze cripto** (categorie diverse) e
non c'e' franchigia. **Il collaterale sconta il 2‰**: Deribit non e' intermediario residente,
quindi non applica il bollo e scatta l'*imposta sul valore delle cripto-attivita'* sul valore al
31/12, in RW (a $2.068 fa **~$4/anno**: obbligo dichiarativo, non un costo). 📌 E la conversione
**USDC→USDE non e' fattispecie realizzativa** — §3.1: «dal 1° gennaio 2023 non costituisce
fattispecie realizzativa lo scambio di una cripto-valuta con un'altra», col valore di carico che
si trasferisce. **Resta da chiedere:** se il perpetual *inverse* regolato in cripto sia il caso
letterale della circolare (che nomina CFD e future) o serva un passaggio in piu'.
**(b) I payout di una prop firm: ancora aperta.** Le fonti convergono su **lavoro autonomo**
(partita IVA, ATECO, forfettario 5% per i primi 5 anni poi 15%, imponibile da coefficiente di
redditivita'), **non** redditi diversi al 26%. **Nessuna prassi ufficiale**, e il coefficiente
esatto dipende dal codice ATECO.
5. ✅ **FATTO (2026-08-26):** `test_leva_massima_da_config...` cancellato con nota in
`tests/test_fee_sensitivity.py` — misurava `frac · n_asset`, con una chiave di scala avrebbe
continuato a passare smettendo di controllare. ✅ **CHIUSO il 2026-09-01:** la chiave esiste e la
sostituzione e' cablata — **T2** (tetto sul PRODOTTO `n_asset · frac · scala ≤ LEVA_LORDA_MAX`) e
**T3** (invariante disaster-SL) in `tests/test_book_scale.py`, che importano i bersagli da
`src.live.book` invece di ridichiararli (P1). Il vecchio test resta **cancellato**, non rilassato,
e **T11 lo verifica**.
6. ⚠️ **TLT ha 13,5 anni di storia in meno** (parte 2016-02 invece del 2002) → **GTAA01 gira su
CINQUE gambe prima del 2016**, e l'assente e' quella obbligazionaria. Non e' un fetch da rifare (IB
ritorna 0 barre). ⇒ in-sample e hold-out di GTAA01 **non sono la stessa strategia**.
7. ✅ **RIPARATO (2026-09-02).** Il docstring di `book_execute.py` prescriveva "ogni ~230 minuti"
mentre il cron gira **ogni ora** (`47 * * * *`): era il docstring a essere sbagliato, e chi
avesse "corretto" il **CRON** verso il docstring avrebbe spostato il libro dalla riga 1h (rotolante:
BTC 0 scatti / ETH 1 in 7-8 anni) alla riga 4h (BTC 2, contro 1 del pavimento); la peggiore
misurata e' 24h (ETH 5, con 2 in 30 giorni) — `r0823_sl_anchor.py`. Ora il docstring dichiara
**CADENZA: ORARIA** con la ragione (giro idempotente: latenza SKH01 ≤1h; il rotolante e'
**controllato** ogni ora e ri-ancorato solo oltre la tolleranza di `ensure_disaster_sl`, mark
+5,263%/−4,762% o taglia >10%, quindi lo stop siede fra **−33,5% e −26,5%** dal mark corrente —
«si ri-ancora ogni ora» era una frase sbagliata, corretta in revisione il 02/09; e «girare piu'
fitto non costa ordini» pure: 22 dei 48 ordini live sono ri-taglie |Δ|≤$10, deadband in valuta
assoluta, C2) e il divieto esplicito. **`tests/test_book_cadenza.py` (10 test)** tiene
d'accordo le tre dichiarazioni — docstring, riga in `cron_book.sh`, **crontab installata**
(letta con `crontab -l`, **tutte** le righe attive: due righe sono due esecuzioni; tre stati —
illeggibile ⇒ SALTATO, leggibile senza questo progetto ⇒ SALTATO, leggibile col progetto ma senza
`cron_book.sh` attivo ⇒ **ROSSO**) — verifica 60 min < `skyhook.LTF_MIN` 230 < 240 (riga 4h),
minuto ≠ :00 **e fuori dallo slot di release** (`venue_probe.in_release_window`, col :07 come
controllo positivo). Diario `2026-09-02b-debito-7-cadenza-docstring.md`.
8. ⚠️ **Il Rulebook Deribit** (ADL, perdita socializzata, *emergency powers*, conti dormienti) **non
lo sorveglia nessuno**; `MAINT_GRACE_HOURS`=2 **presume** gli annunci invece di leggerli.
✅ *Ridotto in parte il 2026-08-25:* `src/live/venue_probe.py` interroga l'API **pubblica**
Deribit e distingue **manutenzione / venue giu' / NOSTRO gateway / non vedo**, e lo slot di
release (**martedi' 09:00 UTC**) e' ora una costante dichiarata e testata. Resta scoperto il
Rulebook vero e proprio: la sonda legge se il venue *risponde*, non cosa il venue *annuncia*.
9. ✅ **INDAGATO E RIPARATO (2026-08-26, `r0826_skh_band_drift.py`).** Il dato regge (taglio
al 02/07 riproduce l'audit: 1,6376; in-sample 1,424 identico su ogni taglio); la deriva era la
finestra hold-out che si allunga — e 📌 **la SOLA settimana 15-22/08 vale +0,35 di Sharpe
hold-out** (rally ETH con SKH01 long): il numero e' fragile, coerente con §2. Il test ora
**taglia il feed al 02/07** e verifica la riproduzione stretta (±0,02): si rompe solo se
cambiano codice o dato sulla finestra congelata. Suite: **775 passati, 0 falliti** (26/08).
10. ⚠️ **Nessuna tabella pubblicata prima del 22/08 contiene fisco E funding insieme.** L'unica
congiunta e' quella in `30-piano-capitale-fisco.md` — le altre vanno lette con lo sconto.
11. 🚨 **Le credenziali Deribit esistono SOLO dentro il gateway** (`cerbero-mcp`): in locale c'e'
solo `CERBERO_TOKEN`. Quindi il gateway e' un **punto singolo di guasto non aggirabile** —
**4 dei 5 traceback in 63 giorni** sono suoi (404 su `get_positions`, 502, due `ReadTimeout`),
ed e' l'unico pezzo della catena che possediamo. Un fallback diretto ai **privati** Deribit
(conto/posizioni/ordini) richiede **chiavi API create dall'operatore** sul conto Deribit:
e' una decisione, non un refactor. Fatto intanto il pezzo che non le richiede: la sonda
**pubblica**, che almeno dice *di chi e' il guasto*.
12. ⚠️ **Un test scriveva nel watermark VIVO** (`data/live/equity_seen.json`): lanciare la suite
ci metteva **$5.000** e il giro successivo del book mandava un allarme falso *"USCITA DI FONDI
−86,6%"*. Non era cosmetico: `cap_fallback = min(cap_config, watermark × frac)` sarebbe passato
da **$334 a $2.500/asset — ~7,5x di leva** su un conto da $668, per giunta sul ramo `eq_fallback`
che **allerta e NON blocca**. ✅ Riparato il 2026-08-25 con una fixture **autouse** in
`tests/conftest.py` (strutturale: non si chiede a ogni autore di ricordarsene — quella scommessa
ha gia' perso il 26/07 e il 21/08) + guardia in `test_cap_watermark.py`. ✅ **Esteso il
2026-08-26:** deviati anche `trades.db` (wrapper su `connect` — il default e' catturato alla
definizione, patchare la costante non bastava) e `docs/journal/`; per `book_executions.jsonl`
(caricato ad-hoc via importlib, irraggiungibile da conftest) impronta a inizio suite e verifica
a fine suite, col falso positivo possibile (fill reale del cron :47) dichiarato nel messaggio.
13. ⚠️ **GTAA01 gira su una finestra che ROTOLA, e la fase di ribilanciamento cambia da sola ogni
notte** (misurato 2026-08-28, `r0828_gtaa_band_phase.py`). IB serve una finestra di **30 anni**
e SPY e' al muro: la sua prima barra avanza di un giorno di borsa ogni notte (1996-07-02 il
24/06 → 1996-09-04 il 28/08). `gtaa._gated_returns` ribilancia su `i % every == 0`, cioe' sulla
**posizione nell'array**: se la prima barra scivola si ri-fasa ogni decisione di trent'anni.
Effetto misurato: su una finestra **chiusa** (pre-2015) lo Sharpe si e' mosso fino a **0,076**
a codice fermo, e la banda scelta al buio cambia fra 25% / 40% / 60% da una notte all'altra.
**Ha gia' ucciso due criteri del gate (A)** (07/08 e 28/08). **Quantificato e innocuo OGGI**
(D5): a livello di portafoglio l'escursione sulle 5 fasi vale **0,029** di Sharpe, dentro la
banda dichiarata [1,81-2,12]. QQQ e IWM arriveranno allo stesso muro **fra 2,5 e 3,7 anni**.
Riparazione (ancorare la fase al calendario) rinviata con la decisione su GTAA01: cambierebbe
**tutti** i numeri registrati dello sleeve.
14. ✅ **RIPARATO (2026-09-02).** `trades_db.py --report` stampava `e1/e0-1` sulla serie grezza —
«**+243%**», per il **96,3% un bonifico** (il versamento di $1.399,39 del 25/08 11:47Z; misurato
il 01/09, diario `2026-09-01-stato-trades.md`). La riparazione esisteva gia' nel giornale
(`journal.movimenti_capitale`) e **non aveva attraversato il confine fra i due lettori della
stessa serie** — variante di P1. Ora **`journal.rendimento_twr`** e' la funzione che entrambi
chiamano: spezza la serie sui movimenti CERTI (gli ambigui restano dentro, dichiarati) e il
report stampa **TWR +10,61% = +11,61% × −0,89%**, `trading da arming +$50,95`, i movimenti
elencati, e il delta $ grezzo etichettato «movimenti INCLUSI» — il `%` grezzo **non compare piu'**.
Test: 5 in `test_journal.py` (fra cui la riproduzione del +10,80% del diario 01/09, M23) + 2 in
`test_trades_report.py` sul testo stampato, con `connect()` deviato in tmp. Diario
`2026-09-02-debito-14-report-twr.md`. ⚠️ **Due limiti dichiarati dalla revisione del 02/09** (D5): (a) **l'intervallo che contiene un movimento certo esce INTERO dal rendimento** — il suo P&L di mercato finisce in `certi` e fuori da `trading`, con errore massimo pari a META' del movimento riconosciuto per costruzione del classificatore (il 25/08: ~$0,5 su $1.399); non si stima, si dichiara (P12); (b) **a base di equity zero `twr` E `trading` sono None**: il salto 0→X del primo versamento e' invisibile al classificatore e `trading` varrebbe l'intero conto. 🚨 **Seconda tornata (02/09, 15:30Z): il classificatore era CIECO ~23 ore al
giorno.** Il feed 1h certificato si ferma alle 00:00 (rebuild 00:30): per le letture successive
`asof` dava la stessa barra a t0 e t1, mercato "fermo" = 0, e **qualunque calo ≥10% del giorno
sarebbe stato un «movimento»** — un crash o un depeg USDE stampato come prelievo, nel giornale
(dal 25/08) e nel report. Riprodotto su copia del DB. Ora un salto fuori dalla copertura del feed
(o con feed assente) e' **«mercato non misurabile»** ⇒ `ambiguo` con la ragione, e `twr`/`trading`
sono **None** con motivo (prima, a feed assente, `e1/e0-1` tornava sotto l'etichetta TWR). Il
«limite ereditato +10% a mercato fermo» scritto qui la mattina era un **artefatto della fixture
piatta**, non un limite del classificatore (con mercato misurato il trading non puo' superare
2·max_mkt): cancellato. E `pnl_giorno` ora **chiama** `rendimento_twr` (prima l'affermazione
«la funzione che entrambi chiamano» era falsa: il giornale rifaceva `cum − certi`); la pagina
stampa il TWR accanto al cumulato e la testata Telegram dell'analista qualifica il cumulato
«di cui versati». `leva_tetto` del classificatore include la scala e il tetto di codice (P1).
15. ⚠️ **Il bound di mercato del classificatore dei movimenti guarda solo BTC/ETH, ma dal 26/08 il
31% dell'equity e' USDE** (trovato in revisione il 02/09). Un depeg dell'USDE a BTC/ETH fermi:
−1,5% (indice 0,95) resta sotto soglia e nel P&L; una rottura piena (−31%) supera 2× un mercato
"fermo" e diventerebbe un **«movimento» scorporato come prelievo**, nel giornale e nel report —
l'invenzione silenziosa che P12 vieta. Il bound corretto somma `quota_usde × |Δ indice usde_usdc|`,
ma l'indice era registrato **una volta al giorno** (`usde_watch`, 12:35Z). ◐ **Primo passo fatto
il 02/09:** `balance_watch` (orario, sola lettura) registra ora `usde_usdc` a ogni campione —
None con la ragione se l'indice non e' leggibile, mai 1,0. **Manca il cablaggio nel bound**, che
si fa quando la serie ha storia. Intanto: chi legge un «movimento» negativo senza bonifico in
uscita **lo verifichi contro `balance_watch.jsonl`** prima di crederci.
16. ✅ **RIPARATO (2026-09-02).** Nessuno dei **18** script di `scripts/live/` usava argparse: un
flag sconosciuto non era un errore, era **il ramo `else`**. Costo misurato lo stesso giorno
durante una revisione: `trades_db.py --help` non stampava l'uso, cadeva in `sync()` e riscriveva
`meta.ultimo_sync`; sugli altri due sarebbe stato peggio — `journal.py --help` avrebbe scritto
pagina e riga di DB, `analista.py --help` avrebbe speso una chiamata al modello e mandato un
Telegram. Ora `src/live/cli.valida` e' la **prima istruzione** di ogni `__main__`: `--help`
stampa l'uso ed esce **0**, un flag ignoto esce **2** con l'elenco di quelli previsti (P4).
Niente argparse: cambierebbe messaggi, codici d'uscita e `--help` di script che il cron gia'
chiama — qui si lascia intatto cio' che gira. **`tests/test_cli_flag.py` (30)**: l'elenco degli
script si **deriva dalla cartella** (uno nuovo senza guardia fa fallire il test), verifica che
`valida` sia la prima istruzione, che l'uso documenti i flag accettati, e che **i flag che il
cron usa davvero restino accettati** (P15/P16). Diario `2026-09-02c-flag-e-pulizia.md`.
17. ✅ **RIPARATO (2026-09-10, issue #3).** Nessuno sorvegliava il CUSCINO USDC di regolamento (aperto il 06/09
con la quota USDE al 68,7%): P&L e funding dei perp si regolano in USDC, una perdita del libro lo consuma e fa
salire la quota da sola; `usde_watch` allerta solo su `quota > 0,85`, e un USDC negativo costa lo 0,05%/giorno.
Ora **`scripts/live/cuscino_watch.py`** (cron **:53**, orario, `cron_cuscino.sh`, sorvegliato da `monitor_health`)
legge l'**EQUITY USDC** (decisione dell'operatore: e' quella che risponde del regolamento, il balance vede il buco
solo a trade chiuso), deriva il cuscino da `usde.cuscino_richiesto_usd` — **la formula si e' spostata in
`src/live/usde.py`, e `usde_convert` la importa da li'** (due lettori, una formula: P1) — e ha cinque stati:
OK · **PREAVVISO** (slack < 10% del cuscino, ⚠️ alla transizione) · **ECCEDENTE** (sotto) · BLIND · **SCOPERTO** (slack < 0: 🚨 e
**riconversione automatica** `usde_convert --quota usde.quota_ripristino(0,20) --esegui`, cioe' **0,64**, che lascia
il cuscino piu' un 20% — il DOPPIO del preavviso, altrimenti ogni 🚨 sarebbe seguito da un ⚠️ per costruzione). Guardie: `execution_enabled` del libro (disarmare il libro disarma anche questo), niente
vendita sotto `depeg_warn` (decide l'operatore), un tentativo ogni 6h, le guardie proprie di `usde_convert`;
marcatore «gia' detto» = esito dell'invio (§5.2). **Primo giro (13:00Z): gia' PREAVVISO, slack +$26** su $1.335
richiesti — la marcatura del libro dal 06/09 lo aveva consumato senza che nessuno lo vedesse. ✅ **Ratchet chiuso lo stesso giorno (issue #7, «riportarla a quota in autonomia»)**: quarto stato **ECCEDENTE** (slack > 40% del cuscino ⇒ **acquisto** di USDE fino allo stesso bersaglio 0,64). Le tre bande stanno in `config/live.json` (`cuscino_preavviso_frac` 0,10 · `cuscino_margine_frac` 0,20 · `cuscino_riacquisto_frac` 0,40, `usde.bande_cuscino` verifica l'ordine) e **`quota_target` 0,70 non esiste piu'**: a 0,70 lo slack era ZERO per costruzione e ogni ora in perdita avrebbe venduto. Isteresi [0 ; 0,40]×cuscino con bersaglio unico 0,20: per oscillare servono ±6% di equity di slack = **±8,6% di equity USDC (~$380)**, un giro costa ~6 bps sull'importo mosso; un bonifico alza lo slack di 0,7×importo e sopra ~9% dell'equity fa scattare il riacquisto da solo. Soglie dichiarate, non ottimizzate (M8). ⚠️ Trovato al primo giro vero (13:53Z): l'allerta PREAVVISO **non e' partita** — Telegram in HTML rifiuta un `<` nudo («(< 10%…)»); l'escape sta nel **sink** (`notifier.notify`, `html.escape` su titolo e valori: copre tutti i 45 chiamanti, incluso il campo `motivo` che la revisione ha trovato ancora scoperto), `allerta_errore` registrato nel record (P3). Un guasto persistente da ECCEDENTE (tetto del venue tornato, book illeggibile) si ritenta **una volta al giorno**, da SCOPERTO ogni 6h; una config con bande fuori ordine da' **BLIND con motivo**, non un traceback ingoiato dal cron. ✅ **0,64 e' la quota DECISA dall'operatore il 10/09** (§3): derivata dal margine 0,20 sul cuscino, sostituisce lo 0,70 del 30/08. 📌 **Allineato il 10/09 14:16Z su ordine dell'operatore**: `usde_convert --quota 0.64 --esegui`, 238 USDE in 3 ordini @ 1,0000, quota 69,4% → 64,02%, slack +$266 = **OK** (era PREAVVISO a +$29). Il tetto del venue in `usde_convert.piano` ora vale **solo in acquisto**: bloccava anche la vendita, e con `venue_cap_frac` rimesso in config la riconversione sarebbe stata morta. `tests/test_cuscino_watch.py` (24).
18. ✅ **RIPARATO (2026-09-09 sera).** `cblib.spot_series` + `asof(ts)` guardava **un'ora avanti** (feed
1h etichettato all'apertura: verificato, chiusura 1h a T == chiusura 5m a T+55 nel 100% delle barre)
**e `dvol_series` fino a 24 ore avanti** (la riga DVOL del giorno D e' la chiusura delle 23:00 di D:
verificato contro la risoluzione 1h dell'API pubblica) — seconda serie con lo stesso difetto, trovata
riparando la prima (D6, quinta occorrenza). Ora `cblib.causale(s, cadenza)` rietichetta le chiusure
all'istante in cui sono note e le due serie escono **gia' causali** (spot +1h, DVOL +1 giorno);
`r0909` non ri-sposta. **§11 rimisurato allo stesso taglio (22/08, n=19)**: prima riprodotto al
millesimo su worktree HEAD (0,714 [0,690-0,779]), poi **0,712 [0,664-0,732]** — le due correzioni
hanno **segno opposto** (solo spot 0,721 · solo DVOL 0,693 · entrambe 0,712; M26) e un DVOL **orario**
di controllo da' 0,717. Il verdetto di §11 non cambia; cambiano i numeri di contorno (Sharpe canonico
BTC 32,58 → 29,61, mediana onesta 1,45 → **2,12**; ETH 3,90 → 7,64; fee 1,44×/1,80× → 1,51×/1,87×;
il regolamento e' ora il prezzo delle 08:00, non delle 09:00: P&L +3,3%). Sul crollo (§75): ETH pre
0,74 → **0,76 [0,71-0,86]**, BTC durante 0,79 → **0,89** (DVOL orario 0,83: nel crollo il DVOL
giornaliero stantio vale −0,04/+0,06 di f). `vrp_f_watch` (cron): f canonico 0,732 → **0,706**, differenza
col candidato +0,054 → **+0,097 [+0,042, +0,140]** — ora esclude lo zero e il criterio (b) e'
soddisfatto, (a) no (28/40). ⚠️ **Resta aperto, con costo misurato**: il DVOL nel feed e' giornaliero,
quindi causale = **stantio fino a 23 ore** (mediana 0,2 pt di vol, max 3 pt; nel crollo 0,06 di f):
la via giusta e' un feed DVOL **orario** (API pubblica, gratuito, `resolution=3600`) con la sua riga
in `cron_daily` — non fatto, e' una decisione sul feed; e lo spot causale resta **stantio ≤25 min** (snapshot
al :25, chiusura al :00; il feed 5m certificato lo ridurrebbe a ≤5). Trovati in revisione altri due lettori:
**`r0730_vrp_real_quotes`** (il f 0,73 di §2 → **0,71**, dichiarato in §2) e **`r0901_btc_collar`** (join
per giorno: riallineato con `causale(·, "-1D")`, bit-exact a prima). `options_vrp_calibrate.spot_series`
(copia propria, numeri del 20/06) **non toccato**. Diario `2026-09-09b-debito-18-cblib-causale.md`.
---
## 6. Le regole di prim'ordine
Estratte dai 69 filoni. Ognuna e' stata pagata almeno una volta. Testo completo e caso d'origine
nei file di memoria.
### Sul dato
- **D1** La verita' e' **Deribit mainnet**; Binance/Coinbase solo come audit indipendente, mai come ancora per "ripulire".
- **D2** **Una riga presente non e' un dato presente**, e **una barra presente non e' una giornata presente**: contare cio' che e' *quotato/chiuso*, non cio' che e' *scritto*.
- **D3** Una certificazione che guarda solo **dentro** la serie non vede cio' che la serie **ha perso** (split 2:1, contaminazione EUR/USD, troncatura: tutte passano integrita', gap, spike, duplicati).
- **D4** Ogni soglia di certificazione **tarata su un valore tondo** va controllata contro il difetto che genera *esattamente* quel valore (una soglia al 50% non puo' sorvegliare gli split 2:1).
- **D5** Quando un buco non si puo' chiudere senza generare falsi positivi, si misura il **danno** del caso non rilevato: un buco quantificato e innocuo e' un risultato, uno taciuto e' un debito.
- **D6** Due serie dello stesso progetto possono avere **convenzioni di etichettatura diverse**: verificare col **lag**, non fidarsi dell'indice. `DatetimeIndex.view/astype("int64")` su risoluzioni miste produce look-ahead **senza eccezioni e senza NaN**.
- **D7** Un guasto **in corso** si misura al **giorno peggiore**, non in media. E prima di cancellare una sorgente si verifica che la copia sia **completa**, non che esista.
### Sul metodo
- **M1** Una strategia direzionale si giudica su `earns_slot` (**Sharpe marginale vs TP01**), mai sullo Sharpe assoluto: gli overlay-su-TSMOM ereditano lo Sharpe del trend.
- **M2** Una famiglia grid-searched si giudica con `study_family_honest` (cella scelta **in-sample-only** + deflated-Sharpe ≥0,95), mai chiamando lo scorer sulla cella a max hold-out.
- **M3** 🚨 **Non basta contare i trial: serve la VARIANZA di screen** — e **la stessa griglia da' verdetti opposti a seconda di come la si partiziona**. La partizione e' un secondo posto dove barare e' indolore e invisibile: dichiararla **prima**, contare **al rialzo**, e pubblicare la **sensibilita' del verdetto al conteggio**.
- **M4** Quando si riapre un parametro **si riapre la sua famiglia**.
- **M5** **Null del de-levering (7 occorrenze):** ogni claim "meno drawdown" si testa a **iso-rischio** prima di crederci — e' il primo test, non l'ultimo. Se la variante e' una pura ri-scalatura il null e' **degenere** (`sh(k·base) ≡ sh(base)`): serve iso-peso sullo Sharpe.
- **M6** Un diversificatore a **basso CAGR** si giudica a **iso-rischio**, mai a iso-nozionale.
- **M7** Su offset/ancore appaiate la statistica e' la **mediana delle differenze**, non la differenza delle mediane. E **se si de-lucka una strategia va de-luckato anche il suo DEGRADO**.
- **M8** Un **argmax dentro un plateau non e' una decisione**; e la mediana da sola puo' nascondere il fatto decisivo (p90 su, p10 giu' = si compra dipendenza dall'ancora, non Sharpe). E un **argmax sul BORDO della griglia non e' una cella: e' una pendenza** — si segue fino al suo limite prima di leggerne il valore, perche' il limite puo' essere un oggetto diverso da quello che si stava studiando (COLLAR01: le 3 celle vincenti su 48 stavano tutte sul bordo, e il limite era una **covered call**, cioe' fuori dalla domanda posta).
- **M9** Un contributo positivo si **scompone per anno** prima di crederci: "24/24 ancore positive" puo' essere **un anno solo**.
- **M10** **Due punti non fanno una tendenza** nemmeno quando la meccanica sembra spiegarla.
- **M11** Un **blocco dichiarato e' un'ipotesi, non un fatto**: si ri-verifica prima di costruirci sopra o di rimandare (3 occorrenze, ogni volta il blocco non esisteva).
- **M12** Un **follow-up dichiarato contiene una previsione**, che va **misurata** non assunta.
- **M13** Un criterio si misura sulla sua **risoluzione** prima che sul suo esito, e un gate si valida **contando quante volte lo passa un candidato a caso**.
- **M14** Un **null di permutazione** va confrontato **a fee zero** (permutare un segnale ne fa esplodere il turnover: il null perderebbe per costo invece che per assenza di informazione) e controllato per **bilanciamento del segno**.
- **M15** Un rilevatore tarato per **non** segnalare va validato su un **controllo positivo** — e un controllo positivo finito dentro un ramo `else` non gira mai.
- **M16** Un self-check su **eventi rari** si campiona sugli **eventi**, non sulla popolazione (altrimenti confronta zeri con zeri: potenza zero).
- **M17** Il **win rate di uno schema parziale+BE non e' merito** (≈ 1/(1+rr1)): convertire ogni claim "WR X%" in **expectancy R netto fee**.
- **M18** Vs claim su livelli "speciali" (Fibonacci, max-pain, expiry) il test e' il **null location-matched**; vs claim di calendario, il **day-boundary robustness**.
- **M19** Mettere nella griglia una variabile che si **sa gia' morta** trasforma *"il candidato perde"* in *"il dato non contiene nient'altro di selezionabile"* — l'unica forma in cui un inventario conclude qualcosa su un'assenza.
- **M20** Un meccanismo si trasferisce a un asset nuovo **coi parametri congelati**, o e' una famiglia nuova; e **il criterio di SELEZIONE va riprovato sull'asset nuovo**.
- **M21** Quando un meccanismo **non generalizza**, chiedersi **perche'** vale piu' del fatto che non generalizzi.
- **M22** Un confronto appaiato eredita **tutti** i parametri della riga in cui compare; un'uscita si giudica appaiata per **INGRESSO** (allineare sull'uscita tiene solo i casi in cui non e' successo niente — 3 occorrenze).
- **M23** Un **Monte Carlo ha una risoluzione e va detta**; e prima di pubblicare un numero nuovo, **far riprodurre alla macchina quello vecchio**.
- **M24** Un **non-arrivo** si codifica **+∞, mai −1**; una **mediana condizionata** si stampa sempre accanto alla sua probabilita'; un **percentile a 0 decimali mente esattamente agli estremi**.
- **M25** Quando **due stimatori di coda non concordano si cita la banda**, non quello che conviene.
- **M26** **Non contare su una compensazione fra correzioni misurate separatamente** — la si misura, e in piu' di una **moneta** (un'interazione piccola cambia segno con la moneta).
- **M27** Prima di dichiarare che un campo di un dataset e' sbagliato, **aprire il codice che lo produce**. E una **fonte normativa citata in un commento si verifica come un numero**.
- **M28** Quando **due affermazioni della stessa memoria si contraddicono, la contraddizione e' informazione**: una delle due e' stata scritta guardando i dati.
- **M29** 🚨 Un edge da **opzioni prezzate a modello** si **riprezza alla volatilita' REALIZZATA** prima di crederci: se sparisce, non era la struttura — era il **premio di varianza**, cioe' VRP01, che il progetto ha gia'. Su BTC il **DVOL sta il 32% sopra la RV-forward** a 7 giorni (**77% dei giorni**), quindi *qualunque* struttura che vende vol **stampa per costruzione del prezzatore**: in COLLAR01 il **72-100%** del drift della cella migliore era questo, e l'angolo cadeva da Sharpe **1,471 a 0,511** — che e' il **0,47** gia' pubblicato di VRP01. Vale anche al contrario: un edge che *compra* vol a modello e' sottostimato dallo stesso fattore.
### Sui costi e l'eseguibilita'
- **C1** Il costo di un venue va modellato nella sua **FORMA** (fisso vs proporzionale), non solo nel livello: un pavimento fisso e' una **tassa regressiva** e due venue a pari "costo medio" danno esiti **opposti** al variare del capitale.
- **C2** Un parametro d'esecuzione espresso in **valuta assoluta** ha effetto che dipende dal capitale: il controllo non e' lo Sharpe ma la **quota di tempo a mercato**.
- **C3** Prima di misurare il rendimento a un capitale dato, misurare il **lotto minimo del venue** — e sapere **quale famiglia di strumenti** si sta guardando (inverse vs USDC-lineare: lotti 7,5× diversi).
- **C4** Un **fattore di errore si giudica moltiplicato per il suo peso** (5,85 al 3% fa meno danno di 2,23 al 18%). Il `f` di una struttura multi-gamba **non e' il `f` di una sua gamba**. E **il segno dell'asimmetria di `f` dipende dal VERSO della gamba**: *"un roll anticipato non paga `f`"* (§46) vale per una copertura **solo LONG** — se c'e' una **gamba VENDUTA da ricomprare**, uscire prima paga `f` *esattamente* sulla parte che a scadenza si regolava gratis, e piu' spesso. **L'asimmetria si INVERTE** (COLLAR01: uscire al 50% del tempo costa 5,6 punti di drift col gate forte, 10,2 col largo).
- **C5** **L'open interest NON misura la negoziabilita'** (su Deribit USDC sono quasi anti-correlati). Prima di credere a un rapporto estremo su un prezzo piccolo, **contare i tick**.
- **C6** La negoziabilita' **sul conto reale** va verificata quando lo sleeve entra in **RICERCA**, non quando entra nel book (PRIIPs costo': 5 settimane di misure). *"Non posso comprare" ≠ "non posso vedere"*: il segnale puo' girare su una serie che non si puo' negoziare.
- **C7** Si cerca per **ISIN, non per ticker**; si prende la linea nella **valuta del proprio saldo**; un costo di conversione e' proprieta' della **coppia strumento-conto**, non dello strumento.
- **C8** La deviazione fra due veicoli sullo stesso indice si misura sul **rapporto cumulato**, mai sulla media delle differenze. Il **carry** si misura sul **log del rapporto dei prezzi**, mai sulla media aritmetica delle differenze.
- **C9** **Una regola d'uscita che scatta piu' spesso sui vincenti che sui perdenti non e' protezione, e' troncatura** — si vede in una riga: la peggior settimana non cambia.
- **C10** Una capacita' mancante (es. API di un broker) si valuta sul **costo di non averla**, non sulla sua assenza.
### Sulla produzione e le sorveglianze
- **P1** 🚨 **Un sorvegliante deve DERIVARE il proprio bersaglio dal codice sorvegliato, mai ridichiararlo.** *Un controllo puntato su una configurazione diversa da quella che gira passa sempre, e non sta controllando niente.* **5 occorrenze**: e' il difetto piu' ricorrente del progetto.
- **P2** Un rilevatore si valida **sul segnale E sul trasporto**.
- **P3** Se un errore si ingoia per non bloccare, **si registra nel punto in cui lo si ingoia** — non c'e' un secondo momento buono: quando la diagnosi serve, il guasto e' rientrato.
- **P4** Un'allerta risponde a **due** domande: *cosa* (decide) e *perche'* (ripara). **Una nota di diagnosi cablata e' peggio di nessuna nota.**
- **P5** Distinguere guasti diversi **anche quando l'azione e' la stessa**; e prevedere lo stato **"non vedo"** (`BLIND`, `flat-senza-dato`, `NUOVO`): *"non vedo" non e' "va tutto bene"*, e il silenzio in una serie di ritorni si legge come **zero**.
- **P6** Una soglia si sceglie con un criterio **dichiarato prima** (i criteri ovvi sbagliano in versi opposti); la **persistenza richiesta E' latenza** e va confrontata con la durata del fenomeno; un **break-even si calcola sulla media**, non sulla coda.
- **P7** Un numero di taratura si etichetta con la **CONFIGURAZIONE**, non solo con la finestra; e uno **"zero" si legge accanto alla quota di campione utilizzabile** (meno falsi allarmi *perche' si vede meglio* e *perche' si vede di meno* hanno lo stesso valore stampato e valore opposto).
- **P8** Un **veto d'integrita' sorveglia l'asse su cui e' stato scritto**: contare *se* il dato c'era non dice *quanto* del giorno copriva.
- **P9** Un **allarme massimo speso per un evento atteso** e' un allarme che non verra' letto il giorno che e' vero.
- **P10** Un modello di rischio **intraday** non si valida sulla marginale del wick ma sul suo **accoppiamento** al rendimento del giorno: `close-only` non e' conservativa, e' **cieca** (0,00 breach da daily-loss su ogni configurazione).
- **P11** Un **dato operativo non ricostruibile non puo' vivere in un file gitignored** — si materializza dove il backup arriva.
- **P12** Fra due fonti che non concordano, una **riparazione silenziosa e' un'invenzione**: si riporta la divergenza.
- **P13** Una **guardia sui NUMERI non copre il RAGIONAMENTO**: l'analisi in prosa si legge come opinione di un lettore fallibile, mai come parte del registro. Chi scrive in un registro va **firmato**.
- **P14** Una **guardia piu' stretta del contratto** produce allarmi che si impara a ignorare; una regola che si accende su $2 di cumulato insegna a saltare la sezione.
- **P15** Una **regola operativa va provata contro il codice che dovrebbe eseguirla**, o si discute per mesi di un knob che non esiste.
- **P16** Il cron gira dal **working tree**: con un branch di ricerca attivo, il cron esegue quel branch.
### Sul piano e sulle decisioni
- **N1** **Il piano si dimensiona sul VERSAMENTO, che e' certo, non sul muro** — il muro e' `prelievo/perpetua`, cioe' un `1/x` su una quantita' che va a zero: l'errore e' **asimmetrico verso l'alto** e la banda e' esplosiva.
- **N2** Un piano di accumulo si giudica sulle sue **deviazioni**, non sul caso nominale (piatto/ininterrotto/per sempre e' l'unico scenario che non succede). Piani di taglia diversa si confrontano su **`$ finale / $ versato`**.
- **N3** Ordine delle leve, da citare quando si parla del piano: **versare o no** (da *mai* a ~16 anni) > **quando** (6×) > **quanto presto si smette** (i primi 5 anni sono il 25% dei soldi e il 58% del risultato) > piatto vs crescente (24%) > frequenza (1-3%). *A orizzonte corto non fai lavorare la strategia: **compri il capitale coi bonifici**.*
- **N4** Un rischio **non-diversificabile dagli sleeve** (venue) si prezza a parte, e si compra con un **secondo CONTO**, non con un secondo sleeve. **P(successo) puo' nascondere P(rovina)**: per una rendita la metrica e' la seconda, perche' **zero e' assorbente**.
- **N5** Quando una metrica **binaria satura**, la decisione si sposta sulla metrica **continua**.
- **N6** Un **obiettivo si dichiara nella sua definizione operativa PRIMA di ottimizzarlo**: *flusso* e *ricchezza sostenibile* sono entrambe difendibili e differiscono di **cento volte** (33,9% contro 0,33%).
- **N7** Uno **sleeve difensivo si giudica sul sinistro, non sul premio**: hold-out negativo non e' evidenza di morte.
- **N8** Una rivalutazione parte dall'elenco di **cosa cambia una decisione**, non dal riassunto di cosa si e' scoperto; quando due correzioni puntano in versi opposti **si misura**; quando le leve hanno **ordini di grandezza diversi, dirlo**.
- **N9** Quando una raccomandazione viene respinta con motivo, si registra **cosa e' stato accettato in cambio** — altrimenti la stessa analisi la ripropone fra tre mesi come se fosse nuova.
- **N10** Una **data in un gate va giustificata col COSTO della misura**, non con la sua difficolta' percepita (due gate d'attesa da mesi eliminati in una sera perche' nessuno aveva contato i secondi). Una **verifica esterna a €0 va fatta PRIMA** di qualunque misura che ne dipenda, e si fa **sul venue, non sul sito** di chi la dichiara.
- **N11** Un numero pubblicato in un diario deve avere **uno script committato che lo riproduce**, e ogni script deve calcolare il proprio **verdetto a runtime** (e' cio' che ha salvato un'ondata interrotta).
---
## 7. IL DATO — fonte di verita' (regola di prim'ordine)
- **La verita' e' Deribit mainnet**, perche' e' dove eseguiamo. Cross-check multi-venue: Deribit
mainnet e' a 0-1 bps dal consenso. **Binance NON e' la verita'** (e' USDT, ~10 bps fuori, fino al 3%
sotto depeg) → audit indipendente, mai ancora per "ripulire" i dati.
- **Aggiornare lo storico SOLO con `rebuild_history.py`** (ccxt Deribit mainnet, base 5m unica +
resample). **MAI** il vecchio downloader Cerbero (token testnet = feed farlocco: e' la causa del reset).
- **Certificare sempre** dopo un rebuild con `certify_feed.py` (integrita' OHLC, zero gap, coerenza
resample maxΔ≈0, spike = solo crash reali, accordo cross-venue per-anno vs Coinbase USD).
**Universo ricercabile certificato**
- **BTC / ETH** — puliti (2-6 bps vs Coinbase USD), liquidi (~0% barre flat a 1h), storia 2018/2019→oggi,
**ogni timeframe** (5m/15m/1h). E' l'unico dato in `data/raw/` col namespace nudo.
- **Alt Deribit: FUORI** (illiquidi/divergenti). SOL vive in `data/raw/alt_sol_*.parquet`, **fuori dal
namespace nudo e non rinfrescato dal cron** — vedi §3 e la lezione: *ricostruire dati per un'analisi
puo' disattivare un guardrail che vive nell'assenza di un file*.
- **Hyperliquid (Cerbero MCP MAINNET): 51 certificati, 19 major usati da XS01**, 1d dal 2024. Storia
nativa ~2,5 anni. ⚠️ Cerbero col token **testnet** e' farlocco; col mainnet e' reale ma **sempre da
certificare**, e il rivelatore del backfill sintetico e' il **VOLUME**, non il flat ne' il cross-venue.
- **Catena opzioni Deribit mainnet — raccolta propria** dal 2026-07-30 (`scripts/live/collect_chain.py`,
cron **:25**). Dettaglio, archivio ereditato, difetti e buchi di colonna in `docs/memory/50-dati-e-feed.md`.
**Perche' si memorizza invece di interrogarla:** una catena opzioni **non e' ricostruibile a
posteriori** — un'ora non raccolta e' persa per sempre.
**Backup.** `data/raw/` e' gitignored → il dato non ricostruibile (catena, `data/paper_*`,
`data/chain_collect`, `data/live`, `venue_watch`, `fee_watch`, `config/live.json`) e' salvato da
`do_pythagoras` in `/opt/docker/scripts/backup.sh` (daily 04:00). ⚠️ `/opt/docker/scripts` **non e' un
repo git**: quella modifica vive solo su disco.
---
## 8. Metodologia obbligatoria per ogni nuova strategia
1. **Ingresso eseguibile**: direzione e prezzo decisi con dati **fino a `close[i]`**, mai `close[i-1]`
con direzione presa da `i`; mai entry sull'estremo (high/low) di una candela.
2. **Backtest NETTO** dopo fee realistiche Deribit (**0.10% RT** taker, conservativo: il tier reale e'
3,50 bps/lato dal 2026-08-01) + leva. ⚠️ **Il funding NON e' nel motore** — vale −2,16%/anno di drift.
3. **Out-of-sample** held-out + robustezza su **griglia parametri** (entrambi gli asset, tutte le celle
positive) + **sweep fee** (0.00-0.20% RT).
4. **Liquidita' & plausibilita'**: incrociare ogni edge con la liquidita' reale del book (quota di barre
flat) e con la plausibilita' del prezzo (cross-venue). Un edge full+OOS robusto su un book fermo o su
wick fantasma **non e' un edge**.
5. **I gate di `altlib.py`** (dettaglio in `docs/memory/60-metodo-e-gate.md`): `study_marginal` /
`marginal_vs_tp01` (ADDS·NEUTRAL·REDUNDANT·HEDGE·NOISE, con persistenza multi-cut, edge in-sample,
hedge-vs-alpha) · `study_family_honest` (+ `deflated_sharpe` ≥0,95, `select_cell_insample`) ·
`day_boundary_robust` · `eval_weights_smallcap` · `implausible_sharpe` · `anchor_luck_band` /
`anchor_luck_delta` · `weights_tilt_null` (**ogni** proposta di cambio pesi).
6. Strategia in `scripts/strategies/` (codice univoco), test in `tests/`, diario aggiornato.
---
## 9. Lezioni critiche storiche (da NON ripetere)
- **Feed contaminato → libreria fasulla (v2.0.0).** Print fantasma testnet + Binance/USDT hanno prodotto
edge inesistenti (+201%/+1238%/+16492% "OOS"), tutti spariti sul feed reale. **Il dato viene prima
della strategia.**
- **Look-ahead squeeze.** Accuratezze 76-82% erano artefatto: direzione dalla candela `i`, ingresso a
`close[i-1]`. Con ingresso onesto: lancio di moneta.
- **Entry sugli estremi di candela.** ETH 2024: +30.848% → +2.725% rimuovendoli.
- **Data leakage con rendimenti log:** `returns[k] = log(close[k+1]/close[k])` usa `close[k+1]`; i
feature devono fermarsi a `returns[i-2]` se il prezzo corrente e' `close[i-1]`.
- **Fee** = vincolo di prim'ordine; **leva**: 5x raddoppia il drawdown, i numeri a leva alta non sono il
caso base.
- **Onesta' sul target €50/giorno.** Non e' raggiungibile a questo capitale: serve ~$313k (banda
[$187k – $1,14M]) o **€1.733/mese per 10 anni** a P=90%. La leva non e' la scorciatoia; la via e'
target-vol + capitale + tempo.
---
## 10. Obiettivo
Ricerca: riconoscimento pattern frattali per trading algoritmico su crypto. Target dichiarato Ricerca: riconoscimento pattern frattali per trading algoritmico su crypto. Target dichiarato
€50/giorno partendo da €1.000. **Onestà prima di tutto**: nessun numero va creduto finché non è €50/giorno partendo da €1.000. **Onesta' prima di tutto**: nessun numero va creduto finche' non e'
netto fee, out-of-sample, robusto su griglia, e su dati certificati + liquidi + eseguibili. netto fee, out-of-sample, robusto su griglia, e su dati certificati + liquidi + eseguibili.
## Stack ## 11. Stack
- **Linguaggio:** Python 3.11+ — **Package manager:** uv (`pyproject.toml`, `uv.lock`) - **Linguaggio:** Python 3.11+ — **Package manager:** uv (`pyproject.toml`, `uv.lock`)
- **Dati:** Parquet in `data/raw/` (gitignored). Solo BTC/ETH (5m/15m/1h). - **Dati:** Parquet in `data/raw/` (gitignored). Solo BTC/ETH (5m/15m/1h) nel namespace nudo.
- **Analisi/ML:** numpy, pandas, scipy, scikit-learn - **Analisi/ML:** numpy, pandas, scipy, scikit-learn
- **Fonte dati storici:** Deribit mainnet via `ccxt` (pubblico, tokenless) - **Fonte dati storici:** Deribit mainnet via `ccxt` (pubblico, tokenless)
## Struttura (post-reset) ## 12. Struttura
``` ```
src/data/downloader.py → load_data(asset, tf): legge i parquet certificati da data/raw/ src/data/downloader.py → load_data(asset, tf): legge i parquet certificati
src/strategies/base.py → Strategy (ABC), Signal, BacktestResult, YearlyStats src/strategies/ → base.py (Strategy/Signal/BacktestResult), indicators.py,
src/strategies/indicators.py → indicatori condivisi (ema, atr, keltner, ...) trend_portfolio.py (TP01), skyhook.py (SKH01)
src/strategies/trend_portfolio.py → TP01: strategia DIFENSIVA robusta (PORT LF1d, >=12h), causale src/portfolio/ → portfolio.py (combina N sleeve + weights_tilt_null),
src/portfolio/ → PORTAFOGLIO DI STRATEGIE estensibile (Sleeve + StrategyPortfolio) sleeves.py (REGISTRY: aggiungere uno sleeve = una riga), gtaa.py
portfolio.py → combina N sleeve per peso su griglia giornaliera; metriche FULL/hold-out/anno src/backtest/harness.py → harness ONESTO (load BTC/ETH, backtest_signals no-leakage, OOS)
sleeves.py → REGISTRY sleeve attivi: TP01 (55%) + XS01 (25%) + VRP01 (20%). Aggiungere = una riga src/live/ → book.py (esecutore netto TP01+SKH01), shadow.py, deribit.py,
src/fractal/ → indicatori frattali (patterns.py, indicators.py, similarity.py) livefeed.py, venue_watch.py, monitor_health.py, notifier.py,
src/backtest/engine.py → engine di backtesting riusabile scale_watch.py (chiave di scala: 3 domande, 3 stati),
src/backtest/harness.py → harness ONESTO (load BTC/ETH, backtest_signals no-leakage, OOS) tradesdb.py · journal.py · analista.py (libro di bordo),
src/version.py → APP_VERSION (legge il file VERSION) revisione.py (revisione settimanale, sola lettura, revisore fable)
scripts/research/ → ricerca: track{A-I}_*.py + options_vrp_*.py + fetch_dvol.py src/data/eq_splits.py, eq_crosscheck.py → guardie sul feed equity
scripts/portfolio/ → run_portfolio.py (report) + xsec_*.py (ricerca/affinamento XS01) scripts/research/ → ricerca (r<data>_*.py). Harness condiviso: alt/altlib.py
scripts/live/paper_trend.py → paper trader forward-only di TP01 (1d) (no esecuzione reale) scripts/analysis/ → SOLO tool sui dati certificati: rebuild_history, certify_feed,
scripts/analysis/ → SOLO i tool dati certificati: audit_feed, multi_source_check, fetch_* , certify_cb_chain
rebuild_history.py → (ri)costruisce lo storico da Deribit mainnet (base 5m + resample) scripts/live/ → book_execute · venue_watch · fee_watch · edge_watch ·
certify_feed.py → certifica il feed (integrità, coerenza resample, spike, cross-venue) monitor_health · collect_chain · paper_* · trades_db ·
audit_feed.py → audit per-barra vs riferimento esterno journal · analista
multi_source_check.py → cross-check multi-venue (quale venue è "vero") scripts/cron_{book,daily,chain,opt_snapshot,vol_term,review}.sh
data/raw/ → btc/eth × {5m,15m,1h} (gitignored). UNICO dato attivo. (la crontab ha anche cron_ombra.sh di TradingBook: vedi §1, OMBRA)
data/instruments_registry.json → registry strumenti (reference) docs/memory/ → LA MEMORIA (indice in testa a questo file)
docs/diary/ → diario di ricerca (1 voce: il reset; aggiungere dopo ogni esperimento) docs/research/ → BRIEF-0822 · RESULTS-0822 (§1-77) · SPEC-scale-key
Old/ → ARCHIVIO: tutto il vecchio (strategie, live, ricerca, dati, diari) docs/diary/YYYY-MM-DD.md → una voce per esperimento (146)
VERSION → semver (2.0.0) docs/journal/YYYY-MM-DD.md → libro di bordo, una voce al giorno, 4 livelli per provenienza
docs/revisioni/YYYY-MM-DD.md → revisione settimanale firmata (lunedi'), opinione del revisore
data/live/trades.db → i trade allineati col tempo (dentro il perimetro di backup)
Old/ → ARCHIVIO pre-reset
VERSION → semver
``` ```
## Comandi ## 13. Comandi
```bash ```bash
uv sync # installa dipendenze uv sync # dipendenze
uv run python scripts/analysis/rebuild_history.py --asset BTC ETH # (ri)costruisci storico da Deribit mainnet uv run python scripts/analysis/rebuild_history.py --asset BTC ETH # storico da Deribit mainnet
uv run python scripts/analysis/certify_feed.py # certifica i feed (locale + cross-venue) uv run python scripts/analysis/certify_feed.py [--local] # certifica i feed
uv run python scripts/analysis/certify_feed.py --local # solo check locali (veloce) uv run python scripts/portfolio/run_portfolio.py # report del portafoglio (ricerca)
uv run python scripts/research/trackD_trendport.py # backtest strategia vincente (full report) uv run python scripts/live/paper_portfolio.py # avanza il paper (forward-only)
uv run python scripts/research/trackD_timing.py # vincitrice su 15m/1h/4h/1d + PnL/DD/trade per anno uv run python scripts/live/trades_db.py --report # stato libro di bordo + P&L (TWR, non e1/e0)
uv run python scripts/analysis/fetch_hyperliquid.py # fetch+certify universo Hyperliquid (Cerbero mainnet) -> data/raw/hl_* uv run python scripts/live/<script>.py --help # uso e flag (dal 02/09: un flag ignoto esce 2)
uv run python scripts/portfolio/xsec_research.py # ricerca cross-sectional su Hyperliquid (XS01) uv run python scripts/live/trades_db.py --reconcile # incrocio delle 3 fonti sui fill
uv run python scripts/portfolio/run_portfolio.py # report del PORTAFOGLIO attivo (TP01+XS01) uv run python scripts/live/journal.py # voce del giorno (numeri + lettura)
uv run python scripts/live/paper_trend.py # avanza il paper trader TP01 (forward-only, 1d) uv run python scripts/live/analista.py --secco # analisi del giorno, senza salvare
uv run pytest # test uv run python scripts/live/revisione.py --secco # taglia del materiale della revisione settimanale (niente modello)
uv run pytest # test (1070, tutti verdi al 10/09)
``` ```
```python ```python
from src.data.downloader import load_data from src.data.downloader import load_data
df = load_data("BTC", "1h") # OK. load_data("SOL", ...) -> FileNotFoundError (guardrail: solo dati certi) df = load_data("BTC", "1h") # load_data("SOL", ...) -> FileNotFoundError (guardrail: solo dati certi)
``` ```
## IL DATO — fonte di verità (regola di prim'ordine) ## 14. Convenzioni
- **La verità è Deribit mainnet**, perché è dove (in futuro) eseguiamo. Cross-check multi-venue: - Strategie in `scripts/strategies/` con codice univoco; **le scartate si documentano** (memoria + diario).
Deribit mainnet è a 0-1 bps dal consenso. **Binance NON è la verità** (è USDT, ~10 bps fuori, e - Diario in `docs/diary/YYYY-MM-DD.md` dopo ogni esperimento significativo; registro per filone in
sotto depeg USDT fino al 3% off) → usare Binance/Coinbase SOLO come audit indipendente, mai come `docs/research/RESULTS-0822.md`.
ancora per "ripulire" i dati. - **Quando un risultato cambia una decisione, aggiorna questo file; quando aggiunge racconto, va in
- **Aggiornare lo storico SOLO con `rebuild_history.py`** (ccxt Deribit mainnet, base 5m unica + `docs/memory/`.** Questo file non deve tornare a crescere senza limite.
resample → coerenza interna garantita). **MAI** il vecchio downloader Cerbero (token testnet =
feed farlocco: è la causa della contaminazione).
- **Certificare sempre** dopo un rebuild con `certify_feed.py` (integrità OHLC, zero gap, coerenza
resample maxΔ≈0, spike = solo crash reali, accordo cross-venue per-anno vs Coinbase USD).
### Universo ricercabile certificato
- **BTC / ETH**: puliti (2-6 bps vs Coinbase USD su tutta la storia), liquidi (~0% barre flat a 1h),
storia lunga (2018/2019→oggi) → **ogni timeframe (5m/15m/1h)**. È l'unico dato in `data/raw`.
- **Alt Deribit (SOL/XRP/ADA/LTC/DOGE/BNB): FUORI.** Illiquidi (LTC 5m 82% barre flat, run ~3 giorni),
divergenti, o non certificabili. Archiviati in `Old/data/raw`.
- **Universo Hyperliquid (Cerbero MCP MAINNET): 19 alt liquidi a 1d, dal 2024** — BTC/ETH/SOL/BNB/XRP/
DOGE/AVAX/LINK/LTC/ADA/ARB/OP/SUI/APT/INJ/TIA/SEI/NEAR/AAVE. Certificati (`fetch_hyperliquid.py`):
flat 0%, cross-venue 4-9 bps vs Binance, >1% ≈0% → `data/raw/hl_*_1d.parquet`. **Caveat:** storia
nativa solo **~2.5 anni** (2024-2026; pre-2024 = backfill, vol 0). Abilita le strategie
CROSS-SECTIONAL (impossibili a 2 asset). NB: Cerbero col token TESTNET = farlocco; col token
**mainnet** (`.env.mainnet`) = reale, ma SEMPRE da certificare (cross-venue + liquidità).
⚠️ **CORREZIONE estrazione (2026-06-20):** il backfill NON è solo pre-2024 — cerbero MCP padda con
barre SINTETICHE (volume 0, prezzi copiati da Binance → matchano cross-venue e non sono flat) ogni
asset listato su HL **dopo** lo START. Il `flat`+cross-venue da soli non lo vedono: il rivelatore è
il **VOLUME**. `fetch_hyperliquid.py` ora (1) taglia il run iniziale a volume 0, (2) scarta chi resta
< 365g reali (es. **AXS 83% sintetico → fuori**), (3) gata i gap vol=0 interni. Universo certificato
= **51** (era 52). I **19 major di XS01 hanno 0 backfill → invariati** (strategia live non toccata).
Verificato direttamente su cerbero MCP. Diario `2026-06-20-cerbero-backfill-fix.md`.
## Metodologia obbligatoria per ogni nuova strategia
1. **Ingresso eseguibile**: direzione e prezzo decisi con dati **fino a `close[i]`**, mai
`close[i-1]` con direzione presa da `i`; mai entry sull'estremo (high/low) di una candela.
2. **Backtest NETTO** dopo fee realistiche Deribit (**0.10% RT** taker; maker ~0%) + leva.
3. **Out-of-sample** held-out + robustezza su **griglia parametri** (entrambi gli asset, tutte le
celle positive) + **sweep fee** (0.00-0.20% RT, margine ampio).
4. **Liquidità & plausibilità** (lezione v2.0.0): incrociare ogni edge con la liquidità reale del
book (quota di barre flat) e con la plausibilità del prezzo (cross-venue). Un edge full+OOS
robusto su un book fermo o su wick fantasma NON è un edge.
5. Strategia in `scripts/strategies/` (codice univoco), test in `tests/`, diario aggiornato.
## Lezioni critiche (da NON ripetere — la storia di questo progetto)
- **Feed contaminato → libreria fasulla (v2.0.0).** Print fantasma testnet + Binance/USDT hanno
prodotto edge inesistenti (+201%/+1238%/+16492% "OOS"). Tutti spariti sul feed reale. Lezione: il
dato viene prima della strategia; certificare sempre.
- **Look-ahead squeeze (storico).** L'intera famiglia squeeze-breakout aveva accuratezze 76-82% che
erano artefatto: decideva la direzione con la candela di breakout `i` ma entrava a `close[i-1]`.
Con ingresso onesto: lancio di moneta. (Dettagli nei diari in `Old/`.)
- **Entry sugli estremi di candela.** Strategie che entrano a `close` quando `close` è all'estremo
del range (≤0.1% o ≥99.9%) gonfiano i ritorni in modo irrealistico (ETH 2024: +30.848% → +2.725%
rimuovendoli). Spesso è un artefatto di dato o di entry non eseguibile.
- **Mean-reversion vs breakout.** Sui dati storici l'unica direzione che mostrava edge era la
mean-reversion (i breakout rientrano) — MA anche quegli edge erano per lo più artefatto del feed:
da riverificare da zero su dati certi.
- **Fee** = vincolo di prim'ordine. 0.10% RT baseline. Molte operazioni = morte per fee.
- **Leva**: testare 3x; 5x raddoppia il drawdown. I numeri a leva alta NON sono il caso base.
- **Data leakage** con rendimenti log: `returns[k] = log(close[k+1]/close[k])` usa `close[k+1]`. I
feature devono fermarsi a `returns[i-2]` se il prezzo corrente è `close[i-1]`. Verificare SEMPRE.
## Convenzioni
- Strategie in `scripts/strategies/` con codice univoco; scartate documentate nel diario.
- Diario in `docs/diary/YYYY-MM-DD.md`, aggiornato dopo ogni esperimento significativo.
- **Nessun segreto nei commit** (token/chiavi). `.env` e `.env.mainnet` sono gitignored. - **Nessun segreto nei commit** (token/chiavi). `.env` e `.env.mainnet` sono gitignored.
- Versionamento: `VERSION` (semver) + `scripts/bump_version.py`. `src/version.py` lo legge. - Versionamento: `VERSION` (semver) + `scripts/bump_version.py`; `src/version.py` lo legge.
## Archivio `Old/` ## 15. Archivio `Old/`
Tutto il lavoro pre-reset (preservato in git per consultazione storica): strategie Tutto il lavoro pre-reset (preservato in git): strategie, stack live e portafogli, ricerca/gate, dati
(`Old/scripts/strategies`), stack live e portafogli (`Old/src/live`, `Old/src/portfolio`, non certificati, 60+ diari, test. Consultabile come riferimento ("come facevamo X"), ma **nessun edge
`Old/scripts/portfolios`), ricerca/gate (`Old/scripts/analysis`), dati non certificati li' dentro e' fidato** finche' non e' ri-validato su dati certi.
(`Old/data`), 60+ diari (`Old/docs/diary`), test (`Old/tests`). Consultabile come riferimento
("come facevamo X"), ma **nessun edge lì dentro è fidato** finché non è ri-validato su dati certi.
```
+117 -387
View File
@@ -1,423 +1,153 @@
# PythagorasGoal # PythagorasGoal
Sistema di riconoscimento pattern frattali e predizione per il trading di criptovalute (BTC, ETH), ispirato al framework teorico di Serleto & Malanga (*Pythagoras Trading Prediction*). Ricerca e esecuzione di strategie algoritmiche su BTC/ETH, con **un libro che gira con soldi veri**
su Deribit mainnet dal 20 giugno 2026.
## Obiettivo > 🚨 **v2.0.0 — RESET del 2026-06-19. Tutto ciò che questo README diceva prima è archiviato in
> `Old/` e non è fidato.** L'intera libreria di strategie "validata out-of-sample" (le famiglie
> FADE/HONEST/PAIRS/TSMOM/SHAPE, i portafogli PORT01-06, gli Sharpe fra 6 e 10) era un **artefatto
> di uno storico contaminato**: print fantasma di un feed *testnet* più storico Binance/USDT.
> Ri-testate sul feed reale ricostruito da Deribit mainnet, **perdono ogni anno**. Documento di
> fondazione: `docs/diary/2026-06-19-deribit-history.md`.
>
> Questo README descrive il progetto **dopo** il reset. È stato riscritto il 2026-09-02, dopo
> essere rimasto fermo al 4 giugno — quindici giorni prima del reset — mentre pubblicava i numeri
> che il progetto aveva già dichiarato falsi.
Partendo da un capitale iniziale di €1.000, raggiungere un profitto medio di €50 al giorno entro 6–8 mesi, tramite un portafoglio di strategie algoritmiche poco correlate fra loro — mean-reversion, trend/rotazione e spread market-neutral — validate out-of-sample e fee-aware. **L'autorità sui numeri e sulle decisioni è `CLAUDE.md`**, e il racconto completo sta in
`docs/memory/`. Questo file è l'ingresso, non la fonte.
## Risultati ---
> ⚠️ **Revisione 2026-05-28.** La famiglia squeeze-breakout (SQ/MT/ML/AD/CM/PD, con ## Cos'è vivo, adesso
> accuracy storiche dichiarate 76-82%) è stata **scartata**: quei numeri erano un
> **artefatto di look-ahead**. I backtest decidevano la direzione dalla candela di
> breakout `close[i]` ma entravano a `close[i-1]` — impossibile dal vivo. Sotto
> ingresso onesto (`close[i]`) e fee reali, l'edge sparisce e tutte perdono, anche
> a fee zero. Dettagli e prove: `scripts/analysis/oos_validation.py`.
Dopo una validazione **out-of-sample, fee-aware** di molte famiglie di strategie, | | |
emergono cinque famiglie con edge netto reale, tutte radicate nella stessa lezione |---|---|
(in cripto la **mean-reversion** funziona, la continuazione no) o nella diversificazione: | libro live | **TP01 + SKH01 a 75/25**, nettati in software su una sola posizione per asset (50/50 BTC/ETH) |
| venue | Deribit mainnet, perpetual lineari USDC. Esecuzione **armata** dal 2026-06-20 |
| capitale | ~$2.050 (USDC + USDE), non i €2.000 nominali di nessun paper trader |
| cadenza | **oraria**, minuto `:47` (`scripts/cron_book.sh`) |
| leva | lorda ~0,28x su un tetto di 1,00x. Il cap non ha mai morso: **il vincolo è il segnale** |
| protezione on-book | un solo disaster-SL rotolante al −30% sulla posizione netta |
| Famiglia | Meccanismo | Strategie | Profilo (netto OOS) | **Non** sono nel libro live: XS01, VRP01, GTAA01, XSR01. Vivono nel portafoglio di **ricerca**
|----------|-----------|-----------|---------------------| (paper, 5 sleeve), che è una serie diversa da quella che gira — quasi tutti i numeri di portafoglio
| **FADE** | mean-reversion intraday 1h (long/short, BTC/ETH) | MR01 Bollinger, MR02 Donchian, MR07 Return-reversal | Acc 52-55%, DD 18-34% | del progetto sono su quella, non su questa.
| **HONEST** | long-only multi-regime multi-crypto | DIP01 dip-buy, TR01 EMA-trend, ROT02 dual-momentum | CAGR 31-56%, DD 15-27% |
| **PAIRS** | spread reversion *market-neutral* (2 gambe) | PR01 ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL | Sharpe 2.0-4.4, corr col mercato ~0.05 |
| **TSMOM** | time-series momentum multi-orizzonte | TSM01 (3/6/12m + risk-off) | diversificatore, DD 15-22% |
| **SHAPE** | ML walk-forward su feature di *forma* del prezzo | SH01 (LogisticRegression, orizzonte 12 barre) | diversificatore, corr +0.08 col resto |
Tutti i numeri sono **netti** dopo fee realistiche (Deribit 0.10% RT single-leg, 0.20% ## I numeri, con la loro lente
RT/coppia sui pairs), leva 3x, su finestra held-out. Le strategie sono robuste su griglia
parametri, sweep fee 0.00-0.20% RT e — per i pairs — validate con **walk-forward** e
config universale (niente cherry-picking).
### Portafoglio combinato (la vera leva anti-drawdown) Ogni numero va scritto con la lente e la banda che gli appartengono. La tabella completa
("non citare" ↔ "citare") è in `CLAUDE.md` §2; qui i tre che contano.
Le famiglie sono **quasi scorrelate fra loro** (~0.05). Combinandole in un unico | grandezza | valore onesto |
portafoglio equipesato il drawdown crolla sotto quello di ogni singola sleeve: |---|---|
| rendimento del libro live | **TWR +10,6%** dall'armamento, spezzato sul versamento del 25/08: +11,61% prima, −0,9% dopo |
| crescita di trading | **+$50** in 71 giorni, su 30 round-trip chiusi e $0,87 di fee totali |
| Sharpe del portafoglio di ricerca | **1,95** [1,81 – 2,12] full, **1,54** [1,11 – 1,91] hold-out |
| Portafoglio | CAGR | Max DD | Sharpe | ⚠️ Il rendimento dell'equity **non** è la performance: il 96% della crescita del conto è un
|-------------|------|--------|--------| bonifico. Chi legge una percentuale su questo progetto deve sapere se è un TWR o un rapporto fra
| FADE (6 sleeve) | ~46% | 8% | 3.9 | due saldi — è stato un difetto reale, riparato il 2026-09-02.
| HONEST (3 sleeve) | ~46% | 13% | 2.2 |
| **MASTER** (FADE + HONEST, 9) | ~47% | **5%** | 4.2 |
| **MASTER + PAIRS + TSM01** (15) | ~67% | ~5% | ~6 |
| **PORT06 live** (17 sleeve, cap pairs 33%, leva 2×, config EXIT-16) | ~79% | **2.6%** | 7.8 (FULL) / 10.1 (OOS) |
> 🔎 **Numeri sobri (anti-overfit).** L'OOS singolo cade nel regime favorevole 2024-25: ## La riga che ordina tutto il resto
> i valori di Sharpe/DD sopra sono ottimistici di circa il 50%. Da pianificare per le
> decisioni: **Sharpe atteso ~5**, **worst-drawdown su 90 giorni ~6%**, profilo che regge
> a leva 2x con slippage raddoppiato. Configurazione raccomandata: equal-weight, leva 2x,
> con un cap sull'allocazione ai pairs (~30-35%, poiché concentrano ~57% del rischio).
> Tutto resta da confermare nel paper trading live.
## Come funziona > La ricerca ha smesso di essere il vincolo il 2026-07-26, e **sei ondate successive lo hanno
> confermato invece che ribaltarlo**. I vincoli sono **il capitale che entra** e **il conto che non
> sparisce**.
### MR01 — Bollinger Fade (mean-reversion) Misurato: il miglior candidato nuovo vale **+0,046 €/giorno**; versare €500/mese invece di €250
porta la probabilità di arrivare al traguardo in 20 anni **dal 14% all'85%**. E €100/mese in più
equivalgono a **+4,07%/anno di drift**, cioè più di tutta la leva autorizzabile.
La strategia attiva sfrutta il fatto, emerso dai dati, che su BTC/ETH a 1h gli estremi ## Metodo — cosa deve superare una strategia nuova
di prezzo **rientrano verso la media** più di quanto proseguano:
1. **Bollinger Bands** (window `n`, `k` deviazioni standard) sul close. Sei requisiti, nessuno negoziabile (`CLAUDE.md` §8, gate in `scripts/research/alt/altlib.py`):
2. **Entry** — quando il close esce *sotto* la banda inferiore → **long** (o *sopra* la superiore → **short**). Ingresso a `close[i]`, eseguibile dal vivo.
3. **Take-profit** alla media mobile (il rientro atteso).
4. **Stop-loss** a `sl_atr × ATR` oltre l'estremo; **time-limit** a `max_bars`.
Nessun look-ahead: direzione e livelli sono calcolati con dati fino a `close[i]`. 1. **ingresso eseguibile** — direzione e prezzo da dati fino a `close[i]`, mai l'estremo di una candela;
2. **backtest netto** dopo fee Deribit realistiche, più la leva;
3. **out-of-sample** held-out, robustezza su griglia, sweep fee;
4. **liquidità e plausibilità** — un edge su un book fermo o su wick fantasma non è un edge;
5. i **gate**: `marginal_vs_tp01` (Sharpe marginale, non assoluto), `study_family_honest` con
deflated-Sharpe ≥ 0,95, `day_boundary_robust`, `anchor_luck_band`, `weights_tilt_null`;
6. codice, test e diario.
### Le altre famiglie Il progetto ha **73 regole di prim'ordine** (`CLAUDE.md` §6) — sul dato, sul metodo, sui costi,
sulla produzione e sul piano — ognuna pagata almeno una volta. La più
ricorrente, cinque occorrenze: *un sorvegliante deve derivare il proprio bersaglio dal codice
sorvegliato, mai ridichiararlo — un controllo puntato su una configurazione diversa da quella che
gira passa sempre, e non sta controllando niente.*
- **FADE** (oltre MR01): MR02 fada la rottura del canale Donchian verso il centro; ## Il dato
MR07 fada il movimento di barra estremo misurato in deviazioni standard dei
rendimenti. Stessa logica di reversione, indicatori indipendenti.
- **HONEST** (long-only, multi-crypto): DIP01 compra i dip estremi e rivende al
recupero; TR01 segue il trend con incrocio di EMA su un paniere; ROT02 ruota ogni
giorno sui tre asset col momentum più forte, andando in cash quando BTC è sotto la
sua media (risk-off). Coprono i regimi di trend e rotazione, complementari alle fade.
- **PAIRS** (market-neutral): scommette sul rientro verso la media del log-ratio fra
due cripto (z-score). Long su una, short sull'altra: l'esposizione netta al mercato è
quasi nulla (correlazione ~0.02), il che la rende un diversificatore eccellente.
- **TSMOM**: tiene gli asset con momentum positivo persistente su più orizzonti
(3/6/12 mesi), con overlay risk-off. Rende meno ma è poco correlato, utile in ensemble.
### Perché lo squeeze breakout è stato abbandonato - **La verità è Deribit mainnet**, perché è dove si esegue. Binance è un audit indipendente, mai
un'ancora per "ripulire": è USDT, ~10 bps fuori, fino al 3% sotto depeg.
- Universo certificato: **solo BTC/ETH**, ogni timeframe. Gli alt sono esclusi.
- Lo storico si aggiorna **solo** con `rebuild_history.py` e si certifica **sempre** con
`certify_feed.py`. Il vecchio downloader è la causa del reset.
- La catena opzioni si **raccoglie** ogni ora (`collect_chain.py`, minuto `:25`): un'ora non
raccolta è persa per sempre.
L'ipotesi originale era opposta — *continuazione* dopo la compressione di volatilità ## Struttura
(Bollinger dentro Keltner → breakout direzionale). Su dati storici sembrava dare
76-82% di accuracy, ma era un **artefatto di look-ahead**: il backtest entrava a
`close[i-1]` con direzione decisa da `close[i]`. Replicando l'esecuzione reale
(ingresso a `close[i]`) l'edge collassa al ~47% (lancio di moneta) e i costi fanno
il resto. Il test sui breakout intra-barra a 5m conferma che il movimento *rientra*
subito (mean-reversion), giustificando MR01. Tutta la famiglia squeeze è in `scripts/waste/`.
### Lezione metodologica
Ogni nuova strategia deve passare: (1) **ingresso eseguibile** senza look-ahead,
(2) backtest **netto** dopo fee realistiche (0.10% RT Deribit), (3) validazione
**out-of-sample** + robustezza su griglia parametri + sweep fee. Strumenti in
`scripts/analysis/` (`strategy_research.py`, `oos_validation.py`, `intrabar_test.py`).
## Struttura progetto
``` ```
PythagorasGoal/ src/
├── src/ data/downloader.py load_data(asset, tf) sui parquet certificati
│ ├── data/ # Download e gestione dati (Cerbero MCP + Binance) strategies/ trend_portfolio.py (TP01) · skyhook.py (SKH01) · base · indicators
│ ├── fractal/ # Indicatori frattali: Hurst, Higuchi FD, self-similarity portfolio/ portfolio.py (N sleeve + weights_tilt_null) · sleeves.py · gtaa.py
│ ├── backtest/ # Motore di backtesting con fee e metriche backtest/harness.py backtest onesto, senza look-ahead
│ ├── strategies/ # Classe base Strategy ABC + indicatori condivisi live/ book.py (esecutore netto) · deribit · livefeed · usde
│ │ ├── base.py # Strategy, Signal, BacktestResult, YearlyStats venue_watch · venue_probe · venue_news · monitor_health · scale_watch
│ │ └── indicators.py # keltner_ratio, detect_squeezes, ema, atr, rv, corr tradesdb · journal · analista · notifier · cli
│ ├── live/ # Paper trading live su Deribit testnet scripts/
│ │ ├── multi_runner.py # Orchestratore multi-strategia (strategie + pairs) live/ book_execute · trades_db · journal · analista · balance_watch
│ │ ├── strategy_worker.py # Worker single-leg con stato persistente paper_* (forward-monitor) · usde_watch · usde_convert · fee_watch
│ │ ├── pairs_worker.py # Worker a 2 gambe per i pairs (market-neutral) research/ r<data>_*.py — un file per esperimento, harness in alt/altlib.py
│ │ ├── strategy_loader.py # Import dinamico classi Strategy analysis/ rebuild_history · certify_feed · audit_feed · multi_source_check
│ │ ├── cerbero_client.py # Client HTTP per Cerbero MCP cron_{book,daily,chain,balance,usde,opt_snapshot,vol_term}.sh
│ │ ├── signal_engine.py # Squeeze + ML real-time (legacy) + validazione OOS docs/
│ │ └── telegram_notifier.py memory/ LA MEMORIA — 6 file, indicizzati in testa a CLAUDE.md
│ └── portfolio/ # Portafogli di prima classe (capitale condiviso, backtest + live) research/ RESULTS-0822 (§1-77, un registro per filone) · BRIEF-0822 · SPEC-scale-key
│ ├── base.py # SleeveSpec, Portfolio (.backtest), load_active_portfolio diary/ una voce per esperimento (144)
│ ├── weighting.py # Schemi di ponderazione: equal, cap, inverse_vol, cluster_rp, manual journal/ libro di bordo, una voce al giorno, 4 livelli per provenienza
│ ├── sleeves.py # Builder unificato equity-per-sleeve (fonte unica, parità report) tests/ 1008, tutti verdi
│ ├── ledger.py # PortfolioLedger: PnL/DD aggregati, persistenza e resume Old/ archivio pre-reset — consultabile, non fidato
│ └── runner.py # PortfolioRunner live (Cerbero v2, sizing, ribilancio giornaliero)
├── scripts/
│ ├── strategies/ # Strategie con edge validato OOS (FADE, HONEST, PAIRS, TSMOM + portafogli)
│ ├── portfolios/ # Definizioni PORT01-06 e report run() dei portafogli di prima classe
│ ├── waste/ # Strategie scartate (squeeze SQ/MT/ML/AD/CM/PD, MR03, ROT01, W01-W28)
│ └── analysis/ # Ricerca/validazione OOS fee-aware, gestione rischio, report
├── strategies.yml # Config multi-strategy paper trader
├── data/
│ ├── raw/ # Parquet OHLCV (gitignored, ~70 MB)
│ └── regime/ # DVOL + funding (Deribit mainnet) + cache feature regime (gitignored)
├── VERSION # versione semver (cotta nell'immagine, mostrata nei msg Telegram)
├── docs/
│ ├── diary/ # Diario di ricerca giornaliero
│ └── specs/ # Specifiche di design
├── Dockerfile
├── docker-compose.yml
└── pyproject.toml
``` ```
## Strategie attive ## Comandi
Le strategie single-asset estendono `src.strategies.base.Strategy`
(`generate_signals() → backtest()`); i pairs hanno un worker dedicato a 2 gambe.
| Codice | Script | Famiglia | Descrizione |
|--------|--------|----------|-------------|
| **MR01** | `MR01_bollinger_fade.py` | FADE | Fada la banda di Bollinger, TP alla media, SL ad ATR |
| **MR02** | `MR02_donchian_fade.py` | FADE | Fada la rottura del canale Donchian, TP al centro |
| **MR07** | `MR07_return_reversal.py` | FADE | Fada il movimento di barra estremo (z dei rendimenti) |
| **DIP01** | `DIP01_dip_reversion.py` | HONEST | Dip-buy long-only su z-score estremo |
| **TR01** | `TR01_ema_trend.py` | HONEST | EMA 20/100 trend-following su paniere cripto (4h) |
| **ROT02** | `ROT02_dual_momentum.py` | HONEST | Rotazione cross-sectional top-3 + risk-off (1d) |
| **PR01** | `PR01_pairs_reversion.py` | PAIRS | Spread reversion market-neutral su 5 coppie |
| **TSM01** | `tsmom_research.py` | TSMOM | Time-series momentum multi-orizzonte + risk-off |
| **SH01** | `SH01_shape_ml.py` | SHAPE | LogisticRegression walk-forward su 17 feature di forma, orizzonte 12 barre (diversificatore) |
Le fade applicano tre protezioni live: un **filtro trend** (`trend_max`/`ema_long`,
salta i segnali col prezzo troppo esteso rispetto alla EMA200), un **loss-guard Hurst**
(`hurst_max=0.55`, salta i segnali in regime persistente/trending dove si concentrano gli stop-loss
— dimezza il drawdown del portafoglio, calcolato dalle sole close) e l'**EXIT-16 close-confirm SL**
(`sl_confirm_atr=0.5`, 2026-06-04: lo stop scatta solo se la barra *chiude* oltre `sl ∓ 0.5·ATR14` —
gli stop intrabar da wick erano falsi negativi, l'overshoot che buca lo stop è proprio il movimento
che la fade fada; a livello PORT06 porta l'OOS Sharpe da 8.82 a 10.06). Più un filtro `min_tp_frac`
che scarta i micro-scalp col take-profit entro il costo delle fee. Le tre protezioni sono
complementari: Hurst toglie il regime tossico, il trend-filter gli ingressi sovra-estesi, il
close-confirm i falsi stop. Portafogli pronti: `PORT01`
(honest), `PORT02` (fade), `PORT03` (master fade+honest), **`PORT06`** (master esteso, default live).
**Scartate** (in `scripts/waste/`): la famiglia squeeze (SQ01-04, ML01, MT01, PD01,
CM01, AD01 — artefatto di look-ahead), MR03 Keltner (debole/ridondante con MR01) e
ROT01 (dominata da ROT02).
### Comandi utili
```bash ```bash
# Backtest di una strategia uv sync # dipendenze
uv run python scripts/strategies/MR01_bollinger_fade.py uv run python scripts/analysis/rebuild_history.py --asset BTC ETH # storico da Deribit mainnet
uv run python scripts/strategies/PR01_pairs_reversion.py uv run python scripts/analysis/certify_feed.py # certifica i feed
uv run python scripts/live/trades_db.py --report # stato del libro + TWR
# Ricerca e validazione fee-aware out-of-sample uv run python scripts/live/journal.py # voce del giorno
uv run python scripts/analysis/strategy_research.py # screening famiglie + deep-dive fade uv run python scripts/live/analista.py --secco # analisi del giorno, senza salvare
uv run python scripts/analysis/strategy_research_v2.py # MR02 / MR03 / MR07 uv run python scripts/portfolio/run_portfolio.py # portafoglio di ricerca
uv run python scripts/analysis/oos_validation.py # perche' la famiglia squeeze e' scartata uv run pytest # 1008 test
uv run python scripts/analysis/pairs_research.py # ricerca + verifica no-look-ahead dei pairs
# Gestione rischio, combinazione, report
uv run python scripts/analysis/risk_management.py # filtro trend + portafoglio fade
uv run python scripts/analysis/combine_portfolio.py # combinare fade + honest
uv run python scripts/analysis/combine_v2.py # master esteso con pairs + TSM01
uv run python scripts/analysis/report_families.py # report per anno di tutte le famiglie
# Validazione dei worker live (replay == backtest)
uv run python scripts/analysis/validate_worker_mr01.py # worker single-leg su MR01
uv run python scripts/analysis/validate_worker_pairs.py # worker a 2 gambe sui pairs
uv run python scripts/analysis/live_smoke_pairs.py # smoke test feed live reale dei pairs
``` ```
## Paper Trading Live Ogni script di `scripts/live/` accetta `--help` e **rifiuta un flag che non conosce** (esce 2): fino
al 2026-09-02 un flag sbagliato eseguiva l'azione di default, e su tre script quell'azione scriveva.
Il multi-strategy runner esegue N strategie in parallelo su dati live da Cerbero MCP, ## Gate aperti
ognuna con €1000 USDC virtuali indipendenti. Gestisce due tipi di worker:
- **Single-leg** (`strategy_worker.py`): per le strategie direzionali. Se un `Signal` Un gate si decide **alla data**, coi criteri scritti **prima**. Elenco completo in `CLAUDE.md` §4.
porta `tp`/`sl`/`max_bars` in `metadata` (come le fade), chiude su take-profit /
stop-loss / time-limit; altrimenti usa il fallback `hold_bars`/stop -2%.
- **Due gambe** (`pairs_worker.py`): per i pairs market-neutral. Apre long su una gamba
e short sull'altra, esce sul rientro dello z-score o per time-limit, conta le fee su
entrambe le gambe. Validato: il replay storico coincide *esattamente* col backtest.
### Avvio | gate | data | dove punta oggi |
|---|---|---|
| STATARB | 2026-09-27 | ritiro (Sharpe −1,61 sulla serie vera) |
| SCALA-01 — leva 1,00 → 1,25 | non prima del 2026-10-01 | chiave costruita e **inerte**; 9 condizioni, 2 fatte |
| XSR01 | 2026-10-23 | sotto la lente rendita il meccanismo vale ~0 |
| DVOLSPREAD | kill 2026-10-24 | serie −4,41 |
| GTAA01 tenere/bloccare | al book a $15k | contributo reale +0,10/+0,12 di Sharpe, non incassabile sotto la soglia |
```bash ## Obiettivo, e cosa lo rende difficile
# Locale
uv run python -m src.live.multi_runner
# Docker Il target dichiarato è **€50/giorno partendo da €1.000**. Non è raggiungibile a questo capitale:
docker compose up -d servono ~$313k (banda [$187k – $1,14M]) o **€1.733/mese per dieci anni** per averlo al 90% di
``` probabilità. La leva non è la scorciatoia — quella difendibile vale quanto €100-150/mese di
versamento. La via è target-vol, capitale e tempo.
### Configurazione **Onestà prima di tutto**: nessun numero va creduto finché non è netto fee, out-of-sample, robusto
su griglia, e su dati certificati, liquidi ed eseguibili. Il resto di questo repo esiste per rendere
Le strategie attive sono definite in `strategies.yml`: quella frase verificabile invece che dichiarata.
```yaml
defaults:
capital: 1000
position_size: 0.15
leverage: 3
strategies: # strategie single-leg
- name: MR01_bollinger_fade
asset: BTC
tf: 1h
enabled: true
params: { bb_window: 50, k: 2.5, sl_atr: 2.0, max_bars: 24, trend_max: 3.0, ema_long: 200 }
pairs: # strategie a 2 gambe (market-neutral)
- name: PR01_pairs_reversion
a: ETH
b: BTC
tf: 1h
enabled: true
params: { n: 50, z_in: 2.0, z_exit: 0.75, max_bars: 72, jump_max: 0.08 }
```
Per aggiungere una strategia: nuova riga in `strategies.yml` (sezione `strategies` o
`pairs`), poi `docker compose restart`. Lo storico delle strategie esistenti rimane intatto.
### Persistenza
Ogni strategia ha la sua directory in `data/paper_trades/`:
```
data/paper_trades/
MR01_bollinger_fade__BTC__1h/
trades.jsonl # Storico trade append-only
status.json # Stato corrente (resume al restart, include tp/sl/max_bars)
```
Notifiche Telegram per ogni trade (richiede `TELEGRAM_BOT_TOKEN` e `TELEGRAM_CHAT_ID` in `.env`).
## Paper Trading a Portafoglio
Accanto al multi-strategy runner originale — in cui ogni strategia gestisce autonomamente il proprio conto virtuale da €1.000 — il progetto dispone ora di un **paper trader a portafoglio** (`src/portfolio/`) che tratta l'insieme delle strategie come un unico organismo con un capitale condiviso.
### Come funziona
La definizione di un portafoglio (`SleeveSpec` + schema di peso) ha due facce sulla stessa sorgente dati:
- **Backtest** (`.backtest()`): ricostruisce le equity-curve di ogni sleeve tramite il builder unificato in `sleeves.py`, le pondera secondo lo schema scelto e calcola le metriche aggregate (CAGR, Sharpe, max DD). La parità con i report prodotti da `report_families.py` è garantita dalla fonte unica.
- **Live** (`PortfolioRunner`): ogni ora il runner scarica le candele aggiornate via Cerbero v2, calcola i pesi correnti, avvia i worker appropriati per ogni sleeve attiva e registra il PnL aggregato nel ledger (`data/portfolios/{code}/`). Il ledger persiste tra i riavvii.
### Schemi di ponderazione
Il modulo `weighting.py` mette a disposizione cinque schemi: `equal` (default), `cap` (tetto per famiglia — p.es. `pairs: 0.33` per limitare la concentrazione), `inverse_vol` (pesi inversamente proporzionali alla volatilità storica), `cluster_rp` (equal tra cluster naturali poi inverse-vol all'interno del cluster) e `manual` (pesi liberi). Lo schema si specifica in `portfolios.yml` insieme al codice portafoglio e alla leva.
### Portafoglio di default: PORT06
La configurazione raccomandata è **PORT06** (`scripts/portfolios/PORT06_master_shape.py`): portafoglio master esteso che include tutte e sei le famiglie (FADE, HONEST, PAIRS, TSMOM, SHAPE), con schema `cap` che limita i pairs al 33% del capitale per moderare la loro concentrazione di rischio. Backtest canonico (dati al 2026-05-28): Sharpe 6.47 (FULL) / 8.82 (OOS), drawdown massimo 4.10% (FULL) / 1.30% (OOS), leva 2×; **con la config live attuale (EXIT-16 close-confirm): Sharpe 7.84 / 10.06, DD 2.60% / 1.15%**.
### Scope live
Il runner esegue **tutti e 17 gli sleeve** di PORT06: **fade** (MR01, MR02, MR07 × BTC/ETH),
**honest** (DIP01, TR01-basket 4h, ROT02-rotation 1d), **pairs** (PR01, cinque coppie),
**TSMOM** (TSM01 1d) e **shape** (SH01 × BTC/ETH). Worker dedicati: `StrategyWorker` (single-leg, fade/
dip/**shape**), `PairsWorker` (2 gambe), `BasketTrendWorker`, `RotationWorker`, `TsmomWorker`. Il runner
fetcha 1h da Cerbero v2 e resampla a 4h/1d; il pool di capitale, il ribilancio giornaliero e il ledger
sono validati == backtest.
> **SH01 (2026-06-01):** gira come `StrategyWorker` normale (il walk-forward è interno a
> `generate_signals`). Il vecchio `MLWorkerWrapper` usava il `SignalEngine` **squeeze scartato** —
> rimosso. **Loss-guard Hurst (2026-06-02):** le fade saltano i segnali in regime persistente
> (rolling-Hurst ≥ 0.55), dove si concentrano gli stop-loss — dimezza il drawdown del portafoglio
> (FULL 4.1%→2.4%; stop-loss fade −67% in numero, perdite totali −68%). Calcolato dalle sole close,
> attivo live (`hurst_max` nei params). Il report orario su Telegram **monitora lo stop-rate fade
> prima/dopo l'attivazione** e dà il verdetto automatico quando il campione è sufficiente.
### Esecuzione reale (shadow, Deribit testnet)
Sette sleeve single-leg — le **6 fade** (MR01/MR02/MR07 × BTC/ETH) e **DIP01** (dal 2026-06-04) —
eseguono ordini **reali su Deribit testnet** accanto al fill simulato (*shadow*: il sim resta la
verità che guida le decisioni; il reale misura la fattibilità). Punti chiave:
- **Strumenti lineari USDC** (`BTC_USDC`/`ETH_USDC-PERPETUAL`): payoff lineare = matematica del
backtest; fee e PnL in USDC. Quantizzazione `Decimal` di amount (step) e prezzi (tick).
- **Take-profit reale = limit reduce-only AL livello** (v1.0.7): piazzato all'apertura, copre la
sola quota del worker (gli strumenti sono condivisi fra worker e nettati per conto); alla
chiusura il worker cancella il resting, riconcilia i fill dal trade history per `order_id` e
chiude a market solo il residuo. Fix della divergenza misurata: il market-on-poll usciva
+235 bps oltre il livello TP. Fill da resting = fee maker (~0%).
- **Stop-loss close-confirm** (v1.1.0): uscita al close che sfonda il livello → market
reduce-only al poll (nessun ordine stop sul book, per scelta: i trigger Deribit generano un
nuovo order_id allo scatto, non verificabile, e i wick non devono stoppare).
- **Verifica sul trade** (order_id in `get_trade_history`), fee reali dai `trades[]`, ledger
reale parallelo persistito (`real_capital`), eventi `REAL_OPEN`/`REAL_TP_RESTING`/`REAL_CLOSE`
nel log + alert Telegram (`REAL_EXEC_LIVE`, `REAL_OPEN_FAIL`).
- Config in `portfolios.yml` → `overrides.execution {enabled, sleeves, instruments}`.
**Pairs/rotation/TSMOM/shape restano simulati**: i pairs richiedono un executor a 2 gambe
(leg-risk), i multi-asset un rebalance-to-target; roadmap nel diario.
### Versione & deploy
Ogni deploy ha una **versione** (file `VERSION`, semver) che compare nei messaggi Telegram (notifiche
trade + report orario), così correli ogni messaggio al codice che l'ha generato. Il sorgente è **cotto
nell'immagine** → per aggiornare il live serve un **rebuild**, non un semplice restart:
```bash
./scripts/deploy.sh # bump patch (1.0.0 → 1.0.1) + commit + rebuild + ricrea container
./scripts/deploy.sh minor # 1.0.x → 1.1.0
```
Il volume `data/` persiste tra i deploy → i worker fanno RESUME dello stato (capitale, posizioni aperte).
### Avvio del paper trader a portafoglio
```bash
# Backtest del portafoglio di default (PORT06)
uv run python scripts/portfolios/PORT06_master_shape.py
# Paper trading live a portafoglio
uv run python -m src.portfolio.runner
# Report orario su Telegram (stato + stop-rate fade prima/dopo loss-guard) — via cron
uv run python scripts/portfolios/hourly_report.py
# Smoke test del data layer Cerbero v2
uv run python scripts/analysis/smoke_portfolio.py
```
## Setup
```bash
# Clona e installa
git clone <repo-url> && cd PythagorasGoal
uv sync
# Scarica dati storici (~70 MB)
uv run python -m src.data.downloader
# Backtest strategia attiva
uv run python scripts/strategies/MR01_bollinger_fade.py
# Paper trading live
uv run python -m src.live.multi_runner
```
### Requisiti
- Python ≥ 3.11
- [uv](https://docs.astral.sh/uv/) come package manager
- Accesso a Cerbero MCP (`cerbero-mcp.tielogic.xyz`) per dati Deribit live
- Docker (opzionale, per deploy su VPS)
## Dati
| Asset | Timeframe | Copertura |
|-------|-----------|-----------|
| BTC, ETH | 5m / 15m / 1h | 2018-01 → oggi |
| SOL, LTC, ADA, XRP, BNB, DOGE | 15m / 1h | 2019-2022 → oggi (variabile per asset) |
Fonte primaria: perpetual Deribit via Cerbero MCP. Fallback: Binance spot via ccxt.
Formato: Apache Parquet (in `data/raw/`, gitignored).
> **Nota sul naming Deribit (per il feed live).** I major sono perpetui *inverse*
> (`BTC-PERPETUAL`, `ETH-PERPETUAL`); gli altcoin sono perpetui *lineari USDC*
> (`SOL_USDC-PERPETUAL`, `LTC_USDC-PERPETUAL`, …) con storia dal 2022. Attenzione:
> `LTC-PERPETUAL`/`ADA-PERPETUAL` non esistono e `SOL-PERPETUAL` restituisce dati
> errati — per gli altcoin usare sempre la forma `_USDC-PERPETUAL`.
### Discovery & validazione strumenti
`src/data/instruments.py` scopre e **valida** gli strumenti disponibili sugli
exchange implementati — **Deribit** e **Hyperliquid** (esclusi Alpaca/stocks e
**Bybit**, feed testnet inaffidabile). Ogni perpetuo viene testato sui dati
storici realmente raccoglibili: esistenza, congruenza OHLC, contratto non-morto,
liquidità e **congruenza prezzo cross-exchange** (mediana per base-coin, tolleranza
5%) — così feed farlocchi e contratti sbagliati (es. `SOL-PERPETUAL`=9.6) vengono
scartati. Il risultato è `data/instruments_registry.json` (strumenti validi +
timeframe + data d'inizio).
**Solo gli strumenti validati possono essere scaricati**: il downloader ha un gate
(`_download_cerbero_range`) che rifiuta quelli non nel registry. Rigenera con:
```bash
uv run python -m src.data.instruments
```
Simboli Deribit: BTC/ETH = `<COIN>-PERPETUAL` (inverse); altcoin =
`<COIN>_USDC-PERPETUAL` (lineari USDC). Registry attuale (testnet): Deribit 18/106
validi (major liquidi, BTC dal 2018), Hyperliquid 66/74.
## Riferimenti
- Serleto, L. & Malanga, C. — *Pythagoras Trading Prediction* (2024)
- Serleto, L. & Malanga, C. — *Libro dei Frattali* (2024)
## Licenza
Uso privato. Non destinato alla distribuzione.
+23 -3
View File
@@ -1,7 +1,27 @@
{ {
"_nota": "Config esecuzione LIVE di TP01. execution_enabled=true + --execute -> ordini REALI. ARMATO 2026-06-20.", "_nota": "Config esecuzione LIVE del BOOK DERIBIT (TP01+SKH01 nettati in software). execution_enabled=true + --execute -> ordini REALI. ARMATO 2026-06-23: esecutore scripts/live/book_execute.py via cron ORARIO scripts/cron_book.sh (SKH01 e' a 230m). disaster-SL on-book -30% sulla posizione netta. Tutto flat all'arming -> nessun ordine finche' un segnale non arma.",
"_nota_cap": "Cap notional per-asset DINAMICO (frontiera 2026-07-03): con max_notional_per_asset_frac=0.5 il cap = equity/2, cosi' cresce col capitale e un deposito non resta strozzato. AGGIORNATO 2026-07-26: max_notional_per_asset_usd alzato 300 -> 3000 in previsione del versamento (EUR 5.000 + 500/mese -> equity ~$6.050, equity/2 ~$3.025). ⚠️ Alzarlo NON e' pericoloso perche' dal 2026-07-26 il cap di FALLBACK (equity reale non leggibile) e' min(questo valore, ultima_equity_reale_osservata * frac) — vedi src/live/book._cap e il watermark data/live/equity_seen.json. Senza quel legame, un cap da $3.000 su un conto da $597 avrebbe permesso $2.000 di nozionale lordo = 3.35x di leva nel momento peggiore. Questo rende inutile l'azione manuale 'al deposito alzare il cap' (pre-registrata 2026-07-02).",
"execution_enabled": true, "execution_enabled": true,
"max_notional_per_asset_usd": 300, "max_notional_per_asset_usd": 3000,
"max_notional_per_asset_frac": 0.5,
"min_order_usd": 5, "min_order_usd": 5,
"disaster_sl_pct": 0.30 "disaster_sl_pct": 0.3,
"_nota_stale": "Staleness-gate (2026-07-25): se l'ultima barra del feed certificato e' piu' vecchia di max_data_age_days, book_execute NON invia ordini e allerta su Telegram. Il 2026-07-14 il book compro' ETH con il feed fermo da 6 giorni (conto online e posizione leggibile -> gli altri due gate non scattavano). Follow-up raccomandato nel diario 2026-07-15-feed-freeze, ora cablato.",
"max_data_age_days": 2,
"_nota_skh_feed": "Freschezza del feed 5m usato per il segnale SKH01 (2026-07-26). fresh_5m ricade sul feed certificato IN SILENZIO se il fetch pubblico Deribit fallisce, e il certificato si rigenera 1x/giorno: senza controllo la latenza d'uscita di SKH01 passa da ~1h a ~1 giorno senza segnalazione. Sopra soglia book_execute ALLERTA e NON blocca (bloccare fermerebbe anche TP01, nettato sullo stesso strumento, per un guasto di rete). Diario 2026-07-26-t1-esecuzione-skh-live.md.",
"skh_feed_max_age_min": 30,
"_nota_usde": "Collaterale USDE a rendimento (test di eligibilita' 2026-08-26: 500 USDE, verdetto entro il 29/08 — diario 2026-08-26-usde-analisi). L'autorita' che LEGGE questa sezione e' src/live/usde.py; la usano shadow._collaterale_usde (equity oraria del book) e scripts/live/usde_watch.py (sorveglianza giornaliera 12:35 UTC). Criteri delle soglie, dichiarati (P6): depeg_warn 0.99 = fuori dalla banda operativa dello spot (~3 bps) e oltre il clamp +-0.5% per fonte dell'indice usde_usdc — a quel prezzo non e' rumore di book; depeg_crit 0.95 = meta' del buffer di haircut (10%) consumata. quota_target 0.70 (CHIAVE TOLTA il 2026-09-10, issue #7: il bersaglio operativo e' DERIVATO dalle bande del cuscino, vedi usde._nota_cuscino — quanto segue e' la storia della decisione) = la quota DECISA dall'operatore il 2026-08-30 (la decisione di quota che il gate USDE-01 apriva; anticipata di un giorno sul rinvio al 31/08, su richiesta esplicita dell'operatore \"porta in usde tutto il capitale che non viene usato\"). Il 70% NON e' un argmax (M8): e' il massimo compatibile col CUSCINO DI REGOLAMENTO, cioe' il vincolo che r0830_usde_quota non aveva guardato — il P&L e il funding dei perp USDC-lineari si regolano in USDC, non nel collaterale, quindi a quota alta il saldo USDC va negativo alla prima perdita del libro e Deribit lo finanzia a interesse. Il cuscino richiesto e' il disaster-SL sulla massima esposizione lorda: n_asset x frac x disaster_sl_pct = 2 x 0.5 x 0.30 = 30% dell'equity, che lascia esattamente il 70%. quota_max_frac 0.50 = tetto di ALLERTA sulla quota USDE/equity totale (N4: la quota e' l'unica leva contro il rischio emittente, -100% = 25 anni di resa, non recuperabile). Alzato a 0.85 il 2026-08-30 in previsione della quota al 70% e RIMESSO A 0.50 lo stesso giorno perche' il 70% pareva irraggiungibile; RIMESSO A 0.85 il 2026-09-06, quando la quota e' arrivata al 68,7% su autorizzazione dell'operatore e la sonda non ha trovato tetto. 🚨 venue_cap_frac: il 06/09 il tetto NON C'ERA (null, vedi venue_cap_misurato) — quanto segue e' la storia del 30-31/08, tenuta perche' il tetto puo' tornare: venue_cap_frac 0.318 = TETTO DEL VENUE sull'USDE, misurato e NON documentato da Deribit (ne' 'Cross collateral specifications' ne' 'Yield-generating collateral' prevedono un limite sulle quantita' detenibili; il Cap ETHENA che esiste diluisce il TASSO a livello di exchange, non limita gli acquisti). Ogni acquisto oltre il tetto e' rifiutato con `not_enough_funds_in_currency` pur avendo $1.400 disponibili: messaggio FUORVIANTE. E' una FRAZIONE dell'equity, non un livello: provato il 31/08 lasciando scendere l'equity di $8, il tetto e' sceso con lei. ⚠️ DIPENDE DAL MODELLO DI MARGINE, ma pochissimo — misurato a saldo neutro sotto entrambi: SEGREGATO S:SM [643,18-644,18) con equity $2.055,56 = 31,29-31,34%; CROSS X:SM [654,18-655,18) con equity $2.054,90 = 31,84-31,88%. Il passaggio a cross ha comprato +0,55pp = **+11 USDE (~$11)**: il modello entra nel tetto, ma non lo spiega. ⇒ la quota resta ~31-32% sotto qualunque configurazione e il 70% di quota_target NON e' raggiungibile (manca un fattore ~2,2x). Il valore 0.318 e' il bordo BASSO del bracket CROSS, che e' il modello attivo: fa fallire il piano PRIMA dell'ordine. Se si torna a S:SM va rimesso a 0.312. haircut 0.05 — ✅ DIVERGENZA CHIUSA il 2026-08-31 (era 0.10, SBAGLIATO). La pagina margini del conto non espone l'haircut come numero: si RICAVA per differenza fra le due righe, perche' il modello CROSS conta l'USDE scontato e il SEGREGATO non lo conta affatto. Contributo dell'USDE al cross $610,81 su $643,05 di valore -> 5,0137%: l'ipotesi 5% torna a $0,09, la 10% sbaglia di $32,06. Riproducibile: `scripts/research/r0831_margini_conto.py` (N11). Il 26/08 il 10% fu registrato come 'verificato sul venue' senza lasciare traccia di come, e non lo era. 🚨 SCOPERTO NELLA STESSA LETTURA, e vale piu' dell'haircut: il modello di margine ATTIVO e' **Segregated: Standard Margin (S:SM)**, NON cross-collateral. Nella tabella del modello attivo l'USDE **non compare**: non fa margine per i perp USDC-settled del book. Percio' l'haircut oggi non si applica affatto — ed e' esattamente il motivo per cui la misura del 31/08 trovava $0,0000 accantonati. Passare a X:SM aggiungerebbe $610,87 di margine utilizzabile: e' una decisione dell'operatore, non un refactor, e porta con se' la meccanica cross (collateral fee 0,05%/giorno sul saldo negativo, ribilanciamento automatico).",
"usde": {
"index_name": "usde_usdc",
"haircut": 0.05,
"_nota_cuscino": "Dal 2026-09-10 (issue #7) la quota USDE NON e' un numero scelto: e' DERIVATA dal cuscino USDC di regolamento (n_asset x frac x disaster_sl_pct = 30% dell'equity) e da queste tre frazioni del cuscino, lette da src/live/usde.py per scripts/live/cuscino_watch.py (cron :53). cuscino_margine_frac 0.20 = bersaglio unico di ogni conversione: quota = 1 - 0.30 x 1.20 = 0.64 (il vecchio quota_target 0.70 lasciava slack ZERO: ogni ora in perdita avrebbe venduto). cuscino_preavviso_frac 0.10 = sotto, allerta. cuscino_riacquisto_frac 0.40 = sopra, si RICOMPRA USDE fino al bersaglio (un bonifico alza lo slack di 0,7 x importo e fa scattare il riacquisto da solo). Isteresi [0 ; 0.40] x cuscino con bersaglio a 0.20: oscillare richiede +-6% di equity di slack, cioe' +-8,6% di equity USDC (slack = 0,7 USDC - 0,3 USDE). Soglie DICHIARATE, non ottimizzate (M8): un giro costa ~6 bps sull'importo mosso. Ordine obbligato: 0 < preavviso < margine < riacquisto (usde.bande_cuscino lo verifica).",
"cuscino_preavviso_frac": 0.1,
"cuscino_margine_frac": 0.2,
"cuscino_riacquisto_frac": 0.4,
"venue_cap_frac": null,
"venue_cap_misurato": "2026-09-06: NESSUN tetto fino al 68,7% (fermata dal cuscino di regolamento al 70%, non dal venue): +2.434 USDE in 39 ordini a saldo crescente, zero rifiuti (r0906_usde_tetto_sonda.py). Il 30-31/08 il tetto c'era: [643-644) e [654-655) USDE su ~$2.055 = 31,3-31,9%. Non spiegato: e' SPARITO, non e' scalato. null = nessun tetto noto; usde_convert si affida al chunk+backoff sui rifiuti",
"quota_max_frac": 0.85,
"depeg_warn": 0.99,
"depeg_crit": 0.95
}
} }
+23 -1
View File
@@ -7,9 +7,31 @@ services:
restart: unless-stopped restart: unless-stopped
command: ["uv", "run", "python", "-m", "src.live.dashboard", "--port", "8787"] command: ["uv", "run", "python", "-m", "src.live.dashboard", "--port", "8787"]
ports: ports:
- "8787:8787" # Bind SOLO su 127.0.0.1: la dashboard non ha autenticazione e mostra conto e
# posizioni reali (Shadow live). Fino al 2026-08-04 era "8787:8787", cioe' pubblicata
# su tutte le interfacce e raggiungibile da internet: ufw NON protegge le porte
# pubblicate da Docker (il DNAT scavalca la catena INPUT). La consuma AI-OS da
# localhost per le risposte via Telegram.
- "127.0.0.1:8787:8787"
volumes: volumes:
- ./data:/app/data:ro - ./data:/app/data:ro
# token mainnet (sola lettura) per lo "Shadow live": conto/posizioni reali sulla dashboard. # token mainnet (sola lettura) per lo "Shadow live": conto/posizioni reali sulla dashboard.
# Montato a runtime (NON nell'immagine: .env.mainnet e' dockerignored). Solo letture, nessun ordine. # Montato a runtime (NON nell'immagine: .env.mainnet e' dockerignored). Solo letture, nessun ordine.
- ./.env.mainnet:/app/.env.mainnet:ro - ./.env.mainnet:/app/.env.mainnet:ro
# IB Gateway (PAPER) per la RICERCA DATI Interactive Brokers — replica il setup provato di BuzWay
# (scout). IBC fa login automatico headless; nessuna GUI desktop. API READ-ONLY (solo dati storici,
# MAI ordini). Bind SOLO su 127.0.0.1 -> non esposto in rete. Credenziali in .env.ibgw (gitignored).
# host 4002 -> container 4004 (socat paper), esattamente come nel connect("127.0.0.1", 4002).
ib-gateway:
image: ghcr.io/gnzsnz/ib-gateway:stable
container_name: pythagoras-ibgw
restart: unless-stopped
env_file: .env.ibgw
environment:
TRADING_MODE: paper
READ_ONLY_API: "yes" # SOLO dati: nessun ordine possibile via API
TWOFA_TIMEOUT_ACTION: restart
TIME_ZONE: Europe/Rome
ports:
- "127.0.0.1:4002:4004" # gateway paper (socat) raggiungibile solo da localhost dell'host
@@ -0,0 +1,68 @@
# PREVDAY block-bootstrap — coda-fortuna vs persistente (blocker #2/#3)
**Data:** 2026-06-21 (chiude la trilogia: fill-haircut → turnover/hedge → bootstrap)
**Script:** `scripts/research/intraday/prevday_bootstrap.py`
**Esito:** PREVDAY-full **non** è più coda-fortuna di TP01 e l'edge è **bootstrap-robusto** (full
99% / hold-out 93% dei resample con uplift>0). MA la gamba short (= tutto il valore) è
**tail-dipendente** (top-5 giorni = 130% del suo netto). PREVDAY = tail-hedge legittimo dal payoff
grumoso. Resta forward-monitor.
## Chiarimento di scope
Il "top-5 giorni = 76-83% del PnL" del diario intraday era sulle GAMBE REVERT del combo a 5 segnali
(vol_event/volume_spike/gap_fill), poi SCARTATE. Il sopravvissuto è PREVDAY (breakout-continuation).
Qui si testa PREVDAY STESSO — e la sua gamba SHORT, che (prevday_turnover) è l'intero valore di
portafoglio. Block bootstrap circolare (blocchi 20g, B=3000) per preservare autocorrelazione/regime.
## [A] Concentrazione del PnL nei top-K giorni
| serie | n | totRet | top5 | top10 | top20 | giorni→50% gain |
|-------|--:|-------:|-----:|------:|------:|----------------:|
| PREVDAY full | 2869 | +182% | 22% | 36% | 59% | 411 (14.3%) |
| **PREVDAY short-only** | 2869 | **+28%** | **130%** | 218% | 345% | 312 (10.9%) |
| PREVDAY long-only | 2869 | +154% | 18% | 30% | 49% | 287 (10.0%) |
| TP01 (riferimento) | 2657 | +116% | 19% | 33% | 55% | 213 (8.0%) |
- **PREVDAY-full NON è più coda-fortuna di TP01**: top5 22% vs 19%, e per il 50% del guadagno serve
*più* tempo (14.3% dei giorni vs 8.0% → più distribuito). Il tail-luck del diario era sulle gambe
revert scartate, non su PREVDAY.
- **Gamba short tail-dipendente:** top5 = **130% del netto** → togliendo i 5 giorni migliori la short
va in perdita (gli altri 2864 giorni nettano −8%). Sono i giorni-crash dove la short paga.
## [B] Circular block bootstrap (20g, B=3000)
| campione | PREVDAY Sharpe (mediana [5°,95°], %>0) | blend 80/20 uplift (mediana [5°,95°], %>0, %>+0.10) |
|----------|----------------------------------------|------------------------------------------------------|
| full (2018-08→2026-06) | +1.24 [+0.64,+1.80] 100% | +0.28 [+0.09,+0.47] 99% / 93% |
| hold-out (2025+) | +1.27 [−0.01,+2.46] 95% | +0.53 [−0.05,+1.21] 93% / 88% |
| short-only hold-out | +1.12 [−0.32,+2.41] 90% | +0.53 [−0.08,+1.31] 92% / 87% |
- **Full sample: edge robustissimo** — 99% dei resample dà uplift>0 (mediana +0.28). Non è "un blocco
fortunato".
- **Hold-out: regge con coda più larga** (5° pctl appena negativo: hold-out corto ~536g + short
tail-dipendente), ma 93% dei resample >0, 88% >+0.10.
## Verdetto blocker #2/#3
- **#3 tail-luck — DECLASSATO per PREVDAY-full, CONFERMATO per la gamba short.** La strategia intera
non è più concentrata di TP01 (che già deployamo); il motore di valore (la short) sì: vive su <10
giorni-crash/anno. Bootstrap-robusto (non un singolo blocco), ma il forward sarà GRUMOSO, non un
liscio +0.56/periodo.
- **#2 null-corr-zero — RIDIMENSIONATO.** L'uplift è genuinamente positivo (93-99% dei resample), non
rumore; il punto era di *efficienza relativa* (rende meno di un ipotetico asset perfettamente
scorrelato), non di esistenza dell'edge.
## Sintesi della trilogia (fill-haircut + turnover/hedge + bootstrap)
PREVDAY, dopo tre attacchi avversariali:
1. **Eseguibile alla taglia reale** ($600): haircut di fill +0.01 (blocker #4 smontato).
2. **Già a turnover efficiente**: ridurlo erode l'edge; nessuna ottimizzazione (config congelata).
3. **È un HEDGE, non alpha**: tutto il valore è la gamba short → tail-hedge di regime-down, additivo
alla flat-stance di TP01 (blocker #1 inchiodato).
4. **Edge bootstrap-robusto** ma **payoff grumoso** (il valore è in pochi giorni-crash) (blocker #3
declassato sul full, confermato sulla short; #2 ridimensionato).
→ **Candidato tail-hedge legittimo**, non sleeve-alpha. Resta in FORWARD-MONITOR: la domanda forward
non è più "è eseguibile / è overfit", ma **"la gamba short continua a pagare nei prossimi crash fuori
da 2022 e 2025-26?"**. Se sì → si valuta come overlay di tail-hedge (peso piccolo, atteso payoff
lumpy); se no → era beta-corto del regime down 2025-26.
@@ -0,0 +1,67 @@
# PREVDAY fill-haircut a basso capitale — il blocker d'esecuzione è BENIGNO (1/4 smontato)
**Data:** 2026-06-21 (follow-up di `2026-06-21-intraday-microstructure.md`)
**Script:** `scripts/research/intraday/fill_haircut.py`
**Esito:** l'haircut del fill reale a $600 è **+0.01 Sharpe** (trascurabile). Lo scettico
d'esecuzione (blocker #4) è **benigno**. Gli altri 3 blocker (hedge / null-corr-zero / tail-luck)
restano → PREVDAY resta in **forward-monitor, non deploy**.
## Domanda
Lo scettico d'esecuzione dell'onda intraday aveva segnalato: il vol-target di PREVDAY fa ~8500
ribilanciamenti/anno per gamba, 97-98% < $1 di nozionale a $600; a quel capitale (min_order $5) NON
puoi piazzarli, quindi il libro MODELED (ribilanciamento continuo, frictionless) è una finzione e lo
Sharpe modellato è gonfiato. Il forward-monitor traccia MODELED-$2000 vs REAL-$600 per misurarlo nei
mesi a venire — qui lo stimiamo SUBITO su tutto lo storico, replicando la STESSA logica dei due libri
di `paper_prevday.py` ma sull'intero path 1h (2019-03 → 2026-06, 63.732 barre).
Due libri identici tranne il fill:
- **MODELED**: ribilancia ad ogni barra (fee proporzionale su ogni |Δ|).
- **REAL-$C**: salta i ribilanciamenti con nozionale `|Δpos|·leg_cap < $5` (posizione stale →
tracking error, ma niente fee sui trade infinitesimi). Sweep C ∈ {600, 2000, 20000}.
## Risultati
| libro | FULL Sh | HOLD Sh | CAGR | DD | rebal/yr | skip% | fee-drag/yr |
|-------|---------|---------|------|----|---------:|------:|------------:|
| MODELED ($∞) | +1.23 | +1.27 | +24.3% | −27% | 17.484 | 0.0% | 2.49% |
| REAL-$20k | +1.23 | +1.27 | +24.4% | −27% | 3.747 | 78.6% | 2.47% |
| REAL-$2000 | +1.23 | +1.27 | +24.4% | −27% | 677 | 96.1% | 2.42% |
| REAL-$600 | +1.22 | +1.26 | +24.2% | −27% | 277 | 98.4% | 2.39% |
**HAIRCUT $600 (MODELED − REAL): FULL Sharpe +0.01, HOLD-OUT +0.01.**
Domanda-soldi (l'uplift del blend regge col fill reale?):
| PV | w | FULL (uplift) | HOLD (uplift) |
|----|---|---------------|---------------|
| MODELED | 20% | 1.58 (+0.28) | 0.86 (+0.56) |
| MODELED | 30% | 1.65 (+0.36) | 1.08 (+0.78) |
| **REAL-$600** | 20% | 1.58 (+0.28) | 0.86 (**+0.55**) |
| **REAL-$600** | 30% | 1.65 (+0.35) | 1.08 (**+0.77**) |
(TP01 solo: FULL +1.30, HOLD +0.31.) L'uplift hold-out sopravvive **quasi intatto**.
## Lettura
Saltare il **98.4%** dei micro-ribilanciamenti a $600 non costa quasi nulla perché quei trade sono
*individualmente infinitesimi*: sia la fee risparmiata sia il tracking-error introdotto sono
trascurabili. Il PnL è dominato dai ~50 flip di direzione/anno + la deriva lenta del vol-target, che
il libro $600 cattura comunque sui movimenti grandi (la fee-drag passa solo da 2.49% a 2.39%). La
"finzione della fee sub-dollaro" è quindi **benigna**: non gonfia lo Sharpe modellato (MODELED e
REAL-$600 coincidono a ±0.01). NB: lo Sharpe **non si degrada** scendendo di capitale → l'edge
modellato di PREVDAY è eseguibile alla taglia reale; il blocker era altrove.
## Conseguenza sul verdetto
Dei 4 blocker che tenevano PREVDAY fuori dal deploy, il **#4 (fill a basso capitale) è SMONTATO**.
Restano in piedi i 3 strutturali (dall'onda intraday, non rivalutati qui):
1. **hedge-shaped** — l'uplift viene dai regimi TP01-down (uplift +0.79 TP01-down vs +0.20 TP01-up);
2. **fallisce il null a corr-zero** — uplift pre-2025 al 20-24° pctl del null di un asset random
scorrelato (aggiunge MENO del rumore);
3. **tail-luck** — top-5 giorni = 76-83% del PnL delle gambe revert, <10 eventi/anno.
PREVDAY resta il lead **più solido sull'esecuzione** di tutta la ricerca post-reset (il dubbio più
"fisico" è caduto), ma **forward-monitor, non deploy**, finché il track record forward non scioglie
hedge/coda/null. Lezione harness: `eval_weights_smallcap` (il gate min-order) va sempre eseguito
PRIMA di scartare un lead per "fill irreale" — qui avrebbe evitato di sopravvalutare il blocker #4.
@@ -0,0 +1,68 @@
# PREVDAY come overlay di tail-hedge sul portafoglio — simulazione d'impatto (NON deploy)
**Data:** 2026-06-21 (segue la trilogia fill-haircut / turnover-hedge / bootstrap)
**Script:** `scripts/portfolio/prevday_overlay.py`
**Esito:** a peso 10%, PREVDAY taglia il maxDD FULL del portafoglio **14.3% → 9.9% (−31%)** e alza
l'hold-out Sharpe **1.66 → 1.97 (+0.31)**. 10% è vicino all'ottimo di DD. MA è tutto IN-SAMPLE: il
prize si materializza solo SE l'edge di PREVDAY persiste forward. PREVDAY resta FORWARD-MONITOR.
## Setup
Simulazione che NON tocca il registry di produzione: prende il portafoglio attivo (TP01 55% + XS01
25% + VRP01 20%), riscala i tre sleeve a (1−W) mantenendone le proporzioni, e aggiunge PREVDAY a
peso W. Sweep W ∈ {0,5,10,15,20%}. PREVDAY = libro 1h breakout-continuation, parametri congelati,
50/50 BTC+ETH, fee 0.10% RT. Outer-join del portafoglio: PREVDAY dal 2018, VRP01 dal 2021, XS01 dal
2024 → nel 2019-20 PREVDAY pesa di fatto >W (solo TP01 accanto); nell'hold-out 2025+ (tutti e 4
attivi) pesa esattamente ~W → **l'HOLD-OUT è il confronto pulito a "10%"**.
## Sweep peso overlay
| peso PREVDAY | FULL Sharpe | FULL DD | HOLD Sharpe | HOLD DD | HOLD ret |
|--------------|------------:|--------:|------------:|--------:|---------:|
| BASELINE (55/25/20) | 1.68 | 14.3% | 1.66 | 3.4% | +16.7% |
| 5% | 1.80 | 11.1% | 1.83 | 3.3% | +17.8% |
| **10%** | **1.88** | **9.9%** | **1.97** | 3.3% | **+19.0%** |
| 15% | 1.93 | 10.3% | 2.06 | 3.3% | +20.2% |
| 20% | 1.95 | 10.6% | 2.09 | 3.4% | +21.4% |
(PREVDAY standalone: FULL Sh 1.23 / DD 26.7%; HOLD Sh 1.28 / DD 10.8%.)
## Lettura a 10%
- **FULL: Sharpe +0.20 (1.68→1.88), maxDD 14.3%→9.9% (−4.4pp ≈ −31%).** Comportamento da tail-hedge:
la gamba short ammortizza i crash storici (2019-21, 2022).
- **HOLD-OUT: Sharpe +0.31 (1.66→1.97), ret +16.7%→+19.0%, DD 3.4%→3.3% (già bassissimo).** Nel
regime recente il beneficio è rendimento/Sharpe, non taglio DD.
- **10% ≈ ottimo di DD.** Oltre, lo Sharpe sale ancora (1.93→1.95) ma il maxDD FULL smette di
scendere (10.3→10.6%): stai solo aggiungendo rischio direzionale short. Argomento per ~10% in
chiave hedge (massimizza il taglio-coda per unità di rischio aggiunto).
## Per anno (baseline → overlay 10%)
| anno | ret | DD |
|------|-----|----|
| 2019 | +11.3 → +15.2 | 10.3 → 8.2 |
| 2020 | +51.1 → +53.1 | 8.4 → 6.3 |
| 2021 | +32.5 → +28.3 | 5.2 → 4.3 |
| 2022 | −3.0 → −1.6 | 3.7 → 3.0 |
| 2023 | +11.2 → +11.4 | 9.2 → 9.9 |
| 2024 | +24.4 → +25.7 | 3.9 → 3.4 |
| 2025 | +12.0 → +12.0 | 3.4 → 3.3 |
| 2026 | +4.2 → +6.2 | 2.6 → 2.2 |
Migliora o pareggia quasi ovunque; costa solo nel toro 2021 (premio d'assicurazione atteso per un
hedge) e leggermente sul DD 2023; paga nel bear 2022 e nel 2026.
## Verdetto
L'overlay 10% è **attraente in simulazione** — taglia il drawdown FULL di ~31% e alza l'hold-out
Sharpe +0.31, con 10% vicino all'ottimo di DD. Ma:
1. **È in-sample.** I guadagni assumono che l'edge di PREVDAY persista — il forward-monitor esiste
proprio per verificarlo. Questa simulazione quantifica il PRIZE, non lo prova.
2. **Outer-join:** il taglio-DD storico è gonfiato dal peso effettivo >10% nel 2019-20; il read
pulito a 10% è l'hold-out (prize = Sharpe +0.31).
3. Incidentale: il 3-way TP01+XS01+VRP01 baseline qui fa FULL 1.68 / HOLD 1.66.
**Azione: nessuna.** PREVDAY resta FORWARD-MONITOR (registry di produzione invariato). Quando il
track record forward avrà ~2-3 mesi, ri-valutare l'overlay 10% con la stessa metrica (taglio-DD +
hold-out Sharpe) su dati VERAMENTE fuori campione. Lo script è il riferimento per quel confronto.
@@ -0,0 +1,64 @@
# PREVDAY — la fee viene dai FLIP (no free lunch sul turnover) + è un HEDGE, non alpha
**Data:** 2026-06-21 (follow-up di `2026-06-21-prevday-fill-haircut.md`)
**Script:** `scripts/research/intraday/prevday_turnover.py`
**Esito:** (1) ridurre il turnover di PREVDAY erode l'edge — la config congelata è già efficiente.
(2) Il test long-only inchioda il blocker #1: **tutto il valore di portafoglio è la gamba SHORT** →
PREVDAY è un **hedge di regime-down**, non alpha. Resta forward-monitor.
## Premessa (da fill_haircut)
Il libro REAL-$600 salta il 98.4% dei ribilanciamenti del vol-target e la fee-drag scende solo
2.49% → 2.39%/anno. Quindi la fee (~2.6%/anno) NON viene dal churn sub-dollaro ma dai **~70 flip di
direzione/anno**. Un deadband d'esecuzione è inutile; l'unica leva è ridurre i flip a LIVELLO DI
SEGNALE. Qui sweep delle leve (buffer, anchor, min-hold) + long-only vs long-short. Libro MODELED
(l'haircut di fill è +0.01, irrilevante). Metrica che conta = **uplift hold-out del blend 80/20**.
## (1) Turnover-reduction — no free lunch
| config | flip/yr | fee/yr | FULL Sh | HOLD Sh | DD | corrTP | blend HOLD upl |
|--------|--------:|-------:|--------:|--------:|---:|-------:|---------------:|
| **BASE** (anchor=1, k=0.30, LS) | 70 | 2.59% | +1.23 | +1.27 | −27% | +0.15 | **+0.56** |
| k=0.50 | 48 | 1.86% | +1.23 | +0.99 | −15% | +0.20 | +0.40 |
| k=0.75 | 32 | 1.31% | +1.06 | +0.13 | −16% | +0.27 | +0.00 |
| k=1.00 | 23 | 1.01% | +0.88 | +0.72 | −22% | +0.36 | +0.22 |
| anchor=2 | 39 | 1.55% | +0.89 | +0.54 | −22% | +0.25 | +0.20 |
| anchor=3 | 27 | 1.14% | +0.67 | −0.18 | −22% | +0.29 | −0.12 |
| anchor=5 | 15 | 0.75% | +1.15 | +0.70 | −19% | +0.41 | +0.25 |
| min_hold=24h | 70 | 2.59% | +1.22 | +1.37 | −32% | +0.15 | **+0.60** |
| min_hold=72h | 65 | 2.39% | +0.86 | +0.67 | −33% | +0.12 | +0.27 |
| combo-LT (k.75+anc2+24h) | 16 | 0.79% | +0.79 | +0.69 | −20% | +0.34 | +0.24 |
- **Allargare buffer/anchor taglia fee e turnover ma l'uplift cala monotonicamente** (k: 0.56→0.40→
0.00). Anchor multi-giorno tutto peggio → conferma il "anchor=1 only" del diario. I flip SONO
l'edge: meno flip = meno edge.
- **min_hold=24h** è l'unico ritocco "quasi gratis" (uplift +0.56→+0.60 a parità di fee) ma
**peggiora il DD −27%→−32%** → non vale cambiare una strategia congelata in forward-monitor.
- **Verdetto: la config base è già sulla frontiera efficiente turnover↔edge. Si lascia congelata.**
## (2) Long-only vs long-short — il blocker #1 inchiodato
| | FULL Sh | HOLD Sh | corrTP | blend HOLD upl | fee/yr |
|--|--------:|--------:|-------:|---------------:|-------:|
| **long-only** (no short) | **+1.55** | +0.52 | **+0.64** | **+0.09** | 1.30% |
| long-short (BASE) | +1.23 | +1.27 | +0.15 | +0.56 | 2.59% |
La versione **long-only ha Sharpe standalone più ALTO** (1.55 vs 1.23) ma è **correlata +0.64 a TP01
e non aggiunge quasi nulla al blend** (+0.09). **Tutto il valore di portafoglio viene dalla gamba
SHORT:** la short *abbassa* lo Sharpe standalone (shortare crypto nel toro 2019-24 perde) ma fornisce
**tutta** la decorrelazione (corrTP 0.64→0.15) e l'uplift hold-out (0.09→0.56).
→ **PREVDAY non è alpha: è strutturalmente un HEDGE di crash/regime-down.** Costa nel toro, paga
nell'orso (2022, 2025-26 down/chop). È additivo a TP01, che va *flat* nel risk-off ma non *short*.
Questo conferma e affina il blocker #1 dell'onda intraday ("l'uplift viene dai regimi TP01-down"):
non è solo conditional sui regimi down, è **interamente la gamba short** = una scommessa direzionale
che i ribassi continuino.
## Conseguenza sul verdetto
- Niente da ottimizzare: la config congelata è già efficiente; nessun cambio.
- **Riframing utile:** se PREVDAY un giorno avrà un ruolo, è come **overlay di tail-hedge** (non
sleeve-alpha), additivo alla difensività di TP01. Ma resta soggetto agli altri due blocker
(fallisce il null a corr-zero; tail-luck: top-5 giorni = 76-83% del PnL delle gambe revert).
- **Forward-monitor invariato.** Il test forward decisivo: la gamba short continua a pagare fuori da
2022 e 2025-26? Se sì → candidato tail-hedge; se no → era regime-luck.
@@ -0,0 +1,62 @@
# 2026-06-22 — Sweep 65-agenti: crypto -> mercati IB (mercati × timing × anni)
## Obiettivo (goal utente)
Usare >=50 agenti per prendere l'anticipazione crypto->equity e trovare la MIGLIORE soluzione,
provando diversi mercati e timing, su piu' anni.
## Setup
- **Dati**: universo IB esteso a **26 ETF certificati** (azioni US/settori/intl/bond/credito/oro/
commodity/REIT), cache su disco (`fetch_ib_equities.py` + BROAD2). Crypto BTC/ETH 1h (Deribit).
- **Harness onesto** (`crypto_lead_harness.py`): per ogni sessione equity, lead = crypto nella
finestra equity-CHIUSO [P 21:00 -> D 13:00 UTC] (overnight; il weekend e' il caso lungo). Predice
gap/intraday/full. Metriche: corr, **t incrementale vs sessione equity precedente**, Sharpe
eseguibile (sign(lead)*predict, net costi) FULL/IS/OOS, **hit per-anno**.
- **Workflow** (`wf_crypto_lead.js`): grid 416 config (2 lead × 26 mercati × 2 giorni × 2 predict ×
2 finestre). **52 agenti sweep** -> **12 agenti verifica avversariale** (stress 10bps + OOS 2024+ +
multi-anno) -> **1 sintesi**. Totale **65 agenti**, 1.7M token.
## Risultato
### Fenomeno fortissimo: crypto overnight -> GAP di apertura equity
Cluster coerente in cima, TUTTI predict=gap/overnight, su ogni target risk-on:
| lead->target | t-incr | Sh OOS@4bps | @10bps | OOS-recente | anni+ |
|---|---|---|---|---|---|
| ETH->IWM gap | 17.1 | 2.49 | 1.96 | 2.41 | 7/8 |
| ETH->QQQ gap | 17.9 | 2.36 | 1.83 | 2.31 | 7/8 |
| ETH->XLK gap | 17.4 | 2.40 | 1.93 | 2.30 | 7/8 |
| **BTC->QQQ gap** | 15.0 | 2.31 | 1.78 | 2.16 | **9/9** |
| BTC->SPY gap | 14.4 | 2.14 | 1.69(lf) | 2.03 | 9/9 |
Statisticamente schiacciante (t 14-18, sopra Bonferroni su 416 test), regge stress costi e OOS
recente, **positivo 8-9 anni su 8-9**.
### Ma DUE killer (i verificatori avversariali concordi)
1. **NON tradabile via ETF**: il gap e' gia' prezzato all'open dell'ETF -> serve un FUTURE indice
tenuto overnight (MNQ/MES/M2K). A $0.5-2k il margin overnight di anche un micro consuma il
capitale e rischia la liquidazione su un gap avverso -> **fuori portata per costruzione**.
2. **E' RISK-BETA, non alpha**: la finestra-lead crypto e' quasi CONTEMPORANEA al gap (stesso shock
macro overnight, equity chiuso). t enorme = co-movimento risk-on/off, non ETH/BTC che *anticipa*.
Firma: la forza e' negli anni alta-vol (2022 hit 0.71-0.75), piatta negli anni calmi (2019/21/23).
corr ~0.37 -> beta implicito ~37%, alpha residuo piccolo.
### L'unico tradabile via ETF e' troppo debole
ETH->XLE intraday 6h (compri XLE al day-open, chiudi +6h): Sh OOS 0.48@4bps **-> 0.15@10bps** (annuo
4.1%->1.0%), t-incr 2.38 **sotto Bonferroni** (~3.5 su 416 test). Edge netto onesto ~ZERO.
## Verdetto (sintesi multi-agente)
**Nessun edge proprietario deployabile a basso capitale.** Il fenomeno crypto->equity-overnight e'
statisticamente reale e robustissimo su 9 anni, ma e' (a) risk-beta condiviso, non anticipazione
sfruttabile, e (b) catturabile solo con futures overnight, fuori dal nostro capitale. L'unica
versione ETF-eseguibile e' dentro il rumore da multiple-testing. Coerente col soffitto del progetto:
"niente di nuovo regge" alla verifica onesta.
**Migliore soluzione (come FENOMENO da forward-monitor, non deploy):** BTC->QQQ gap overnight — la
storia piu' lunga (9/9 anni), lead noto prima dell'open. Da monitorare; deployabile solo con capitale
~>$20-30k su micro-futures indice e con i costi notturni modellati.
## Lezione
Anche con 65 agenti e una ricerca esaustiva su mercati/timing/anni, la disciplina onesta
(tradabilita' al capitale reale + multiple-testing + beta-vs-alpha) riduce un "Sharpe 2.5 su 9 anni"
a un non-edge per noi. Il valore della ricerca: aver QUANTIFICATO e CLASSIFICATO il fenomeno
(risk-beta overnight) invece di scambiarlo per alpha.
Artefatti: `crypto_lead_harness.py`, `wf_crypto_lead.js`.
@@ -0,0 +1,53 @@
# 2026-06-22 — Crypto × mercati IB: correlazioni e ANTICIPAZIONI (lead-lag)
## Obiettivo
Cercare correlazioni e soprattutto ANTICIPAZIONI tra crypto e mercati IB: un mercato fa capire
l'andamento dell'altro? Dati: cache su disco (BTC/ETH Deribit 1h->1d UTC; ETF eq_* con OPEN). Nessun
IB online. Disciplina: attenzione ai tranelli di timing daily (crypto chiude 00:00 UTC, US equity
21:00 -> lag-0 contaminato), test del segno + OOS + multiple-testing.
Script: `crypto_macro_leadlag.py`, `crypto_weekend_signal.py`.
## (1) Correlazione contemporanea
Crypto = asset RISK-ON: corr BTC/ETH ~ **+0.32/0.37** con SPY/QQQ/IWM, **+0.25/0.28** con HYG
(credito), **+0.13** GLD, **~-0.02** TLT (bond). Atteso.
## (2) Lead-lag giornaliero: NIENTE
corr(BTC_{t-k}, ETF_t) ha picco a **k=0** (~0.32) e crolla a rumore (±0.05) per |k|>=1. Al daily
**nessuno anticipa l'altro** (ne' crypto->equity ne' viceversa). Honest negative.
## (3) EFFETTO WEEKEND: anticipazione PULITA, significativa, OOS-robusta
La crypto si muove Sab+Dom (azionario chiuso) -> quel movimento e' info PRIOR al lunedi'.
- **Anticipa il GAP del lunedi'**: corr +0.22/+0.24 (SPY/QQQ/IWM/HYG), hit 59-62%, e **si RAFFORZA
OOS (2022+): +0.30/+0.36**. Coerente su 4 ETF (non cherry-pick).
- Intraday del lunedi' (open->close) piu' debole ma presente (corr 0.10-0.15, OOS 0.18-0.22).
### Validazione avversariale
- **(A) INCREMENTALE vs venerdi'**: regressione `Mon ~ weekend_crypto + friday_eq`. Coeff weekend
crypto significativo ovunque (QQQ gap **t=+4.7**, intr t=+2.9; SPY +4.4/+2.0; IWM +4.7/+2.7);
friday_eq NON significativo. -> e' info CRYPTO-SPECIFICA del weekend, non momentum equity.
- **(B) TRADABILE** (osservo weekend crypto Dom 24:00, entro Monday OPEN, esco CLOSE, net 4bps):
| ETF | hit | Sharpe FULL / IS / OOS22+ | long-flat OOS | ann |
|---|---|---|---|---|
| QQQ | 60% | 1.46 / 1.61 / 1.33 | **1.91** | ~+9-11% |
| SPY | 60% | 0.96 / 0.91 / 1.01 | 1.70 | ~+5% |
| IWM | 56% | 0.89 / 0.73 / 1.04 | 1.07 | ~+6% |
## Verdetto
**Trovata UNA anticipazione reale**: il weekend crypto anticipa il lunedi' azionario (massimo su QQQ,
risk-on/tech). Significativa (t>4 sul gap), incrementale al venerdi', tradabile net costi, **regge e
si rafforza OOS**, coerente su piu' ETF. Meccanismo economico sensato: crypto = proxy 24/7 del
risk-sentiment; nel weekend l'equity e' chiuso e lunedi' "recupera" la direzione crypto.
### Caveat onesti
- **Capacita' bassa**: ~52 lunedi'/anno, intraday -> ~+9%/yr sul capitale impiegato il lunedi', non
una macchina da compounding. E' un segnale TATTICO, non un cornerstone.
- Il GAP (t=4.7) e' piu' forte dell'intraday (t=2.9) ma per catturarlo serve entrare PRIMA del Monday
open -> via **futures indice IB (MNQ/MES, aperti la domenica sera)**: enhancement eseguibile da
validare (cattura gap+sessione).
- Multiple-testing 3 ETF x 2 target: ma TUTTI significativi e coerenti -> effetto ampio, non fortuna.
- Niente IB online qui (cache); per il deploy servirebbe il feed crypto live la domenica sera.
## Prossimo (se si procede)
Validare la variante FUTURES (MNQ domenica sera -> cattura il gap del lunedi') e il sizing a basso
capitale; eventualmente paper-trade. E' la prima ANTICIPAZIONE cross-mercato trovata: crypto come
lead di sentiment sul lunedi' equity.
@@ -0,0 +1,40 @@
# 2026-06-22 — Combo DEPLOYABLE: TP01 (Deribit) + GTAA (IB)
## Perche'
Il combo crypto-pieno (TP01+XS01+VRP01)+GTAA diversificava (Sharpe 1.81), ma XS01/VRP01 sono
STAT-MODE (non eseguibili a $600). Validazione del combo ONESTO/eseguibile: solo le gambe deployable
a basso capitale — TP01 (gia' armato live su Deribit) + GTAA vt12 (eseguibile su IB, frazioni,
switch mensile). `eq_tp01_gtaa_combo.py`. TP01 compoundato sul calendario giorni-di-borsa.
## Risultati (finestra comune 2019-03 .. 2026-06, ~7y)
| | Sharpe | CAGR | volAnn | maxDD |
|---|---|---|---|---|
| TP01 (crypto, Deribit) | 1.25 | 16.4% | 12.9% | 14% |
| GTAA vt12 (equity, IB) | 1.12 | 6.0% | 5.3% | 8% |
| **blend 50/50** | **1.48** | 11.3% | 7.5% | **8%** |
| blend 40/60 (best cap-mix) | 1.52 | 10.2% | 6.6% | 8% |
| risk-parity (29c/71e) | 1.52 | 9.1% | 5.9% | 8% |
**corr TP01<->GTAA = +0.21**. Il blend (1.48-1.52) batte entrambe le gambe (best solo 1.25),
maxDD 14%->8%. **DIVERSIFICA anche da deployable.**
## Caveat onesti
- Per-anno 50/50: 2019 2.11, 2020 2.51, 2021 1.66, **2022 -2.64**, 2023 1.40, 2024 1.73, 2025 0.98,
2026 0.94. Anni boom iniziali gonfiano lo Sharpe assoluto; il **2022 e' negativo** (trend whipsaw
su entrambe le gambe nel bear). Recenti ~0.95. -> il numero robusto e' il GUADAGNO da
diversificazione (+0.27 Sharpe del blend vs solo), non il livello assoluto.
- **Costo deployability**: crypto-pieno+GTAA = 1.81 vs deployable = 1.48. I ~0.33 di Sharpe persi sono
cio' che XS01/VRP01 darebbero se eseguibili (servirebbe ~20k).
- **Cross-venue** Deribit+IB: due conti, capitale split. Entrambe switch mensile/basso turnover,
frazionabili a $0.5-2k.
## Verdetto
Combo deployable VALIDO: due trend difensivi scorrelati (corr 0.21) su mercati diversi -> Sharpe
~1.5 / maxDD ~8%, meglio di ciascuna gamba. E' il candidato concreto per un paper-trade cross-venue.
NON risolve EUR50/g (resta capitale), ma e' la migliore configurazione rischio-aggiustata
EFFETTIVAMENTE eseguibile trovata finora. Lezione cross-mercato confermata: il salto di qualita' non
e' un nuovo alpha ma un SECONDO mercato scorrelato.
## Prossimo (se si procede)
Paper-trade della gamba GTAA su IB (forward-only, come paper_trend per TP01), per validare
l'esecuzione cross-venue a rischio zero prima di qualunque capitale reale.
@@ -0,0 +1,57 @@
# 2026-06-22 — EQ-GTAA01 (trend multi-asset) + COMBO cross-mercato equity×crypto
## (1) EQ-GTAA01 — trend difensivo multi-asset (GTAA)
EQ-TREND01 (trend su SPY) taglia il DD. Diversificare le SORGENTI di trend (azioni US/tech/small +
bond + oro + high-yield) migliora il rischio-aggiustato. `eq_gtaa_trend.py`: ogni asset gestito col
proprio trend long-flat (TSMOM multi-orizzonte), equal-weight tra gli asset disponibili (outer-join,
cash dove off/assente). Universo SPY/QQQ/IWM/TLT/GLD/HYG. Causale, netto fee, OOS 2015+.
| strategia | CAGR | Sharpe (pre15/OOS) | maxDD | corr SPY |
|---|---|---|---|---|
| SPY buy&hold | 9.7% | 0.58 (0.45/0.82) | 55% | — |
| EW statico (no trend) | 9.4% | 0.59 | 62% | 0.89 |
| SPY-trend mono | 5.5% | 0.56 (/0.78) | 30% | 0.72 |
| **GTAA lf vt12%** | 3.8% | **0.64** (0.53/**0.89**) | **15%** | **0.64** |
| GTAA vt12 (6-asset, 2016+) | 5.6% | **1.08** | **8%** | 0.60 |
DD nei bear (GTAA vs SPY): dot-com 32%/49% · GFC **14%/55%** · COVID **10%/34%** · 2022 11%/24%.
Marginale vs SPY: corr 0.64; 50/50 uplift +0.041 FULL / **+0.086 OOS** (meglio del mono-SPY). Plateau
stabile (Sh 0.55-0.61, DD 25-35%). **Migliore sleeve equity**: Sharpe più alto, maxDD bassissimo
(8-15%), corr SPY più bassa (0.64) = diversificatore migliore. Tradeoff: CAGR molto più basso
(fortemente difensiva). Caveat: la finestra 6-asset (Sh 1.08) è tutta OOS ma un solo regime (toro).
## (2) COMBO cross-mercato — equity-trend × crypto
La via che alza il Sharpe COMPLESSIVO senza nuovo alpha: combinare due book scorrelati.
`eq_crypto_combo.py`: crypto = portafoglio attivo TP01+XS01+VRP01 (`StrategyPortfolio.combined_daily`,
rinormalizzato); equity = GTAA lf vt12%. Crypto compoundato sul calendario giorni-di-borsa (cattura
i weekend). Finestra comune = era crypto (2019-03 .. 2026-06, 1827 giorni di borsa).
| | Sharpe | CAGR | volAnn | maxDD |
|---|---|---|---|---|
| crypto TP01+XS01+VRP01 | 1.60 | 18.7% | 11.1% | 14% |
| equity GTAA vt12 | 1.12 | 6.0% | 5.3% | 8% |
| **blend 50/50** | **1.81** | 12.4% | 6.6% | **7%** |
| risk-parity (32c/68e) | 1.78 | 10.1% | 5.5% | 8% |
**Correlazione crypto↔equity = +0.167** (bassissima). Il blend 50/50 fa **Sharpe 1.81 > di ciascuno**
(crypto 1.60, equity 1.12), **maxDD dimezzato 14%→7%**. VERDETTO: DIVERSIFICA (blend > miglior solo
di +0.21 Sharpe). È il guadagno STRUTTURALE: due fonti di rischio scorrelate alzano il Sharpe
complessivo senza cercare un nuovo edge.
### Caveat onesti
- **Finestra crypto corta (~7y) e favorevole**: il crypto Sharpe 1.60 e' alto (regime toro + XS01/VRP01
STAT-MODE a storia corta). Gli SHARPE ASSOLUTI sono ottimistici. Ma il PUNTO della diversificazione
(corr 0.17, blend > solo, DD dimezzato) è robusto al livello assoluto.
- **Cross-venue**: crypto su Deribit, equity su IB → due conti, due percorsi d'esecuzione. A $0.5-2k
totali, ogni sleeve è minuscola. La parte equity (GTAA) e la TP01 sono entrambe eseguibili a basso
capitale; XS01/VRP01 restano STAT-MODE (il blend "reale" deployable è ~TP01 + GTAA).
## Lettura strategica
Il fronte equity da' due cose: (a) una sleeve difensiva robusta (GTAA, maxDD ~10%), (b) — piu'
importante — un DIVERSIFICATORE quasi-scorrelato al crypto che alza il Sharpe del portafoglio
complessivo da ~1.6 a ~1.8. Non risolve €50/g (resta capitale), ma e' il primo miglioramento
STRUTTURALE del rischio-aggiustato complessivo trovato in tutta la ricerca post-reset, ed e' del tipo
giusto (diversificazione vera, non alpha fittizio). Prossimo: validare il combo deployable TP01+GTAA
(solo le due gambe eseguibili), e valutare l'operativita' cross-venue.
@@ -0,0 +1,45 @@
# 2026-06-22 — Fronte EQUITY aperto + EQ-MOM01 (momentum settoriale): NON batte SPY
## Apertura fronte (branch research/equities-ib)
Le 4 ondate crypto hanno esaurito gli angoli su BTC/ETH (soffitto ~1.3). L'unico modo di superarlo è
un **mercato diverso**. Aperto il fronte azioni/ETF via IB (paper, `gnzsnz/ib-gateway`, read-only).
**Dati certificati + cache su disco** (`fetch_ib_equities.py` → `data/raw/eq_*.parquet`, ADJUSTED_LAST
div+split, gitignored = cache locale; loader `eqlib.py` con lru_cache → ricerca legge da disco, MAI
da IB). Universo: 9 SPDR settoriali classici dal **1998 (27.5y)** + XLRE(2015)/XLC(2018) + SPY(1996,
30y)/QQQ/IWM/GLD/HYG/TLT. Tutti integri (monotoni, no dup, no spike>50%, 0 gap lunghi).
NB bug timestamp risolto: `pd.Timestamp` a risoluzione µs → salvati in secondi, corretti a ms.
## EQ-MOM01 — momentum cross-sectional settoriale
Costruzione causale (`eq_sector_momentum.py`): ogni 21g, momentum = blend lookback [63,126,252]g con
skip-21 (12-1 classico), z-score cross-sectional. long-only top-k (full-invested, confronto
like-for-like con SPY) e long-short (dollar-neutral, test alpha puro). Netto fee, hold-out OOS 2015+.
### Risultati (9 settori, 1998-2026)
| strategia | CAGR | Sharpe (pre15/OOS15+) | maxDD | corr SPY |
|---|---|---|---|---|
| **SPY buy&hold** | 8.2% | **0.51** (0.31/0.82) | 55% | — |
| EW 9 settori | 8.9% | 0.56 (0.44/0.76) | 53% | 0.96 |
| MOM long top-3 | 7.7% | 0.50 (0.32/0.76) | 47% | 0.85 |
| MOM long vol-target 15% | 7.3% | 0.52 | 39% | 0.75 |
| **MOM long-short top-3** | −0.9% | **−0.08** (−0.19/0.08) | 32% | −0.20 |
### Verdetto: NESSUN edge vs SPY
- **Long-short Sharpe −0.08** → l'alpha cross-sectional di momentum settoriale è **morto** su 27 anni
(decadimento post-2000 noto in letteratura). Niente alpha market-neutral.
- **Long-only ≈ SPY**: corr 0.85, **uplift marginale ~0.00** (blend 75/25 +0.012 FULL / +0.001 OOS;
50/50 +0.015 / −0.010). È un SPY a beta più basso, non un edge. Plateau stabile ma sempre ~0.50
(vs SPY 0.51); sugli 11 settori (2018+) fa peggio (0.69 vs 0.82). Fee-robusto (ma niente da salvare).
- L'unico beneficio (maxDD 55%→39%) è del **vol-target**, non del momentum (lo daresti a SPY stesso).
## Lezione (coerente col progetto)
Il momentum **relative-value** è morto anche in equity, come nel crypto (ortho wave). Il baseline
equity da battere è SPY buy&hold (Sharpe ~0.51 full / 0.82 OOS), ostico come il toro crypto.
## Prossimo angolo plausibile (NON ancora testato)
L'analogo equity di TP01 (l'unica cosa che ha retto nel crypto = trend DIFENSIVO): **time-series
trend su SPY long-flat/long-bonds** — non per battere il CAGR ma per **tagliare il 55% di drawdown**
restando vicino al ritorno. È il punto dove vive il valore robusto in equity (e dove il cross-section
NON guarda). Da provare con lo stesso gauntlet: marginale vs SPY, OOS lungo, plateau.
@@ -0,0 +1,48 @@
# 2026-06-22 — EQ-TREND01: trend DIFENSIVO su SPY = edge difensivo REALE (analogo di TP01)
## Contesto
Il momentum cross-sectional settoriale è morto (EQ-MOM01: long-short Sharpe −0.08, long-only ≈ SPY).
Ma nel crypto l'unica cosa che ha retto NON era relative-value: era **TP01**, un trend DIFENSIVO che
taglia il drawdown. L'equity ha lo stesso buco: SPY buy&hold Sharpe ~0.54 ma maxDD **55%**.
## Costruzione (causale, stile TP01)
`eq_spy_trend.py`. TSMOM multi-orizzonte [21,63,126,252]g, target = frazione di orizzonti in
trend-up (allocazione graduale 0..1), opz. vol-target. Posizione decisa a ≤i-1, tenuta da i. Netto
fee. Varianti: long-flat (cash in risk-off), long-bonds (TLT, solo 2016+), SMA-200 (Faber). Dati da
cache eqlib (ADJUSTED, nessun IB). Periodo 1997-2026, OOS 2015+.
## Risultati
| strategia | CAGR | Sharpe (pre15/OOS) | maxDD | in-mkt |
|---|---|---|---|---|
| SPY buy&hold | 9.0% | 0.54 (0.38/0.82) | 55% | 99% |
| **SMA-200 (Faber)** | 7.0% | **0.65** (0.52/0.88) | **29%** | 76% |
| TSMOM lf cap1.0 | 5.7% | 0.57 (0.44/0.78) | 30% | 92% |
| TSMOM lf vt15% | 5.7% | 0.62 (0.51/0.78) | **25%** | 92% |
**Drawdown nei bear (TSMOM vs SPY):** dot-com 26%/49% · GFC **19%/55%** · COVID 17%/34% · 2022 16%/24%.
**Plateau** (long-flat): ogni config Sharpe 0.56-0.65 (> SPY 0.54), maxDD 25-31% (~metà di SPY).
SMA-200 il più semplice E il migliore (Sh 0.65, OOS 0.88, DD 29%). **Fee-robusto** (Sh 0.48 a
0.10%/lato), basso turnover.
**Marginale vs SPY:** corr 0.73. blend 50/50 uplift +0.035 FULL / +0.031 OOS (modesto positivo);
100% trend uplift −0.012 / −0.041 (nel toro recente la difesa costa).
## Verdetto: edge DIFENSIVO reale (non alpha) — analogo di TP01
- ✅ Sharpe 0.54→0.62/0.65, **maxDD dimezzato** (55%→~27%, nei bear lenti più che dimezzato),
plateau robusto, fee-robusto, **eseguibile a $0.5-2k** (switch mensile SPY/cash).
- ⚠️ NON genera ritorno (CAGR −2/3pp): è risk-management, come TP01.
- ⚠️ I tagli grossi (dot-com/GFC) sono IN-SAMPLE; l'OOS 2015-26 è quasi tutto toro → lì ha seguito
SPY a beta minore (ma COVID, OOS, dimezzato). La difesa "serve" nei bear, rari nell'OOS.
- ⚠️ long-bonds (TLT) non convince (TLT distrutto 2022).
## Lettura strategica
Primo positivo del fronte equity, e dello stesso TIPO che ha retto nel crypto: trend difensivo, non
relative-value. Conferma la lezione cross-mercato: **il valore robusto è nel ridurre il rischio
(trend long-flat), non nel battere il buy&hold**. Da solo non risolve €50/g (problema di capitale).
## Prossimo angolo plausibile
**Trend multi-asset / GTAA** sull'universo ETF in cache (SPY/QQQ/IWM + TLT/GLD/HYG): un portafoglio
di trend long-flat su classi d'attivo diverse di solito batte il trend mono-SPY sul rischio-aggiustato
(diversificazione dei trend). + domanda cross-mercato: la sleeve equity-trend DIVERSIFICA il
portafoglio crypto (TP01+XS01+VRP01)? (esecuzione split Deribit+IB).
+96
View File
@@ -0,0 +1,96 @@
# 2026-06-22 — Funding-CARRY cross-sectional su Hyperliquid (FC01): LEAD fragile, NON regge
## Contesto
Onda "nuova ricerca mirata" (l'utente ha chiesto di cercare un angolo non coperto dalle due grandi
ondate — sweep 104-ipotesi e ortho relative-value, entrambe esaurite sul *prezzo* BTC/ETH). L'unico
meccanismo con una **fonte di ritorno diversa** non ancora testato su dati certi è il **carry da
funding**: incassare il cashflow dei perp stando delta-neutral.
### Scan di fattibilità dati (prima di tutto, lezione v2.0.0)
- **Funding price-clock** (drift attorno agli stamp 00/08/16) sul feed Deribit certificato →
già testato nell'onda intraday (`agent_03_funding_clock_15m`) = **FAIL** ("il funding è un cashflow
perp-vs-spot; il prezzo index non ha drift tradabile attorno allo stamp al netto del trend").
- **Funding carry su Deribit** (dove eseguiamo) → ccxt `fetch_funding_rate_history` = **0 righe**
(bloccato), Cerbero MCP espone solo `get_historical` (candele), endpoint funding = 404.
- **Funding carry su Hyperliquid** → API pubblica `/info {"type":"fundingHistory"}` = **disponibile**,
oraria, tokenless, serie native dal 2023-05. HL è già l'universo certificato di XS01.
### Dato scaricato e certificato
`scripts/research/fetch_hl_funding.py` (backoff anti-429) → **19 major** (gli stessi di XS01),
`data/raw/hlfund_<sym>_1h.parquet`. Certificazione: cadenza ~1h, **0 gap**, copertura 98-100%,
funding annualizzato per asset da **APT +1.0%** a **NEAR +21.6%** (mediana ~+11.7%). Pochi `cap_hit`
(ore con |funding|>0.06%/h) su INJ/TIA/SEI, plausibili in alt ad alta vol. Dato pulito.
## Ipotesi e costruzione (FC01)
Book dollar-neutral che **SHORTA i k perp ad alto funding** e **COMPRA i k a basso** → incassa il
premio (chi è long paga il funding). Ritorno perp per un long = `price_ret − funding`. Causale come
XS01: ogni H=10 giorni, segnale = media causale del funding giornaliero realizzato sugli ultimi L
giorni (shift 1), rank cross-section, vol-target 20%, fee 0.05%/lato sul turnover.
`scripts/research/funding_carry_hl.py`. Domanda chiave: **edge reale e ORTOGONALE a XS01**, o XS01
travestito? (gli alt ad alto funding sono spesso i pompati = quelli che XS01 *compra*; qui li
*shortiamo* → potenziale anti-correlazione, oppure il carry domina).
## Risultati
### Premio reale ma direzione-dipendente
`carry` (short alto-funding) batte sistematicamente `anti` (long alto-funding, sempre molto negativo)
→ **il premio di funding esiste**: shortare i perp ad alto funding paga, in aggregato.
### Ma il book NON regge il gauntlet (19 asset, 2024-2026, 904g)
- **Standalone base (L=7 k=5): FULL Sharpe −0.12, in-sample 0.44, HOLD −0.50, DD 28.6%**, −2.8%/anno.
Decadimento netto: 2024 **+0.44** → 2025 −0.06 → 2026 **−1.42**.
- Correlazioni: TP01 −0.02, **XS01 −0.19** (ortogonale, come da ipotesi — NON è XS01 travestito),
VRP01 +0.05.
- **`marginal_vs_tp01` = DILUTES**: `has_insample_edge=False` (in-sample 0.44 < 0.5),
`multicut_persistent=False`, blend w25 uplift FULL −0.21 / HOLD −0.39.
- **Non aggiunge a XS01**: uplift w25 FULL −0.04 / HOLD −0.19.
### Il colpo di grazia: FRAGILITÀ all'universo
Un preview su 17 asset (mancavano NEAR e AAVE) dava FULL **+0.62**, ADDS, +0.22 uplift — un PASS
tentatore. Sui 19 completi: **DILUTES**. Jackknife lascia-fuori-uno (base L=7 k=5):
```
19 asset: FULL -0.12 HOLD -0.50
-SUI FULL -0.39 ... -BTC FULL +0.17
-SEI FULL -0.31 -AAVE FULL +0.26
-BNB FULL -0.29 -NEAR FULL +0.30
=> FULL oscilla in [-0.39, +0.30] togliendo UN solo asset (range 0.70), attraversa lo zero.
```
Togliere **NEAR o AAVE** (i due assenti nel preview) **recupera il segno** → il preview era fortunato
*proprio* perché quei due non c'erano ancora. **Un edge robusto non cambia segno per un singolo nome.**
Le poche celle "buone" del plateau (es. L=7 k=3: HOLD 0.91) hanno **in-sample debole + hold-out forte**
= la firma del hold-out-luck che la metodologia indurita uccide.
## Perché fallisce (meccanismo)
Tensione fondamentale **carry vs momentum**: il funding-carry shorta i forti (alto funding = domanda
long aggressiva), ma in un mercato alt toro i forti **continuano a correre** (NEAR/AAVE: alto funding
*e* prezzo su → shortarli perde più del premio incassato). Il premio di funding è reale in aggregato,
ma il book cross-sectional equal-weight top-k è dominato da pochi nomi a funding estremo che *anche*
trendano, e su 2.5 anni / 19 nomi questo basta a ribaltare il segno.
## Verdetto
**FC01 NON è uno sleeve.** Né deploy (è STAT-MODE: 10 gambe market-neutral, non eseguibile a $600),
né lead affidabile: fragile all'universo (sign-flip su un nome), DILUTES vs TP01, non aggiunge a XS01,
in-sample edge < 0.5, niente persistenza multi-cut, decadimento 2026. Conferma — di nuovo — il
soffitto del progetto: promettente su un sottoinsieme fortunato, collassa sotto il gauntlet onesto.
**Win metodologico:** lo scorer indurito + il jackknife d'universo hanno intercettato un falso
positivo che il preview a 17 asset avrebbe promosso.
## Lascito / lavoro futuro (NON inseguire ora)
- I 19 parquet funding (`hlfund_*`) restano certificati per ricerca futura. Il fetcher NON va in cron
(FC01 fallito → niente da monitorare in forward).
- Idee se mai si tornasse sul carry (NON ora): (a) **gate sul LIVELLO** di funding (short solo quando
estremo, regime-filter alla VRP01 IV-rank) invece dello short-top-k incondizionato; (b) cap sul peso
per-nome / neutralizzazione momentum per togliere il dominio NEAR/AAVE. Entrambe rischiano
overfitting su storia corta — soglia di prova alta.
## Nota IB (thread parallelo, stessa sessione)
Esplorato come fonte per il **basis CME crypto** (cugino eseguibile del carry). Gateway paper
`gnzsnz/ib-gateway` su `127.0.0.1:4002` (read-only, `docker-compose.yml`), sonda `ib_probe.py`.
Esito dati: **backtest del basis NON fattibile** (ContFuture back-adjusted; contratti scaduti = 1
barra). IB resta valido per esecuzione/forward, non per scoprire l'edge. Dettagli nel corpo sessione.
@@ -0,0 +1,33 @@
# 2026-06-23 — Combo DEPLOYABLE in PAPER: TP01 (Deribit) + GTAA (IB), cross-venue
## Decisione
Dopo aver esaurito (onestamente) la ricerca di nuovi edge e anticipazioni cross-mercato, l'unica cosa
VERA e deployabile e' la DIVERSIFICAZIONE: TP01 (crypto, Deribit) + GTAA (equity, IB), corr ~0.21 ->
blend Sharpe ~1.5, maxDD dimezzato (diari 2026-06-22-deployable-combo). Si va in PAPER cross-venue.
## Costruito
- **`src/portfolio/gtaa.py`** — GTAA come sleeve di prima classe: trend difensivo long-flat TSMOM
[21/63/126/252g], vol-target 12%, EW su SPY/QQQ/IWM/TLT/GLD/HYG. Espone `gtaa_returns()` (Sharpe
full 0.64, 7542 barre 1996+) e `gtaa_weights()` (pesi ETF CORRENTI azionabili). Legge cache eq_*.
- **`scripts/live/paper_combo.py`** — paper-tracker FORWARD-ONLY del blend 50/50 TP01+GTAA (crypto
compoundato sul grid giorni-di-borsa). Stato in data/paper_combo/. Mostra le posizioni azionabili
su entrambi i venue. SOLO le gambe eseguibili (XS01/VRP01 STAT-MODE esclusi).
- **`fetch_ib_equities.py --only SPY,QQQ,...`** — refresh mirato dei 6 ETF GTAA (per il cron).
- **`scripts/cron_daily.sh`** — aggiunto: up gateway IB (idempotente) -> refresh ETF GTAA ->
avanza paper_combo. Dipendenza cross-venue gestita (gateway paper sempre-up, restart unless-stopped).
## Stato iniziale (2026-06-23)
Paper combo init a 2000, forward da 2026-06-22. Posizioni azionabili:
- TP01 (Deribit): BTC/ETH 0.0x (flat, TSMOM risk-off — coerente col live).
- GTAA (IB): SPY 13% / QQQ 8% / IWM 9% / TLT 17% / GLD 2% / HYG 17% / cash 34% (difensivo).
Catena end-to-end testata: gateway -> refresh ETF -> avanza paper. OK.
## Onesta'
- E' PAPER (rischio zero). Valida l'OPERATIVITA' cross-venue prima di capitale reale.
- Sharpe atteso ~1.5 e' ottimistico (finestra crypto corta/favorevole); il dato robusto e' la
diversificazione (corr 0.21, DD dimezzato), non il livello assoluto.
- A capitale reale e' un portafoglio su DUE conti (Deribit ~$600 + IB); GTAA frazionabile a basso
capitale, TP01 gia' armato. Prossimo passo eventuale: dashboard del combo + (molto dopo) capitale.
## Prossimo
Lasciar girare il paper forward (cron giornaliero) e ricontrollare l'equity tra qualche settimana.
@@ -0,0 +1,38 @@
# 2026-06-23 — Cross-market crypto-lead OLTRE l'SP500: bond, commodity, indici esteri -> niente
## Obiettivo
Estendere il test "crypto anticipa il mercato?" oltre SP500/azionario USA: commodity, bond, indici
ESTERI (Europa/Asia, fasi orarie diverse = il caso a priori piu' favorevole a un lead vero).
## Dati (IB, orari, cache fut_*_1h)
ES/NQ/RTY (gia'); + ZN (T-note 10y), ESTX50 (Euro Stoxx50), DAX, NKD (Nikkei). Storia ~2-2.4y (2024+).
Commodity GC/CL/HG: VUOTE (market-data subscription COMEX/NYMEX mancante sul paper) -> non testate.
## Test (`fut_leadlag_generic.py`): crypto[T-8h->T] -> future[T->T+6h], non-sovrapposto, controllo=moto proprio future
- ES/NQ/RTY: nessun edge (gia' noto).
- ZN (bond): NEGATIVO (0/3 anni).
- NKD (Nikkei): debole (t_crypto 0.2, Sharpe 0.66 ~ overnight drift, non crypto).
- **ESTX50 / DAX: forte all'apparenza** — BTC->T0h: t_crypto ~7.8, Sharpe 2.5, ann ~22%, 3/3 anni.
## Ma e' un ARTEFATTO DI CONFINE UTC (deep-dive `eu_overnight_deepdive.py`)
- **Picco a coltello a T=00:00 UTC**: t/Sharpe salgono T20->T0 (2.5->7.8 / 0.24->2.45) e CROLLANO a
T=1h (t 1.3, Sharpe -0.09). Un lead vero non e' a coltello su una sola ora.
- **GAP test**: inserendo 1h tra fine-segnale (00:00) e inizio-cattura, l'effetto MUORE
(Sharpe 2.45 -> -0.52, t 7.8 -> 1.6).
- **Singola ora**: T=0h/H=1h (cattura 00:00->01:00) Sharpe +2.93 (t 8.7); T=1h/H=1h (01:00->02:00)
Sharpe -1.02. L'INTERO "edge" e' la barra di confine 00:00->01:00.
- vs SEMPRE-LONG: always-long overnight e' negativo (-0.8/-1.2), quindi non e' overnight-drift; ma
l'uplift del crypto e' tutto nella barra di confine.
-> Firma esatta di `day_boundary_robust` (CLAUDE.md): effetto che vive/muore spostando il confine del
giorno UTC di poche ore = etichettatura/contaminazione, NON anticipazione economica.
## Verdetto
NIENTE di tradabile oltre l'SP500 nemmeno. Su TUTTI i mercati il legame crypto->X e' o co-movimento
contemporaneo (risk-beta) o artefatto di confine. L'anticipazione crypto->altri-mercati sfruttabile
NON esiste su dati onesti (finestre non-sovrapposte + boundary-robust + gap). Conferma definitiva del
soffitto del progetto, ora anche cross-mercato.
## Cosa resta di valore (immutato)
La diversificazione TP01(crypto)+GTAA(equity), corr 0.21 -> Sharpe portafoglio ~1.5, DD dimezzato.
Quello e' strutturale e deployabile; l'anticipazione cross-mercato no.
Script: fetch_ib_futures.py (multi-exchange), fut_leadlag_generic.py, eu_overnight_deepdive.py.
@@ -0,0 +1,29 @@
# 2026-06-23 — "Monitor Deribit / trade IB": il gap crypto->equity e' LOOK-AHEAD
## Idea testata (utente)
Guardare crypto live su Deribit (24/7) e tradare l'indice su IB sul segnale del gap overnight.
## Trappola trovata
Il segnale crypto [P 21:00 -> D 13:00 UTC] e il "gap" equity [P close -> D open 13:30] coprono QUASI
LE STESSE ORE. Condizionare il gap sul crypto-overnight = correlare due ritorni dello STESSO intervallo
notturno -> look-ahead. All'entrata (D 13:00, pre-open) il gap e' GIA' avvenuto: non catturabile.
## Prova (net 2bps, sqrt(252))
| target | OVERLAP gap (look-ahead) | TRADABILE intraday (post-entrata) |
|---|---|---|
| SPY | Sharpe 3.60 (OOS 5.23) | -0.03 (OOS 0.12) |
| QQQ | Sharpe 4.01 (OOS 5.47) | 0.25 (OOS 0.43) |
| IWM | Sharpe 3.98 (OOS 5.72) | 0.15 (OOS 0.44) |
Lo "Sharpe 5" e' artefatto. L'edge REALE tradabile via ETF (intraday, entri all'open) ~0, muore a costi.
NB: anche i Sharpe "gap" del workflow 65-agenti erano (a) look-ahead di overlap e (b) sotto-annualizzati
(sqrt(52) invece di sqrt(252)); il verdetto "non deployabile" resta, rafforzato.
## Cosa resta possibile (non testato, serve dato)
L'unica versione onesta dell'idea: entrare a META' notte via FUTURES IB e vedere se crypto [P21:00->T]
predice il future indice [T->open] su finestre NON sovrapposte (crypto come sensore di rischio piu'
veloce). Richiede dati INTRADAY dei futures (ES/NQ/RTY), non in cache -> data step se si vuole indagare.
## Lezione
Un risultato "troppo bello" (Sharpe 5) e' un test di disciplina: era overlap di finestre. Catturato.
Script: crypto_overnight_equity.py (versione artefatto), crypto_overnight_honest.py (decomposizione).
@@ -0,0 +1,37 @@
# 2026-06-23 — "Monitor Deribit / trade IB" su futures: test ONESTO non-sovrapposto -> edge ~0
## Idea
Monitorare crypto live (Deribit 24/7) ed entrare sul FUTURE indice IB (ES/NQ/RTY, tradato di notte)
a meta' notte, catturando il moto SUCCESSIVO -> finestre NON sovrapposte (no look-ahead, vs il "gap"
che era contemporaneo al segnale).
## Dati
`fetch_ib_futures.py` -> data/raw/fut_{es,nq,rty}_1h.parquet (ContFuture orario, UTC). ES 3y (2023-06+),
NQ 2.75y, RTY 2.3y. (NB: ContFuture NON accetta endDateTime -> chiamata singola "4 Y" = ~3y max orari.)
## Test (`fut_overnight_leadlag.py`)
entrata a T (ora UTC notturna): segnale = crypto[P21:00->T]; controllo = future[P21:00->T] (moto
PROPRIO del future); cattura = future[T->open 13:00]. Incrementale: crypto predice la cattura OLTRE il
moto proprio del future? Trade: sign(crypto[P21:00->T]) * future[T->open], net 2bps. T in {0,3,6,9}h.
## Risultati
| future | miglior Sharpe (trade crypto) | t_crypto incrementale | esito |
|---|---|---|---|
| ES (S&P500) | ~0 / negativo (-0.03..-0.93) | 0..1.5 | NESSUN edge |
| NQ (Nasdaq) | 0.41 (T=3h) | 0.5 (debole) | momentum del future, non crypto |
| RTY (Russell) | 0.40-0.77 | 2.0-2.7 (BTC->RTY) | soffio debole, non robusto |
- **SP500: NIENTE.** Il crypto della prima notte non predice l'ES della seconda. Il "Sharpe 5" del gap
era interamente look-ahead (finestre sovrapposte): catturato e ucciso.
- **RTY (small-cap)** e' l'unico con t_crypto incrementale ~2-2.7 e crypto che AGGIUNGE oltre il moto
proprio del future (futOwn Sharpe negativo). MA: Sharpe 0.4-0.5 modesto, 24 config (multiple-testing),
storia 2.3y, per-anno INCOERENTE (BTC->RTY T=3h: 2024 +0.99 / 2025 +0.52 / 2026 -0.31).
## Verdetto
L'idea "monitor Deribit / trade IB" NON da' un edge tradabile, men che meno su SP500. Il forte
fenomeno crypto<->equity e' CO-MOVIMENTO contemporaneo (risk-beta overnight), non anticipazione: quando
si impone una finestra causale non-sovrapposta, l'edge svanisce (efficienza di mercato). L'unico
residuo (crypto->small-cap overnight) e' debole, borderline su multiple-testing e instabile per anno
-> forward-monitor al piu', NON deploy. Coerente col soffitto del progetto.
Script: fetch_ib_futures.py, fut_overnight_leadlag.py. (look-ahead documentato: 2026-06-23-crypto-overnight-lookahead.md)
+141
View File
@@ -0,0 +1,141 @@
# 2026-06-23 — SKH01 "Skyhook": porting onesto del sistema ES dual-timeframe su BTC/ETH
Branch: `strategy_skyhook`. Engine: `src/strategies/skyhook.py`. Harness: `scripts/research/skyhook/skyhooklib.py`.
Test: `tests/test_skyhook.py` (5 pass). Ricerca: `scripts/research/skyhook/{sweep,grid,check_v1}.py` + `runs/`.
## Il brief
Sistema "Skyhook" (origine ES / E-mini S&P, genetico, a doppio timeframe), da portare su crypto:
- **data2 = 690 min (segnale)**, **data1 = 230 min (esecuzione)**. NB **690 = 3 × 230**.
- NON trend-follower: entra **solo** quando coincidono (a) un **regime** di volatilità/volume e
(b) un **pattern** di breakout.
- Pipeline per barra: indicatori (BuzVola su ATR, BuzVolume su volume, tipo-Chande 0-100) →
fasce regime → pattern (Donchian/breakout su data2) → composer (regime AND pattern) →
ingresso (max 1/giorno, stop-and-reverse) → uscite (time-based asimmetrico uscitalong=24 /
uscitashort=18 + stop/profit).
- Ancore demo: trend lineare → **BuzVola=50** (vol steady → neutro), **BuzVolume=100** (volume in rampa).
## Ricostruzione (fedele + onesta)
- **Resample dal feed 5m certificato** con `origin='epoch'`: 230 min = 46×5m, 690 min = 138×5m,
e i confini 690 sono un **sottoinsieme** dei confini 230 → una barra HTF chiude esattamente su
una chiusura LTF. Merge HTF→LTF causale: `merge_asof` backward sulla **chiusura HTF** (≤ chiusura
LTF), così una barra HTF è usata solo quando è davvero chiusa. (~2287 barre/anno LTF, ~762 HTF.)
- **BuzVola / BuzVolume = `chande01`** (Chande Momentum Oscillator normalizzato 0-100): serie
steady → 50, rampa-su → 100, rampa-giù → 0. Le ancore demo sono soddisfatte a livello di
indicatore (è la lettura fedele: "vol steady → neutro"). NB: l'EMA-ATR su un *linspace* sintetico
dà 100 per drift di warm-up/floating-point, non per comportamento reale — su BTC reale BuzVola
oscilla intorno a 50 (EMA-ATR vs SMA-ATR corr 0.90).
- **Pattern** = Donchian breakout leak-free (shift(1)) su HTF, `ptn_n` barre (default 13 da 13/13/1).
- **Regime** = bande-soglia tunabili su BuzVola/BuzVolume (i magici interi 4/3/2 - 4/2/2 non sono
nel brief; ricostruiti come `[vola_lo,vola_hi]` × `[vol_lo,vol_hi]`).
- **Composer** = regime AND pattern. **Ingressi** ≤1/giorno (prima barra qualificante).
- **Uscite**: time-based asimmetrico (`uscitalong`/`uscitashort` barre LTF) + hard stop/profit. Lo
"stop 2000 / profit 5000" in $ del sistema ES → **multipli di ATR LTF** (scale-free): default
`sl_atr=2.0`, `tp_atr=5.0` (~ rapporto 40:100 pt ES), con modalità `pct` alternativa.
- Engine espresso come **entries `{dir,tp,sl,max_bars}`** per `backtest_signals` (motore onesto del
progetto: TP/SL intrabar, max_bars, non-overlap). Causalità verificata con prefix-recompute
(0 mismatch).
## Baseline → V1 (lever scout + grid, inline, veloce)
- **Baseline** (default 13/13, sl2/tp5, vola[35,95], vol_lo50): causale, fee-surviving, FULL Sharpe
BTC +0.91 / ETH +0.64, ma **HOLD-OUT debole** (BTC −0.09 / ETH +0.17) → FAIL del gate onesto.
- **Lever scout** (`sweep.py`): gli **short servono** (long_only → HOLD −0.52); il **regime gate
conta** (togliere la banda vola → HOLD −0.80); il **floor di volume** a 50 *frenava* l'hold-out
(vol_lo=40 o 0 → PASS); **breakout più lento** (ptn_n=55) e **stop più larghi** (sl2.5/tp6)
alzano l'hold-out.
- **Grid combinato** (`grid.py`): vincitrice **SKH01-V1**
`SkyhookParams(ptn_n=55, sl_atr=2.5, tp_atr=6.0, vola_lo=35, vola_hi=95, vol_lo=0.0)`:
- **min-asset FULL +0.69, HOLD-OUT +0.64** (BTC 0.64 / ETH 0.64), **PASS**, fee-surviving a 0.30%RT.
- BTC FULL +0.69/+275% DD49% ; ETH FULL +1.01/+871% DD31% ; entrambi HOLD-OUT positivi.
- **Marginal vs TP01 = ADDS** e regge i gate induriti: **corr 0.06** (ortogonale, NON trend-beta),
`has_insample_edge=True` (Sharpe in-sample standalone 1.15), `is_hedge=False`, multi-cut
persistente. Blend **0.75·TP01 + 0.25·SKH01: HOLD Sharpe 0.31 → 0.74 (+0.44), DD 11.9%**;
blend 50/50 HOLD 0.88, DD 17.8%.
- Unico sub-gate fallito: `clean_year_uplift` +0.014 (sotto 0.02) → `earns_slot=False` per un pelo,
nonostante tutto il resto sia forte. **Debolezza principale: DD standalone alto (40-49%).**
→ SKH01 è un **diversificatore quasi-ortogonale** reale (non un TP01 travestito): da solo è
volatile, ma come sleeve al 25% migliora moltissimo l'hold-out del portafoglio a DD bassissimo.
## Onda 1 (`skyhook-improve`, 30 agenti) — winner intermedio
Famiglie: param (RR, ptn_n, regime bands, exit bars, chande, local), regime-redef (percentile,
realized-vol, vol-expansion, LTF), pattern (confirmation, ROC, Keltner, NR, dual), exit + overlay,
ognuna verificata da 2 scettici. Risultato: **winner intermedio**
`SkyhookParams(ptn_n=45, sl_atr=2.5, tp_atr=7.0, uscitalong=24, uscitashort=16, vola_lo=35, vola_hi=95, vol_lo=0)`
— **minFull +0.83, minHold +0.81** (vs V1 +0.69/+0.64), causale, fee-surviving 0.30%RT, marginal
**ADDS** (corr 0.05, has_insample_edge, robust_oos, multicut, clean_year_uplift +0.37), blend w25
uplift_hold +0.58. **MA standalone maxDD ancora 34% (BTC) / 31% (ETH) → l'unico goal mancato era il DD<30%.**
## Onda 2 (`skyhook-improve-v2`, 14 famiglie DD-reduction) — SKH01-V2-DD vince
Obiettivo: tagliare il **DD standalone <30%** tenendo hold-out + `earns_slot`, e alzare l'uplift di
portafoglio. 14 famiglie (ensemble param/struct, vol-target, DD kill-switch, RR/stop grid, regime
tight, percentile, vol-expansion, breakout confirmation, dual-TF, asimmetria L/S, cadenza, chande,
Keltner), ognuna verificata da 2 scettici avversariali (window-luck/multicut/jackknife +
causalità/fee/plateau/overfit). Esito: **il winner intermedio cade.** Nuovo campione **SKH01-V2-DD**
(famiglia ASYM_LS, `src/strategies/skyhook.py:SKH01_V2_DD`, run `runs/SKH2_ASYM_LS.py`):
- **Config:** stesso SEGNALE del winner (`ptn_n=45, vola_lo=35, vola_hi=95, vol_lo=0, exit-bars 24/16`)
ma EXIT commutati da ATR a **percentuale fissa ASIMMETRICA** — long `sl=4% / tp=10%`, short
`sl=2% (più stretto) / tp=8%`. Motivazione meccanica: in crypto lo short si fa steamrollare da uno
spike vola e lo stop-ATR si allarga lasciando correre la perdita → il %-SL stretto sullo short
**cappa la perdita per-trade** che FORMA il maxDD. (Implementato come override per-direzione nel
motore, backward-compatible: campi `*_short=None` → comportamento simmetrico invariato.)
- **Numeri veri (verificati indipendentemente via `sk.study(SKH01_V2_DD)`):** standalone maxDD
**BTC 21.4% / ETH 27.4%** (<30% ✓, vs 34.4/30.5 del winner) — **goal RAGGIUNTO**; minFull **+0.99**,
minHold **+1.26**; causalità **0/400** entrambi gli asset; fee@0.30%RT BTC +1.05 / ETH +0.80
(positiva anche a 0.40%). Marginal vs TP01 **ADDS** (corr 0.09, has_insample_edge, is_hedge=False,
robust_oos, multicut, clean_year_uplift +0.57). **Blend 0.75·TP01 + 0.25·SKH: uplift_hold +0.87**
(vs +0.58 del winner); **blend 50/50: full 1.84 / hold 1.59 / DD 10.7%**. earns_slot=True,
beats_winner=True. **Plateau reale** (i vicini Spct_mb14/16 sl2% tengono DD 27-28%), non knife-edge.
Entrambi gli scettici: holds_up=True, confidence high, killer_finding=null.
**Top-3 dell'onda 2 (criteri onesti):**
| # | Famiglia | maxDD (BTC/ETH) | minHold | w25 uplift_hold | Verifica |
|---|---|---|---|---|---|
| **1** | **ASYM_LS → SKH01-V2-DD** | 27.4% (21.4/27.4) | +1.26 | **+0.87** | 2/2 high, killer=null ✅ |
| 2 | ENS_STRUCT (3-regime ensemble) | **22.9%** (21.2/22.8) | +1.00 | +0.67 | 2/2 high — ma 3 motori da eseguire |
| 3 | TPSL_DD (%-SL/TP hard) | 28.0% (28/25.5) | +1.11 | +0.75 | 1/1 (rate-limit) — caveat hedge-like |
**Lezioni anti-DD:**
- **Ha funzionato (STRUTTURA dell'exit, non i parametri):** cambiare il MECCANISMO di uscita — %-SL
hard, asimmetria L/S, o ensemble di exit/regime diversi (decorrelazione). Il DD del winner nasce
dalla coda intra-trade negli spike ATR; il %-SL la cappa.
- **NON ha funzionato (la leva non raggiunge il DD vincolante):** DD kill-switch entry-only (sopprime
solo le NUOVE entry, non chiude il trade aperto che forma il maxDD → floor 33-36%); vol-target
causale (DD<30 e uplift≥0.55 mutuamente esclusivi; cap>1 PEGGIORA il DD levereggiando nel pre-crash);
cadenza/FREQ (accorciare gli hold short fa esplodere ETH a 50-66%); dual-TF (LTF è resample dello
stesso prezzo → quasi-tautologico, DD invariato).
- **Bocciato dagli scettici come overfit:** PATTERN_CONF (sub-30 solo a vola_lo=45, knife-edge: sl_atr
±0.5 → ETH 40-47%; la conferma "close_loc" da sola NON taglia il DD). Esempio canonico del perché
serviva la doppia verifica.
- **Non promuovibili:** PCTL_DD (numeri spettacolari ma **0 verifiche**, le 2 sono morte per rate-limit
→ forward-monitor, non fidato); ENS_PARAM / TPSL_DD (battono i gate ma uplift recency/hedge-loaded,
concentrato nei regimi TP01-down → forward-monitor).
**Promozione (questa sessione):** `SKH01_V2_DD` canonico nel motore + override exit-short
asimmetrici (backward-compatible, V1/winner invariati) + 3 test nuovi (8/8 pass).
**Sleeve cablato @0.25 effettivo** (`src/portfolio/sleeves.skyhook_sleeve` → `active_sleeves`): i tre
sleeve preesistenti scalati nel restante 0.75 mantenendo il rapporto 55:25:20 → **TP01 41.25% / XS01
18.75% / VRP01 15% / SKH01 25%**. Report del portafoglio (4 sleeve, `run_portfolio.py`):
| | FULL Sharpe | FULL DD | HOLD-OUT Sharpe | HOLD-OUT DD |
|---|---|---|---|---|
| 3 sleeve (TP01+XS01+VRP01) | 1.68 | 14.3% | 1.63 | 3.4% |
| **+ SKH01 @25%** | **2.13** | **7.8%** | **2.30** | 3.5% |
| Δ | **+0.45** | **−6.5pt** | **+0.67** | ~0 |
→ aggiungere Skyhook **alza lo Sharpe full +0.45 e DIMEZZA il DD full (14.3→7.8%)**, e alza l'hold-out
+0.67 a DD invariato. Portafoglio combinato: FULL Sh 2.13 / ret +365% / DD 7.8%, HOLD Sh 2.30 / DD 3.5%,
positivo ogni anno (2019-26, DD annuo ≤7.8%) vs buy&hold 50/50 FULL Sh 0.93 / DD 76%.
**Caveat onesti / NON deploy:** è un portafoglio di **ricerca** (peso fisso, no costi di ribilanciamento
reale a $600; lo Sharpe daily-step di Skyhook è la convenzione del lens). ETH DD standalone 27.4% ha
margine sottile vs 30%. Prima di un eventuale deploy: ri-verificare la causalità sul **codice di
esecuzione reale** (qui è l'harness di ricerca) e i costi del book a 230m (ribilanciamento più frequente
del resto). XS01/VRP01 restano STAT-MODE/lead. Per ora: research win + sleeve cablato, forward-monitor.
+66
View File
@@ -0,0 +1,66 @@
# 2026-06-23 — Tail-hedge / protezione DD del combo (incl. OPZIONI): vince la guardia-drawdown
## Obiettivo (goal utente)
Trovare uno sleeve/overlay da AGGIUNGERE al combo (TP01+GTAA) per proteggere il drawdown e gli anni
tipo 2022. Valutare anche le opzioni.
## Diagnosi del rischio (decisiva)
Il MaxDD del combo (1x) e' **8.4%** e il 2022 fu **-4.4%**: NON un crash, un **grind lento** (peggior
giorno -2.8%, peggior mese 2022 -1.6%). Il doppio trend (TP01+GTAA long-flat) gia' taglia i crash
veloci. Il tail residuo = (a) whipsaw da mercato choppy (2022), (b) gap/crash overnight LATENTE (TP01
non reagisce intraday, non nel campione storico), (c) la LEVA.
## Candidati testati (`tail_hedge_lab.py`)
| protezione | MaxDD | 2022 | Sharpe | CAGR |
|---|---|---|---|---|
| combo baseline | 8.4% | -4.4% | 1.48 | 11.3% |
| **+ guardia-DD -4%** | **5.8%** | **-1.8%** | 1.38 | 9.2% |
| + vol-target 5% | 8.4% | -5.9% | 1.46 | 8.0% |
| + opzioni (put/put-spread, budget 3%/y) | 8.4% | -4.4% | 1.48 | 11.3% |
### OPZIONI (valutate): NON adatte al 2022
- Put-spread/long-put LONG su indice 50/50 BTC/ETH (mirror di VRP01), premio BS su DVOL reale, payoff
sul path. Strike corretti (compra -0.30delta, vende -0.10delta).
- Sempre-on costa **~50%/anno** di premio -> con budget 3%/anno size ~0.06-0.10x = effetto ~nullo.
- Nel 2022 (grind, niente crash settimanali) **sanguinano** (scadono inutili) -> Δ2022 ~0.
- Pagano SOLO nei crash secchi: stress -30% overnight -> put paga **+25% netto**, put-spread +3.8%.
- Verdetto: assicurazione BLACK-SWAN cara e fuori-bersaglio per il grind. Utile solo come piccola
copertura del gap overnight latente, NON come fix del 2022.
### GUARDIA DRAWDOWN: centra il rischio
De-risk (esposizione 1.0->0.4) quando il DD da picco supera -4%, ri-rischia a -1.6%. Targetizza il
grind: MaxDD 8.4%->5.8%, 2022 -4.4%->-1.8%, ogni anno DD intra <=5.4%. Costo: Sharpe 1.48->1.38,
CAGR -2.1pp (de-risca sui cali, perde rimbalzo — prezzo onesto della protezione).
### A LEVA (dove il tail morde)
guard applicato pre-leva: 2x 2022 -15.6%->-10.9%, MaxDD 28%->24%; 3x resta MARGIN-CALL (DD 39%>=33%).
-> la protezione rende il 2x sopportabile; il 3x va evitato comunque.
## Raccomandazione
AGGIUNGERE una **guardia-drawdown a livello di portafoglio** al combo (overlay, niente premio):
e' la protezione che colpisce il rischio reale (grind/2022) a costo Sharpe minimo. Le opzioni NO come
fix del 2022; eventualmente una micro-allocazione deep-OTM come assicurazione black-swan separata.
Vol-target NON aiuta (il 2022 non e' uno spike di vol).
## Onesta'
- Il guard e' REATTIVO (de-risca dopo l'inizio del DD, restituisce un po' di rimbalzo) -> costa CAGR.
- Trade: -2.1pp CAGR per dimezzare il MaxDD e azzerare quasi il 2022. Sensato se la priorita' e' il DD.
- Parametri (-4% trigger) semplici; il meccanismo (non la soglia esatta) e' la sostanza.
Script: tail_hedge_lab.py.
## Aggiornamento — protezioni CLASSICHE (stop-loss), goal "prova anche SL" (`stops_lab.py`)
Confronto equo (trigger/re-entry sul NAV di mercato, non sull'equity congelata):
| protezione | Sharpe | MaxDD | 2022 | CAGR | in-mkt |
|---|---|---|---|---|---|
| baseline | 1.48 | 8.4% | -4.4% | 11.3% | 100% |
| **soft-guard -4% (0.4x)** | **1.38** | **5.8%** | **-1.8%** | 9.2% | 100% |
| trail-stop -4% (uscita tot.) | 1.07 | 7.5% | +0.0% | 6.6% | 42% |
| trail-stop -6% (re:newhigh) | 1.34 | 6.6% | -2.1% | 9.0% | 72% |
| trail-stop -8% | 1.41 | 8.3% | -4.2% | 10.0% | 87% |
| stop mensile -5% | 1.48 | 8.4% | -4.4% | 11.3% | 100% (mai scatta) |
| vol-stop (>90pctl) | 1.48 | 8.4% | -4.4% | 10.4% | 100% |
VERDETTO: lo SL classico funziona solo a -6% (e resta inferiore al soft-guard); a -4% fa WHIPSAW
(Sh 1.48->1.07, fuori mercato 58%) perche' l'uscita TOTALE viene choppata nel grind. Il soft-guard
alla stessa soglia non whippa (de-risk parziale 0.4x). Stop mensile/vol inutili (bersaglio sbagliato).
Conferma: per un DD da grind, de-risk PARZIALE > stop-loss duro. Soft-guard -4% confermato come scelta.
+69
View File
@@ -0,0 +1,69 @@
# 2026-06-26 — Cash-and-carry (basis trade) delta-neutral su HL (CC01): premio REALE, Sharpe ARTEFATTO, NON deployabile
**Goal utente:** dopo lo scarto del gamma scalping, "provare" gli altri due angoli proposti —
funding-carry cross-sectional e basis/cash-and-carry. Il **funding cross-sectional (FC01) è già
SCARTATO** (diario 2026-06-22: DILUTES, sign-flip su un nome). L'angolo non testato è il
**cash-and-carry delta-neutral (CC01)**. Branch `research/gamma-scalp-options`,
script `scripts/research/cash_carry_hl.py`.
## Meccanismo (diverso da FC01)
FC01 pickava cross-section (short alto-funding / long basso-funding) → scommessa relativa, fragile.
CC01 **non picka**: harvesta il premio di funding AGGREGATO restando delta-neutral sullo *stesso*
asset. Long spot + short perp (stessa size): le gambe lineari nel prezzo si cancellano → ritorno
≈ **+funding** (lo short incassa il funding quando f>0), zero esposizione direzionale. Dati: funding
orario reale HL dal 2023-05 (`hlfund_*_1h.parquet`), gli stessi 19 major di XS01.
## Risultato grezzo — e perché NON va creduto
| config | Sharpe | CAGR | maxDD | per-anno |
|---|---|---|---|---|
| BTC/ETH CC-static | **+12.9** | +13% | 0.8% | 2023:+10 2024:+23 2025:+8 2026:+1% |
| BTC/ETH CC-gated | +13.9 | +14% | 0.3% | tutti positivi |
| 19-major CC-gated | +11.6 | +16% | 0.4% | tutti positivi |
**Uno Sharpe di 13 con DD 0.3% è un ALLARME, non un edge.** È la firma di un modello che cattura
solo un cashflow liscio (il funding) e azzera la volatilità reale. Il marginal scorer dà **ADDS /
robust_oos / has_insample_edge=True / multicut_persistent** su OGNI config — ma questo **espone un
punto cieco dello scorer**: si fida della vol riportata dal candidato e non ha un gate "Sharpe
implausibile → rischio nascosto". Un Sharpe di 13 dovrebbe squalificare-e-indagare, non passare.
## Il rischio è NASCOSTO, non assente
- **Mark-to-market della base** (`premium` col → `r = funding − Δpremium`): sgonfia lo Sharpe solo
13→11. La colonna premium di HL è già lisciata/clampata → a risoluzione daily il basis-vol è
minimo. **Quindi il basis-from-data NON è il rischio vero.**
- **I rischi che giustificherebbero uno Sharpe realistico (~1-3) sono ASSENTI dal dataset:**
1. **2022 mancante.** Lo storico funding parte 2023-05 → niente deleveraging LUNA/3AC/FTX, il
regime di funding profondamente negativo + basis blow-out che farebbe il vero drawdown.
2. **Procyclicità.** Funding aggregato BTC/ETH: +23% nel toro 2024 → **+1.7% nel bear 2026**
(e 19-major CC-static 2026 = **−1%**). Solo 10% di giorni a funding negativo *in-sample* — ma
in un vero bear quella frazione esplode. Il carry **non è all-weather**: è un risk-on premium.
3. **Liquidazione dello short** in uno squeeze e **slippage** su spot+perp: non modellati.
- **Sharpe reale di un crypto basis-trade ≈ 1-3 con code brusche** (Mar-2020, Mag-2021, FTX), non 13.
## Eseguibilità a $600 — muro indipendente
Serve spot **+** perp per gamba: BTC/ETH = 4 posizioni, 19-major = 38. Su Deribit (dove operiamo) lo
storico funding è **bloccato** (404) e non tradiamo spot HL. **STAT-MODE**, come XS01/VRP01 ma peggio
(doppia gamba per asset). Non deployabile a questo capitale.
## Verdetto
**CC01 = premio di funding REALE (~+8-14%/anno aggregato, positivo ogni anno in-sample) e
genuinamente ortogonale a TP01 (corr ~0.05, NON direzionale).** È la "fonte di ritorno diversa" più
concreta trovata finora. MA:
- lo **Sharpe headline è fiction** (rischi di coda strutturalmente fuori dal dataset);
- è **procyclico** (si comprime/inverte nel bear — proprio quando servirebbe);
- **non eseguibile** a $600 / sul nostro venue.
→ **LEAD da rivedere a scala** (capitale ~20k+ e un venue con funding eseguibile), **non uno sleeve**.
Nessun impatto sul book live (branch separato).
## Sottoprodotto metodologico (raccomandazione)
CC01 ha passato ogni gate del marginal scorer pur essendo un'illusione di rischio. **Prossima
indurita dello scorer:** un gate di *plausibilità dello Sharpe* — uno standalone Sharpe ≫ 4 deve
declassare a "SUSPECT/INVESTIGATE" invece di alimentare ADDS, perché segnala vol sottostimata
(mark-to-cashflow, dati che escludono il regime di stress, leva nascosta). Documentato qui, non
implementato in questa passata per non toccare lo scorer condiviso su `main`.
@@ -0,0 +1,58 @@
# 2026-06-26 — "Short su fondamentali/notizie NEG ma prezzo SU": screener forward, edge non provato
**Goal utente (chiarito):** se i dati finanziari/notizie di un'azienda sono negativi ma la
quotazione è positiva (sale), andare SHORT — scommessa che il prezzo scenda a riallinearsi ai
fondamentali. Branch `research/equity-meanrev-ib`, script `scripts/research/eq_fundnews_short.py`.
## Gate dati (lezione v2.0.0) — NON backtestabile
I fondamentali e le notizie scaricabili dalla rete (Yahoo) sono **snapshot CORRENTI**, non
point-in-time storici. Applicarli a prezzi passati = **look-ahead** (restatement + survivorship):
esattamente la classe di errore che ha prodotto la libreria fasulla v2.0.0. Un backtest onesto
richiede un DB point-in-time (Compustat PIT, news storiche con timestamp) — **assente**. Quindi,
come per la vol term-structure: **niente backtest**, l'unica via onesta è uno **screener forward**.
## Cosa è scaricabile (feasibility, fatto)
- **Fondamentali strutturati** via Yahoo quoteSummary (flusso cookie+**crumb**, tokenless):
`recommendationMean` (1=buy..5=sell), `revenueGrowth`, `earningsHistory` surprise%,
`recommendationTrend` (skew buy/sell). ✅
- **Notizie**: Yahoo news search (headline + publisher), sentiment lessicale crudo. ✅ (proxy debole)
- **Momentum**: chart API (return 1m/3m). ✅
## Screener costruito + eseguito dal vivo
`fund_neg` ∈ [0,1] (media di: recMean→sell, surprise negative, ricavi in calo, analisti a sell) +
`news_neg` lessicale + momentum. **SHORT candidate = (fond/news neg) AND prezzo in salita** (la
divergenza). Idempotente, logga forward su `data/raw/fundnews_short_screen.parquet`.
**Run di oggi (2026-06-26): NESSUN candidato.** Quasi tutto l'universo ha momentum 1m **negativo**
(mercato in flessione ampia, coerente col bear) → la gamba "prezzo che sale" non scatta. I peggiori
per fondamentali (TSLA 0.48, BA 0.39, NKE 0.38) stanno comunque *scendendo*. Output sensato.
## L'intuizione analitica chiave (il valore vero di questa analisi)
La premessa ha una **tensione interna** che la rende la versione *rischiosa* dell'anomalia:
- **Shortare un prezzo che SALE combatte il momentum** — una delle anomalie più robuste e persistenti
(i winner continuano a vincere su 3-12 mesi). Si scommette contro di essa.
- **Il PEAD** (post-earnings drift) dice che dopo cattive notizie il prezzo continua a **scendere**;
ma qui il prezzo *sale malgrado* le cattive notizie → spesso significa che il mercato sta
**prezzando informazione** che i fondamentali *trailing* non contengono (turnaround, M&A, squeeze).
- Quindi: la versione *pulita* dell'edge "short su fondamentali deboli" funziona meglio quando il
prezzo **conferma** (fondamentali deboli + prezzo che SCENDE = momentum e fondamentali allineati),
**non** quando diverge. La richiesta "shorta il titolo che sale su brutte notizie" è il caso
contrarian, più difficile e storicamente più punito (squeeze, perdita illimitata).
## Eseguibilità (muro)
Short = **borrow** (locate + fee; hard-to-borrow caro/assente), **perdita illimitata**, **squeeze**,
**PDT $25k** per i day-trade, IB instabile qui, $600, universo single-stock (non i nostri ETF). NON
deployabile.
## Verdetto
**Non un edge schierabile, né dimostrabile ora.** Deliverable onesto = lo **screener forward**
(funzionante, da dati di rete) + il log che accumula i candidati per una validazione futura, con
la chiara avvertenza che l'edge è **non provato** e che la *direzione contrarian* della scommessa
(short sulla forza) è la parte fragile. Strumento utile (fond+news+momentum da rete in un colpo),
tesi da maneggiare con scetticismo. Nessun impatto sul book live (branch separato).
@@ -0,0 +1,57 @@
# 2026-06-26 — Scalping azioni IB "quando sottoquotate" + check dati dalla rete
**Goal utente:** su IB, comprare azioni quando "sottoquotate" (oversold/sotto fair-value), con
verifica incrociata dei dati dalla rete. Branch `research/equity-meanrev-ib`,
script `scripts/research/eq_meanrev_ib.py`. Due pezzi.
## 1) CHECK DATI DALLA RETE — il pezzo richiesto (e perfettamente in-metodo)
Confronto i dati certificati IB (`data/raw/eq_*_1d.parquet`, ADJUSTED_LAST) con una **sorgente di
rete indipendente** (Yahoo Finance chart API, tokenless). È la lezione fondante del progetto: non
fidarti di un feed solo (il disastro v2.0.0 era un feed contaminato).
**Risultato (180g, BTC… no: 6 ETF):** dopo l'allineamento corretto **tutti CONCORDE**, deviazione
sui rendimenti **≤1.2bps**, ultimo close identico (0.0bps). Il feed IB è validato.
**La lezione (errore che ho fatto e corretto):** un primo confronto naïf (nostro close *adjusted*
vs `close` *grezzo* di Yahoo) ha **falso-allarmato 4/6 ticker** a 30-52bps (SPY 30, TLT 40, HYG 52).
Le divergenze erano **tutte su singoli giorni = stacco dividendo**: confrontavo dividend-adjusted vs
non-adjusted. Usando l'`adjclose` di Yahoo (apples-to-apples) → ~0bps. **Regola: ogni divergenza va
SPIEGATA prima di gridare "feed sporco" — e prima di tradarci sopra.** Lo strumento resta come
validatore di feed riutilizzabile / template del pre-trade price-check live.
## 2) "SCALPING quando sottoquotata" — non testabile/eseguibile; testato lo swing MR
Lo **scalping intraday non è valutabile**: (a) non abbiamo dati intraday (solo `eq_*_1d`), (b) non
è eseguibile — **PDT rule**: il day-trading di azioni US sotto **$25.000** è limitato a 3
day-trade/5gg → lo scalping è *regolatoriamente bloccato* al capitale del progetto (l'analogo equity
del muro STAT-MODE a $600 sul crypto), (c) IB Gateway è instabile qui (timeout ordini diagnosticato).
Versione onesta e testabile = **swing mean-reversion** "compra quando sottoquotata": Connors RSI2<10
+ filtro trend MA200, exit a MA5. Causale (segnale ≤ close[i], entry a close[i]), netto fee, hold-out 2015+:
| ETF | FULL Sh | DD | CAGR | expo | HOLD Sh | **B&H HOLD Sh** |
|---|---|---|---|---|---|---|
| SPY | +0.75 | 15% | +5% | 13% | +0.70 | **+0.81** |
| QQQ | +0.50 | 16% | +4% | 14% | +0.56 | **+0.92** |
| IWM | +0.32 | 22% | +2% | 13% | +0.15 | +0.53 |
| DIA | +0.38 | 13% | +2% | 14% | +0.55 | +0.74 |
| EEM | +0.41 | 20% | +3% | 13% | +0.36 | +0.46 |
Fee sweep SPY: Sh 0.82 (0bps) → 0.75 (3) → 0.70 (5) → 0.58 (10bps RT).
**Lettura onesta:** la mean-reversion "buy the dip" sugli indici equity ha un edge **reale ma
modesto** (Sharpe ~0.5-0.75, investito solo ~13% dei giorni) **che NON batte il buy&hold
risk-adjusted** (B&H hold-out 0.81 su SPY vs 0.70 della MR), con CAGR piccolo (2-5%) e sensibile ai
costi. È capital-efficient in teoria (cash 87% del tempo) ma il valore aggiunto vs "tieni l'indice"
è negativo o nullo, e la frequenza *scalping* che potrebbe aggiungere valore è bloccata dalla PDT.
## Verdetto
- **Check dati dalla rete: FATTO e utile** — feed IB validato (≤1.2bps vs Yahoo); strumento
riutilizzabile. Unico vero keeper della sessione equity.
- **Scalping "sottoquotate": NON deployabile** — non testabile (no intraday), non eseguibile (PDT
$25k, IB instabile). Lo swing MR daily testabile **non batte il buy&hold** → niente edge schierabile.
Conferma il pattern del progetto: l'idea promettente sopravvive solo finché non incontra
eseguibilità + benchmark onesto. Nessun impatto sul book live crypto (branch separato).
@@ -0,0 +1,74 @@
# 2026-06-26 — "Scalping BTC/ETH con copertura in opzioni" = gamma scalping → SCARTATO
**Domanda (goal utente):** analizzare lo scalping su BTC/ETH con copertura in opzioni come
possibile nuovo sleeve. **Esito: negativo, strutturale, su tutte le frequenze. Non è uno sleeve,
non è nemmeno un hedge.** Branch `research/gamma-scalp-options`, script
`scripts/research/options_gamma_scalp.py`.
## Cos'è davvero "scalping con copertura in opzioni"
L'interpretazione rigorosa è il **gamma scalping**: compri un'opzione (la *copertura* = long
gamma), delta-hedgi il sottostante a cadenza fissa (lo *scalp*), e il P&L netto è
≈ dollar-gamma × (vol realizzata² − vol implicita²). È lo **specchio esatto del VRP01** (short-vol):
VRP01 incassa IV−RV (positivo in media), il gamma scalping incassa **RV−IV** (negativo in media).
Modello (mirror della struttura VRP per comparabilità): long straddle ATM, tenor 7g, IV = DVOL
Deribit (la stessa fonte del VRP), delta-hedge sui prezzi certificati, fee opzioni cap 12.5% del
premio + fee perp 0.05%/lato sull'hedge turnover, return-on-notional vol-targeted 20%.
## La diagnostica strutturale (il cuore)
| asset | IV (DVOL) | RV 1d | IV−RV 1d | RV 1h | IV−RV 1h |
|---|---|---|---|---|---|
| BTC | 60.9% | 56.0% | **+4.9pp** | 64.5% | −3.6pp |
| ETH | 74.9% | 76.0% | −1.0pp | 81.0% | −6.1pp |
- A **rehedge giornaliero** l'IV ≈ o > la RV → il long gamma **paga il VRP** (sei sul lato sbagliato
del premio). Perde gross, prima di ogni fee.
- A **rehedge orario** la RV *supera* l'IV (BTC +3.6pp, ETH +6.1pp gross) — sembrerebbe un edge…
**ma è una trappola doppia:** (a) la RV_1h è gonfiata da microstruttura (bid-ask bounce), quindi
il "gross edge" è in parte fittizio; (b) il rehedge orario paga **24× la fee di hedge**, che
spazza via qualunque edge intraday reale.
## I numeri (ogni variante, ogni anno, ogni frequenza: PERDE)
| variante | rehedge | Sharpe | CAGR | per-anno |
|---|---|---|---|---|
| NAKED | 1d | **−3.99** | −56% | 2021..2026 tutti −25..−68% |
| CHEAP-GATED (IVr<0.30) | 1d | −3.05 | −47% | tutti negativi |
| RICH-SKIP (IVr>0.90) | 1d | −3.92 | −55% | tutti negativi |
| NAKED | 1h | **−6.06** | −71% | tutti −38..−81% (peggio: le fee) |
| CHEAP-GATED (IVr<0.30) | 1h | −4.96 | −64% | tutti negativi |
Il gate "compra vol solo quando è a sconto" (lo specchio del gate vincente del VRP, *vendi vol solo
quando è cara*) **migliora ma non salva**: −3.05 invece di −3.99. Il segno resta negativo perché
l'IV-rank basso non garantisce RV > IV su 7 giorni.
## Scoring marginale vs TP01
Tutte le varianti: **DILUTES**, `is_hedge=False`, `has_insample_edge=False` (IS Sharpe −3..−4.5),
blend-25 uplift hold −1.2/−1.5. Non aiuta nemmeno come hedge: perde sia quando TP01 è su
(uplift −1.2..−1.6) sia quando TP01 è giù (uplift −2.5..−3.2). Corr a TP01 ≈ 0 ma il drift negativo
domina la matematica di diversificazione.
## Eseguibilità a ~$600 (muro indipendente)
- **BTC**: contratto 1 BTC, min 0.1 BTC → notional minimo **$5.968** ≫ $600 → **NON eseguibile**.
- **ETH**: min 0.1 ETH → **$157** → marginalmente OK, ma un solo straddle = ~25% del conto in premio.
Anche se l'edge esistesse, BTC è fuori e ETH è troppo grosso per diversificare.
## Conclusione
Lo "scalping con copertura in opzioni" è **schiacciato tra due muri**: rehedge lento → paghi il
premio (RV < IV); rehedge veloce → paghi le fee (24×/day). **Nessuna frequenza vince.** Conferma
due lezioni di prim'ordine del progetto, ora quantificate sul long-vol:
1. **Le fee uccidono lo scalping** (il rehedge orario, vera frequenza di scalping, è la variante
*peggiore*: −6 Sharpe).
2. **Vol-da-modello è fragile in entrambe le direzioni.** Regola gemella del VRP: *niente long-vol
scalp da modello in deploy*.
**Il VRP01 (lato short, gated, rischio-definito) resta l'unico edge opzioni del progetto** —
e funziona proprio perché sta sul lato *giusto* dello stesso premio che il gamma scalp paga.
SCARTATO. Script preservato come riferimento. Nessun impatto sul book live (branch separato).
@@ -0,0 +1,66 @@
# 2026-06-26 — TP01 × DVOL vol-targeting: NON migliora (il taglio di DD è solo de-levering)
**Goal utente:** "continua" ad analizzare strategie. Dopo i tre angoli di diversificazione tutti
STAT-MODE (gamma scalp scartato, funding cross-sectional già morto, cash-and-carry lead non
deployabile), ho puntato sull'angolo a **più alto valore perché ESEGUIBILE**: migliorare il
risk-sizing del book **live** TP01 (BTC/ETH perp Deribit, già armato). Branch
`research/gamma-scalp-options`, script `scripts/research/tp01_dvol_overlay.py`.
## Ipotesi
TP01 vol-targeta sulla vol **realizzata** 30g (backward-looking). Il **DVOL** (vol implicita 30g
Deribit, forward-looking, che spesso anticipa i salti di vol) come denominatore → de-risking più
tempestivo prima dei crash → DD più basso / hold-out migliore senza affondare il FULL.
Onestà: DVOL parte 2021-03 → confronto TUTTE le varianti sulla **finestra comune 2021-04 → 2026**
(1891g, perdo il toro 2019-2020 pre-DVOL). Causale, fee 0.10% RT, config canonica TP01.
## Risultati (finestra comune, hold-out 2025+)
| variante (denominatore vol) | FULL Sh | FULL DD | CAGR | HOLD Sh |
|---|---|---|---|---|
| **realized** (baseline) | **+0.75** | 12.3% | +8% | +0.30 |
| dvol (implicita) | +0.70 | 9.3% | +6% | +0.33 |
| blend 50/50 | +0.72 | 10.4% | +7% | +0.32 |
| max(realiz, dvol) | +0.70 | 9.2% | +6% | +0.36 |
| derisk (gate DVOL>p90 ×0.5) | +0.75 | 12.3% | +8% | +0.30 |
Le varianti DVOL **abbassano il DD** (12.3% → ~9.2%) ma **anche** Sharpe FULL (−0.04/−0.05) e CAGR
(8% → 6%). Lo Sharpe è scale-invariant → sospetto: il taglio di DD è solo *posizioni più piccole*
(l'IV > RV per il VRP → denominatore più grande → leva minore), non vero timing.
## Il controllo decisivo
Confronto le varianti DVOL col **realized a target_vol RIDOTTO** (stesso de-levering, senza DVOL):
| | FULL Sh | DD | CAGR | HOLD Sh |
|---|---|---|---|---|
| **max-DVOL** | +0.70 | 9.2% | +6% | +0.36 |
| **realized @ vol-tgt 15%** | **+0.75** | 9.4% | +6% | +0.30 |
| **realized @ vol-tgt 13%** | +0.75 | **8.1%** | +5% | +0.30 |
**Conclusivo:** il realized a 15% eguaglia il DD del max-DVOL (9.4% ≈ 9.2%) a Sharpe **più alto**
(0.75 > 0.70) e stesso CAGR; a 13% fa DD ancora più basso (8.1%), sempre a 0.75. **Il taglio di DD
del DVOL è interamente "leva minore", replicabile MEGLIO con un semplice target_vol più basso.**
## Verdetto
**DVOL vol-targeting NON migliora TP01.** Risk-adjusted è marginalmente *peggiore* (FULL 0.70 vs
0.75 a parità di DD). L'unico residuo a favore — hold-out +0.06 (max 0.36 vs 0.30) — è **single-window**
su 5 anni scarsi di storia DVOL: sotto la soglia di **persistenza multi-cut** del progetto (la lezione
che ha ucciso 13/14 falsi positivi nello sweep alt). Il gate **DVOL-spike de-risk è RIDONDANTE col
trend**: quando il DVOL esplode (crash) TP01 è già flat (momentum negativo → posizione 0) → il gate
non tocca nulla (Δ 0.00 su tutto). Niente da deployare.
## Lezioni
1. **Per meno DD sul book live, la leva giusta è `target_vol`, non un overlay DVOL.** Abbassare TP01
da vol-tgt 20% → 15% taglia il DD 12.3% → ~9.4% allo **stesso Sharpe** (0.75). Dial pulito e noto,
se mai si volesse un profilo più difensivo (oggi 20% è la scelta canonica — invariata).
2. **La vol implicita non batte la realizzata come denominatore di sizing per un trend long-flat**:
il segnale di trend gestisce già il de-risking direzionale; il denominatore fissa solo la
magnitudine, e la realizzata lo fa marginalmente meglio per unità di rischio.
3. Conferma indiretta del soffitto: anche un raffinamento "ovvio" e *eseguibile* su TP01 non produce
alpha; al massimo sposta il punto sulla stessa frontiera rischio/rendimento.
SCARTATO come miglioria. Nessun impatto sul book live (branch separato, config canonica invariata).
@@ -0,0 +1,47 @@
# 2026-06-26 — Calendar-vol / term-structure DVOL: il DATO STORICO NON ESISTE (data-first gate)
**Goal utente:** "continua" — angolo scelto: scaricare e certificare la term-structure DVOL per
testare un calendar-vol (front IV vs back IV). **Esito: bloccato a monte dal gate "il dato prima
della strategia" (lezione v2.0.0).** Branch `research/gamma-scalp-options`.
Script: `scripts/research/probe_vol_termstructure.py` (scan) + `log_vol_termstructure.py` (forward).
## Scan di fattibilità (prima di costruire qualunque backtest)
Cosa l'API pubblica Deribit espone davvero per la vol per-scadenza:
| dato | disponibile? |
|---|---|
| Snapshot CORRENTE della term-structure ATM (mark_iv per scadenza) | **SÌ** (book_summary_by_currency, tokenless) |
| DVOL storico | solo **30g** fisso — nessun indice 7g/60g/90g pubblico |
| Trade-history IV per strumento | solo per strumenti **VIVI** (gli scaduti spariscono) |
| **Serie storica continua front-vs-back IV** | **NO** — il front-month rotola/espira → irricostruibile |
**Snapshot oggi (2026-06-26), per riferimento:**
- BTC spot $59.9k: 7g 45.6% · 30g 43.2% · 60g 42.7% · 90g 42.9% · 180g 44.5% — **contango** lieve.
- ETH spot $1.58k: 7g 57.6% · 30g 56.4% · 90g 57.5% · 180g 59.2% — contango (+1.6pp slope).
- (I valori sono interpolati a tenor fissi: il front a 1-giorno grezzo, 38%/54%, è rumore escluso.)
## Verdetto
**Un calendar-vol NON è backtestabile ora su dati certificati.** La storia per-scadenza non è
pubblica su Deribit (la nostra fonte di verità), e — coerentemente con la metodologia — **nessun
edge va creduto senza backtest OOS su dati certificati**. Costruire un calendar-vol su uno snapshot
singolo o su una storia ricostruita-a-pezzi sarebbe esattamente il tipo di scorciatoia che ha
prodotto la libreria fasulla v2.0.0. Quindi: **stop, niente backtest.**
## L'unica via legittima: costruire il dato in avanti
`scripts/research/log_vol_termstructure.py` — logger forward idempotente: ogni run prende lo snapshot
ATM, lo interpola ai tenor fissi {7,30,60,90,180}g e appende una riga/asset a
`data/raw/vol_term_<asset>.parquet`. Seminate le prime righe BTC/ETH oggi. Test offline
`tests/test_vol_termstructure.py` (interpolazione pura).
**Non auto-cablato in cron** (è ricerca forward, e non tocco il cron live senza ok). Per accumulare:
aggiungere una riga giornaliera al crontab. Dopo **~6-12 mesi** → certificare (monotonia, spike,
cross-venue) e SOLO ALLORA testare front-vs-back. Prima, nulla.
## Lezione
Il data-first gate ha funzionato: ha fermato un backtest su un dato che non esiste, invece di
produrre un numero non falsificabile. La term-structure è in **contango** oggi (regime calmo) —
osservazione da forward-monitor, non un edge. Nessun impatto sul book live (branch separato).
+118
View File
@@ -0,0 +1,118 @@
# 2026-06-29 — DVOL come segnale DIREZIONALE/REGIME su BTC/ETH: l'unico edge è un HEDGE, non alpha
**Filone A — "DVOL-direzionale".** Tesi: usare la vol IMPLICITA Deribit (DVOL, `data/raw/dvol_*.parquet`,
2021-03→oggi) come **segnale direzionale o di regime** sul perp BTC/ETH (long-flat o L/S sul LIVELLO di
mercato), non come denominatore del vol-target. Script `scripts/research/dvol_directional.py`, test
`tests/test_dvol_directional.py`. Branch `research/equity-meanrev-ib` (separato, nessun impatto live).
## Cosa è diverso dal lavoro DVOL precedente
- `tp01_dvol_overlay.py` (2026-06-26): DVOL come **denominatore** del vol-target → solo de-levering, SCARTATO.
- VOL03/04/10/11 (sweep alt 100-agent): DVOL che **gata/scala un TSMOM** → eredita lo Sharpe di trend di
TP01 (il marginal scorer li boccia NEUTRAL/REDUNDANT).
- `agent_14_dvol_spread` (onda ortho): IV **relativa BTC-vs-ETH**, market-NEUTRAL 2-leg (l'unico LEAD vivo).
Qui invece: DVOL/IV-RV come segnale **direzionale STANDALONE sul livello di mercato**, per vedere se porta
alpha direzionale **ortogonale** a TP01 (non un overlay sul trend). Tutto causale (decisione ≤ `close[i]`,
tenuta in `i+1` dallo shift di `eval_weights`), fee 0.10% RT, vol-target 20%, leva cap 2x, harness onesto
condiviso `altlib`. Allineamento DVOL: `al.dvol` (merge_asof backward) → DVOL close del giorno *t* (≈
contemporaneo a `close[i]`), noto a decisione; verificato leak-free (`causality_ok` max_tail_diff 0.0).
DVOL parte 2021-03 → pre-DVOL il segnale è flat. Valuto sia **FULL** (col flat pre-2021, deflaziona lo
Sharpe) sia **ERA-only** (da 2021-10, equo per la tesi).
## 1) Probe direzionale (corr segnale[i] vs ritorno[i+1], pooled BTC+ETH, era DVOL)
| segnale | corr | long bps | flat bps | **edge bps** | frac_long |
|---|---|---|---|---|---|
| VRP-Z+ (long VRP ricco, IV-RV alto) | +0.010 | +7.8 | −0.9 | **+8.6** | 0.52 |
| VRP-Z− (flip) | −0.017 | −0.9 | +7.8 | −8.6 | 0.48 |
| **DVOL-LV fear (rank>0.5 → long)** | **+0.024** | +20.4 | +0.9 | **+19.5** | 0.14 |
| DVOL-LV calm (rank<0.5 → long) | −0.013 | +0.8 | +21.2 | −20.4 | 0.86 |
| DVOL-MOM (DVOL in calo → long) | −0.041 | −10.0 | +22.9 | **−32.9** | 0.59 |
| VRP>0 (quasi buy&hold) | +0.003 | +5.3 | −0.7 | +5.9 | 0.72 |
Lettura: l'unico contenuto direzionale reale è **"buy-the-fear"** (long quando il DVOL è alto nel suo
percentile espandente: edge +19.5 bps il giorno dopo). Il VRP-ricco→long è coerente ma debolissimo (+8.6).
Il "DVOL in calo → long" è **negativo** (−33 bps): comprare quando la paura scende è perdente (regola
falsificata). Nota: il percentile espandente è dominato dai picchi 2021-22 → "fear" scatta solo nel 14%
delle barre (gli spike veri), non metà del tempo.
## 2) Robustezza assoluta (study_weights 1d, fee sweep 0.00-0.20% RT) — ERA-only il giudizio equo
| segnale | abs | minFull Sh | minHold Sh | feeOK | **ERA Sh** | ERA DD | ERA CAGR |
|---|---|---|---|---|---|---|---|
| **DVOL-fear q0.4 LF** | WEAK | +0.39 | +0.14 | sì | **+0.59** | **8%** | +5% |
| VRP-Z60 LF | FAIL | +0.42 | −0.39 | sì | +0.46 | 23% | +7% |
| DVOL-fear q0.5 LF | FAIL | +0.31 | −0.17 | sì | +0.40 | 10% | +3% |
| VRP-Z90 LF | FAIL | +0.32 | −0.26 | sì | +0.32 | 29% | +4% |
| VRP-Z90 L/S | FAIL | +0.25 | +0.32 | sì | +0.31 | 28% | +3% |
| DVOL-calm q0.5 LF | FAIL | +0.00 | −1.05 | no | +0.09 | 37% | −0% |
| DVOL-MOM k10/k20 LF | FAIL | −0.6/−0.7 | <−1 | no | −0.6/−0.7 | ~40% | ~−10% |
| DVOL-MOM k10 L/S | FAIL | −1.16 | −1.29 | no | −1.23 | 72% | −23% |
Nessun segnale supera lo Sharpe assoluto in **valore** (tutti < 0.6, soffitto direzionale BTC/ETH ~1.3
confermato). Unico con profilo decente: **DVOL-fear q0.4 long-flat** (ERA Sh +0.59, DD **8%**) — il DD
bassissimo perché è long solo nei picchi di paura (poche barre, mean-reversion). Le famiglie momentum e
"buy-the-calm" sono nettamente negative e non sopravvivono nemmeno alle fee.
## 3) Marginal vs TP01 (il gate vero) — DVOL-fear q0.4 long-flat
| | corr→TP01 | in-sample Sh | uplift_full w25 | uplift_hold w25 | multi-cut persistente | is_hedge | verdetto |
|---|---|---|---|---|---|---|---|
| **ERA-only** (2021-10+) | 0.37 | 0.54 (has_edge) | +0.06 | +0.17 | sì | **No** | **ADDS** (earns_slot=True) |
| **FULL** (gate ufficiale) | 0.28 | 0.64 (has_edge) | +0.03 | +0.17 | sì | **Sì** | **HEDGE** (earns_slot=**False**) |
Il candidato ha tutto ciò che serve a un nuovo sleeve **tranne una cosa**: il gate canonico full-history
lo classifica **HEDGE**, non alpha. `hedge_yearly_corr(TP01-Sh, uplift) = −0.76`, `uplift TP01-up −0.003`
/ `uplift TP01-down +0.194` → **paga SOLO quando TP01 è debole**. Ha perfettamente senso: il DVOL esplode
durante i crash, proprio quando il trend di TP01 è flat/in-drawdown; comprare la paura cattura il rimbalzo
e smorza il DD del portafoglio, ma **non è un premio permanente**. Il blend 0.75·TP01 + 0.25·cand alza
l'hold-out 0.30→**0.47** (w50 → 0.62) e taglia il DD a ~11%/8% — un effetto **drawdown-dampener** reale,
ma classificato (giustamente) come hedge.
Perché ERA dice ADDS e FULL dice HEDGE: il rivelatore di hedge richiede ≥3 anni; sulla finestra ERA
(2021-10+) la `corr(TP01-Sh annuale, uplift)` è meno netta e non scatta. **Il gate full-history è quello
giusto** (più dati per il test di hedge) → mi attengo a quello: **HEDGE, non alpha.**
Gli altri tre candidati (VRP-Z60/90, DVOL-fear q0.5): **NEUTRAL o HEDGE**, mai ADDS. I VRP-Z hanno beta a
TP01 alto (0.88-0.90) → sono trend-correlati travestiti (resid Sharpe ~0), uplift hold-out negativo.
## 4) Causalità, alignment, eseguibilità, sign-falsification
- **Causale**: `causality_ok` ok=True, max_tail_diff **0.0** su tutti i candidati (rank espandente +
z-score ricalcolati su prefisso = identici → nessun future-peeking). Test dedicato `test_expanding_rank_is_causal`.
- **Alignment DVOL**: laggando il segnale di +1 giorno (extra-conservativo, usa solo DVOL di ieri) l'ERA
Sharpe del leader scende +0.59 → **+0.45**. L'edge sopravvive ma è **sensibile all'allineamento**
(parte del vantaggio è nel reagire allo spike DVOL del giorno stesso) → cautela in esecuzione.
- **Eseguibile a $600**: `eval_weights_smallcap` (min_order $5, cap $300/asset): haircut Sharpe **≈ 0.00**
su BTC ed ETH (segnale long-flat a basso turnover, ~210-270 trade su tutta la storia) → lo Sharpe netto
onesto a $600 = quello modellato. È l'unico aspetto pienamente promosso.
- **Sign-falsification**: tesi buy-the-fear ERA Sh +0.40 vs flip buy-the-calm +0.09; VRP-Z+ +0.32 vs
VRP-Z− (flip) −0.14. Il segno della tesi è quello giusto (l'edge è reale, non rumore simmetrico).
## Verdetto onesto: **LEAD (hedge / drawdown-dampener), NON sleeve.** SCARTATO come alpha direzionale.
- Nessun segnale DVOL-direzionale ha Sharpe assoluto sopra ~0.6 → **conferma il soffitto BTC/ETH
direzionale ~1.3** (la via per superarlo resta il cross-sectional XS01, non un nuovo segnale a 2 asset).
- L'unico con edge in-sample reale + eseguibile + leak-free è **DVOL-fear "buy-the-fear" long-flat**, ma il
gate canonico lo bolla **HEDGE** (`is_hedge=True`, paga solo quando TP01 è in difficoltà). Per la regola
del progetto un hedge **non si arma come slot di alpha** → **earns_slot=False**.
- È comunque un **LEAD utile in forward-monitor** come **smorzatore di drawdown** del portafoglio: il blend
porta l'hold-out 0.30→0.47/0.62 e abbassa il DD. Se in futuro si vorrà esplicitamente un tail/DD-hedge
*eseguibile* (a differenza del tail-hedge in opzioni, non eseguibile a $600), questo è il candidato più
pulito visto finora — ma da prezzare **come hedge**, non come ritorno atteso permanente.
## Caveat
1. **Storia DVOL <5 anni** (2021-03→oggi, ~4.7 anni; era valutata 2021-10+) → multiple-testing e
finestra corta. Il multi-cut 2026 è un assurdo +1.944 (manciata di giorni, picco DVOL recente):
l'uplift hold-out è trascinato dal regime 2025-26 ad alta-paura, non da un edge stazionario.
2. **È un hedge, non alpha**: il valore è condizionato ai drawdown di TP01 (2022, ed eventuali futuri).
In un toro lungo a bassa vol il segnale resta **flat l'86% del tempo** e non contribuisce nulla.
3. **Sensibile all'allineamento** DVOL (haircut −0.14 Sharpe col lag +1g): l'esecuzione reale dovrebbe
usare il DVOL già stampato a decisione, non assumere il close contemporaneo.
4. Long-flat → cattura il rimbalzo post-paura ma **non protegge** durante la discesa (non è uno short):
è "buy-the-dip gated by fear", con tutti i rischi del comprare coltelli che cadono se il regime peggiora.
Nessun impatto sul book live (branch separato, nessuno sleeve registrato, config canonica invariata).
+145
View File
@@ -0,0 +1,145 @@
# 2026-06-29 — Filone B: INTRADAY REGIME BTC/ETH — ERM (efficiency-ratio) è un LEAD reale, forward-monitor
**Tesi.** Cercare un meccanismo **sub-daily** sui dati certificati 1h→12h BTC/ETH che sia ortogonale
**sia** a TP01 (TSMOM trend daily, long-flat) **sia** a SKH01 (regime BuzVola/BuzVolume + Donchian a
230m). SKH01 prova che il sub-daily PUÒ funzionare ed essere quasi-ortogonale: qui un MECCANISMO DIVERSO,
basato sulla **qualità del moto intraday** (efficiency-ratio / vol-expansion / thrust) come **regime** che
condiziona una posizione direzionale tenuta ~1 giorno. Script `scripts/research/intraday_regime.py`, test
`tests/test_intraday_regime.py`. Branch `research/equity-meanrev-ib` (separato, nessun impatto live).
Killer ricorrente del progetto sotto le 12h = **muro-fee 0.10% RT + overfitting**. Ricetta SKH01:
decisione sub-daily ma **hold ~1 giorno** → pochi trade → la fee non uccide. Ogni meccanismo qui è
costruito a basso turnover e giudicato col **fee-sweep alla sua frequenza reale**.
## Meccanismi provati (tutti come posizione CONTINUA decisa ≤ `close[i]`, causali)
| | meccanismo |
|---|---|
| **ERM** | **Efficiency-Ratio regime momentum** (Kaufman): ER = \|moto netto su L barre\| / \|percorso\|. Prendi la direzione del moto netto **solo quando ER ≥ soglia** (regime intraday "pulito"/trendy), altrimenti flat |
| VEM | Vol-Expansion Momentum: direzione = segno del moto, attiva solo quando vol-corta > vol-lunga |
| VBR | Volatility/thrust breakout (Larry-Williams ROLLING, no calendario): segui i moti > k·ATR |
| TOD | Time-of-day seasonality — **CONTROLLO calendario**, incluso APPOSTA per `day_boundary_robust` |
## Selezione + fee-sweep a frequenza reale (vincitori per famiglia, min-asset)
```
ERM: 8h L=2.0 thr=0.35 L/S minFull +0.88 minHold +0.99 f@.20 +0.55 feeOK=True turn/y 125
VEM: 12h Lmom=3 Ls=2 Ll=10 minFull +0.72 minHold -0.29 f@.20 +0.51 feeOK=True (hold<0 → out)
VBR: 12h k=1.0 atr=14 L/S minFull +0.33 minHold +1.20 f@.20 +0.25 feeOK=True
TOD: 1h minFull -3.99 minHold -4.49 feeOK=False (controllo → FAIL atteso)
```
Solo **ERM** e **VBR** sopravvivono al gate fee+OOS. VEM ha hold-out negativo. TOD esplode (vedi sotto).
## Il candidato: ERM 8h L=2.0 thr=0.35 (L/S) — `earns_slot=True`
```
abs=PASS marginal=ADDS EARNS_SLOT=True
standalone: cand FULL 0.919 / HOLD 1.105 (TP01 ref FULL 1.297 / HOLD 0.303)
corr->TP01 full 0.146 hold 0.057 beta 0.197 resid Sharpe 0.738 alpha/yr 0.121
robust_oos=True (clean-year +0.103, drop-best-month +0.283)
multi-cut persistence: 2020 .166 / 2021 .167 / 2022 .298 / 2023 .337 / 2024 .418 / 2025 .497 / 2026 2.861 persistent=True
has_insample_edge=True (standalone PRE-holdout Sharpe 0.874, > null-pctl 0.317)
is_hedge=False (yearly corr(TP01-Sh, uplift) -0.762; paga sia TP01-up 0.139 sia TP01-down 0.384)
blend w25: FULL 1.481 (+0.184) HOLD 0.80 (+0.497) DD 11.0%
corr con SKH01: full 0.278 hold 0.291
day_boundary=INVARIANT (spread 0.0) haircut $600 ≈ 0.00 su BTC/ETH
```
È il **primo sub-daily da SKH01** a passare TUTTI i gate del marginal scorer indurito: edge in-sample
reale (non diversification-math), persistenza multi-cut, robust_oos, NON hedge, scorrelato a TP01 (0.15).
### ERM aggiunge OLTRE SKH01? (gate #5 — il book esistente ne ha già uno sub-daily)
| blend | FULL Sh | FULL DD | HOLD Sh | HOLD DD |
|---|---|---|---|---|
| TP01 | +1.30 | 14.3% | +0.30 | 7.5% |
| TP01+SKH 75/25 | +1.78 | 9.4% | +1.17 | 6.2% |
| **TP01+SKH+ERM 60/25/15** | **+1.88** | 8.9% | **+1.46** | 5.3% |
| TP01+SKH+ERM 55/20/25 | +1.84 | 8.8% | +1.48 | 5.1% |
Sì: corr con SKH01 solo 0.28 → ERM **aggiunge oltre SKH** (FULL +0.10, HOLD +0.29 a peso 15%, DD ancora
giù). Non è SKH01 travestito.
## Il controllo TOD (calendario) — fa esattamente ciò che doveva
`TOD` (direzione per ora-del-giorno, media espandente causale) è incluso come **trappola**: è il tipo di
effetto che uccise `open_drive` (artefatto di etichettatura UTC). Esito: **FAIL** (FULL −3.99, 31.811
trade, fee-killed), marginal=DILUTES. `day_boundary_robust=INVARIANT` → l'effetto è **robustamente
negativo** a ogni offset (non un artefatto di confine giorno: è proprio che la time-of-day-direzionale non
ha edge e sanguina fee). Il controllo conferma che l'harness non si fa ingannare e che il segno
dei segnali di prezzo (ERM/VBR) è reale, non rumore di calendario.
## Causalità / eseguibilità
- **Leak-free**: `causality_ok=True`, max_tail_diff **0.0** su tutti i candidati (ER, rank espandente,
medie su prefisso = identiche → nessun future-peeking). Test dedicato in `test_intraday_regime.py`.
- **day_boundary_robust=INVARIANT** (spread 0.0) per ERM/VBR/TOD: segnali di prezzo, non di calendario.
- **Eseguibile a $600**: `eval_weights_smallcap` haircut **≈ 0.00** su BTC ed ETH. **MA** ERM a 8h fa
~3.158 trade BTC / ~2.823 ETH su tutta la storia (turnover 125/anno): haircut nullo nel modello, ma
l'esecuzione reale sub-daily sul book è operativamente più pesante di un segnale 1d (slippage/spread
intraday non interamente catturati dalla fee proporzionale).
## Caveat (perché LEAD, non sleeve)
1. **Plateau hold-out a UNA SOLA RIGA.** Il FULL è robusto su tutta la griglia L∈[2.0,3.0] (+0.6..+1.0),
ma l'**hold-out è positivo SOLO a L=2.0** (a L=2.5/3.0 crolla a −0.5..−0.8). Il plateau sul full è
ampio, quello che conta — l'hold-out — è single-row. Da rinforzare prima di credere alla stazionarietà.
2. **Standalone FULL 0.92 < soffitto ~1.3.** Coerente col soffitto direzionale BTC/ETH: il valore di ERM
è **marginale/diversificante** (corr 0.15 a TP01, 0.28 a SKH01), non assoluto. Non rompe il soffitto.
3. **Multiple-testing non deflazionato.** 102 celle testate (60 ERM + 16 VEM + 24 VBR + 2 TOD) senza
deflated-Sharpe (a differenza del filone C). Il multi-cut 2026 = +2.861 è una manciata di giorni che
gonfia. Storia sub-daily certificata utile ~quanto SKH01 → finestra non lunghissima.
4. **Esecuzione 8h** = complessità operativa reale (vedi sopra), oltre il modello a haircut nullo.
## Analisi di robustezza / de-bias (`intraday_regime_analysis.py`) — il lead NON regge
I caveat #1 (plateau hold-out single-row) e #3 (multiple-testing) erano i sospetti giusti. Tre test di
de-bias li trasformano da sospetto in **bocciatura** dello slot:
| test | esito |
|---|---|
| **A) Deflated-Sharpe** (Bailey & Lopez de Prado) su 122 trial cercati | **FAIL.** DSR 0.000 (tutti) / **0.163 (escludendo i trap TOD)** / 0.241 (solo-ERM) — tutti ≪ 0.95. Lo Sharpe winner (0.92) è sotto lo Sharpe-max-atteso-null (1.16–2.51): il search ha trovato celle a 1.6 full / 1.7 in-sample, il winner 0.92 **non è eccezionale**. |
| **B) Selezione IN-SAMPLE-only** (scelgo la cella ERM col solo Sharpe < 2025) | **earns_slot=False.** La cella migliore pre-hold-out è un'**ALTRA** (8h L=2.0 thr=0.4 **long-flat**), con corr→TP01 **0.53** (è trend-beta travestito) → marginal=**NEUTRAL**. Il winner max-hold **non si seleziona senza guardare l'hold-out** → il suo `earns_slot=True` era **selezione-sull'hold-out**. |
| **C) Ensemble del plateau** (media 20 celle L×thr, niente cherry-pick) | **earns_slot=False.** marginal=ADDS, in-sample Sh 1.01, corr→TP01 0.18 — ma **`robust_oos=False`** (clean-year + jackknife): l'uplift hold-out è trascinato dal **2026 (+2.09 multicut)**, manciata di giorni. |
**Dove vive l'(eventuale) edge** (per-anno, blend 3-way 60/25/15 vs 2-way 75/25): uplift FULL solo **+0.10**,
**negativo nel 2021 (−0.23) e 2022 (−0.15)**, positivo altrove; l'uplift HOLD **+0.30 è concentrato nel
2026 (+0.46)**. corr(ERM,SKH) 0.28 full (fino a 0.42 in alcuni anni) → **parziale sovrapposizione con SKH**,
non ortogonalità piena.
**Lettura.** Il segnale efficiency-ratio non è rumore puro (l'ensemble ha in-sample Sh ~1.0, positivo nella
maggior parte degli anni), ma come **slot** fallisce ogni de-bias: il `earns_slot=True` della scoperta era
prodotto da **(1) selezione della cella sull'hold-out** + **(2) coda 2026** + **(3) multiple-testing non
corretto**. È lo stesso falso-positivo che l'alt-sweep 100-agent imparò a uccidere — qui ucciso dai gate.
## Caveat originari (ora risolti dall'analisi sopra)
1. ~~Plateau hold-out single-row~~ → **confermato fatale**: l'edge hold-out a L=2.0 è cell-selection.
2. ~~Multiple-testing non deflazionato~~ → **deflazionato: DSR FAIL** anche senza i trap.
3. Esecuzione 8h: irrilevante ormai (lo slot non c'è).
## Verdetto onesto: **NON è uno slot. Falso positivo da selezione-hold-out + coda 2026.** SCARTATO come sleeve.
Lo "earns_slot=True" della scoperta **non sopravvive** alla de-selezione: deflated-Sharpe FAIL (anche
escludendo i controlli), selezione in-sample-only → NEUTRAL su un'altra cella (trend-beta corr 0.53),
ensemble del plateau → robust_oos FAIL. **Conferma ennesima del soffitto direzionale BTC/ETH ~1.3**: un
segnale a 2 asset non lo supera; la via resta il cross-sectional (XS01). Resta al più una **curiosità in
forward-monitor** (l'efficiency-ratio ha un debole edge in-sample reale), ma da non armare come alpha.
Gli altri tre meccanismi: VBR=NOISE, VEM hold-out<0, TOD=controllo FAIL come atteso.
**Lezione harness (CODIFICATA).** Lo script di scoperta selezionava il vincitore per `min_hold` massimo
sulla griglia = **selezione-sull'hold-out**, il punto cieco che ha generato il falso PASS. Il marginal
scorer da solo non basta se la *cella* è scelta guardando l'hold-out: serve **(a)** scegliere la cella
in-sample-only (o walk-forward) **prima** di valutare il marginal, e **(b)** deflazionare per il numero di
celle/famiglie testate. Stesso buco segnalato per CC01 ("Sharpe implausibile") e per l'alt-sweep
(hold-out-fitting): qui in forma "selection-on-holdout". Ora è **codice** in `altlib` (LESSON 4): tre
funzioni nuove — `deflated_sharpe()` (Bailey & Lopez de Prado), `select_cell_insample()` (scelta cella
col solo Sharpe pre-HOLDOUT), e il gate combinato **`study_family_honest()`** (`earns_slot_honest =
earns_slot[cella in-sample] AND deflated-Sharpe≥0.95`). Verificato: su ERM il gate ritorna
`earns_slot_honest=False` (cella in-sample = trend-beta NEUTRAL, DSR 0.74). Analisi completa in
`scripts/research/intraday_regime_analysis.py`; test in `tests/test_harness_realism.py`.
**Regola nuova: una strategia direzionale grid-searched si giudica con `study_family_honest`, non
chiamando `study_marginal` sulla cella a max hold-out.**
Nessun impatto sul book live (branch separato, config canonica invariata).
@@ -0,0 +1,71 @@
# 2026-06-29 — Filone D: MACRO regime-gate sul book crypto — RIDONDANTE col trend, SCARTATO
**Tesi.** Usare segnali macro/cross-market — equity (SPY/QQQ/IWM), credito (HYG/LQD), oro (GLD/SLV),
tassi (TLT/IEF) — come **gate risk-on/risk-off** sul book BTC/ETH, per migliorare il *timing* del
drawdown di TP01: regime risk-off (credito che cede, equity sotto trend, fuga sui bond) → riduci/azzera
l'esposizione crypto; risk-on → lascia agire TP01. **È eseguibile** (gata solo BTC/ETH perp, non aggiunge
gambe). Script `scripts/research/macro_regime_gate.py`, test `tests/test_macro_regime_gate.py`. Branch
`research/equity-meanrev-ib` (separato, nessun impatto live). Dati: `data/raw/eq_*_1d.parquet` (ETF daily,
allineati causale `merge_asof backward` sul calendario SPY).
**NON è un lead-lag direzionale** (già morto: diari 2026-06-22/-23). L'angolo nuovo = un overlay
binario/continuo di **de-risk** sul book esistente.
## Il rischio noto in partenza (CLAUDE.md)
La lezione DVOL-spike (2026-06-26): un gate di de-risk rischia di essere **ridondante col trend** — TP01
è già long-flat e va a 0 nei crash (Δ 0.00). Questo script DOVEVA dimostrare che il gate aggiunge **oltre**
quel che TP01 fa da solo. **Non ci riesce.**
## Gate provati (tutti causali: SMA/ratio/z-score rolling, merge_asof backward)
`SPY>MA{50,100,150,200,250}`, `HYG>MA`, ratio di credito `HYG/LQD`, `HYG/IEF`, combo a maggioranza
(SPY+HYG+HYG/LQD, binario e continuo), flight-to-quality (`TLTup&SPYdn`, `GLDup&SPYdn`), regime di vol
equity `SPYvol_z1` (proxy "VIX-spike" senza VIX). g_off ∈ {0.0, 0.5}.
## Esiti
I gate di trend equity alzano lo Sharpe FULL della combo (SPY>MA150/200/250 → FULL ~1.22-1.25 vs TP01-solo
1.30) ma **non l'hold-out** (HOLD ~0.17-0.19) → è **de-levering**, non timing: tagliano DD spegnendo il
book in mercati equity laterali, non anticipando i crash crypto. Il miglior profilo DD è `SPYvol_z1`.
### Deep-dive `SPYvol_z1` — il controllo decisivo (ridondanza col trend)
| | exposure TP01 risk-off | exposure risk-on | giorni risk-off | **giorni in cui il gate LAVORA** | corr(1-gate, 1-expo) |
|---|---|---|---|---|---|
| BTC | 0.023 | 0.093 | 18% | **3%** | 0.278 |
| ETH | 0.013 | 0.068 | 16% | **2%** | 0.296 |
"Il gate lavora" = giorno risk-off **E** posizione TP01 non già flat. Accade nel **2-3% dei giorni**: nel
resto, quando il gate vorrebbe de-riskare, TP01 è **già flat da solo**. Il gate spegne un motore già spento.
### Marginal scorer vs TP01 (gate come candidato-sleeve)
```
abs=FAIL marginal=REDUNDANT EARNS_SLOT=False
corr->TP01 full 0.989 hold 0.984 beta 0.978 resid Sharpe 0.739
multi-cut persistent=True has_insample_edge=True (standalone 1.634) is_hedge=False
blend w25: full 1.323 (+0.026) hold 0.257 (-0.046) blend w50: full 1.348 (+0.051) hold 0.21 (-0.093)
```
corr→TP01 **0.989**, beta 0.98: lo stream gated **È** TP01. L'uplift hold-out è **negativo** (de-levering
che toglie ritorno fuori dai crash). overlay-delta (gated−solo) come stream a sé: `verdict=NEUTRAL`.
## Causalità / eseguibilità (gli unici aspetti promossi)
- **Leak-free**: `causality_ok=True` (max_tail_diff 0.0); STRICT align (1 barra equity extra di lag) →
FULL invariato; `day_boundary_robust=INVARIANT` (spread 0.0). Allineamento macro→crypto backward-only.
- **Eseguibile a $600**: haircut `eval_weights_smallcap` ≈ **0.00** su BTC ed ETH. Fee-survivente
(0.00→0.30% RT: 1.42→1.33). Tecnicamente impeccabile — semplicemente **non aggiunge alpha**.
## Verdetto: **SCARTATO (ridondante col trend).** earns_slot=False.
Conferma esatta della lezione in CLAUDE.md: un overlay di de-risk su un book che è **già** long-flat e
già a 0 nei crash non ha quasi nulla da fare (lavora il 2-3% dei giorni, corr→TP01 0.99). Il taglio di DD
che mostra è **de-levering**, replicabile meglio con un `target_vol` più basso (stessa lezione del
TP01×DVOL overlay del 2026-06-26). Il macro-regime **non anticipa** i drawdown crypto meglio del prezzo
crypto stesso. Nessuno sleeve registrato; nessun impatto sul book live.
**Sottoprodotto utile:** il gate `redundancy_diag` (exposure risk-off vs risk-on + "quota giorni in cui il
gate lavora") è il test pulito da riusare ogni volta che si propone un overlay di de-risk — se "il gate
lavora" è basso e corr→TP01 ~1, è ridondante, a prescindere dallo Sharpe FULL che mostra.
@@ -0,0 +1,106 @@
# 2026-06-29 — Ricerca strategie a 5 thread paralleli: 0 nuovi sleeve, 1 LEAD che rompe 2 muri su 3
**Mandato.** "Cerca altre strategie" (+ "senza correlazioni, a segnale" + "a 1 gamba in/out a segnale").
Cinque ricerche parallele su aree genuinamente inesplorate, tutte sull'harness onesto condiviso
(`altlib` + `xsec_v2_nonmom`) con TUTTI i gate: causalità (prefix-check), netto fee 0.10% RT + sweep,
OOS hold-out 2025+, **deflated-Sharpe** (multiple-testing), **gate anti-selection-on-holdout**
(`study_family_honest`: cella scelta IN-SAMPLE-only), marginal vs TP01/XS01, corr vs book, haircut $600.
Branch `main`, **nessun impatto live** (solo file nuovi, nessuno sleeve registrato).
Premessa onesta (base-rate): il soffitto direzionale BTC/ETH ~1.3 è già confermato e lo sweep di 104
ipotesi (2026-06-20) non produsse nulla di nuovo che reggesse. L'attesa era "quasi tutto SCARTATO".
## Esiti per thread
| # | Thread | File | Verdetto |
|---|--------|------|----------|
| 1 | **XSEC low-risk cousins** (MAX/lottery, idio-vol, Amihud) | `xsec_v3_lowrisk.py` | 1 LEAD (IVOL), 0 sleeve |
| 2 | **XSEC momentum-structure** (risk-adj/accel/frog-in-pan/vol-managed vs XS01) | `xsec_v3_momstruct.py` | tutto REDUNDANT/SCARTATO |
| 3 | **Meta-allocazione** (allocazione dinamica tra i 4 sleeve) | `meta_allocation.py` | pesi fissi vincono |
| 4 | **Segnali ortogonali ETH/BTC** (relative-value dollar-neutral) | `orthogonal_signals.py` | 2 LEAD (STATARB, DVOLSPREAD) |
| 5 | **1-gamba a segnale** (MACD/RSI/Supertrend/Donchian/BBands/EMA) | `signal_inout_1leg.py` | 0/12 earns_slot |
**Netto: 0 nuovi sleeve.** Il soffitto regge. Test 143/143.
### Thread 1 — Low-risk cross-sectional (51 alt HL)
Tre fattori mai provati (il filone C aveva fatto total-vol e BAB, non questi). **IVOL** (idiosyncratic-vol
basso, 19-major B30 H5 k8): FULL 1.06 / HOLD **1.22** / corr ~0 a XS01 e TP01 / positivo ogni anno /
uplift portafoglio HOLD +0.42/+0.50 — l'unico LEAD di valore. **MAX** e **AMIHUD-liquido** sono lo stesso
tema "evita speculativo/illiquido/volatile" in altre vesti (corr fra loro 0.33-0.59). **AMIHUD
long-illiquido SCARTATO** (premio illiquidità invertito in crypto: vincono i major liquidi). Bocciatura
del claim forte: **deflated-Sharpe 0.30-0.37 ≪ 0.95** (96 trial), storia ~2.5 anni, book 10-16 gambe →
**STAT-MODE**. Nota di rigore: il naive best-HOLD atterrava su celle in-sample-negative (holdout-fitting) →
l'agente ha auto-aggiunto il gate has_insample_edge. → **forward-monitor IVOL**.
### Thread 2 — Momentum-structure vs XS01
4 varianti (risk-adjusted, acceleration, frog-in-pan, vol-managed). **Nessuna batte né diversifica XS01**
(standalone 1.42). Sostituire XS01 con una variante **distrugge l'hold-out** del portafoglio (−0.58…−1.38)
— prova diretta che l'edge di XS01 sta nella sua struttura SPECIFICA (blend z-score [30,90] + gate
dispersione), non in varianti generiche. Deflated-Sharpe max 0.49. Tutte REDUNDANT/SCARTATO.
### Thread 3 — Meta-allocazione dinamica
Vol-parity / momentum-of-sleeves / dispersion-regime / drawdown-control vs pesi fissi, con costo di
ribilancio realistico. **Nessuno batte i pesi fissi OOS.** Vol-parity = trappola da manuale (+0.09…+0.44
sui tagli in-sample 2022-24, **−0.11 sull'hold-out 2025** → intercettato dal multi-cut). Drawdown-control
RIDONDANTE (TP01 va già flat nei crash, il gate non si attiva mai). I 4 sleeve sono già quasi-scorrelati
(corr ~0.12 max) → i pesi fissi sono già vicini al risk-parity ottimo statico. **Mantenere i pesi fissi.**
### Thread 4 — Segnali ortogonali ETH/BTC (il risultato più notevole)
Relative-value dollar-neutral sul ratio log(ETH/BTC): 6 segnali, evaluator a 2 gambe (fee × 2), cella
scelta in-sample-only.
| segnale | FULL/HOLD | corr→book | β-mkt | marginal | DSR (grid/same-sign) | exec $600 | verdetto |
|---|---|---|---|---|---|---|---|
| **STATARB-RESID** (residual relative-mom ETH−β·BTC, W45 **sgn+1**) | 0.84/0.56 | **0.027** | 0.013 | **ADDS** | 0.056 / 0.929 | haircut ~0 | **LEAD** |
| DVOLSPREAD (IV relativa, W60) | 0.74/0.77 | 0.017 | 0.012 | ADDS | 0.082 / 0.907 | haircut ~0 | LEAD |
| RATIO-MOM/REV/ACCEL | 0.25-0.68 / ≤0 | ~0 | ~0 | NEUTRAL | <0.23 | ok | NEUTRAL (diversification-math) |
| VOLSPREAD | −0.24/−1.47 | ~0 | 0.013 | DILUTES | — | — | SCARTATO |
**STATARB-RESID rompe 2 dei 3 muri storici:** è **ortogonale per costruzione** (corr→book 0.027, beta di
mercato 0.013 — meglio di SKH ~0.09) **ED eseguibile a $600** (book a 2 gambe BTC+ETH perp Deribit,
haircut ≈ 0, fee-survive fino a 0.30%/gamba → **NON STAT-MODE**, a differenza di XS01 e delle opzioni). Il
muro che **resta** è l'**edge**: Sharpe 0.84 / DSR 0.929 same-sign (ottimistico) ma comunque <0.95.
Verificato indipendentemente dal coordinatore: residuo causale (β OLS rolling backward, decisione a
close[i], return in i+1), fee a 2 gambe corretta. **⚠ Correzione di etichetta:** la cella vincente è
**sgn=+1**, NON sgn=−1 → NON è mean-reversion ma **momentum relativo sul residuo** (long lo spread quando
ETH è ricco vs il suo fit su BTC: le dislocazioni ETH-vs-BTC *continuano* a 1d; la MR pura sgn=−1 perde
−1.4 in-sample). L'ortogonalità (β~0) viene dalla struttura dollar-neutral, non dal verso. → **LEAD
forward-monitor** (monitorabile a costo reale ~0), NON deploy. **CABLATO:** `scripts/live/paper_statarb.py`
(config CONGELATA W=45/sgn=+1, doppio libro MODELED/REAL-$600, riusa il segnale esatto di
`orthogonal_signals.py`), aggiunto al cron giornaliero accanto a `paper_prevday`; test `tests/test_paper_statarb.py`.
**DVOLSPREAD** ri-valida l'ex-lead `dvol_spread`: ADDS ma storia DVOL corta (2021+) → resta forward-monitor
come già noto. Secondario crypto-vs-macro = "TSMOM travestito" (corr→book 0.17-0.20), non ortogonale.
### Thread 5 — 1-gamba a segnale (eseguibile)
12 famiglie (MACD/RSI/Supertrend/Donchian/BBands/EMA, ±ADX) su 1d/12h/8h. **0/12 earns_slot_honest.**
**Eseguibilità validata** (haircut $600 = 0 ovunque; RSI-MR ~2.5 trade/anno) — ma è l'unica cosa che
regge. I trend-follower sono **TP01 travestito** (corr 0.44-0.79, full ~1.2-1.3 = il soffitto) e le celle
sub-daily scelte in-sample **collassano OOS** (dimostrazione da manuale del gate selection-on-holdout). La
mean-reversion è morta (BBands-MR has_insample_edge=False). I "low-corr interessanti" (RSI-MR, MACD-LS,
Donchian-LS) sono **HEDGE non alpha** (`is_hedge=True`, pagano solo quando TP01 è debole), e con
deflated-Sharpe <0.95 (RSI-MR 0.861; Donchian-LS passa DSR ma is_hedge). **A $600 un 1-gamba a segnale è
eseguibile ma non aggiunge nulla a TP01.**
## Sintesi / cosa ho imparato
1. **0 nuovi sleeve, soffitto ~1.3 riconfermato** dal lato direzionale e dal lato struttura-momentum. La
ricerca è onesta: ogni candidato è stato ucciso dal gate giusto (deflated-Sharpe, is_hedge,
selection-on-holdout, sostituzione-XS01, multi-cut), non da un giudizio a occhio.
2. **Il LEAD di valore è STATARB-RESID** (ETH/BTC residual mean-reversion). È il primo stream visto che è
**insieme ortogonale (β~0) ED eseguibile a 2 gambe** — cadono i due muri che bloccano XS01 (STAT-MODE)
e le opzioni. Manca solo l'edge sopra-soglia. È il candidato n.1 per il **forward-monitor**, e l'unico
che — se la finestra forward confermasse l'edge — sarebbe *deployabile* a $600 (non statistico).
3. **Forward-monitor (STAT-MODE / sub-soglia):** IVOL (idio-vol XS, 19-major), DVOLSPREAD (storia corta),
STATARB-RESID (eseguibile — il più promettente). Nessuno armato come sleeve.
4. **I gate nuovi funzionano:** `study_family_honest` (selection-on-holdout) ha intercettato i collassi
OOS dei trend 1-gamba e dei low-risk XS; il deflated-Sharpe ha tenuto sotto la soglia ogni Sharpe ~1
su storia corta. La lezione del filone B (de-bias prima di credere) è ora applicata di default.
## Caveat
- Universi/finestre: HL ~2.5 anni, DVOL dal 2021 → multiple-testing reale; tutti i LEAD sono sotto la
soglia deflazionata. Niente di questo va creduto come alpha finché una finestra forward non lo conferma.
- Nessuno sleeve registrato, config canonica invariata (TP01+XS01+VRP01+SKH01 a pesi fissi). Book live
intatto. Tutto il lavoro è statistico/forward, su `main` come ricerca.
Script: `scripts/research/{xsec_v3_lowrisk,xsec_v3_momstruct,meta_allocation,orthogonal_signals,signal_inout_1leg}.py`.
Test: i rispettivi `tests/test_*.py` (143/143 verdi).
+65
View File
@@ -0,0 +1,65 @@
# 2026-06-29 — Filone C: cross-sectional NON-momentum su Hyperliquid — DEBOLE / forward-monitor
**Tesi.** XS01 (sleeve attivo) è momentum cross-sectional sui 19 major HL. Lezione del progetto
(2026-06-19/20): **espandere il numero di asset NON aiuta il momentum** (gli small-cap diluiscono/
invertono il segnale). Quindi qui NON si ri-prova l'espansione-universo: si cerca un **meccanismo
DIVERSO dal momentum** che, market-neutral e scorrelato, possa diversificare il portafoglio. Script
`scripts/research/xsec_v2_nonmom.py`, test `tests/test_xsec_v2.py`. Branch `research/equity-meanrev-ib`.
## Meccanismi provati (tutti L/S dollar-neutral, vol-target ~20%, ribilancio periodico, CAUSALI)
| | meccanismo |
|---|---|
| REV | short-term reversal grezzo (long loser / short winner di breve) |
| IREV | reversal **idiosincratico** (sul residuo dopo aver tolto il mercato, beta-adjusted) |
| LOWVOL | factor **low-vol** (long bassa vol realizzata / short alta vol) |
| IMOM | momentum **idiosincratico** (sul residuo, ≠ raw mom) — *riferimento* |
| BAB | betting-against-beta (long basso beta / short alto beta) |
| MOM | momentum grezzo — *riferimento* |
Universi: **19 major** e **51 all** (i parquet certificati). Gate canonico di selezione: FULL>0.5,
HOLD>0, |corr→XS01|<0.6 (escluse le famiglie momentum MOM/IMOM, che sono riferimento, non candidati).
## Esiti — un solo candidato non-momentum supera il gate standalone
```
[OK] LOWVOL 19-major B30 H10 k5 FULL +1.07 HOLD +1.07 DD 19% corrXS +0.16 corrTP -0.28
[--] BAB 19-major B60 H10 k8 FULL +0.47 HOLD +1.15 DD 28% corrXS +0.20 corrTP -0.27
[--] REV/IREV (19 e 51) FULL ~0 o NEGATIVO (reversal cross-sectional non paga)
[--] LOWVOL 51-all FULL +0.42 (il long-tail diluisce, come per il momentum)
```
- **REV / IREV negativi** (FULL −0.10..−0.70): il reversal cross-sectional grezzo o idiosincratico **non
è un edge** su questo universo/finestra — coerente con la morte storica del mean-reversion del progetto.
- **BAB** ha un buon hold-out ma FULL solo +0.47 (sotto soglia) e DD 28%.
- **LOWVOL 19-major** (betting-against-vol) è l'unico idoneo: FULL **1.07** / HOLD **1.07** / DD 19%,
causale (max_tail_diff 0), corr→XS01 +0.16 (scorrelato), corr→TP01 −0.28.
- Espandere a **51 asset peggiora** anche il low-vol (FULL 1.07→0.42): riconferma che i margini
cross-sectional sono nella **struttura del segnale**, non nel numero di asset.
### Uplift portafoglio (4 → 5 sleeve, LOWVOL come 5° sleeve)
```
BASE (TP01+XS01+VRP01+SKH01) FULL 2.12 DD 8% | HOLD 2.25 DD 3%
+LOWVOL @10% FULL 2.17 (+0.05) | HOLD 2.57 (+0.32)
+LOWVOL @15% FULL 2.19 (+0.06) | HOLD 2.62 (+0.37)
```
## Il muro (perché NON è uno sleeve)
1. **Deflated Sharpe 0.130 ≪ 0.95** (N=216 trial globali; soglia Sharpe-max-null annualizz. 1.79). Con il
numero di celle/famiglie/universi testati, lo Sharpe 1.07 **non è significativo** dopo la correzione
per multiple-testing. Per-anno: 2024 +0.23 / 2025 +0.50 / **2026 −0.09** (il 2026 è già negativo).
2. **Storia ~2.5 anni** (HL nativo 2024-2026): finestra troppo corta per un fattore cross-sectional.
3. **Non eseguibile a $600**: book L/S a molte gambe (10+ per lato) → **STAT-MODE**, mai deploy. Stesso
vincolo strutturale di XS01 (serve ~20k di capitale).
## Verdetto: **DEBOLE / forward-monitor (STAT-MODE).** Nessuno sleeve registrato.
Il **low-vol cross-sectional** (betting-against-vol sui 19 major) è l'unico meccanismo non-momentum con un
profilo decente e scorrelato sia a XS01 sia a TP01, e migliorerebbe l'hold-out del portafoglio (+0.32/+0.37).
**MA** non supera il deflated-Sharpe (multiple-testing), ha storia cortissima ed è non-eseguibile a questo
capitale. → lavoro **puramente statistico**, da tenere in forward-monitor come *secondo* segnale
cross-sectional a fianco di XS01, da rivalutare solo a scala (capitale ~20k+) e con più storia HL.
Reversal cross-sectional (REV/IREV) **confermato non-edge** su HL. Nessun impatto sul book live.
@@ -0,0 +1,91 @@
# 2026-07-01 — Breadth / market-internals del mercato ALT come segnale su BTC/ETH — SCARTATO
**Tesi.** Gli "internals" del mercato crypto — la partecipazione degli alt — come segnale
direzionale o gate di de-risk su BTC/ETH perp (2 gambe, eseguibile a ~$600): % di alt sopra la
propria SMA(N), advance/decline, % di alt che battono BTC (risk-appetite relativo), breadth-thrust.
Script `scripts/research/r0701_breadth_internals.py` (non committato per policy del filone; harness
`altlib`). Dati: i 51 parquet certificati `data/raw/hl_*_1d.parquet` → panel di **49 alt**
(esclusi hl_btc/hl_eth dalla breadth; hl_btc solo come riferimento per la famiglia RS), barre a
volume 0 mascherate (lezione backfill 2026-06-20; il fetch le aveva già ripulite: vol0=0 su tutti
i file, gate comunque attivo).
**Limite strutturale dichiarato in partenza:** l'universo HL parte dal 2024-01 → dopo il warmup
(max 120g) la finestra comune è **2024-05-05 → 2026-07-01 (~2.2 anni)** e l'in-sample pre-HOLDOUT
è **~8 mesi del toro 2024**. Qualunque esito poteva essere al massimo un lead.
## Famiglie e griglia (108 celle, tutte contate nel deflated Sharpe)
4 famiglie × N∈{20,50,100} × soglia∈{0.3,0.5,0.7} × forma∈{LS, long-flat, gate-su-TP01}:
- **FAM-MA**: % di alt validi con close > SMA(N) (breadth classica).
- **FAM-AD**: frazione di advancers (ret 1g>0), SMA(N).
- **FAM-RS**: % di alt che battono BTC sul ritorno a N giorni (≈ market-neutral, l'angolo più ortogonale).
- **FAM-TH**: breadth-thrust = Δ a N giorni della breadth MA20 (thrust/collapse), score 0.5+Δ.
Tutte causali (rolling/shift soltanto), MIN_VALID=20 asset per data (osservato: 42-49). LS/LF
vol-target 20% cap 2x (sizing TP01-style); GATE = posizione TP01 × gate binario. Fee 0.10% RT +
sweep 0-0.30%. Procedura onesta = mirror di `study_family_honest` sulla finestra comune (il
padding pre-2024 avrebbe contaminato il ranking full-history: le celle GATE con gate=1 pre-storia
erediterebbero lo Sharpe 2019-2024 di TP01): **cella scelta col SOLO Sharpe in-sample**, DSR su
tutti i trial, `marginal_vs_tp01` di altlib sulla cella scelta.
## ⚠️ Bug trovato e corretto: allineamento merge_asof su indice non-ns
La prima versione di `_align` usava `b.index.view("int64")//10**6` per i timestamp della breadth:
su un DatetimeIndex tz-aware **a risoluzione non-ns** (pandas 2.x) la scala esce sbagliata →
`merge_asof backward` matchava OGNI barra BTC/ETH all'**ultimo** valore della breadth = **il futuro
broadcast su tutta la storia**. Sintomo: decine di celle con lo stesso identico Sharpe (il segnale
era una costante). **`causality_ok` NON lo vede** — la serie breadth è un input esterno *fisso*,
quindi il target sul prefisso troncato coincide col target full per costruzione. Fix: epoca
esplicita `(idx - Timestamp(1970, tz=UTC)) // Timedelta(1ms)` (come `resample_tf`). **Lezione
harness:** ogni allineamento di un panel esterno via merge_asof va fatto con epoch-ms esplicita, e
il sintomo "molte celle con Sharpe identico" è un red-flag di allineamento rotto (gemella
dell'osservazione merge_asof del 2026-06-20).
## Esito (procedura onesta, finestra comune 2024-05+)
104/108 celle valutabili (4 degeneri flat), 47 con FULL>0. **Cella scelta in-sample** (IS 2.11,
la selezione non tocca mai l'hold-out): **TH N=100 thr=0.7 long-flat** — long solo dopo un
breadth-thrust (+0.2 di breadth MA20 in 100g), attiva il 32% dei giorni.
| metrica | valore |
|---|---|
| standalone finestra comune | IS **+2.11** → FULL **+0.99**, HOLD **+0.41** |
| assoluto (per-asset, trimmed) | **PASS** — minFull +0.68, minHold +0.38, fee-survive 0.30%RT, DD 7-11% |
| marginale vs TP01 | **ADDS** — corr full **0.401**/hold 0.358, resid Sharpe 0.87, multicut {2025:+0.076, 2026:+0.366} persistente, is_hedge=False |
| **robust_oos** | **False** — jackknife drop-best-month **−0.068** (l'uplift hold-out sta in piedi su UN mese) |
| **deflated Sharpe** | **0.433** su 104 trial (null-max atteso 1.10) — lontanissimo dal PASS ≥0.95 |
| earns_slot / earns_slot_honest | **False / False** |
| causality_ok | True (post-fix) |
| smallcap $600 | haircut ≈ **0.00** (BTC −0.01, ETH +0.00; 137-152 trade) — eseguibile |
**Ridondanza col trend (il rischio n.1, lezione macro-gate):** qui NON è la modalità di morte.
corr(pos, TP01pos) 0.15-0.30 e il segnale "lavora" (off mentre TP01 non è flat) nel **24-32% dei
giorni** (il macro-gate lavorava nel 2-3%). Le forme direzionali LS/LF sono genuinamente diverse
da TP01 (corr→TP01 0.1-0.4). La forma **gate-su-TP01** invece sì: best gate = NEUTRAL a corr
0.803, e i gate a soglia bassa = REDUNDANT corr 1.0 (gate mai off → TP01 identico). **La breadth
come gate di de-risk non aggiunge nulla; come segnale direzionale è diversa dal trend ma l'edge
non è dimostrabile.**
**Il gemello in hindsight (trasparenza, NON selezionabile).** TH N=100 thr=0.7 **LS** fa FULL 1.13
/ HOLD 1.06, corr→TP01 **−0.26**, marginal ADDS con robust_oos=True e jackknife +0.46. MA il suo
in-sample (1.30) è sotto quello della cella lf (2.11): sceglierlo = **selezione-sull'hold-out**
(esattamente il falso positivo ERM del 2026-06-29). E comunque **DSR 0.518 < 0.95**: anche la
lettura più caritatevole muore sulla deflazione multiple-testing.
## Verdetto: SCARTATO (niente sleeve, niente forward-monitor cablato)
1. La cella scelta onestamente è ADDS ma **robust_oos=False** (uplift a un mese) e **DSR 0.433**
su 104 trial: su ~8 mesi di in-sample (toro 2024) un IS di 2.1 è indistinguibile dal massimo
atteso per caso (1.10) e non regge.
2. Il candidato migliore col senno di poi (TH-LS) sarebbe selezione-sull'hold-out e fallisce
comunque il DSR (0.518) — il gate `study_family_honest` fa esattamente il suo lavoro.
3. Il limite è la **storia**: 2.2 anni totali, 8 mesi di in-sample. Non c'è modo onesto di
dimostrare l'edge oggi.
**Cosa resta.** (a) La famiglia **breadth-thrust (TH)** è l'unico angolo con celle OOS-positive e
bassa/negativa corr a TP01 — **rivisitabile quando il panel HL avrà ≥1-2 anni di storia nativa in
più** (in-sample multi-regime, DSR ricalcolabile); nessun cablaggio forward oggi, il costo
dell'attesa è zero. (b) Il breadth-**gate** su TP01 va in bacino con macro-gate e DVOL-gate: terza
conferma che TP01 non ha bisogno di de-risk esterno (long-flat, già flat nei crash). (c) Il fix
`_align` (epoch esplicita) è la lezione riusabile per ogni futuro panel esterno.
@@ -0,0 +1,58 @@
# 2026-07-01 — Book live: verifica gate SKH01 + emersione errori silenziosi
## Contesto
Il BOOK DERIBIT armato (TP01 0.75 + SKH01 0.25 nettati) è **flat da quando è stato armato
(2026-06-23)**: 193 run orari, tutte HOLD, zero ordini reali. Domanda: il flat è legittimo o il
gate di SKH01 è muto per un bug?
## Verifica del gate SKH01 — SANO
- **Logica viva:** `skyhook_entries` produce 335 entry (BTC, 222 long/113 short) e 341 (ETH,
226/115) su tutta la storia. Non è degenere.
- **Shorta davvero i crash:** ha aperto SHORT sulla gamba di crollo di fine maggio/inizio giugno —
BTC 05-28→06-04 ($73k→$64k), ETH 06-02→06-06 ($1865→$1555).
- **Flat da 06-23 = legittimo:** ultimo entry 06-06, `max_bars=16 × 230m ≈ 2,5g` → chiuso ~06-08/09,
**prima** dell'arming (06-23). Dal grind post-crash nessun setup breakout+regime valido → flat
corretto per design ("NON trend-follower"). Contesto prezzo al 01-07: BTC −53% dal picco, ETH
−67,5%, momentum negativo su 1/3/6/12 mesi → anche TP01 (long-flat TSMOM) è a 0x.
- **Entrambi i feed valutano senza crash:** certificato e live `fresh_5m` → `skh_error=None`.
## Bug scoperto e corretto — pattern "eccezione ingoiata → stato safe silenzioso"
`src/live/` aveva più `try/except` che, in errore, producono uno stato safe (flat/fallback) **senza
farlo emergere**. Rischio: quando l'errore è transitorio ma reale, l'esecutore opera su dati sbagliati
credendoli legittimi.
### (1) `skh_error` — CORRETTO
`book_report` scriveva `skh_error` in un dict locale **mai incluso nel return** → `r.get("skh_error")`
sempre `None`; e `book_execute` non lo leggeva comunque. Un feed SKH rotto avrebbe forzato SKH→flat in
silenzio (entry mancato, nessun alert). Fix: `skh_error` esposto nel return + `book_execute` emette
log `⚠️ SKH FEED ERRORE` + alert Telegram. (commit 31369b3)
### (2) Gate fail-safe posizione (Opzione A) — CORRETTO
`src/live/shadow.py::_positions`: se la read della posizione reale Deribit lancia, assume flat (0.0)
con una `note`, MAI propagata (`pos_src`) a `book_report`/`book_execute`. Severità mitigata a valle
da `rebalance_signed` che **rilegge la posizione fresca** (no doppia-posizione), ma resta il caso
"target≈0 + posizione aperta + read fallita → close saltato quel run" (transitorio, backstoppato dal
disaster-SL −30%). **Scelta A = gate fail-safe:** `_positions` ritorna un `pos_error` esplicito →
propagato `shadow_report → book_report → book_execute`; se presente (ONLINE ma posizione IGNOTA)
l'esecutore **NON opera a cieco** (return + alert), come già fa per `online`.
### (3) Diagnostica equity (Opzione B) — CORRETTO
`src/live/shadow.py::_equity`: se `account_summary('USDC')` e tutte le per-asset falliscono,
`real_eq=None` e `shadow_report` ripiega su `paper_cap` (~$2000 dallo state paper) mentre il conto
reale è ~$598 → il book dimensionerebbe su $2000 invece di $598 (**sovradimensiona ~33%**). Il danno
è limitato dall'**hard-cap $300/asset** in `book_net_target`. **Scelta B = SOLO DIAGNOSTICA** (niente
gate/halt, l'hard-cap già protegge il downside): `shadow_report` calcola `eq_fallback` (ONLINE +
equity reale non leggibile + no override), propagato `→ book_report → book_execute`, che stampa
`⚠️ EQUITY FALLBACK` + alert Telegram **ma prosegue** (a differenza del gate posizione, che blocca).
## Test
Suite completa **156/156** (era 148; +4 gate A + 4 diagnostica B). Dry-run reale di `book_execute`
invariato (nessuna riga d'errore, nessun ordine, conto $598.06 al target). Path live: `pos_error=None`,
`skh_error=None`, `eq_fallback=None`.
## Sintesi finale — i 3 pattern "errore silenzioso" del path live sono ora tutti tracciati
| # | Punto | Comportamento | Emersione |
|---|-------|---------------|-----------|
| 1 | `book_report` feed SKH | SKH → flat | log `⚠️ SKH FEED ERRORE` + alert |
| 2 | `_positions` read fallita | posizione → flat | **HALT** (non esegue) + alert (gate A) |
| 3 | `_equity` non leggibile | sizing → paper_cap | log `⚠️ EQUITY FALLBACK` + alert (diagnostica B) |
+114
View File
@@ -0,0 +1,114 @@
# 2026-07-01 — Funding rate come segnale TIME-SERIES direzionale su BTC/ETH (R0701): SCARTATO
## Contesto
Filone: il **funding orario Hyperliquid come proxy di POSIZIONAMENTO/sentiment** con valenza
direzionale a orizzonte giornaliero su BTC/ETH — NON carry. Angolo diverso dal prior art già
chiuso: **FC01** (carry cross-sectional delta-neutral 19 alt → LEAD fragile SCARTATO,
`2026-06-22-funding-carry-hl.md`) e **funding price-clock** intraday (drift attorno agli stamp →
FAIL, onda intraday). Qui l'ipotesi è: funding estremo = affollamento long → fade; funding in
espansione = domanda persistente → follow; funding affollato = de-risk del trend (gate).
Attrattiva a priori: 2 gambe BTC/ETH perp = **eseguibile al capitale reale ~$600** (non STAT-MODE
come XS01/opzioni) — se avesse retto sarebbe stato deployabile.
Script: `scripts/research/r0701_funding_ts.py`.
## Dati e causalità (data-first)
- `data/raw/hlfund_{btc,eth}_1h.parquet`: **2023-05-12 → 2026-06-22, 1138/1138 giorni validi,
0 gap** dopo il 2023-06 (primi ~27 giorni a cadenza 8h — la somma giornaliera degli stamp li
gestisce indifferentemente). Funding medio **+14.4%/anno BTC, +14.6% ETH**; std del funding
giornaliero ~5.5 bps.
- **Join causale** (il punto delicato): le barre 1d di `altlib.get` sono **open-labeled**
(datetime = 00:00 UTC del giorno D; il close della barra D è noto alle 00:00 di D+1). Il
feature-day D aggrega i SOLI stamp in **[D 00:00, D+24h)** — l'ultimo alle 23:00 — quindi tutto
è noto PRIMA della decisione al close della barra D; `eval_weights` shifta la posizione al
giorno D+1. Prefix-consistency check esplicito: **max diff 0.0** (nessun leak).
- **Valutazione su finestra TRONCATA** alla copertura funding, non sul frame prezzi 2018+: fuori
copertura il target sarebbe zero per costruzione e i giorni-zero (a) **gonfiano il T del
deflated-Sharpe** (anti-conservativo) e (b) diluiscono `cand_insample_sharpe` (il gate
`has_insample_edge` scatterebbe a vuoto). La logica di `study_family_honest` è replicata
ESATTAMENTE sui frame troncati coi primitivi altlib (selezione IN-SAMPLE-ONLY → gates
study_marginal → DSR sull'intera griglia). Cross-check `study_marginal` non-troncato in coda:
stessi verdetti (abs WEAK / marginal NEUTRAL / earns_slot False).
- ⚠️ **STORIA CORTA**: ~3.1 anni totali → in-sample pre-HOLDOUT ~1.6a (meno warmup z), hold-out
2025+ ~1.5a. Dichiarato: nessun numero qui ha il peso statistico di TP01 (7 anni).
## Metodo
Famiglia a griglia modesta, 1d, 50/50 BTC+ETH, vol-target 20% cap 2x (convenzione TP01), fee
0.10% RT + sweep 0.00-0.30%:
- **FADE**: z-score(funding daily, lb) ≥ thr → short; ≤ −thr → long (fade dell'affollamento).
- **FOLLOW**: z ≥ thr → long; ≤ −thr → short (sentiment momentum).
- **GATE**: trend long-flat TP01-like (sgn mom 30d+90d) ma FLAT quando z ≥ thr (de-risk crowding).
- **DIVERGE**: momentum prezzo 20d seguito se funding NON affollato (z ≤ −thr), fatto se z ≥ thr.
Griglia: 4 forme × lb {7,14,30,60}g × thr {0.5,1.0,1.5} = **48 celle**. Selezione cella
**in-sample-only** (mai sul hold-out), deflated-Sharpe su tutte le 48, gates marginali
(`marginal_vs_tp01`), boundary-shift della finestra di aggregazione funding (−0/3/6/9/12h),
`eval_weights_smallcap` a $600.
## Risultati
Best in-sample per forma: **fade 0.34, follow 0.81, gate 1.76, diverge −0.34** — il segnale
puro-funding è debole ovunque; solo la forma che CONTIENE il trend ha Sharpe.
**Cella scelta (in-sample): GATE lb=60 thr=1.5** — IS 1.76, FULL 1.16, HOLD 0.29.
| Gate | Esito |
|---|---|
| Deflated-Sharpe (48 celle) | **0.215** (null-max atteso 1.59) → **FAIL** (soglia 0.95) |
| Assoluto (frame troncati) | **WEAK** (minFull +0.97, ma minHold **+0.04** BTC); fee-survive fino a 0.30% RT |
| Marginale vs TP01 | **NEUTRAL**: corr **0.879** (hold 0.92), beta 0.77; uplift w25 hold **+0.001**; robust_oos=False (jackknife −0.074); multicut 2026 **−0.423** |
| earns_slot / earns_slot_honest | **False / False** |
| Realism | prefix-diff 0.0 (causale); boundary-shift sign-stable (uplift spread 0.047); smallcap $600 haircut ~0.00 (eseguibile, irrilevante senza edge) |
**Controllo decisivo (lezione TP01-DVOL-overlay)** — lo stesso trend long-flat SENZA gate funding:
```
trend NUDO : IS 1.65 FULL 1.14 HOLD 0.37
trend+GATE : IS 1.76 FULL 1.16 HOLD 0.29 corr(gated,nudo)=0.928
delta del gate funding: FULL +0.013, HOLD −0.080
```
→ **tutto lo Sharpe della "vincitrice" è il trend**; il contributo del funding è ~zero in-sample
e **negativo sul hold-out**. Il gate è TP01 travestito.
**Miglior cella puro-funding** (la vera tesi del filone): FOLLOW lb=60 thr=0.5 — IS 0.81 ma
**FULL −0.28, HOLD −1.69**, marginale **DILUTES** (uplift w25 hold −0.778). L'in-sample 0.81 era
"long-il-toro-2023/24" travestito: z-alto di funding = rally già in corso; nel 2025-26 la stessa
regola è sistematicamente dalla parte sbagliata. FADE (shortare il crowding) perde sul toro e non
recupera abbastanza nel chop; DIVERGE negativa ovunque. NB: esistono celle gate con HOLD migliore
(es. gate 7/1.5 HOLD 0.96) — sceglierle sarebbe **selection-on-holdout**, il gate del 2026-06-29
esiste esattamente per questo.
## Perché fallisce (meccanismo)
1. Su asset MAJOR il funding è **quasi sempre positivo e segue il prezzo con lag**: lo z-score
alto coincide col momentum già espresso → FOLLOW è trend-beta ritardato (muore quando il regime
gira), FADE è shortare il toro. Non c'è l'anti-persistenza ("crowding → reversal") che la tesi
richiede — a 1d, su BTC/ETH, le liquidazioni-da-crowding sono già nel prezzo prima che lo
z-score giornaliero diventi estremo.
2. L'unico uso "funzionante" (gate di de-risk sul trend) è **ridondante**: TP01-like è già flat
quando serve. Stesso verdetto di macro-regime-gate (corr 0.989) e DVOL-overlay: la famiglia
"overlay prudenziale su TSMOM" è esaurita — eredita lo Sharpe del trend e non aggiunge nulla.
## Verdetto
**SCARTATO.** `earns_slot=False`, `earns_slot_honest=False` (DSR 0.215). Il funding time-series
non ha informazione direzionale propria su BTC/ETH a 1d; l'unica cella con Sharpe è trend
travestito con contributo funding OOS negativo. Niente forward-monitor: non c'è una componente
funding da monitorare. Con FC01 (carry cross-sectional) e il price-clock intraday, il filone
"funding come segnale" su dati certi è ora **chiuso su tre lati**.
## Lascito
- `scripts/research/r0701_funding_ts.py` riusabile: (a) loader funding→daily **causale** per barre
open-labeled (finestra [D, D+24h), gestione cadenza mista 8h/1h, flag validità copertura);
(b) pattern "**truncation-honest**" per dataset a copertura parziale — replica di
`study_family_honest` su finestra troncata per non gonfiare il T del DSR né diluire
`has_insample_edge` con anni di zeri (riusabile per ogni serie corta tipo DVOL/HL).
- I parquet `hlfund_*` restano certificati. Se mai si tornasse sul funding: gli estremi VERI
(squeeze) vivono sugli alt, ma è di nuovo cross-sectional → STAT-MODE a $600, soglia di prova
alta (e FC01 ha già mostrato la fragilità d'universo).
@@ -0,0 +1,174 @@
# 2026-07-01 — Pesi statici ri-ottimizzati + guardia-DD sul portafoglio a 4 sleeve
## Mandato
Migliorare il portafoglio ATTIVO (TP01 41.25 / XS01 18.75 / VRP01 15 / SKH01 25) SENZA nuove
strategie: (A) ri-ottimizzazione onesta dei pesi statici, (B) guardia-drawdown a livello
portafoglio (replica del soft-guard vincente del tail-hedge lab 2026-06-23), (C) combinazione.
NON meta-allocazione dinamica (già scartata, thread 3 del 2026-06-29).
Script: `scripts/research/r0701_portfolio_opt.py`. Solo ricerca: nessun file di src/ o live toccato,
i pesi sono PROPOSTI, non applicati.
## Baseline riprodotta
`run_portfolio.py` oggi: **FULL Sh 2.12 / HOLD 2.21 / DD full 7.8% / CAGR 23.3%** (vs 2.13/2.30
del diario Skyhook: i dati sono avanzati di una settimana, coerente). Matrice sleeve outer-join
2019-03-14 → 2026-07-01 (TP01/SKH01 dal 2019, VRP01 dal 2021-05, XS01 dal 2024-01), combine
identico a `portfolio.combined_daily` (pesi rinormalizzati per-riga sugli sleeve attivi).
## (A) Pesi statici — metodo
- Ottimizzazione SOLO in-sample (pre-cut), valutazione OOS (post-cut), multi-cut
{2024-01, 2024-07, 2025-01}. Sleeve con <120 giorni in-sample al cut (XS01 al 2024-01)
PINNED al peso corrente (l'ottimizzatore non ha dati per giudicarli).
- Criteri: MAXSH (max-Sharpe del combo simulato), RP (inverse-vol), ERC, MINVAR-R (min-var con
vincolo ritorno ≥ pesi correnti). Null: EW (25×4) e CURRENT. Vincoli 5%≤w≤60%, Σ=1.
- **Cap STRUTTURALI dichiarati** (prudenza, non statistica): **VRP01 ≤ 15%** (sleeve MODELLATO su
DVOL ATM, stress-f non catturato — "niente short-vol da modello in deploy"), **XS01 ≤ 25%**
(STAT-MODE, storia ~2.5 anni). Varianti sotto cap: MAXSH-STR (ottimizzato) e EW-STR
(EW proiettato sui cap, parameter-free → TP 30 / XS 25 / VRP 15 / SKH 30).
### Risultati (pesi ottimizzati pre-2025, valutati FULL e HOLD-OUT 2025-26)
| criterio | pesi TP/XS/VRP/SKH | FULL Sh | FULL DD | FULL CAGR | HOLD Sh | HOLD DD | HOLD CAGR | multi-cut ΔSh OOS | anni vinti |
|---|---|---|---|---|---|---|---|---|---|
| CURRENT | 41.2/18.8/15/25 | 2.12 | 7.8% | +23.3% | 2.21 | 3.5% | +16.0% | — | — |
| MAXSH | 27.6/17.5/**39.5**/15.4 | 2.17 | 6.3% | +21.8% | 2.27 | 2.8% | +12.7% | +0.24/+0.08/+0.06 | **1/8** |
| RP-invvol | 26.7/15.5/**41.6**/16.3 | 2.17 | 6.4% | +21.8% | 2.25 | 2.8% | +12.4% | +0.28/+0.07/+0.04 | — |
| ERC | 26.6/16.2/**41.6**/15.7 | 2.17 | 6.3% | +21.7% | 2.25 | 2.8% | +12.4% | +0.29/+0.07/+0.05 | — |
| MINVAR-R | 26.7/23.3/**29.6**/20.4 | 2.18 | 6.4% | +23.3% | 2.37 | 2.6% | +16.1% | +0.20/+0.10/+0.16 | 4/8 |
| MAXSH-STR | 38.6/25/15/21.4 | 2.14 | 7.5% | +23.4% | 2.28 | 3.3% | +16.8% | **−0.00**/+0.03/+0.07 | 3/8 |
| EW | 25/25/25/25 | 2.14 | 7.0% | +24.5% | 2.39 | 2.8% | +18.1% | +0.16/+0.17/+0.18 | 6/8 |
| **EW-STR** | **30/25/15/30** | 2.10 | 8.5% | +25.2% | **2.35** | 3.2% | **+19.7%** | **+0.06/+0.13/+0.14** | **7/8** |
### Lettura onesta
1. **Gli OTTIMIZZATORI non aggiungono nulla — anzi overfittano.** Tutti (MAXSH/RP/ERC/MINVAR-R)
convergono sulla stessa mossa: scaricare TP01 e caricare **VRP01 al 30-42%** perché ha la vol
più bassa (7.7%/anno). Ma quella è la vol del MODELLO (premio BS su DVOL, coda di stress non
catturata): è esattamente il punto cieco tipo-CC01 ("Sharpe/vol implausibile → rischio
nascosto"). E per-anno MAXSH vince **1/8 anni** vs CURRENT — l'uplift multi-cut è smoothing di
vol modellata, non alpha di allocazione. **Dentro i cap** l'ottimizzatore (MAXSH-STR) converge
quasi sui pesi correnti (38.6/25/15/21.4) e NON è persistente (−0.00 al cut 2024-01) →
**i pesi correnti sono già ~ottimi per ciò che il backtest può giudicare lecitamente**.
2. **L'unico segnale robusto è la DE-CONCENTRAZIONE parameter-free**: EW-STR (EW sotto i cap,
nessun parametro fittato) vince **7/8 anni** (unica perdita 2021 −3.1pp), tutti i cut OOS
(ΔSh +0.06/+0.13/+0.14), HOLD Sh 2.21→2.35, HOLD CAGR +16.0→+19.7%. Classico "1/N batte
l'ottimizzazione" (DeMiguel). La sostanza: CURRENT dà il 41% al peggior Sharpe FULL del book
(TP01 1.30) e EW-STR sposta ~11pp da TP01 verso SKH01 (+5pp) e XS01 (+6.25pp).
3. **MA non è un free lunch risk-adjusted**: FULL Sh 2.12→**2.10** e FULL DD 7.8→**8.5%**
(più SKH01, che ha DD standalone 18%, pesa di più nei primi anni a 2 sleeve). L'uplift è un
TILT di ritorno verso gli sleeve research-grade con la storia più corta/caveat più pesanti
(SKH01 = research win, book 230m da verificare a deploy; XS01 = STAT-MODE non eseguibile a 2k).
E TP01 resta l'unico sleeve *deployed* live: il suo 41% nel report riflette una scelta di
prudenza/eseguibilità, non solo statistica.
### VERDETTO (A)
- **Ottimizzazione formale: NON MIGLIORA** (viola i cap strutturali o converge ai pesi correnti).
**Per il book reale i pesi correnti reggono.**
- **Candidato PROPOSTO (non applicato): EW-STR = TP01 30 / XS01 25 / VRP01 15 / SKH01 30** —
uplift OOS persistente e per-anno (7/8), dentro i cap, al costo di FULL DD +0.7pp e FULL Sh
−0.02. È una decisione di risk-appetite (più ritorno atteso spostando peso su sleeve
research-grade), non un miglioramento dominante. Se si vuole adottare, farlo consapevoli che
aumenta la dipendenza da SKH01/XS01, e NON tocca il book Deribit eseguibile (TP75/SKH25).
### Caveat metodologici (A)
- Le 3 finestre multi-cut sono ANNIDATE (tutte contengono il 2025-26): non 3 conferme
indipendenti. Il test disgiunto vero è il per-anno (7/8 per EW-STR è il dato forte).
- EW-STR è stato costruito DOPO aver visto EW vincere (proiezione del null sui cap dichiarati):
costruzione principled e parameter-free, ma va detto — non era nella griglia iniziale.
- I pesi CURRENT stessi furono fissati (2026-06-23) conoscendo l'hold-out → il confronto
"in-sample-opt vs CURRENT su hold-out" è semmai sbilanciato A FAVORE di CURRENT; EW-STR vince
comunque.
## (B) Guardia-drawdown a livello portafoglio — metodo
Soft-guard causale sul combo 4-sleeve (pesi CURRENT): esposizione del giorno D decisa dal DD
dell'equity fino a **D−1**; trigger/re-entry sul **NAV ombra** non-guardato (lezione stops_lab:
sull'equity congelata a expo=0 il DD non rientra mai); isteresi re-risk a 0.4·X come nel
tail-hedge lab. Griglia X∈{3,4,5,6}%, derisk∈{0,0.5}. Selezione cella IN-SAMPLE (max Calmar
pre-2025), verifica hold-out + multi-cut, **null de-levering** (expo costante c che pareggia il
MaxDD in-sample della guardia: Sharpe di c·r è invariante → la guardia vale solo se batte quello).
### Risultati
- Cella scelta in-sample: **X=5% / derisk=0.5** (IS Calmar 3.64 vs 3.24 baseline; IS DD 7.8→6.6%,
IS CAGR 25.3→23.9%, IS Sh 2.13→2.12). In-sample batte il null de-levering c=0.84 a pari DD
(CAGR 23.9% vs 21.0%) — il timing esiste in-sample.
- **MA OOS è INERTE**: a ogni cut la cella scelta non scatta MAI (ΔSh +0.00, ΔDD 0.0pp, ΔCAGR
0.0pp su tutti e 3 i cut) perché il DD OOS del 4-sleeve resta 3.5-4.8% < trigger 5%.
**La diversificazione a 4 sleeve fa già il lavoro della guardia** (il 2022 del book è +11.6%
con DD 3.6%: non c'è il grind da proteggere che aveva il combo TP01+GTAA del tail-hedge lab,
DD 8.4% / 2022 −4.4%).
- Trigger più stretti che scattano davvero COSTANO: X=3%/d=0.5 → HOLD Sh 2.10 (< 2.21), CAGR
13.7% (< 16.0%); X=3-4%/d=0 whipsaw pieno (HOLD Sh 1.83-2.09; a X=4/d=0 il DD guardato IS
sale addirittura a 8.8% > 7.8% baseline — accumulo di perdite su cicli off/on, lo stesso
fenomeno visto in stops_lab con l'uscita totale).
### VERDETTO (B)
**NON MIGLIORA.** La guardia-DD che vinceva sul combo TP01+GTAA (DD 8.4%, 2022 −4.4%) qui non ha
bersaglio: il 4-sleeve ha già DD ~3.5-4.8% OOS. Coerente col thread meta-allocazione 2026-06-29
(drawdown-control ridondante). Nota operativa: la cella X=5%/d=0.5 è *innocua* (non fa nulla
finché il DD non supera il 5%) e in-sample mostrava timing genuino sopra il null de-levering —
può valere come **circuit-breaker di emergenza sul live** (risk management, non alpha), ma non è
un miglioramento statistico e non la si adotta come tale.
## (C) Combinazione
(B) è inerte → niente da combinare. Per completezza: EW-STR + guard X=5%/d=0.5 → FULL Sh 2.08,
DD 6.7%, CAGR 23.7% | HOLD invariato 2.35/3.2%/19.7% (la guardia lima il DD 2021-2023 del tilt
a costo di −0.02 Sh FULL). Nessuna adozione proposta.
## Sintesi
| config | FULL Sh | FULL DD | FULL CAGR | HOLD Sh | HOLD DD | HOLD CAGR |
|---|---|---|---|---|---|---|
| **CURRENT (attivo)** | 2.12 | 7.8% | +23.3% | 2.21 | 3.5% | +16.0% |
| EW-STR (proposta A, non applicata) | 2.10 | 8.5% | +25.2% | 2.35 | 3.2% | +19.7% |
| CURRENT + guard 5%/0.5 (B) | 2.11 | 6.6% | +22.3% | 2.21 | 3.5% | +16.0% |
| EW-STR + guard (C) | 2.08 | 6.7% | +23.7% | 2.35 | 3.2% | +19.7% |
- **(A) NON MIGLIORA in senso forte** — i pesi correnti reggono; l'unico candidato onesto è il
tilt de-concentrante EW-STR (30/25/15/30), un trade-off di risk-appetite da decidere, non un
upgrade dominante. Gli ottimizzatori in-sample o violano i cap strutturali (VRP01 40%) o
riconvergono sui pesi correnti.
- **(B) NON MIGLIORA** — guardia inerte OOS sul 4-sleeve; utile al più come circuit-breaker.
- Nessuna modifica a `src/portfolio/sleeves.py` o al live. Test 160/160 verdi.
Script: `scripts/research/r0701_portfolio_opt.py` (~4s, vettoriale).
## Verifica avversariale (agente scettico)
Script: `scripts/research/r0701_portfolio_skeptic.py`. **VERDETTO: NON APPLICARE — CURRENT resta.**
I numeri dell'agente riproducono ESATTAMENTE (via `StrategyPortfolio.combined_daily`, path di
produzione: CURRENT 2.12/2.21, EW-STR 2.10/2.35, multi-cut +0.06/+0.13/+0.14, |diff|=0). Il claim
muore altrove: l'uplift è **selezione-sull'hold-out di 2° ordine**, non alpha di allocazione.
1. **L'uplift OOS vive TUTTO nel 2025-26 — la finestra che ha selezionato i beneficiari.**
Finestre OOS **DISGIUNTE** (i 3 cut del diario sono annidati): ΔSh EW-STR vs CURRENT =
**−0.12** (2024H1) / +0.06 (2024H2) / **+0.14** (2025+). L'unica finestra OOS non toccata
dalla selezione hold-out è negativa. Sharpe standalone IS→HOLD per sleeve: TP01 1.49→**0.30**,
SKH01 1.42→**1.64**, XS01 1.22→**1.51**: EW-STR compra esattamente i due sleeve ammessi/affinati
(2026-06-23 / 2026-06-19) PERCHÉ forti sull'hold-out e vende quello che lì collassa. Meccanico.
2. **Pre-2025 (finestra non contaminata) EW-STR PERDE risk-adjusted**: ΔSh aggregato **−0.05**,
Sharpe per-anno vinti **2/6** (2021 −0.29, 2020 −0.10, 2023/2024 negativi).
3. **"7/8 anni vinti" è un artefatto di metrica**: è RITORNO composto (un tilt a più vol/ritorno
li vince quasi per costruzione), non risk-adjusted. Su **Sharpe per-anno: 3/8**. E due dei 7
"vinti" (2023, 2024) hanno margine **+0.03pp** = tie. Bilancio materiale sul ritorno:
5 vinti / 1 perso (2021 −3.1pp) / 2 pari.
4. **Plateau: liscio ma il gradiente è solo "meno TP01"**; a TP fisso, alzare SKH 25→30 è
piatto/negativo (min multi-cut a TP35: +0.07→+0.02). Scomposizione: il tilt **solo-SKH**
(+5pp, TP 36.25) da solo NON è persistente (multi-cut **−0.00**/+0.05/+0.04); il tilt
**solo-XS** (TP35/XS25/VRP15/SKH25) è l'unico positivo su tutte le finestre disgiunte
(+0.05/+0.02/+0.11) — ma pre-2025 fa ΔSh −0.00 (edge ≈ zero fuori dal 2025-26) e carica lo
sleeve MENO eseguibile (STAT-MODE).
5. **Realismo**: con l'outer-join rinormalizzato EW-STR tiene SKH01 al **50% effettivo nel
2019-20 e 40% nel 2021-23** (book research 230m a metà portafoglio: da lì il FULL DD 8.5%).
Punto onesto A FAVORE: un haircut d'esecuzione a drag su SKH01(-20/30%) e SKH+XS non ribalta
il ranking hold-out (ΔSh resta +0.08..+0.13), ma i livelli assoluti crollano (HOLD Sh CURRENT
2.21→1.64 al −30% su entrambi) e il beneficio resta di CARTA: il book Deribit eseguibile
(TP75/SKH25) non è toccato dalla decisione.
6. **Forking paths quantificato**: ≥15 config valutate sull'hold-out (7 vettori pesi + 8 celle
guardia), EW-STR costruito dopo aver visto EW vincere. Su **500 tilt CASUALI cap-respecting**:
51% batte CURRENT sull'hold-out (mediana ΔSh +0.00), solo 11% sul FULL, 30% su tutti e 3 i cut.
EW-STR è al **94° percentile** dell'uplift hold-out fra i tilt casuali ≈ il **massimo atteso di
~15 tentativi** (k/(k+1)=93.8%): l'uplift osservato è indistinguibile dal "best of 15 tilt
casuali scelto sull'hold-out".
**Conclusione**: il tilt non è disonesto nei conti ma non è evidenza — è la stessa lezione del gate
SELECTION-ON-HOLDOUT applicata al livello dei PESI (2° ordine: gli sleeve stessi sono stati
selezionati su quell'hold-out). Unica direzione sopravvissuta: XS01 18.75→25 (solo-XS, positivo su
tutte le finestre disgiunte), MA edge ≈0 fuori dal 2025-26, sleeve STAT-MODE non eseguibile a $600,
e l'hold-out-strength di XS01 è a sua volta concentrata dal gate di dispersione nel regime 2025-26
→ da rivalutare SOLO con più storia forward, non ora. **CURRENT (41.25/18.75/15/25) resta.**
@@ -0,0 +1,132 @@
# 2026-07-01 — Ondata multi-agente a 6 filoni: 0 nuovi sleeve, pesi CURRENT confermati, 1 gate nuovo
**Goal utente:** "cerca con diversi agenti altre strategie di trading. Prova di tutto e arriva a
migliorare il portfolio presente. Lo scopo è sempre 50 euro days."
**Esito in una riga:** 6 filoni nuovi (scelti dopo scan dei ~65 diari per non ripetere strade morte)
+ 1 verifica avversariale → nessun candidato supera i gate onesti; il portafoglio a 4 sleeve
(41.25/18.75/15/25) **sopravvive a un attacco serio**, che è l'esito corretto per un book onesto.
Miglioramento concreto dell'ondata = metodologico: **gate `weights_tilt_null`** codificato (sotto).
## I 6 filoni (tutti su harness onesto: study_family_honest, marginal scorer, DSR≥0.95, smallcap $600)
| # | filone | verdetto | perché muore |
|---|---|---|---|
| 1 | **Funding time-series** BTC/ETH (posizionamento, non carry) — `r0701_funding_ts.py` | SCARTATO | FOLLOW = trend-beta ritardato (HOLD −1.69), FADE = shortare il toro; la cella gate è TP01 travestito (controllo senza funding = stessi numeri, corr 0.93, ΔHOLD −0.08); DSR 0.215. **Filone funding chiuso su 3 lati** (FC01 carry, price-clock, TS-signal). |
| 2 | **Breadth/internals alt** (51 HL) → BTC/ETH — `r0701_breadth_internals.py` | SCARTATO (rivisitabile) | Unico non-ridondante col trend (corr→TP01 0.40, lavora dove TP01 è attivo), assoluto PASS, marginal ADDS — ma jackknife −0.068 (uplift su UN mese) e DSR 0.433/104 celle. Con ~8 mesi di IS il 2024-toro non basta. **Rivisitare tra 1-2 anni di storia HL nativa.** |
| 3 | **Residual momentum XS** (β-hedged vs BTC, 19 major) — `r0701_xs_residmom.py` | REDUNDANT | Cross-section la residualizzazione è quasi un no-op (lo z-score di XS01 già rimuove il mercato): corr→XS01 0.54, HOLD −0.24, corr(IS,HOLD) tra le celle **−0.37** (anti-predittivo = rumore). L'edge residuo-momentum vive nella coppia ETH/BTC (STATARB-RESID, resta in `paper_statarb`), non generalizza. |
| 4 | **Pesi + guardia-DD** — `r0701_portfolio_opt.py` | vedi sotto | Unico candidato dell'ondata (EW-STR) → refutato dallo scettico. Guardia-DD X5%/d0.5: in-sample batte perfino il null de-levering, ma **OOS non scatta mai** (DD book 3.5-4.8% < trigger): la diversificazione fa già il lavoro. Utilizzabile solo come circuit-breaker di emergenza (risk mgmt, non alpha). |
| 5 | **Affinamento VRP01** (sizing IV−RV, DVOL-mom, gate TP01) — `r0701_vrp_refine.py` | NON MIGLIORA | L'alpha è già tutto nel gate binario IV-rank; il gate TP01 è la trappola IS perfetta (schiva il 2022, ma taglia le settimane migliori dell'hold-out: multi-cut 0/5). **3° fallimento del filone "affinare VRP dentro il modello" → esaurito** finché cerbero-bite non cattura un crash reale (f di stress). |
| 6 | **Stagionalità cross-sectional** HL — `r0701_xs_seasonal.py` | SCARTATO (allo step statistico) | Nessuna persistenza split-half sopra il null permutato max-statistic (p 0.16-0.23); l'unica struttura è il canale-beta dell'effetto weekday di mercato (famiglia trackF, già morta). Turnover ~2×gross/die = fee-death comunque. |
## EW-STR: il candidato refutato (caso di scuola di selezione-sull'hold-out di 2° ORDINE)
Il filone 4 proponeva **EW-STR** (TP01 30 / XS01 25 / VRP01 15 / SKH01 30 = equal-weight proiettato
sui cap strutturali): HOLD Sh 2.21→2.35, multi-cut +0.06/+0.13/+0.14, "7/8 anni vinti" — dichiarando
onestamente i caveat. La verifica avversariale (`r0701_portfolio_skeptic.py`, addendum nel diario
pesi) lo uccide:
1. **Selezione di 2° ordine**: SKH01 fu ammesso (2026-06-23) *perché* alzava l'hold-out 2025-26;
XS01 fu affinato conoscendo l'hold-out. EW-STR vende lo sleeve che collassa OOS (TP01 IS 1.49→
HOLD 0.30) e compra i due selezionati su quell'OOS. Pre-2025: **ΔSh −0.05** (perde risk-adjusted).
2. **Su finestre OOS disgiunte**: −0.12 (2024H1) / +0.06 (2024H2) / +0.14 (2025+) — tutto l'uplift
vive nella finestra che ha selezionato gli sleeve. "7/8 anni" era sul ritorno composto; su
Sharpe è 3/8.
3. **Firma best-of-k**: su 500 tilt casuali cap-respecting, EW-STR siede al 94-100° percentile ≈
k/(k+1) con k≈15 config viste sull'hold-out → uplift indistinguibile dal *best-of-15 scelto
sull'hold-out*.
4. **Realismo**: in pesi effettivi (outer-join rinormalizzato) EW-STR = SKH01 al 40-50% del book
2019-23 (sleeve research a book 230m). Il book Deribit eseguibile (TP+SKH) non cambierebbe comunque.
Residuo onesto: il sub-tilt XS01 18.75→25 è positivo su tutte le finestre disgiunte ma edge≈0
pre-2025 e STAT-MODE → rivalutare solo con storia forward.
## GATE NUOVO codificato: `weights_tilt_null` (src/portfolio/portfolio.py)
La lezione è ora codice, come per marginal-scorer e study_family_honest:
- **`combine_outer(daily_cols, weights, lo, hi)`** — la combinazione outer-join/rinormalizzata di
`combined_daily` estratta come funzione su pesi arbitrari (riusabile per studi di tilt).
- **`weights_tilt_null(daily_cols, w_current, w_proposed, caps, floor, n, seed, k_seen)`** —
null di tilt casuali uniformi sul simplesso dentro floor/caps: riporta `delta_hold/full/insample`,
`frac_random_beat_hold`, `pctl_hold`, `bestofk_pctl=k/(k+1)` e `gate_pass`.
**Regola: un cambio-pesi si applica solo se (1) delta_insample ≥ 0 e (2) pctl_hold < firma
best-of-k** (necessario, non sufficiente: restano finestre disgiunte + realismo).
Sul caso reale EW-STR: delta_hold +0.139, delta_insample **−0.054**, pctl **100°** vs best-of-15
93.75° → `gate_pass=False`. Test: `tests/test_weights_tilt_null.py` (5 test, sintetici,
deterministici; incluso lo sleeve "forte-solo-nell'hold-out" che DEVE fallire il gate).
## Lezione tecnica riusabile (dal filone 2)
`DatetimeIndex.view("int64")` su indici **tz-aware a risoluzione non-ns** (pandas 2.x) produce
timestamp in scala sbagliata → un `merge_asof` può broadcastare l'ultimo valore su tutta la storia
= **look-ahead che `causality_ok` non vede** (input fisso). Sintomo: decine di celle con Sharpe
identico. Fix: epoca esplicita in ms. Verificato: `altlib.py` non è affetto (grep pulito); dettagli
nel diario breadth.
## Onestà sul goal €50/giorno
Invariata (vedi CLAUDE.md): a capitale reale ~$600 il book onesto fa ~+€1.5/giorno atteso; la via
resta capitale + tempo + target-vol, non un tilt di pesi né leva. Questa ondata conferma che il
book attuale è vicino al massimo estraibile dai dati certificati disponibili oggi; le opzioni
reali di crescita restano (a) storia forward che promuova i lead (STATARB-RESID, breadth tra 1-2
anni), (b) capitale, (c) nuove fonti di dato (f di stress reale per VRP).
**File dell'ondata:** `scripts/research/r0701_{funding_ts,breadth_internals,xs_residmom,portfolio_opt,portfolio_skeptic,vrp_refine,xs_seasonal}.py`; diari `2026-07-01-{funding-ts-signal,alt-breadth-internals,xs-residual-momentum,portfolio-weights-ddguard,vrp-refinement,xs-seasonality}.md`; gate in `src/portfolio/portfolio.py` + `tests/test_weights_tilt_null.py`.
## ADDENDUM (stessa sera) — GTAA01 promosso a 5° SLEEVE: il miglioramento c'era, ma era in casa
Il secondo passaggio sull'archivio (non sui dati!) ha trovato il candidato che l'ondata di *ricerca*
non poteva trovare: **EQ-GTAA01** (`src/portfolio/gtaa.py` — trend difensivo equity 6-ETF, vt12%,
~30 anni di storia, netto fee IB) era stato validato il 2026-06-22 come *"primo miglioramento
STRUTTURALE del rischio-aggiustato trovato in tutta la ricerca post-reset"*, messo in paper
cross-venue (`paper_combo`, nel cron dal 2026-06-23) e **mai valutato come 5° sleeve del
portafoglio attivo** (il giorno dopo arrivò SKH01 e il filone si fermò).
### Valutazione onesta (`r0701_gtaa_5th_sleeve.py`) — perché GTAA passa dove EW-STR è morto
| gate | EW-STR (refutato) | +GTAA01 (passa) |
|---|---|---|
| uplift IN-SAMPLE (pre-2025) | **−0.05** | **+0.09..+0.13** (2.134→2.23-2.26) |
| finestre OOS disgiunte | −0.12 / +0.06 / +0.14 | **+0.05 / +0.19 / +0.25** (tutte >0) |
| multi-cut (4 tagli) | solo annidate | **+0.21 / +0.21 / +0.22 / +0.25** |
| provenienza dell'edge | sleeve selezionati sull'hold-out crypto | validato su OOS equity 2015+, **indipendente** dall'hold-out crypto |
| corr al book | — | **+0.10** full, ~0.00 hold-out; is_hedge +0.30 (non-hedge) |
| plateau | gradiente generico anti-TP01 | **monotono su w 10-30%, ogni cella migliora IS/FULL/HOLD/DD** |
Convenzione di realismo cross-venue (nuova, cablata nello sleeve): nei giorni senza barra equity
(weekend/festivi US) il rendimento è **0.0** — capitale IB fermo, NON rinormalizzato sul crypto
(due conti reali non si travasano nel weekend). Numeri quasi identici alla versione outer-join
(differenze al 3° decimale) ma il modello è quello giusto. Attivazione nel book all'era crypto
(2019-03-14): senza troncatura l'outer-join farebbe partire il book nel 1996 con 23 anni di
solo-GTAA rinormalizzato al 100%.
### Decisione pesi
Cella IS-best = w=30% (bordo griglia), **ingresso @20%** per scelta strutturale dichiarata:
(a) cross-venue IB con paper operativo di soli 8 giorni — non diventa lo sleeve più grande del
book al day-one; (b) precedente: ogni sleeve nuovo è entrato ≤25% (SKH01 25%, VRP01 15%);
(c) costo CAGR (a 30%: 16.8% vs 18.8% a 20%) — e l'obiettivo €50/g vive di CAGR, non solo di
Sharpe. Tutte le celle 10-30% passano comunque ogni gate. Pesi nuovi: **TP01 33 / XS01 15 /
VRP01 12 / SKH01 20 / GTAA01 20** (i 4 preesistenti scalati ×0.80, rapporti conservati).
### Portafoglio 5-sleeve (run_portfolio, capitale 2k)
| | FULL Sh | FULL DD | FULL CAGR | HOLD Sh | HOLD DD | HOLD CAGR |
|---|---|---|---|---|---|---|
| 4-sleeve (baseline) | 2.12 | 7.8% | +23.3% | 2.21 | 3.5% | +16.0% |
| **5-sleeve (+GTAA01 20%)** | **2.24** | **6.2%** | +18.8% | **2.46** | **2.2%** | +14.6% |
Per-anno: tutti gli 8 anni positivi, 2022 +7.0% (era +11.6%: GTAA soffre il whipsaw 2022, unico
anno con dSh negativo −0.49 — dichiarato). Il trade-off è esplicito: −4.5pp di CAGR full per
+0.12/+0.25 di Sharpe e DD 7.8→6.2 / hold-out 3.5→2.2. A pesi research (XS/VRP/SKH modellati o
STAT-MODE) il CAGR era comunque di carta; lo Sharpe/DD del book è la metrica di verità.
### Cosa NON cambia
Il **book live Deribit** (`deribit_book_sleeves` TP01+SKH01 75/25, `book_execute`) è INTATTO —
GTAA è su IB, già tracciato forward da `paper_combo`. `paper_portfolio` da oggi traccia la
composizione a 5 (regime-break dichiarato qui). Test: `tests/test_gtaa_sleeve.py` (registry,
weekend-zero, attivazione, book live invariato) — suite 168/168.
### Lezione dell'addendum
Prima di una nuova ondata di *ricerca*, ri-leggere l'archivio dei **validati-ma-non-integrati**:
l'unico upgrade onesto del book in 3 ondate (104+5+6 filoni) era un edge già validato che
aspettava solo la valutazione da sleeve. La diversificazione strutturale (secondo mercato,
corr ~0.1) resta l'unica cosa che alza lo Sharpe del book senza nuovo alpha.
+98
View File
@@ -0,0 +1,98 @@
# 2026-07-01 — Affinamento VRP01 (sizing IV−RV / filtro DVOL-momentum / gate TP01): NON MIGLIORA
**Script:** `scripts/research/r0701_vrp_refine.py` (solo ricerca: `src/` e `scripts/live/` non toccati).
**Esito: NON MIGLIORA — VRP01 baseline resta la config canonica.** La cella IS-best (gate TP01-skip)
è un falso positivo in-sample da manuale: IS Sharpe 2.07 ma multi-cut **0/5**, hold-out **−0.14**
(vs 0.59 del baseline), DSR 0.71. Nessuna modifica a `sleeves._vrp_combo_returns`.
## Cosa testava (celle NUOVE, verificate non ripetute nei diari)
Stessa pipeline di `options_vrp_v2.py` (pricing BS su DVOL reale, payoff sul path certificato,
fee 12.5% del premio, f=1.0, tenor 7d, spread −0.28/−0.10) — cambiati SOLO gate/sizing:
1. **Sizing sul gap IV−RV** (carry atteso): size lineare `clip(vrp/scale,0,1)` (scale 8/12 pt) o
percentile espandente causale del VRP; in aggiunta o in sostituzione del gate binario IV-rank.
NB: il gate composito "IV-rank>0.30 AND IV−RV>0" è **già il baseline** (`gate_vrp=True`).
2. **Filtro DVOL-momentum**: non vendere se `dvol[i]−dvol[i−k] > thr` (k∈{5,10}, thr∈{0, 5pt}).
(Diverso da `dvol_directional` 2026-06-29, dove il DVOL-mom era segnale direzionale sul perp.)
3. **Gate di regime da TP01**: skip o half-size quando TP01 è flat su entrambi gli asset (risk-off).
4. Croce completa: **105 celle**, tutte contate nel deflated-Sharpe.
NON ripetuto (già scartato): gestione attiva intra-trade (PT/SL/vol-stop/delta-exit,
`2026-06-20-vrp-active-management.md` → hold-to-expiry vince).
Metodo: selezione cella **in-sample (pre-2025)** con floor di attività IS ≥20%, hold-out 2025-26,
**multi-cut 5 tagli** (2023-01→2025-01, richiesti ≥4/5 uplift>0), `altlib.deflated_sharpe` su tutti
i 105 trial, effetto sul **portafoglio 4-sleeve** (TP01 41.25 / XS01 18.75 / VRP 15 / SKH01 25).
## Risultati (book 50/50 BTC+ETH, rendimenti settimanali)
Baseline riprodotto esattamente: **FULL Sh 1.09 / IS 1.26 / HOLD 0.59 / DD 12% / worst −7.4% / attivo 41%.**
| cella | IS Sh | FULL | HOLD | DD | worst | attivo |
|---|---|---|---|---|---|---|
| **BASELINE** bin+ivr30 | 1.26 | **1.09** | **0.59** | 12% | −7.4% | 41% |
| sizing lin 8pt (+ivr30) | 1.20 | 1.05 | 0.61 | 11% | −7.4% | 41% |
| sizing lin 12pt (+ivr30) | 1.12 | 0.98 | 0.54 | 11% | −7.4% | 41% |
| sizing rank (+ivr30) | 1.07 | 0.94 | 0.54 | 9% | −5.7% | 41% |
| sizing lin 8pt **al posto di** ivr | 0.89 | 0.58 | **−0.38** | 21% | −7.4% | 86% |
| sizing rank al posto di ivr | 1.03 | 0.69 | **−0.36** | 11% | −5.7% | 86% |
| mom k=5 thr=5pt | 1.24 | 1.02 | 0.37 | 9% | −6.5% | 34% |
| mom k=10 thr=5pt | 1.26 | 1.08 | 0.55 | 9% | −6.5% | 31% |
| mom k=5 thr=0 | 1.78 | 1.24 | −0.10 | 5% | −3.9% | 20% |
| mom k=10 thr=0 | 1.36 | 0.78 | **−0.47** | 7% | −3.9% | 18% |
| tp01-skip | **2.05** | 1.43 | **−0.14** | 7% | −4.7% | 27% |
| tp01-half | 1.72 | 1.34 | 0.27 | 7% | −4.7% | 41% |
| IS-best: lin8+tp01-skip | **2.07** | 1.43 | **−0.14** | 6% | −4.2% | 27% |
**Multi-cut della IS-best vs baseline: uplift negativo in 5/5 tagli** (−0.35 → −0.73, monotono
peggiorando verso il presente). **DSR** IS-best 0.709 (<0.95); baseline 0.472 dentro questa griglia
(contesto onesto: nemmeno il baseline è statisticamente distinguibile su 105 trial correlati — ma è
pre-committed, non selezionato qui). Celle che battono l'hold-out del baseline: **1/105** (lin8pt
tp-off, +0.02 — rumore; non selezionabile: sarebbe selection-on-holdout).
### Frequenza d'intervento dei gate (settimane-trade del baseline = 163)
- **TP01-skip: blocca il 32.5%** delle settimane tradabili (TP01 flat il 38% dei giorni della
finestra DVOL). NON è ridondante col baseline — lavora tanto — ma lavora **male** OOS.
- mom thr=5pt: blocca 24-32%; mom thr=0: blocca 60-64% (quasi metà del book).
### Portafoglio 4-sleeve (VRP @15%)
| VRP nello slot | FULL Sh | FULL DD | HOLD Sh | HOLD DD |
|---|---|---|---|---|
| **baseline** | **2.12** | 7.8% | **2.21** | 3.5% |
| IS-best (lin8+tp01-skip) | 2.11 | 7.8% | 2.12 | 3.5% |
Anche a livello portafoglio la variante **peggiora** l'hold-out (2.21→2.12) e non migliora nulla.
## Lettura (perché non migliora)
1. **L'alpha del VRP è già tutto nel gate IV-rank binario** ("vendi solo vol ricca"). Il sizing
proporzionale al gap IV−RV è ridondante *dato* il gate (Δ ≈ ±0.05, dentro il rumore); usato al
posto del gate, riporta dentro le settimane di vol povera e distrugge l'hold-out (−0.36/−0.38).
Il carry atteso (IV−RV) NON è un segnale di *intensità* utile oltre il suo segno+rank.
2. **Il gate TP01 è la trappola in-sample perfetta** (la lezione macro-gate al contrario): schiva il
2022 (−6%→0%) gonfiando l'IS a 2.05, ma nel 2025-26 TP01 è flat proprio nei regimi di vol ricca
in cui la vendita gated di put **guadagna** — il gate taglia le settimane migliori dell'hold-out
(0.59→−0.14). Short-vol gated e trend sono complementari, non condizionabili l'uno sull'altro.
3. **Il DVOL-momentum non aggiunge protezione**: il crash-skip IV-rank>0.90 + il long wing dello
spread coprono già il run-up di vol; thr=0 è troppo aggressivo (blocca ~60%), thr=5pt è neutro
(mai meglio del baseline su hold-out).
## Onestà / caveat (invariati)
Premio MODELLATO su DVOL ATM (no skew), book 1d, f di stress reale non catturato → tutto questo
resta dentro il modello; il verdetto massimo possibile era "sleeve modellato migliorato", e non è
stato raggiunto. Il DSR sulla griglia è un limite *superiore* (celle correlate + ~20 config storiche
di options_vrp_lab/_v2 non contate).
## Azione
**Nessuna.** VRP01 resta com'è (`bin + gate_vrp + ivr30 + crash-skip 0.90`, hold-to-expiry).
Terzo tentativo di affinamento fallito (dopo active-management e — per il portafoglio — DVOL
overlay): il filone "migliorare VRP01 dentro il modello" è da considerarsi **esaurito**; il prossimo
passo utile resta quello noto: f di stress reale quando cerbero-bite cattura un crash + skew reale
sul long wing.
Script: `scripts/research/r0701_vrp_refine.py` (`--skip-portfolio` per la sola griglia).
@@ -0,0 +1,74 @@
# 2026-07-01 — Residual (idiosyncratic) momentum cross-sectional sui 19 major HL — SCARTATO/REDUNDANT
**Tesi.** STATARB-RESID (thread 4, 2026-06-29) ha mostrato che il momentum del residuo ETH−β·BTC
(β OLS rolling, **sgn=+1**: le dislocazioni continuano a 1d) passa quasi tutti i gate su 2 gambe,
fallendo solo il deflated-Sharpe (0.929<0.95). Ipotesi qui: portare lo **stesso meccanismo
cross-sectional** sui 19 major di XS01 — per ogni alt, residuo vs β·BTC (β OLS rolling B), momentum
del residuo (blend z-score [30,90] come XS01 o singolo L), long top-k / short bottom-k, vol-target
20% — sperando che la **breadth** (18 stream invece di 1) alzasse il DSR dove il 2-gambe falliva.
Script `scripts/research/r0701_xs_residmom.py` (riusa l'harness collaudato `xsec_v2_nonmom`:
load_matrix, xs_engine — uguaglianza verificata maxdiff 0 —, deflated_sharpe, StrategyPortfolio).
Distinzione dal già-testato: IREV (idio-**reversal**, sgn=−1) era FALLITO nel filone C; IMOM di
xsec_v2 usava il mercato equal-weight come fattore, B=60 fisso, senza blend ed era solo riferimento.
Qui fattore = **BTC** (come STATARB-RESID, BTC escluso dal cross-section), B in griglia, blend
z-score, probe con gate di dispersione p30 (parità strutturale con XS01), **selezione in-sample-only**.
## Setup
- Universo: 19 major HL certificati (`data/raw/hl_*_1d.parquet`), 913 giorni [2024-01-01 → 2026-07-01],
barre vol=0 escluse. Fee 0.10% RT/gamba + sweep fino a 0.30%.
- Griglia (57 trial): β-window {60,90,120} × lookback {blend[30,90], 30, 90} × k {3,5} × H {5,10,20}
+ 3 probe gated (blend, k5, H10, gate dispersione p30). Cella scelta col solo Sharpe **pre-2025**;
hold-out 2025-01-01 bloccato. Causalità: prefix-check ok (max_tail_diff 0).
- Baseline (stessa finestra, sleeve attivi): XS01 FULL Sh **1.38** / HOLD **1.51** / DD 11%;
book 4-sleeve FULL 2.12 / HOLD 2.21.
## Esito — collasso OOS della cella in-sample e nessuna cella competitiva
Cella scelta in-sample: **B60 L30 k3 H20** (IS Sh 2.00):
```
FULL +0.67 | HOLD −0.24 | DD 35% | per-anno 2024 +54% / 2025 −15% / 2026 +5%
corr→XS01 +0.54 | corr→TP01 −0.09 | DSR 0.510 (57 trial) | fee-sweep ok (F+0.59 a 0.30%)
small-cap $600/min$5: haircut ≈ 0 (ma book multi-gamba → STAT-MODE comunque, come XS01)
```
Portafoglio (il bar del mandato):
```
BASE 4-sleeve FULL 2.12 DD 7.8% | HOLD 2.21 DD 3.5%
SOSTITUZIONE XS01 → cand FULL 2.01 (−0.10) | HOLD 1.18 (−1.03) ← distrugge l'hold-out
AGGIUNTA 5° sleeve @10/15% HOLD −0.31 / −0.53 ← diluisce
MARGINAL vs BOOK: corr +0.23, uplift@10% full −0.04 / hold −0.31, multi-cut 2025 −0.31 / 2026 −0.14
```
**Il verdetto non dipende dalla selezione** — aggregato delle 57 celle:
- FULL max **+0.94**, HOLD max **+0.82** (mediane +0.52/+0.33): *nessuna* cella si avvicina a XS01
(1.38/1.51), nemmeno cherry-pickando sull'hold-out.
- corr→XS01 in [+0.47, +0.71], mediana **+0.62**: è momentum XS01 travestito (la residualizzazione
vs β·BTC sposta poco: lo z-scoring cross-sectional di XS01 già rimuove implicitamente il mercato).
- Solo 4/57 celle passerebbero un gate "diversificatore" (|corrXS|<0.6, FULL>0.5, HOLD>0), tutte con
FULL ≤0.68 e IS incoerente.
- **corr(Sharpe in-sample, Sharpe hold-out) attraverso le celle = −0.37**: l'in-sample è
anti-predittivo dell'OOS su questa griglia — la firma del rumore, non di un edge con plateau.
## Perché la tesi è falsa (3 righe)
1. La breadth non ha alzato il DSR (0.51 ≪ 0.95) perché non c'è edge da deflazionare: il residuo
vs β·BTC sul cross-section degli alt NON eredita l'edge del 2-gambe ETH−β·BTC — quel lead vive
nella coppia specifica ETH/BTC (i due asset profondi/cointegrati), non nel long-tail degli alt.
2. Cross-sectional, la residualizzazione è quasi un no-op: demeaning z-score (XS01) ≈ togliere il
mercato → il candidato è una variante rumorosa di XS01 (corrXS mediana 0.62) con meno segnale.
3. In-sample = solo 2024 (~1 anno utile dopo il warmup): la selezione onesta atterra su una cella
2024-lucky che perde nel 2025-26 — l'ennesima conferma del gate selection-on-holdout.
## Verdetto: **SCARTATO/REDUNDANT.** Nessuno sleeve, nessun forward-monitor.
Coerente con il filone momentum-structure (2026-06-29): l'edge di XS01 sta nella sua struttura
specifica (blend + gate dispersione), e le sue varianti — incluso l'idio-momentum vs BTC — sono
REDUNDANT o peggio. Chiude anche il cerchio su STATARB-RESID: il meccanismo residuo-momentum resta
valido SOLO come coppia ETH/BTC (forward-monitor `paper_statarb`), non generalizza al cross-section.
Nessun impatto sul book live; config canonica invariata.
Script: `scripts/research/r0701_xs_residmom.py` (non committato, prefisso r0701_xs).
+69
View File
@@ -0,0 +1,69 @@
# 2026-07-01 — Stagionalità CROSS-SECTIONAL sull'universo Hyperliquid → SCARTATO
## Ipotesi
Effetti calendario **relativi tra i 19 alt major HL** (weekday tilt, turn-of-month,
pattern weekend→lunedì nel cross-section), long/short market-neutral. L'angolo è diverso
dal prior art già morto (trackF seasonality BTC/ETH = buy&hold travestito;
crypto_weekend_signal/overnight = look-ahead; open_drive = artefatto calendario ucciso da
`day_boundary_robust`): essendo il segnale **demeaned cross-section**, il buy&hold
travestito è strutturalmente escluso… *in prima battuta* (vedi diagnostica beta sotto).
## Metodo (test statistico PRIMA della strategia)
Script `scripts/research/r0701_xs_seasonal.py`. Dati `data/raw/hl_*_1d.parquet`, 19 major
XS01 (lista `src/portfolio/sleeves.XS_UNIVERSE`), **912 giorni** (2024-01-02 → 2026-07-01,
~2.5 anni), 0 barre vol=0. Ritorno relativo x[t,a] = r[t,a] − media cross-section del
giorno. Per ogni bucket calendario: **tilt bucket-specifico** per asset = media di x nel
bucket − tilt incondizionato dell'asset (isola il calendario dal drift relativo generico).
**Persistenza split-half**: Spearman rank-corr del vettore tilt (19 asset) H1 vs H2, per
bucket. **Null**: 2000 permutazioni delle etichette entro ciascuna metà → distribuzione del
**max-statistic** (controlla il multiple-testing sui bucket e il confound "alpha persistente
dell'asset"). Soglia severa p<0.05 sul max. Regola del mandato: senza persistenza →
**nessun backtest**.
## Numeri
| Test | Statistica | Null 95° pctl | p | Esito |
|---|---|---|---|---|
| [A] Weekday (7 bucket) | max rank-corr **+0.511** (Wed); Mon +0.38, Sun +0.37, Fri +0.04 | +0.604 | **0.159** | FAIL |
| [B] Weekend vs feriali | +0.268 | +0.428 | **0.178** | FAIL |
| [C] Turn-of-month (±2gg) | +0.221 | +0.451 | **0.226** | FAIL |
| [D] IC weekend→lunedì | FULL −0.053 (t=−1.94); H1 −0.006 (t=−0.17) vs H2 −0.100 (t=−2.4) | — | non persiste | FAIL |
Con ~65 osservazioni per weekday per metà, lo std di una rank-corr su 19 asset è ~0.24 → il
max-su-7 sotto puro rumore arriva a ~0.60: il +0.51 reale è *dentro* il rumore.
## Diagnostica: perché tutte le rank-corr weekday sono positive?
Non è tilt idiosincratico, è il **canale-beta**: il mercato EW ha un pattern weekday di
*livello* che si ripete nelle due metà (Sun −42/−30 bps, Sat +26/+25, Mon +35/+32) e la
dispersione di beta (0.53→1.26) lo proietta nel cross-section — rank-corr(tilt, beta):
**Sun −0.642**, Sat +0.325, feriali ~0. Cioè la poca "persistenza" visibile è l'effetto
weekday di MERCATO (dominio trackF, già scartato come buy&hold travestito) che rientra
dalla finestra via beta. Un eventuale L/S "weekday tilt" sarebbe stato in gran parte un
book short-beta-la-domenica — non un edge calendario cross-sectional.
## Note sui gate non raggiunti
- **day_boundary_robust** (obbligatorio per ogni effetto calendario): NON eseguibile sui
19 alt — i dati HL locali sono **solo 1d**, il confine giorno non è ri-tagliabile. Anche
con persistenza, il verdetto massimo sarebbe stato LEAD-forward *condizionato* a barre
orarie HL, mai sleeve. Con lo SCARTATO allo step 1 il punto è moot, ma resta il vincolo
per chiunque riapra il filone.
- **Fee**: mai arrivati al backtest; nota strutturale: un weekday-tilt L/S ribilancia ogni
giorno (weekday di domani ≠ oggi) → turnover ~2×gross/die, morte-per-fee quasi certa a
0.10% RT anche con edge lordo.
- **DSR**: non calcolato (nessuna cella backtestata — il branch strategia esiste nello
script ma non si attiva senza persistenza).
## Verdetto
**SCARTATO** allo step statistico, senza backtest. Tre motivi: (1) nessuna persistenza
split-half sopra il null permutato (p 0.16–0.23 su tutti i test, IC weekend→lunedì non
persiste tra le metà); (2) la sola struttura visibile è il canale-beta di un pattern
weekday di mercato — la stessa famiglia già scartata in trackF, non un effetto
cross-sectional; (3) ~2.5 anni × effetto calendario × turnover giornaliero = rumore +
morte-per-fee anche nello scenario migliore.
File: `scripts/research/r0701_xs_seasonal.py` (deterministico, seed 20260701, ~2 min).
@@ -0,0 +1,132 @@
# 2026-07-02 — Audit anchor timing-luck su XS01 e SKH01 (chiusura del pendente dell'ondata TIMING)
**Contesto.** L'ondata TIMING+CRT dello stesso giorno (`2026-07-02-timing-crt-wave.md`) ha stabilito
che l'hold-out di TP01 (0.31) è la **migliore delle 24 ancore daily possibili** (mediana 0.04,
P~0.86 di uno spike così per caso). Lo scettico ha flaggato l'audit come **pendente** sugli altri
due sleeve a ribilanciamento/griglia ancorata: **XS01** (fase del ciclo di ribilanciamento H=10
giorni) e **SKH01** (offset della griglia dual-TF 230m/690m, `origin='epoch'`). Questo diario
chiude entrambi. Due agenti indipendenti, metodologia identica allo scettico TP01
(`r0702_skeptic_offset.py`): ancore dichiarate **a priori**, parametri **identici** in ogni
fase/offset (zero tuning per-ancora), **sanity replica bit-exact** della sleeve canonica prima di
qualsiasi numero, block-bootstrap congiunto per P(spike).
**Script:** `scripts/research/r0702_anchor_xs01.py`, `scripts/research/r0702_anchor_skh01.py`.
Nessun file di produzione toccato dagli agenti (solo docstring/narrativa aggiornate a valle, qui).
---
## Verdetto in una riga
**Il finding TP01 si replica su TUTTI e tre gli sleeve ancorati — su SKH01 più forte che su TP01 —
e i numeri headline del book (HOLD 2.46) sono in parte best-of-anchors.** Ciò che sopravvive
de-luckato: XS01 resta un diversificatore ammissibile (ensemble di fase FULL 1.25 / HOLD 1.31 /
DD 11%); SKH01 resta ADDS (uplift del blend positivo a **tutte** le 23 fasi, corr ~0.08) ma i suoi
numeri headline e — cruciale — **il gate DD<30% che l'ha selezionata** non reggono alla fase
mediana. Stima onesta de-luckata del book 5-sleeve: **HOLD ~1.9–2.1, FULL ~2.0–2.2** (vs 2.46/2.24
dichiarati).
---
## XS01 — fase del ciclo di ribilanciamento H=10 (10 fasi)
Sanity: replica di `_xsec_returns` con parametro `phase` → **max|Δ|=0.0 bit-exact** vs la canonica.
NB: la canonica sui dati di oggi fa FULL 1.367/HOLD 1.479/DD 10.8% (i dichiarati 1.50/1.71/11%
erano del 2026-06-19; deriva dati, confronto interno coerente).
| metrica | min | mediana | max | canonica (f0) | pctl f0 |
|---|---|---|---|---|---|
| Sh FULL | 0.41 | 1.21 | 1.64 | 1.37 | 85° |
| Sh HOLD | 0.15 | 1.17 | 1.71 | 1.48 | 65° |
| maxDD | 10.0% | 15.5% | 29.1% | 10.8% | **15°** |
- **Firma diversa da TP01: la fortuna NON è nell'hold-out** (65° pctl, non estremo) **ma nel
DD** (15° pctl: il "DD 11%" dichiarato è uno dei più bassi delle 10 fasi; la fase tipica fa
~15.5%, la peggiore 29%) e nel FULL (85°).
- **Bootstrap**: spike osservato +0.38 su hold-out; **P(una fase qualsiasi ≥ +0.38) = 0.91–0.94**
(block 10/20/40, B=4000) → la canonica è il massimo atteso di 10 stime correlate (corr mediana
fra fasi 0.71).
- **Ensemble 10 fasi** (lens di reporting onesta): **FULL 1.25 / HOLD 1.31 / DD 10.9%** — la
diversificazione di fase riporta il DD al livello canonico con Sharpe ≈ mediana.
- **Book 5-sleeve**: HOLD 2.44 (canonica) → 2.26 (fase mediana) → 1.75 (peggiore, marginalmente
PEGGIO del book senza XS01 = 1.77) → 2.35 (ensemble). **Eredità di fortuna ~+0.17 HOLD.**
FULL quasi insensibile (2.10–2.28).
- **Gate di ammissione a fase mediana**: FULL 1.08 / HOLD 1.10 / DD 20.7% — **i numeri dichiarati
non reggono** (Sharpe −0.3/−0.6, DD raddoppia). **La decisione però regge**: nessuna fase
negativa, 8/10 con FULL≥1.0, book migliore a ogni fase tranne la peggiore (dove è neutro) →
slot da diversificatore @15% difendibile; cambia la NARRATIVA (banda/ensemble, non 1.50/1.71/11%).
- **Caveat**: storia ~2.5 anni (CI95 Sh HOLD canonica **[−0.04, +2.72]** — nessuna stima puntuale
affidabile); dimensione **ora-del-giorno non testabile** (solo barre 1d HL: resta luck residua
10 fasi × 24 ore non certificabile); XS01 è STAT-MODE → impatto su reporting/gate, non sul book
live Deribit.
## SKH01-V2-DD — offset della griglia dual-TF 230m/690m (23 offset × 30m)
Sanity: offset 0 riproduce `_skyhook_returns()` **bit-exact** (max|Δ|=0.0 su 2666 giorni); maxDD
harness BTC 21.4%/ETH 27.4% = identici al diario di ammissione; riuso diretto di
`skyhook_entries`/`htf_features`/`merge_htf_to_ltf` con `resample(origin='epoch', offset=...)`,
confini 690 ⊂ 230 verificati a ogni offset.
| metrica (book 50/50) | min | mediana | max | off0 (canonico) | pctl off0 |
|---|---|---|---|---|---|
| Sh FULL | 0.78 | 1.05 | 1.48 | 1.46 | 93° |
| Sh HOLD | 0.44 | 0.93 | 1.64 | 1.64 | **98° (max)** |
| minFull (2 asset) | 0.35 | 0.67 | 1.01 | 0.99 | 93° |
| minHold | −0.10 | 0.39 | 1.25 | 1.25 | **98° (max)** |
| blend 0.75·TP01+0.25·SKH, HOLD | 0.49 | 0.72 | 1.16 | 1.16 | **98° (max)** |
- **È uno spike, non un plateau**: gli offset adiacenti ±30m crollano (book HOLD 1.64 → 0.88 a
off30). Firma identica all'ancora TP01, ma **più forte**: il canonico è al 93–98° pctl di OGNI
metrica; minHold +1.26 e blend "0.31→1.17" sono il **massimo dei 23**.
- **Gate DD<30% — il criterio per cui V2-DD fu selezionata — FALLISCE in 15/23 offset**
(mediana DD: BTC 23.5%, ETH **29.2%** — pass per 0.8pt; peggiori 35.9%/42.1%). Il margine ETH
"già sottile" (27.4%) è in realtà **sotto la mediana di fase**: la proprietà DD<30% è in larga
parte fortuna di fase.
- **Ciò che regge de-luckato**: **uplift del blend positivo a TUTTE le 23 fasi** (min +0.18,
mediana +0.42, canonico +0.86) e corr→TP01 in [0.05, 0.11] a ogni fase → il verdetto
ADDS/diversificatore sopravvive, ridimensionato. Alla fase peggiore invece non regge
(minHold −0.10, DD fail).
- **Bootstrap**: spike blend +0.44; **P(un offset qualsiasi ≥ +0.44) ≈ 0.70** (block 10/20/40);
P(uplift≤0) = 0.03–0.04 → l'uplift è reale, l'ampiezza è best-of-23.
- **Book 5-sleeve**: HOLD 2.44 (off0 = max dei 23) → mediana **1.96** → ensemble 2.12; FULL 2.24 →
mediana 2.01. **Eredità di fortuna ~+0.5 HOLD** — molto più dei ~+0.10 dell'ancora TP01.
- **Rilevanza LIVE (SKH = 25% del book Deribit reale)**: il cron è orario, i confini 230m no →
ritardo uniforme {0..50} min (media 25). Re-sim del path reale (fill al close 5m del prossimo
run orario, exit SOFTWARE come da `book.py`): book 50/50 **FULL 1.46→1.19, HOLD 1.64→1.15,
DD 18.1%→24.6%**. La maggior parte del gap è l'assunzione fill-al-livello del backtest, non il
ritardo orario in sé: nei crash le barre 230m **gappano attraverso lo SL software** (short
sl2% modellato −2% → realizzato **−11/−23%**: ETH 2021-05-19, 2021-01-04, COVID 2020-03-13).
Il disaster-SL on-book −30% copre solo la coda estrema della posizione netta.
- **Caveat**: equity daily-step (lens Sharpe, come il canonico); l'ensemble di offset NON è
eseguibile live (gira una sola griglia) → serve solo come stima de-luckata; sim hourly senza
slippage/parziali.
## Book 5-sleeve — stima de-luckata congiunta (approssimata)
Ogni audit varia UN solo sleeve (gli altri restano canonici), quindi gli effetti non si sommano
esattamente; ordine di grandezza dell'eredità di fortuna sull'HOLD 2.46: TP01-ancora ~+0.10,
XS01-fase ~+0.17, SKH01-offset ~+0.5. **Stima onesta: HOLD ~1.9–2.1, FULL ~2.0–2.2, DD ~6%
(invariato)** — il book resta largamente positivo e diversificato a ogni combinazione testata,
ma il 2.46 è un massimo di ~24×10×23 configurazioni di ancora, non la stima centrale.
## Regole codificate in narrativa (CLAUDE.md aggiornato)
1. **I numeri headline di OGNI sleeve ancorato si citano con la banda d'ancora** (o come ensemble
di fase): vale già per TP01, ora anche per XS01 e SKH01 e per l'HOLD del book.
2. **Un gate di selezione (es. DD<30%) va verificato sulla banda di fase, non sull'ancora
canonica** — SKH01-V2-DD fu selezionata per una proprietà che tiene in 8/23 fasi.
3. Il candidato gate `anchor_luck_band()` in altlib sale di priorità: tre sleeve su tre ancorati
mostrano la stessa firma, e il deflated-Sharpe non conta questo multiple-testing.
## Follow-up (non eseguiti, da valutare)
- **Rivalutare il peso 25% di SKH01 nel book live Deribit**: l'aspettativa onesta della gamba SKH
è ≈ fase-mediana + path orario (blend HOLD ~0.72, non 1.17) con gap-through-stop reale nei
crash. L'uplift resta positivo a ogni fase → non c'è motivo di rimuoverla, ma il sizing fu
deciso su numeri best-of-23.
- Cadenza cron a 230m (o trigger sui confini di barra) per chiudere il gap di path orario.
- `anchor_luck_band()` in `altlib.py` come gate standard per candidati ancorati.
- Audit ora-del-giorno di XS01 quando esisterà un feed HL intraday certificato.
**Stato:** XS01/SKH01/pesi/book live INVARIATI (nessun cambio operativo da questo audit — è un
audit di reporting e di gate, e ogni cambio pesi dovrà passare `weights_tilt_null` +
selection-on-holdout). Test suite 168 verdi. Script audit committati.
@@ -0,0 +1,168 @@
# 2026-07-02 — Ondata "video claims": Elliott (3 filoni), Albimarini (2), capital scaling 2-5k
**Contesto.** Su richiesta: meccanizzare e testare le claim falsificabili di 4 video didattici
italiani (3 sulle onde di Elliott, 1 ricostruzione della "strategia Albimarini" — double diagonal
a credito su SPX), più l'audit dei muri di scala visto l'annuncio che il conto live verrà portato
a **2.000-5.000 $**. Sei agenti indipendenti, harness altlib, fee 0.10% RT, hold-out 2025-26 mai
usato per selezionare, banda d'ancora obbligatoria (regola dello stesso giorno). Nessun PASS →
nessuno scettico necessario. Nessun file di produzione toccato.
**Scripts:** `scripts/research/r0702_ell_{rangecycle,fibconfluence,channel}.py`,
`r0702_alb_{structure,claims}.py`, `r0702_capital_scaling.py`.
---
## Verdetto in una riga
**Elliott 3/3 SCARTATO** (range-cycle = rumore 0/24 Bonferroni; canale = Donchian travestito che
non batte il Donchian; Fibonacci = effetto posizione, non numeri magici). **Albimarini 2/2
SCARTATO** (la diagonale non domina nemmeno nel modello ed è fee-negativa su Deribit; il track
record dichiarato è consistente con zero skill al 20-45%, e va in rovina in ogni finestra storica
con una coda). **Capital scaling: l'unico vincolo vero a 2-5k è il cap $300/asset** — da alzare a
equity/2 al momento del deposito; tutto il resto si scioglie da solo o resta fuori comunque.
---
## ELL-A — "range-cycle" (onda 1 compressa → onda 3 ampia): RUMORE
Claim di Frost&Prechter/Larry Williams meccanizzato senza conteggio soggettivo: 2 definizioni di
segmento (flip TSMOM, zigzag k·ATR causale), impulso iniziale (N∈{3,5,10} barre, range/ATR
pre-segmento) vs ampiezza del seguito (claim A) e troncatura dell'ultimo terzo (claim B).
BTC/ETH 1d+1w, Spearman con null permutato (2000), Bonferroni m=24.
- **0/24 celle significative** (miglior p raw: A 0.061, B 0.058; Bonferroni 1.00 ovunque, FULL e
pre-2025). 7-9/12 celle col segno "giusto" = moneta su celle correlate.
- **Nessuna cella weekly regge a tutte e 7 le ancore** (p 0.02-0.05 di singole ancore = il
timing-luck d'ancora che da oggi non crediamo più; alcune celle flippano segno tra ancore).
- **Artefatto previsto e smascherato**: normalizzando col range POST-impulso la correlazione
diventa negativa per pura meccanica del denominatore — chi "conferma" il claim così misura
l'artefatto.
- Coerente con le famiglie di compressione già fallite nello sweep 104 (BRK08 NR7, BRK10
BB-squeeze, CMB05, VOL12). Campione strutturalmente piccolo (mediana 78 segmenti daily, ~30
weekly). Strategizzazione correttamente non eseguita (statistica prima della strategia).
⚠️ **LEZIONE PANDAS (gemella di `view("int64")` del 2026-07-01):** `resample("7D",
origin=...)` in pandas 2.x **ignora silenziosamente `origin`** ("D" non è Tick-like, solo un
RuntimeWarning) → tutte le ancore weekly uscivano identiche e la banda d'ancora sarebbe stata una
banda finta di larghezza zero. Serve **`"168h"`**. Da ricordare per ogni futura banda d'ancora
settimanale.
## ELL-B — Confluenza di Fibonacci: EFFETTO POSIZIONE, non numeri magici
Zigzag causale non-repainting (livelli usabili solo dalla conferma del pivot, causality_ok
max_tail_diff=0.0), tocco fresh intrabar, reazione ATR-normalizzata a 5/20 barre, ~24k/14k tocchi
IS a 1h. **Tre null in scala di durezza**: (A) rapporti uniformi casuali, (B) ri-sorteggiati per
swing, **(C) location-matched** (Fib ± jitter 2-8%: "0.618 è speciale vs 0.58/0.66?").
- Vs null A/B i Fib sembrano buoni (pctl 0.82-1.00) — **vs null C crollano a 0.39-0.68 = puro
caso**. L'apparente vantaggio è interamente l'effetto di *posizione* (i rapporti Fib cadono in
zone mediamente decenti del range), non dei numeri di Fibonacci.
- **Confluenza** (2 griglie entro 0.25·ATR): FAIL 4/4 celle — non reagisce più delle confluenze
di rapporti casuali. Break-rate al tocco ~46-50% (moneta); su 1h i Fib veri vengono bucati più
spesso del placebo.
- In assoluto comunque nulla da tradare: +2.6/+5.6 bps a 5 barre (fee = 10 bps), negativo a 20
barre e su 1d. Strategizzazione correttamente saltata da gate a priori.
- **Pattern di test riusabile**: il null location-matched è IL test giusto per ogni claim su
"livelli speciali" (Fib, pivot, round numbers) — separa la qualità della posizione dal numero.
## ELL-C — Tecnica del canale (Ftaonline): DONCHIAN TRAVESTITO
Implementazione onesta completa (zigzag causale, vincolo onda-2>origine, canale 0→min-2 con
parallela dal max-1, entry al close della barra fuori, target 1.618×, stop=invalidazione,
speculare short, 27 celle TF×k×varianti).
- **family_honest boccia**: cella scelta in-sample (1h k4 long, IS 1.40) → hold-out **−0.87**;
DSR 0.685 < 0.95; earns_slot=False. Marginale vs TP01: uplift positivo solo 2020-21 =
beta-trend del toro (corr 0.35).
- **Il Donchian banale a pari geometria/frequenza eguaglia o batte il canale a ogni TF**
(corr 0.43-0.53): vincoli d'onda + 1.618 non aggiungono nulla. Il segnale-2 ("onda 5") è
quasi inerte (+0.00-0.07).
- **Target 1.618 = geometria, non magia**: toccato con la frequenza di distanze identiche
piazzate a caso (5/6 celle p>0.18). Claim discriminante "in canale = correttivo":
direzionalmente sensata, mai significativa (p 0.08-0.45); l'uscita dal canale è momentum da
breakout, già in casa.
- **Anchor-luck di nuovo**: la miglior cella 4h fa hold 1.54 all'ancora 00:00, la migliore delle
4 (banda [0.35, 1.54]) — quarta conferma della firma nello stesso giorno.
## ALB-A — Double diagonal "Albimarini" su BTC/ETH: NON DOMINA, niente LEAD
Portata su Deribit (che ha le scadenze giornaliere per la long T+1) col motore DVOL di VRP01
(riprodotto esatto: 1.09/0.59/11.8%), strike scalati in vol (2σ/5g ≈ il "9% su SPY"), gate
IV-rank canonico non riottimizzato, 2021-26 con LUNA/FTX/2022, banda skew f∈{0.6,0.8,1.0,1.3}.
- **Il claim strutturale del corso è falsificato**: gated, l'iron condor stessa-scadenza batte la
diagonale a ogni f (1.05 vs 0.95 a f=1.0), Δ negativo ogni anno. La long T+1 è **assicurazione
di coda quantificata** (+12/+33 bps nei 5% peggiori vs ~1 bps di costo medio), non dominanza.
- **Senza gate tutte le strutture perdono** a f≤1.0 → terza conferma indipendente: nel VRP
l'alpha è il filtro di regime, non la vendita di premio. VRP01 resta superiore su tutta la
banda f (CAGR 8.3% vs 1.4%).
- **Il meccanismo dell'illusione riprodotto in vitro**: celle z≥2.5 = 0 perdite su 142 trade,
Sharpe 5.9-∞ (il punto cieco CC01 in forma opzioni); la best in-sample (7.88) crolla a −0.51
in hold-out. Seconda occorrenza del pattern "0-perdite = Sharpe implausibile" in una settimana
→ **si rafforza il caso per il gate `implausible_sharpe` in altlib** (raccomandato dal filone
CC01, ora con 2 casi d'uso).
## ALB-B — Audit dei numeri dichiarati (28 trade, 82%, PF 5.16, "420% annuo"): ZERO SKILL
SPY 1d 1996-2026 (parquet già in repo dal filone GTAA) + BTC/ETH certificati; MC 200k; replay
claim-anchored calibrato per riprodurre esattamente il video.
- **L'82% è incoerente col "deep OTM" in entrambe le letture**: strike a 9% → win strutturale
99.5% (P(|move 4td|>9%) = 0.53%, fat-tail 88× la normale); 82% letterale → strike a 2.63% ≈
1.2σ, non deep. In entrambi i casi win-rate = delta venduto.
- **P(track record del video senza edge) = 20-45%**; il **78.6%** di tutte le finestre 6-mesi
1996-2026 lo avrebbe prodotto (lettura deep). Il PF ~5.1 esce per costruzione quando la coda
non è campionata.
- **Replay attraverso le code reali**: rovina nel 1998/2002/2020 col sizing 1→4 dichiarato;
perfino regalando +20% di premio, 1 contratto fisso fa CAGR +4.1% con maxDD −95%. La stessa
semestrale del video annualizza a +73-77%, non 420%. Su BTC/ETH a EV=0: +12%/DD−68% e
+0%/DD−88%.
- **La diagonale lascia passare il 12-40%** della perdita naked in un −10% overnight (dipende dal
vol-spike). Su Deribit la double diagonal è **fee-negativa a qualsiasi size** (fee 8 gambe =
194-221% del theta raccolto a questi strike): il capitale sposta solo il muro di margine.
- Che cosa distingue VRP01 (sopravvissuto allo stesso tipo di audit): defined-risk per
costruzione, gate IV-rank che ribalta l'hold-out, sizing fisso — l'opposto esatto su tutti e
tre gli assi.
## Capital scaling 600 → 2000/3500/5000 (r0702_capital_scaling.py)
| capitale | TP01 haircut Sh | book investibile % (cap $300) | K=2 exec-turn % | statarb haircut | spread ETH conc. | XS01 exec-turn % |
|---|---|---|---|---|---|---|
| 600 | +0.010 | 100.0% | 90.5 | −0.004 | 0 | 56.9 |
| 2000 | −0.002 | 85.9% | 95.7 | 0.000 | 3 | 87.4 |
| 3500 | −0.002 | 63.7% | 97.5 | 0.000 | 5 | 89.3 |
| 5000 | −0.002 | **48.9%** | 98.2 | 0.000 | 7 | 90.8 |
- **Il vincolo dominante è UNO: `max_notional_per_asset_usd`=300.** A 5k il book girerebbe a
metà del target (cap binding nel 39-46% delle barre). **Proposta config (da applicare AL
deposito): cap = equity/2** → $1000 a 2k, $1750 a 3.5k, $2500 a 5k. `min_order_usd`=5 va
LASCIATO (il fee drag risale solo al tetto noto ~0.4%/anno; l'isteresi artificiale costerebbe
più in lag — lezione ondata timing).
- Min-order/haircut TP01 ≈ 0 a ogni capitale (conferma indipendente del "−74% ordini" a 600 →
39-43% saltati a 5k, tutti micro). Statarb: haircut 0 da 2k (il muro era l'edge, non la scala).
- Tranching K=2: matematicamente regge a 5k (98.2% turnover-tranche), ma il blocco vero resta il
feed intraday fuori path certificato + beneficio solo di varianza → **non cablare**.
- Opzioni: il muro d'ingresso ETH cade a ~2.6k (3-7 spread concorrenti a 2-5k, fee solo 5-6% del
credito grazie al cap 12.5%; rettifica vs ALB-A: margine spread ETH oggi $66-76). BTC granulare
da ~$4.7k. **La regola "niente short-vol da modello" non decade col capitale.**
- XS01: soglia ~20k confermata (a 5k il 9%+ del turnover non esegue). CC01: il capitale non è
mai stato il muro (fuori per ragioni strutturali).
- **Aspettativa onesta**: col CAGR de-luckato del book live (10-15%, audit SKH01): **2k ≈
€0.55-0.82/giorno; 5k ≈ €1.37-2.05/giorno**. Il salto di capitale cambia cosa è eseguibile,
non l'ordine di grandezza del ritorno (€50/g ≈ 130k, invariato).
## Lezioni
1. **Il null giusto smonta il livello "speciale"**: location-matched (ELL-B) per i livelli,
Donchian-equivalente (ELL-C) per i pattern, EV=0-calibrato (ALB-B) per i track record. In
tutti e tre i casi il claim sopravviveva ai null ingenui e moriva su quello giusto.
2. **`resample("7D", origin=...)` ignora origin in pandas 2.x** → usare `"168h"` per le bande
d'ancora settimanali.
3. Secondo caso "0-perdite = Sharpe implausibile" (celle deep-OTM di ALB-A, dopo CC01) → il gate
`implausible_sharpe` in altlib sale in coda ai lavori insieme ad `anchor_luck_band`.
4. L'anchor-luck è comparso spontaneamente anche in questa ondata (celle weekly ELL-A, 4h ELL-C)
— la regola della banda d'ancora sta già pagando.
**Stato:** nessun nuovo sleeve, nessun forward-monitor aggiunto, book live INVARIATO. Un'azione
operativa pende sul FUTURO deposito: alzare `max_notional_per_asset_usd` a equity/2 (decisione
utente al momento del funding). Test suite verde. 6 script committati.
+186
View File
@@ -0,0 +1,186 @@
# 2026-07-02 — Ondata timing + CRT (8 filoni multi-agente + scettico): 0 nuovi sleeve, 1 finding strutturale (anchor timing-luck di TP01)
**Obiettivo (goal utente):** "cerca su Deribit altre strategie profittevoli magari con timing
differenti oltre a quelle già valutate". Prima ondata interamente dedicata al TIMING: dopo che le
ondate precedenti hanno coperto segnali (104 famiglie alt-sweep), universi (HL cross-sectional),
opzioni (VRP/gamma) e pesi (EW-STR/weights_tilt_null), qui si attacca la dimensione rimasta: *quando*
si campiona, si decide e si esegue. Su richiesta utente, seconda tranche dedicata alla **CRT (Candle
Range Theory)**, il pattern sweep-and-reclaim a 3 candele di scuola ICT/Wyckoff.
Inventario preventivo per non rifare lavoro: SEA01-09 coprivano già hour-of-day, day-of-week,
weekend, turn-of-month, sessioni; l'onda intraday 2026-06-21 il sub-daily (con il lead prevday in
forward-monitor); `tp01_lowfreq` i TF 4h/12h/1d. Angoli NON coperti individuati e testati: clock a
eventi, calendario scadenze Deribit, ancora di ribilanciamento, clock più lenti del daily, velocità
del segnale regime-condizionata — più i 3 tagli CRT (base, multi-TF, contesto).
**Esito: 7 filoni FAIL + 1 finding strutturale confermato dallo scettico (timing-luck dell'ancora
di TP01). Nessun nuovo sleeve. Nessuna modifica al book live. Il soffitto ~1.3 direzionale
BTC/ETH resta intatto anche cambiando il clock.**
---
## Filone 1 — Event-clock bars (tempo-informazione): FAIL
`scripts/research/r0702_eventclock.py`. Volume/vol/range bars da 5m certificato (soglie causali
EWMA-90g shift(1), barre medie 4h/12h/24h), 5 strategie (TSMOM multi-orizzonte, Donchian 10/30d,
EWMA-cross), 45 celle event + 15 controlli wall-clock = 60 trial.
- Null decisivo (stesso segnale, stessa frequenza, wall-clock): event batte wall su ENTRAMBE le
finestre solo in **4/45 coppie (9%)** — rumore. Pattern incoerenti (EWMA event vince IS 9/9 ma
perde HOLD 9/9; Donchian-30d l'esatto opposto = selection-on-holdout in agguato).
- Cella scelta in-sample (volume-bars 24h, DONCH-10d): IS 1.45 → **HOLD −0.46** (2025 −7.4%,
2026 −18.1%). Marginal NEUTRAL (corr 0.74 a TP01 = trend travestito), earns_slot_honest=False.
- Executability comunque assente: in alta attività le barre "24h" chiudono in 3.6-4.6h (p5) → il
cron orario le eseguirebbe in ritardo; i clock 4h richiedono monitoraggio sub-orario.
**Lezione: campionare a tempo-informazione non normalizza nulla di monetizzabile sul feed
certificato; il clock non è la dimensione dove vive l'edge.**
## Filone 2 — Calendario scadenze Deribit: FAIL (0/24 celle)
`scripts/research/r0702_expiry_calendar.py`. Griglia dichiarata a priori: 4 finestre × 3 tipi expiry
(weekly ven 08:00 UTC / monthly ultimo ven / quarterly) × 2 asset, Bonferroni |t|≥3.08; 3 null
(placebo weekday, anchor-shift ±2/4h, permutation 500 calendari).
- Nessuna cella passa Bonferroni (max |t| 2.69). Il post-expiry drift monthly (+0.61/+0.77%) ha il
segno della teoria ma: non batte il placebo giovedì, permutation pctl 84-95 (non estremo), si
INVERTE sul quarterly (dove l'OI massimo dovrebbe amplificarlo) ed è guidato dal 2019 → rumore.
- Unica cella robusta ai null: weekly [-24,0) negativa (gio→ven), ma è indistinguibile dal
day-of-week (famiglia SEA già morta) e netta fee fa Sharpe ~0.08 (52 eventi/anno × 0.10% RT).
- Best-in-sample tradabile: IS +0.90 → **HOLD −0.52**; DSR 0.230 su 24 trial.
- Nota tecnica: colpito ESATTAMENTE il pitfall pandas 2.x documentato (epoca in secondi da
`date_range` su tz-aware → matching vuoto); fix con epoca ms esplicita. La lezione 2026-07-01
ha pagato.
## Filone 3 — Anchor timing-luck di TP01 + tranching: FINDING (verificato dallo scettico)
`scripts/research/r0702_tp01_offset.py` + scettico indipendente `r0702_skeptic_offset.py`
(ricostruzione bit-exact con codice diverso, zero riuso; h=0 riproduce `tp01_baseline_daily`
esattamente; vol-target ricalcolata per ancora; nessun look-ahead — verificato con troncamenti).
**Claim 1 CONFERMATO: l'hold-out 2025-26 "Sharpe 0.31" di TP01 è in larga parte fortuna
dell'ancora 00:00 UTC.** La stessa strategia CANONICAL alle altre 23 ancore orarie: HOLD mediano
**0.04**, banda **[−0.13, +0.30]** — e il massimo è proprio h=0 (98° pctl; in-sample era al 10°:
sfortunato lì, fortunato qui). Spike, non plateau (h=23/h=1 fanno 0.13/0.04). Bootstrap dello
scettico: P(una qualsiasi ancora mostri uno spike ≥ così) = **0.86** — è il massimo atteso di 24
stime correlate, non un'anomalia; best-anchor per finestra annuale ruota a caso (16→23→21→12→5→0,
Spearman ≈ 0, nessuna seasonality d'ancora). Formulazione corretta (NON "il vero hold-out è 0.07",
che ha CI95 [−1.2,+1.4] su 547 giorni): **l'hold-out 2025-26 non risolve l'edge di RITORNO di TP01**
(ritorno totale mediano ancore ≈ 0%); ciò che regge A OGNI ancora è il claim DIFENSIVO
(DD 6.7-10.1% vs ~60% B&H). Che è da sempre il vero valore dichiarato di TP01.
**Claim 2 (tranching multi-ancora) RIDIMENSIONATO:** K=4 ≡ esattamente EW di 4 book ancorati
(diff 1.4e-17), turnover identico (~8.3/y), haircut $600 ≈ 0. MA il "miglioramento" IS 1.49→1.56 è
per ~90% *tornare alla media delle ancore* (h=0 era sfortunato in-sample): vs ancora tipica
+0.005 mediano, P(K4≤h0)=0.18 n.s.; il taglio DD strutturale è ~0.5pt (non 2.8: la mediana delle
singole è già 12.6%). Ciò che regge: la compressione della VARIANZA DELLA STIMA (HOLD
[−0.12,+0.30]→[−0.01,+0.13] a K=4) → **lens di reporting, non alpha**.
**Impatto a valle (quantificato dallo scettico):**
- Blend SKH: HOLD 1.16 (h=0) → 0.97 mediana ancore, ma l'UPLIFT a mediana è +0.93 > +0.86
dichiarato → **il verdetto ADDS di SKH01 era conservativo, regge**.
- Book 5-sleeve: HOLD 2.44 → 2.34 mediana (min 2.22), FULL 2.24→2.22 → eredita **~+0.10** di
fortuna d'ancora (non +0.25: il peso di TP01 diluisce). Nessuna decisione (GTAA/SKH/pesi) cambia.
- NON toccati: tutti i FULL (h=0 al 31° pctl = normale), plateau, deflated-Sharpe, fee-sweep,
causalità, validazione GTAA (equity OOS), gate weights_tilt_null (relativo).
**Raccomandazione operativa (sottoscritta dallo scettico): cambio di narrativa e di standard di
reporting, NESSUN cambio del book live oggi.** (1) I numeri hold-out di TP01 si citano d'ora in poi
come banda d'ancora (mediana ~0.04, [−0.13,+0.30]) con valore = taglio DD; (2) valutazione
anchor-agnostic (media 24 ancore) come lens di reporting per i futuri hold-out; (3) NO deploy
K=2/K=4 a $600: guadagno ≈ 0, e a $225/asset di quota TP01 i delta per-ancora (~$1-2) sono sotto il
min-order $5 → degenererebbe comunque in K=1; inoltre le ancore intraday richiederebbero un feed
fresco fuori dal path certificato (staleness ×4 finestre di guasto). **Rivalutare K=2 (0,12) a
capitale ≥ ~5-10k.** (4) ⚠️ Audit analogo RACCOMANDATO su XS01 (rebalance 10g ancorato = spazio di
luck 10g×24h, potenzialmente peggiore) e SKH01 (fase griglia 230m/690m) — TP01 è oggi l'unico
sleeve de-luckato.
## Filone 4 — Clock lenti + banded rebalancing: FAIL (negativo utile)
`scripts/research/r0702_slow_clock.py`. Fatto a monte che chiude il filone: il fee drag di TP01 a
1d è **~0.40%/anno ≈ 0.03 Sharpe** (8 turnover/y × 0.10% RT) — il tetto di QUALSIASI risparmio.
- Clock N∈{2,3,5,7}g: degrado monotono dell'ensemble di fase (HOLD 0.34→0.11 da N=2 a N=7); lo
spread TRA fasi esplode a N≥5 (HOLD −0.19…+0.37 a N=7) = timing luck pura, coerente col filone 3.
- Bande di isteresi {2.5,5,10,20}%: tagliano il 77-94% degli ORDINI ma quasi zero TURNOVER (gli
ordini di TP01 sono micro-aggiustamenti del vol-target). Cella best-IS (band 20%): hold-out
0.13 vs 0.30 baseline, e il "guadagno" IS è effetto-segnale (posizioni stantie fortunate), non
effetto-costo → fitting. Non-monotonia sulla griglia = firma di rumore.
- **Finding utile per il live: a $600 il vincolo min-order $5 È GIÀ la banda ottimale** (ordini
427→111/y a costo Sharpe ~0, banda implicita 1.67%): cattura ~100% del risparmio catturabile.
Nessun cambio al book, a nessun capitale testato (600/2k/10k).
## Filone 5 — Velocità del trend regime-condizionata: FAIL
`scripts/research/r0702_regime_speed.py`. Pesi tra gli orizzonti TSMOM 30/90/180g condizionati al
percentile espandente di vol (realized e DVOL), 16 celle, sanity = riproduzione esatta del canonico.
- Cella best-IS (alta-vol→lento, linear, rv): FULL +0.06 ma **HOLD BTC −0.31**, 50/50 +0.005 →
dominanza fallita; multi-cut a segno instabile (+0.18/−0.08/+0.00).
- Null decisivo (300 pesi statici Dirichlet): la cella sta al pctl 0.71-0.72, sotto il p90 —
un peso statico casuale la batte spesso. Meccanismo smascherato: corr(peso-30d, Sharpe) = +0.93 →
le celle "regime" vincono in-sample perché tengono il tilt-30d la maggior parte dei giorni =
**tilt statico travestito da regime**, la stessa trappola di EW-STR. E il tilt statico verso il
30d NON regge su BTC hold-out (−0.15). RV e DVOL indistinguibili come misura di regime (coerente
con l'esito overlay DVOL 2026-06-26). Pesi canonici 1/3-1/3-1/3 confermati.
## Filoni 6-8 — CRT "Candle Range Theory" (base / multi-TF / contesto): FAIL 3/3
Il pattern sweep-and-reclaim a 3 candele (C1 range forte; C2 rompe un estremo ma chiude dentro =
"manipolazione"; C3 ingresso contro il breakout, stop dietro lo sweep, target all'estremo opposto),
meccanizzato onestamente in tre tagli. Overlap dichiarato: MRV01-11 e MIC07 non coprivano questa
meccanica; ora è coperta.
**6. Base single-TF** (`r0702_crt_base.py`, 864 trial su 1h/4h/12h/1d, motore trade-level
conservativo SL-first cross-checkato con l'harness): **DSR 0.000** (il null best-of-grid atteso è
Sharpe 2.27, ottenuto 0.74); cella best-IS (4h long color-rule) IS 0.90 → HOLD 0.07 con 2026 a
WR 0%; anchor-shift +1/+2h flippa l'hold-out a −1.0 (artifact-risk); lo **short su sweep dell'alto
(la narrativa smart-money canonica) perde perfino in-sample (−0.59)**. Autopsia: l'expectancy IS
veniva dal time-exit in trend (beta del toro ETH 2021-23), non dal target strutturale. Dettaglio
informativo: CRT batte nettamente sia il fade incondizionato (IS −0.49) sia il breakout-confermato
(IS −0.31) → il close-back-inside FILTRA davvero tossicità, ma "meno tossico del fade morto" non è
un edge.
**7. Multi-timeframe** (`r0702_crt_mtf.py`, 4h→15m e 1h→5m, ~10k trade): expectancy netta negativa
OVUNQUE (FULL e HOLD, entrambi gli asset); il MTF alza il R:R medio da ~3 a ~10-20 ma il WR collassa
da ~36% a 9-16% → "migliora" solo perdendo meno. **Refutazione strutturale: il ritest è informazione
negativa** — pattern CON ritest −40 bps, SENZA +52 bps (non tradabile: condiziona sul futuro):
aspettare il ritest per entrare seleziona sistematicamente i pattern peggiori; i buoni scappano
subito e il metodo non li prende mai. A fee ZERO l'edge lordo è ~0 (non è morte per fee: non c'è).
Stop 0.1-0.35% ineseguibili col cron orario (26-75% dei segnali già invalidati all'esecuzione).
**8. Contesto** (`r0702_crt_context.py`, 22 trial: livelli prevday/Donchian/prevweek × equal-H/L ×
FVG × sessioni): baseline incondizionata morta (8/8 celle HOLD<0); FVG semmai peggiora; sessione
EU consistentemente negativa; unica cella IS-positiva (sweep in Asia su livello prevday) uccisa 4
volte (DSR 0.001, anchor-flip a −2/−4h con la firma di open_drive — la sessione "Asia" inizia dove
il livello prevday viene ricreato —, solo-ETH, morta a 0.20% fee). **Sottoprodotto prezioso: sugli
STESSI livelli prior-day, FOLLOW batte FADE ogni singolo anno 2019-2026** (follow IS/HOLD
+1.22/+1.25 vs fade −0.66/−1.46, corr −0.19/−0.27) → conferma indipendente e rafforzativa del lead
prevday-breakout in forward-monitor (paper_prevday).
**Verdetto CRT: concetto Wyckoff riverniciato che, spogliato della discrezionalità, non contiene
edge su BTC/ETH Deribit certificati. La direzione giusta sui livelli affollati resta il FOLLOW
(breakout), non il fade — coerente con SKH01 (breakout) vivo e mean-reversion morta.**
---
## Lezioni codificabili
1. **Il timing-luck dell'ancora è una dimensione di multiple-testing NON coperta dai gate
esistenti** (deflated-Sharpe conta i trial, non le ancore implicite). Nuova regola di reporting:
ogni metrica hold-out di una strategia a ribilanciamento ancorato si cita con la banda d'ancora
(o la media anchor-agnostic). Candidato gate futuro: `anchor_luck_band()` in altlib. Audit
pendente: XS01 (10g), SKH01 (fase 230m/690m).
2. **La famiglia day_boundary_robust / anchor-shift continua a uccidere** (CRT base, CRT-Asia,
6/24 celle expiry): ogni effetto legato a etichettatura di barre VA spostato d'ancora prima di
crederci. Confermata la regola 2026-06-21.
3. **Il fee drag di TP01 (~0.4%/anno) non è un problema da risolvere** — chiude a priori il filone
"esecuzione più furba" a questo turnover; il min-order small-cap è già la banda ottimale.
4. Il pitfall pandas tz-aware/epoca (2026-07-01) è stato evitato/gestito 2 volte su 9 agenti grazie
alla documentazione in CLAUDE.md — il costo di documentare i bug paga.
## Stato finale
- 0 nuovi sleeve; portafoglio e book live INVARIATI (5-sleeve 33/15/12/20/20; book Deribit
TP01+SKH01 75/25, flat da armamento — il segnale resta risk-off).
- Narrativa TP01 aggiornata (CLAUDE.md + docstring): hold-out = banda d'ancora, valore = difesa DD.
- Script: `scripts/research/r0702_{eventclock,expiry_calendar,tp01_offset,slow_clock,regime_speed,
crt_base,crt_mtf,crt_context,skeptic_offset}.py`. Test suite: invariata, verde.
+111
View File
@@ -0,0 +1,111 @@
# 2026-07-03 — Frontiera rischio/rendimento del book: quanto caldo correre a 2k-5k
**Contesto.** Dopo la diagnosi strategica ("€50/g è un problema di capitale e di frontiera, non di
alpha; hai costruito una macchina difensiva a DD 6% ma hai capitale piccolo e obiettivo di
crescita"), goal: **misurare** (non cercare segnali) la frontiera CAGR/DD/P-rovina in funzione del
target-vol, pesata per confidenza per-sleeve, a €2k e €5k — per decidere quanto caldo girare il book.
Workflow: 3 filoni (curva / onestà-della-coda / eseguibile+Kelly), refuter fat-tail su ciascuno,
scettico sintetizzatore. 7 agenti, 0 errori. Sanity bit-exact di entrambi i book prima di ogni numero.
**Scripts:** `scripts/research/r0703_frontier_{curve,tail,exec}.py`. Nessun file di produzione
toccato, nessun commit dagli agenti, `config/live.json` NON modificato (cap solo proposto).
---
## Verdetto in una riga
**La tesi "corri più caldo" era in gran parte un MIRAGGIO DI REGIME.** Il "~6% attuale" non è un
target scelto: è la vol *realizzata* in regime risk-off (TP01 spesso flat 0.0x → il conto è flat
*by design*). A lambda=1 il book LIVE a 2 sleeve gira **già a ~11% vol / 9.4% DD**. Quindi "saltare
da 6% a 10%" NON è aggiungere leva — è solo assumere che il book non sia risk-off. **Il numero
onesto è: gira alla vol NATIVA (~10%, banda 8-11%), non levare.** Guadagno reale vs il 6% risk-off:
**+€0.2/g @2k, +€0.5/g @5k** — reale ma modesto, comprato con un DD plausibile di ~€500 su €2k. €50/g
resta ~130k, invariato.
---
## I numeri (frontiera fidata, non full-Sharpe)
Sanity (deriva nulla): 5-sleeve FULL Sh **2.238** / HOLD 2.452 / DD 6.17% / vol nativa 7.84%;
2-sleeve live FULL Sh **1.776** / HOLD 1.162 / DD 9.42% / vol nativa 10.96%.
**Scale-invarianza confermata da tutti e 3 i refuter:** il capitale NON cambia la matematica del
target-vol (le tabelle sono in %), cambia solo l'ESEGUIBILITÀ → **stesso % a 2k e 5k.**
### Book LIVE 2-sleeve (TP01+SKH01) — l'unico eseguibile <20k
- **Target-vol raccomandato: ~10%, banda [8%, 11%], lambda ≈ 0.9.** Sopra la vol nativa non si va.
- €/giorno al punto fidato (haircut): CAGR full-sample 12.9% → €0.71@2k / €1.77@5k; ma **HOLD-onesto**
(de-luck) CAGR ~4.5% → **€0.25@2k / €0.62@5k**. Il lato-reward headline è ~3× l'onesto (HOLD≪FULL).
- **Stima centrale onesta: €0.3-0.7/g @2k, €0.8-1.8/g @5k.**
### Book PIENO 5-sleeve — ASPIRAZIONALE, non gira <20k
Frontiera fidata regge ~12-15% sotto tail estremo, ~20% sotto tail mite — ma XS01 serve ~20k e VRP01
è modellato → rilevante solo per il tracking di `paper_combo`, non per una decisione di deploy a 2-5k.
---
## I quattro insegnamenti strutturali
### 1. La rovina-50% è la metrica SBAGLIATA (trappola esposta dal curve-refuter)
P(rovina-50%|5y) resta <1% fino a ~20-22% di target-vol su ogni book — i book sono troppo lisci/
diversificati per bruciare metà capitale entro la distribuzione campionaria. **La risposta letterale
"max CAGR a P(rovina)<1%" direbbe "gira al 22%" — ed è un suicidio**: lì P(DD>30%|5y) ≈ 20-25%. Il
vincolo che MORDE è **P(DD>30%), super-lineare** (raddoppia ~ogni 2.5 punti di vol). E la rovina-50%
non è nemmeno robusta ad alta vol (block-15 vs block-20 danno 7.1% vs 0.9% a tv30%) → altro motivo
per stare bassi.
### 2. Il muro fat-tail ONESTO è ~12%, più basso della carta (~15%)
Tre ragioni che il modello sottostima: **(a) gap-through-stop SKH già osservato reale** (sl2%
modellato → −11/−23% realizzato — la coda vera NON è nei rendimenti modellati; l'iniezione dei
finder usava lo *clean-stop* → ~2× troppo mite); **(b) il 2-sleeve è 4× più crash-sensibile del
5-sleeve** (+14.5pt vs +3.5pt di P(DD>30) all'iniezione, diversificazione sottile); **(c)
vol-targeting a lambda costante lagga nello spike** → sei più levato *entrando* nel crash.
**LIVE 2-sleeve: non superare ~12%; mai 15-20%** (triplica il DD-in-euro senza margine di coda).
### 3. Aggressività differenziata-per-confidenza (TP01 più caldo di VRP) — REFUTATA
La mia proposta era intuitiva ma **sbagliata, e i numeri lo dicono netto**: differenziare la vol per
confidenza PEGGIORA la frontiera (5s Sharpe 2.24→2.11, 2s 1.78→1.69) perché **taglia la
diversificazione** di VRP/XS (corr uniforme-vs-differenziato 0.98-0.99). **Regola corretta: la bassa
fiducia sull'EDGE si esprime DE-MEANando lo sleeve in aspettativa (= la frontiera haircut), NON
riducendone l'esposizione/vol.** La confidenza vive nell'haircut della media, non nella leva. Tutti
gli sleeve alla stessa leva.
### 4. La diversificazione LIMA la coda sinistra in-sample (sorpresa onesta)
Per il 5-sleeve ben diversificato il block-bootstrap dà P(DD>30) SOTTO il Gaussiano iso-vol (30%:
10.6% reale vs 21.1% gauss) — la coda in-sample è benigna. Il segnale fat-tail vive in due posti:
l'**iniezione di crash sintetico** (il campione non contiene il crash peggiore di ogni sleeve) e
il **book live sottile** (2 gambe, drift haircut) dove il bootstrap SUPERA il Gaussiano. Cioè: la
frontiera è affidabile finché il futuro somiglia al passato campionato, e fragile esattamente dove
le storie sono corte (VRP mai stressato reale, XS 2.5y, nessun 2018/pre-2018).
---
## Azione concreta (proposta, NON applicata)
1. **Nessun cambio di leva sul codice.** Il book gira già ≈ al punto fidato: LASCIARE `target_vol=20%`
di TP01 (canonico, la vol nativa del book emerge a ~8-11%). Non c'è una leva da girare su.
2. **⚠️ L'UNICO cambio che conta: `config/live.json` `max_notional_per_asset_usd` da $300 a
equity/2** ($1000@2k / $1750@3.5k / $2500@5k). Senza, il cap $300 tappa la vol raggiungibile a
13%@2k / 8%@3.5k / **6%@5k** → **throttling paradossale: più capitale = book più freddo**, forzato
sotto il punto fidato. Da applicare AL deposito. (config NON toccato ora.)
3. `min_order_usd=5`: LASCIARE (banda d'isteresi gratuita). Tranching K=2: NON cablare. Vol
differenziata: NON implementare (Q3).
---
## Brutalità sui limiti
- **Storie corte = il difetto strutturale.** TP01/SKH dal 2019 (no 2018), VRP dal 2021, XS **2.5
anni** (no 2022). Il block-bootstrap non può campionare un crash mai visto; l'iniezione sintetica
è l'unico proxy, e quella dei finder era ~2× troppo mite.
- **VRP01 è MODELLATO** (f-di-stress mai catturato su un crash reale) → l'haircut −50% è stima, non
misura; resta STAT-MODE anche a 5k (regola: niente short-vol da modello in deploy).
- **HOLD ≪ FULL sul book live** (1.78 vs 1.16) → il lato-reward headline è in gran parte artefatto
full-sample; citare i €/g su base HOLD-onesta.
- **€50/g NON è risolto e non lo sarà da questo.** Il warm-up compra ~€0.2/g@2k. La via resta
**capitale + tempo**; la regola "niente leva alta come base" è rispettata (la raccomandazione è
"gira alla vol nativa", non "corri caldo").
**Numero unico da portare a casa:** book LIVE a **~10% target-vol (lambda ≈ 0.9, banda 8-11%)**,
uguale a 2k e 5k, con **cap → equity/2** come unica azione config; muro invalicabile a **~12%**;
guadagno reale vs il 6% risk-off ~**+€0.2/g@2k / +€0.5/g@5k** — reale ma modesto.
+47
View File
@@ -0,0 +1,47 @@
# 2026-07-03 — Cap notional per-asset DINAMICO (= equity/2): operazionalizza la decisione frontier
**Contesto.** La frontiera del 2026-07-03 (`docs/diary/2026-07-03-book-frontier.md`) aveva identificato
**una sola** azione config con impatto reale: portare `max_notional_per_asset_usd` da $300 fisso a
**equity/2**, perché il cap fisso strozza il book man mano che si deposita (paradosso: più capitale =
book più freddo — a $5k il cap $300 fa girare il libro al ~49% del target). Il diario la lasciava
"da applicare AL deposito". Qui la **operazionalizzo in codice** rendendo il cap dinamico, così è
sempre corretta e non richiede un edit manuale al deposito.
## Cosa è cambiato
- **`src/live/book.py` — `_cap()`**: se in config c'è `max_notional_per_asset_frac` (opt-in), il cap
per-asset diventa **`equity × frac`** (0.5 → equity/2). Senza la chiave → comportamento vecchio
(cap fisso `max_notional_per_asset_usd`). Il call site in `book_report()` passa
`equity`, `real_equity`, `eq_fallback` a `_cap()`.
- **`config/live.json`**: aggiunto `max_notional_per_asset_frac: 0.5` (+ nota). `max_notional_per_asset_usd`
resta come **cap fisso di fallback**.
- **`tests/test_book_live.py`**: +4 test (scaling con equity fidata, fallback su eq_fallback/real=None/
equity 0, no-frac, integrazione online). Suite: **172 passed**.
## Il guardrail di sicurezza (il punto delicato)
Il cap dinamico si usa **SOLO con equity reale fidata** (letta dal conto). Se l'equity reale non è
leggibile — `eq_fallback` attivo, `real_equity=None`, offline, o equity ≤ 0 — si **torna al cap fisso
$300**. Motivo: in fallback `equity` è il paper-cap ($2000 ipotetico); calcolare `equity/2 = $1000` su
un conto di importo reale **ignoto** sizerebbe troppo. Preserva esattamente la protezione downside che
il test `test_book_execute_eq_fallback_warns_but_proceeds` verificava (l'hard-cap $/asset protegge
quando E è ignota). Regola: **equity/2 solo quando ci fidiamo di E; altrimenti $300 fisso.**
## Verifica
- **Live dry-run reale** (nessun `--execute`, nessun ordine): `cap/asset **$299**` = $598.06/2 →
**INERTE** oggi (≡ vecchio $300). Book flat, HOLD.
- Offline / `equity_override`: cap resta **$300 fisso** (nessuna equity reale da fidarsi) → il test
di parità pre-esistente regge invariato.
- A $5.000 di equity il cap diventerebbe automaticamente **$2.500** (equity/2), rimuovendo il
throttling che la frontiera aveva quantificato.
## Impatto e limiti
- **Già attivo**: il cron orario (`cron_book.sh`) esegue dal working tree → il prossimo run legge già
`frac=0.5`. Nessun deploy separato. **Inerte a $600**, si "accende" da sé quando l'equity cresce.
- **NON avvicina €50/g**: la frontiera lo aveva già detto — è una miglioria marginale (+€0.2/g @2k,
+€0.5/g @5k), il cui unico scopo è non lasciare capitale futuro strozzato. €50/g resta un problema
di **capitale + tempo** (~130k @ CAGR onesto), non di questo cap.
- Nessun cambio di **leva** (TP01 `target_vol=20%` invariato, la vol nativa ~10% emerge da sola —
coerente col verdetto frontier "gira alla vol nativa, non levare").
@@ -0,0 +1,156 @@
# 2026-07-03 — STATO COMPLETO DEL PROGETTO (snapshot)
Foto d'insieme dopo le ondate di ricerca del 1-3 luglio 2026 (timing/CRT, anchor-audit,
video-claims Elliott/Albimarini, capital-scaling, migliora-e-proteggi VRP01). Serve come punto di
riferimento unico: *dove siamo, cosa gira, cosa è provato, cosa resta aperto.*
---
## 1. In una frase
Progetto post-reset v2.0.0: su dati Deribit mainnet certificati (solo BTC/ETH) abbiamo costruito un
**portafoglio di 5 strategie diversificate** (research Sharpe ~2.2, DD ~6%), di cui **2 sono
eseguite live su Deribit** in un book nettato in software. Il conto reale è **~$598, flat** perché
il segnale trend è risk-off. Il valore delle strategie è **difensivo** (taglio del drawdown), non
generazione di ritorno: il target €50/giorno resta lontano (serve ~130k di capitale). L'onestà
metodologica è il vero asset accumulato: ~10 gate anti-illusione codificati, decine di edge
falsificati.
---
## 2. Il book LIVE (soldi reali)
- **Conto:** Deribit mainnet, USDC linear, **equity reale $598.06** (NON i €2000 nominali del paper).
- **Cosa gira:** `deribit_book_sleeves` = **TP01 (0.75) + SKH01 (0.25)** nettati in software su un
solo conto; UN ordine con segno per asset (BTC, ETH). `config/live.json`
**`execution_enabled=true`** → esecuzione ARMATA e reale.
- **Cadenza:** cron ORARIO `scripts/cron_book.sh` → `scripts/live/book_execute.py` (SKH01 decide su
griglia 230m; exit software, latenza fino a fine barra).
- **Guardrail:** cap **$300 notional/asset**, min order $5, **disaster-SL on-book −30%** sulla
posizione netta, alert Telegram su esecuzione/errori, gate fail-safe su posizione/equity non
leggibili (non opera a cieco).
- **Stato corrente (ultimo cron 2026-07-03 07:00Z):** BTC e ETH **flat, HOLD a target** — il target
TSMOM è risk-off (trend 0.0x) e SKH01 è flat (nessun breakout) → **zero ordini reali mai eseguiti**
da quando è armato (2026-06-23): il conto è flat *by design*, non per un errore.
- **NON nel book live:** XS01, VRP01, GTAA01 (research/paper/STAT-MODE).
## 3. Il portafoglio RESEARCH (5 sleeve) — `src/portfolio/sleeves.active_sleeves`
| Sleeve | Peso | Meccanismo | Dati | Stato |
|---|---|---|---|---|
| **TP01** | 33% | TSMOM difensivo trend BTC/ETH 1d, long-flat, vol-target 20% | 2019→ | **Deploy pieno** (nel book live) |
| **SKH01** | 20% | Dual-TF regime+breakout BTC/ETH, L/S, exit %-asimmetrici | 2019→ | Research → nel book live |
| **GTAA01** | 20% | Trend difensivo equity 6-ETF (IB), ~30 anni storia | 1996→ | Paper (paper_combo) |
| **VRP01** | 12% | Options short-vol (put credit spread + gate IV-rank) | 2021→ | LEAD modellato (STAT-MODE) |
| **XS01** | 15% | Cross-sectional momentum 19 alt Hyperliquid | 2024→ | STAT-MODE (serve ~20k) |
- **Combinato (research, ancore canoniche):** FULL Sharpe **2.24**, HOLD-OUT **2.46**, DD full **6.2%**.
- **⚠️ Stima DE-LUCKATA onesta** (dopo gli anchor-audit, vedi §5): **HOLD ~1.9-2.1, FULL ~2.0-2.2,
DD ~6%**. Il 2.46 è un massimo di configurazioni d'ancora, non la stima centrale.
- Sleeve a date d'inizio diverse → outer-join con pesi rinormalizzati (`combine_outer`).
- Report: `scripts/portfolio/run_portfolio.py`. Il book live (TP01+SKH01 75/25) è un sottoinsieme.
## 4. Paper trader / forward-monitor attivi (nessun soldo reale)
- **paper_trend** — TP01 1d, capitale nominale 2000, forward-only.
- **paper_combo** — book 5-sleeve completo (incl. GTAA/VRP/XS) dal 2026-06-22.
- **paper_statarb** — STATARB-RESID (ETH−β·BTC residual momentum, W=45/sgn=+1 congelati), doppio
libro MODELED/REAL-$600. LEAD eseguibile a $600 sotto soglia solo sull'edge (DSR 0.929).
- **paper_prevday** — FOLLOW prior-day levels (3 trade registrati); confermato indipendentemente da
più ondate (FOLLOW > FADE ogni anno 2019-26).
---
## 5. Finding strutturale del blocco 1-3 luglio: ANCHOR TIMING-LUCK (audit COMPLETO 4/4)
Le strategie a ribilanciamento/griglia ancorata hanno un'ancora "canonica" che è spesso il
**migliore** di molte configurazioni equivalenti (giorno/ora/offset) — un multiple-testing che il
deflated-Sharpe NON conta. Audit eseguito su tutti e 4 gli sleeve ancorati:
| Sleeve | Spazio d'ancora | Firma | Conseguenza |
|---|---|---|---|
| **TP01** | 24 ore (barra daily) | canonica = migliore (P=0.86) | hold-out 0.31 non risolve l'edge di ritorno; regge solo il taglio DD |
| **XS01** | 10 fasi (ciclo 10g) | canonica al 15° pctl di DD | numeri headline conservativi sul DD, non sull'hold-out |
| **SKH01** | 23 offset (griglia 230/690m) | canonica = 93-98° pctl (peggiore firma) | gate DD<30% fallisce in 15/23 offset; ~+0.5 HOLD di fortuna sul book |
| **VRP01** | 7 giorni (ciclo settimanale) | **canonica = PEGGIORE** (7° pctl) | **numeri CONSERVATIVI**, non gonfiati — unico sleeve senza luck |
**Regola codificata:** i numeri hold-out di strategie ancorate si citano **con banda d'ancora**.
Candidato gate futuro: `anchor_luck_band()` in altlib. Diari: `2026-07-02-timing-crt-wave.md`,
`2026-07-02-anchor-audit-xs01-skh01.md`, `2026-07-03-vrp-improve-dd.md`.
---
## 6. Cosa è PROVATO e MORTO (per non ri-testarlo)
- **Soffitto BTC/ETH-direzionale ~1.3** confermato da ogni ondata; superato solo dal cross-sectional
(XS01) e dalla diversificazione multi-sleeve.
- **Sweep 104 famiglie** (2026-06-20): 1 sola sopravvissuta, comunque non deployabile.
- **Opzioni long-vol** (gamma scalping): specchio del VRP, perde ogni anno/variante/frequenza.
- **Cash-and-carry (CC01):** premio reale ma Sharpe artefatto (manca il 2022, procyclico) → STAT-MODE.
- **Timing/clock alternativi** (event-clock, expiry calendar, clock lenti, regime-speed): 0 edge.
- **CRT "Candle Range Theory"** (3/3 FAIL): DSR 0.000, expectancy negativa anche a fee zero, il
ritest è informazione negativa; sui livelli prior-day FOLLOW > FADE.
- **Elliott (3/3 FAIL):** range-cycle = rumore; Fibonacci = effetto posizione non numeri magici;
canale = Donchian travestito.
- **Albimarini double-diagonal (2/2 FAIL):** non domina il condor, fee-negativa su Deribit, track
record consistente con zero skill (P=20-45%), rovina nei replay con code reali.
- **VRP01 miglioramenti (0/7 filoni):** struttura, overlay-DD, gate nuovi (4° fallimento), sizing,
gate SPX (confound di modello) — **VRP01 non migliorabile; la protezione DD si compra con la size.**
## 7. Regole/gate anti-illusione codificati (l'asset metodologico)
- **Certificazione dati** obbligatoria (solo Deribit mainnet, BTC/ETH; alt esclusi).
- **`marginal_vs_tp01` / `study_marginal`** (earns_slot) — Sharpe MARGINALE, non assoluto.
- **`study_family_honest` / `select_cell_insample` / `deflated_sharpe≥0.95`** — anti selection-on-holdout.
- **`day_boundary_robust`** — effetti calendario che si invertono spostando il confine = artefatto.
- **`eval_weights_smallcap`** — Sharpe haircut reale a capitale piccolo (sub-min-order = finzione).
- **`weights_tilt_null`** — ogni cambio pesi vs null dei tilt casuali cap-respecting.
- **Banda d'ancora** (nuova, luglio) — per ogni costrutto ancorato.
- **Candidati in coda:** `anchor_luck_band` (multiple-testing d'ancora); `implausible_sharpe`
(0-perdite / Sharpe implausibile — 3 occorrenze: CC01, ALB-A, griglia struttura VRP).
- **Lezioni pandas:** mai `DatetimeIndex.view("int64")` su tz-aware; `resample("7D", origin=)`
ignora origin (usare `"168h"`); un gate che si correla con un errore di modello è indistinguibile
da alpha finché non correggi il modello.
---
## 8. Onestà sui numeri e sul target
- **€50/giorno da €1.000-2.000 NON è raggiungibile** in 1-2 anni: serve ~130k di capitale o un DD da
rovina. La leva non è la scorciatoia (5x raddoppia il DD). La via è target-vol + capitale + tempo.
- Aspettativa onesta col CAGR de-luckato del book (10-15%): **~€0.6-0.8/giorno a 2k, ~€1.4-2/giorno
a 5k**. Il salto di capitale cambia *cosa è eseguibile*, non l'ordine di grandezza del ritorno.
- Il valore reale di TP01/del book è il **taglio del drawdown ~6× vs buy&hold**, non l'alpha.
## 9. Capitale in arrivo 2-5k — cosa cambia (audit r0702_capital_scaling)
- **Unico vincolo binding: il cap `max_notional_per_asset_usd=300`.** A 5k il book live girerebbe al
~49% del target. **Azione pendente sul deposito: alzare il cap a equity/2** ($1000/$1750/$2500 a
2k/3.5k/5k). `min_order_usd=5` da lasciare.
- Tranching K=2: matematicamente regge a 5k ma serve feed intraday fuori path certificato → non cablare.
- Opzioni ETH eseguibili da ~2.6k (spread), ma **la regola "niente short-vol da modello in deploy"
non decade col capitale**. XS01 resta fuori fino a ~20k. CC01 fuori per struttura.
- ⚠️ Disambiguazione unità: il "12%" come peso book (~0.014 Kelly) ≠ "12%" come margine/equity
(~0.27 Kelly) — **fattore 19x**.
## 10. Aperto / prossimi passi
1. **Al deposito 2-5k:** alzare il cap $/asset (proposta pronta, `config/live.json` non ancora toccato).
2. **Forward-monitor da maturare:** paper_statarb (edge sotto soglia DSR), paper_prevday (FOLLOW),
paper_combo (book completo). Se la finestra forward conferma STATARB-RESID → deployabile a 2 gambe.
3. **Gate da codificare:** `anchor_luck_band`, `implausible_sharpe`.
4. **Rivisite temporizzate:** term-structure DVOL (logger dal 2026-06-26, rivalutare a 6-12 mesi);
breadth/internals HL (1-2 anni di storia nativa); tranching a ≥5-10k; VRP stress-f su un crash reale.
5. **Ricerca strategie nuove:** il soffitto direzionale ~1.3 è saturo; i margini restano in meccanismi
ORTOGONALI (cross-sectional, relative-value, options gated) e nella diversificazione, non in nuovi
segnali direzionali BTC/ETH.
---
## 11. Stato tecnico
- **Versione:** 2.0.0 (semver in `VERSION`). **Test:** 168 verdi (28 file). **Diari:** 76.
- **Ultimi commit:** `26f8d27` (migliora+proteggi VRP01), `76120b5` (video-claims + capital-scaling),
`a74cc69` (anchor-audit XS01/SKH01), `e6657fc` (GTAA01 5° sleeve).
- **Working tree pulito, tutto pushato.** Book live sano e invariato da tutta la ricerca (research
isolata: nessun agente tocca src/config/live).
+167
View File
@@ -0,0 +1,167 @@
# 2026-07-03 — Ondata "migliora e proteggi VRP01 dai DD" (7 filoni + verifica a 2 lenti + scettico incrociato)
**Contesto.** Dopo la chiusura del dossier Albimarini (3 backtest indipendenti convergenti: premio
piccolo e reale, code non campionate, numeri del corso spiegabili al 100% dalla struttura del
payoff), goal esplicito: **migliorare la strategia short-vol** — la famiglia Albimarini → il nostro
**VRP01**, l'unica forma sopravvissuta agli audit — **e proteggerla dai drawdown**, con
orchestrazione a decine di agenti. Workflow deterministico: 7 filoni di ricerca in parallelo, 2
refuter avversariali (lente selection-bias + lente de-levering) su ogni miglioramento proposto,
scettico incrociato finale sui sopravvissuti. **26 agenti, 0 errori.**
**Scripts:** `scripts/research/r0703_vrpimp_{structgrid,ddoverlay,sizing,newgates,anchor,spxgate,stresslab}.py`.
Nessun file di produzione toccato, nessun commit dagli agenti. Motore riusato: `r0702_alb_structure.py`
(DVOL, riproduce VRP01 bit-exact: baseline bridge max|diff|=0.00e+00 su 266 settimane).
---
## Verdetto in una riga
**VRP01 non è migliorabile oltre lo status quo, e la protezione DD si compra SOLO con la size.**
Zero nuovi sleeve, zero overlay che reggono, zero gate nuovi, zero cambio di sizing. I due unici
"sopravvissuti" alla verifica **non propongono alcun cambiamento** (una conferma dello status quo +
una lente di misura). Il candidato più luccicante dell'ondata — un gate term-structure VIX su SPX
con ΔSharpe +0.90 e DSR 0.992 — è stato smontato dallo scettico come **confound di modello al
100%**. Deliverable reale = **audit anchor-luck di VRP01 CHIUSO** (ultimo sleeve ancorato): la fase
canonica è all'estremo **conservativo** della banda, quindi i numeri di ammissione reggono e da ora
si citano con banda.
---
## I 7 filoni
### 1. Griglia di struttura (288 celle) — NESSUNA batte VRP01
6 strutture (vertical put/call, condor, 3 diagonali) × distanza {1,1.5,2,2.5}σ × ali {0.5,1,2}σ ×
tenor {3,5,7,10}g, gate IV-rank canonico sempre attivo. La cella scelta col **solo in-sample**
(DIAG-PUT z=1.0 3g, ShIS 2.28) crolla in hold-out a **+0.19** vs 0.86 del bridge stesso-motore;
DSR 0.000/0.004 su 288 trial; multi-cut negativo a 3-4 cut su 4; banda d'ancora che non tiene
nemmeno il segno (ShH [−0.21,+0.64]). **Metà griglia (150/288) è il pattern "0-perdite = Sharpe
implausibile"** (celle z≥2 lunghe, 0 perdite su ~97 trade, ShH fasulli 4-6.5) — **terza occorrenza
dopo CC01 e ALB-A**. Quarta conferma indipendente: nel VRP l'alpha sta nel gate di regime + nella
zona ~δ-0.28 dove la coda è campionata, non nella geometria.
### 2. Overlay di protezione DD (14 celle) — 4/4 REFUTED (2 lenti ciascuno)
(a) exit intra-settimana su spike DVOL, (b) stop-loss MTM, (c) ala di coda comprata (broken-wing),
(d) cooldown post-perdita. **Nessuno batte il null del de-levering** a pari maxDD su tutta la banda
f; nessuno passa multi-cut (max 1/4) né DSR (0.70-0.88, tutti <0.95). Esempio decisivo: SL MTM 3x fa
DD 7.9%/worst −5.7%, ma VRP01 × 0.66 (semplice riduzione di size) fa lo **stesso DD a Sharpe
invariato e worst-week migliore (−4.9%)**. Meccanismo confermato: i trigger di spike scattano solo
2-3 volte in 5 anni **perché il gate IV-rank/crash-skip evita già gli ingressi vicino alle
esplosioni di vol** — la protezione crash vive nel gate d'ingresso, non serve un overlay a valle.
Coerente con TP01×DVOL (2026-06-26): "per meno DD la leva è la size, non un overlay".
### 3. Sizing anti-rovina — CONFERMA (12% ≈ quarter-Kelly), 1 candidato REFUTED
Il sizing non crea alpha (Sharpe del flusso invariante ~0.95 a ogni frazione). Frontiera onesta
CAGR-DD-P(rovina) mappata su 92 trade gated ETH 2021-26 (pooled banda-f + coda sintetica full-loss):
Kelly onesto q*=44% → il **12% del book = 0.27 Kelly, già in zona quarter-Kelly anti-rovina**
(P(rovina-50%|5y) 0.0-0.1%, P(DD>30%) 9-18%, CAGR med 13.5-17% a 2k/5k). Salire al 25% → P(DD>30%)
> 92%; Albimarini 1→4 → P(rovina) 53-55%. **Nessun cambio raccomandato.** Il candidato anti-streak
(N=2, size 12%→3% dopo 2 vittorie, l'opposto di Albimarini) era il più luccicante mai visto sullo
sleeve (FULL CAGR +19.4%/DD 6.3%/Sh 2.08, random-null 0.996, DSR 0.999) ma **auto-refutato come
artefatto di selezione**: plateau assente (solo N=2 vince, N=3/5 collassano), P(loss|streak) non
monotona, delever-null perde in 2/7 ancore — tutto l'effetto sono ~6 perdite su 15 trade a
streak==2 (binomtest p=0.033, CI contiene la base). Istruttivo: mostra come un DSR 0.999 possa
convivere con l'assenza di meccanismo.
### 4. Gate nuovi — 4° FALLIMENTO su 4 (barra alta)
(a) term-structure DVOL **non testabile oggi** (storia vol_term = 7 giorni, logger forward dal
2026-06-26 → rivalutare a 6-12 mesi); (b) vol-of-vol, (c) RV-acceleration, (d) combinazioni-AND. Il
candidato IS-best (vol-of-vol pctl>0.80) passa DSR 0.960 e il de-levering all'ancora di default ma
la **banda d'ancora lo smaschera** (mediana uplift FULL −0.07 su 7 ancore, uplift concentrato in UNA
finestra 2021-22 di 5 settimane, hold-out uplift 0.00). Bonus strutturale: i veti RV-acceleration
bloccano settimane **profittevoli** (+0.93/+1.25% vs +0.6% tenute) — dopo il gate IV-rank, la vol
che accelera è dove il premio venduto è più ricco. Conferma il verdetto 2026-07-01: l'alpha è tutto
nel binario IV-rank>0.30.
### 5. Audit anchor-luck VRP01 — CHIUSO: primo sleeve SENZA firma di luck
VRP01 è l'ultimo sleeve ancorato dopo TP01/XS01/SKH01. Ciclo settimanale → 7 ancore (giorno di
apertura). Replica bit-exact della sleeve (max|diff|=0.0). Le 7 fasi con parametri identici:
| metrica | canonica (fase-0) | mediana 7 fasi | banda | pctl canonica |
|---|---|---|---|---|
| Sh FULL | 1.09 | 1.32 | [1.09, 1.83] | **7° (peggiore)** |
| Sh HOLD | 0.59 | 0.59 | [−0.03, 1.11] | 50° (mediana) |
| maxDD | 11.8% | 7.2% | [5.7, 11.8%] | **93° (peggiore)** |
**Firma OPPOSTA a TP01/XS01/SKH01**: lo spike bootstrap è NEGATIVO (g0 HOLD −0.06, FULL −0.21,
P(g0≤0) 0.54/0.74) → niente da de-luckare. La fase canonica ha beccato le settimane crash 2022
**peggio** di ogni altra (unico anno-fase negativo, −5.8%). **I numeri di ammissione FULL 1.10 /
HOLD 0.60 / DD 12% sono quindi CONSERVATIVI, non gonfiati** — il timore di "protezione fittizia" è
refutato: il DD 12% è il caso peggiore della banda, non quello fortunato. Impatto della fase sul
book 5-sleeve ≤ 0.04 Sh (banda ShFULL 2.23-2.27, ShHOLD 2.35-2.48, DD 6.2-6.3%). **Con questo
l'audit anchor-luck è completo su tutti gli sleeve ancorati (4/4).**
### 6. Gate di regime sulla diagonale SPX (l'esperimento mancante) — REFUTED, con confound istruttivo
L'esperimento che mancava ai 3 backtest Albimarini: il gate di regime sulla diagonale SPX (VIX +
VXV da FRED, motore BS sintetico con skew log-lineare). **Domanda secca: il gate IV-rank ribalta gli
anni di coda su SPX come su crypto? NO.** Il gate VIX-rank canonico *abbassa* lo Sharpe (1.36→1.19),
non ribalta nessun anno di coda, peggiora il 2018, muore sul de-levering (ΔSh −0.17). Meccanismo:
su SPX il VRP è già positivo l'**84% dei giorni** (vs ~58% delle settimane crypto) → il filtro di
rank non ha lavoro discriminante; su equity IV-rank alto = crisi, non vol ricca.
Il candidato **term-structure VIX/VXV<1 (contango)** sembrava reale — Sh 1.18→2.08, DD 3.5→1.3%,
ΔSh **+0.90** a pari DD, multicut 3/3, flippa il 2020, DSR 0.992, plateau su c∈[0.93,1.05], jackknife
robusto — **e passa la lente selection-bias pulito**. Ma la lente de-levering lo affonda:
**l'intero uplift è un confound di modello, quantificato al 100%.** La variabile del gate (VIX/VXV>1)
coincide 1:1 con la variabile dell'errore di pricing (tenor 6g prezzato a VIX-30g). Il refuter ha
riprezzato con σ(6g)=VIX·(VIX/VXV)^α term-structure-consistent (α=1.42 = estrapolazione log-lineare
zero-parametri della pendenza osservata 30g→93g) → l'edge sparisce. **Lezione: un gate che si
correla con un errore di modello è indistinguibile da alpha finché non correggi il modello** — vale
per ogni futuro test su strutture prezzate BS-flat.
### 7. Stress lab di coda — fisica dello strumento, nessun cambio
La protezione di coda del VRP01 viene per ~metà dall'**ala far-OTM** (nel replay COVID taglia ~90%
della perdita naked) e ~metà dal **gate canonico** (sulle 10 peggiori finestre 14g taglia la perdita
cumulata del 44-71% saltando i re-entry a IV-rank>0.90). L'ala T+1 "Albimarini" è assicurazione solo
contro i gap **medi** (−15/−20%, dove atterra ATM con un giorno di time value: +150bps) e **NON**
contro i gap profondi (k(−30%)=0.98 → il de-levering la batte), con valore interamente dipendente
dal vol-spike (banda f/mult da −324 a +263bps). Worst-case onesto a sizing 12%: piccolo in
convenzione book (−€12/sett a 2k, −€31 a 5k alla cella −30%) ma **è il margine intero** se il 12%
fosse deployato fisicamente come margine (−€164..−227).
---
## Scettico incrociato — verdetto e disambiguazione critica
I 2 sopravvissuti (sizing-conferma, anchor-ensemble) usano leve diverse (posizione sulla frontiera
vs varianza della stima), ma lo scettico ha trovato **tre sovrapposizioni che i refuter singoli non
potevano vedere**:
1. **Stessa dipendenza dal modello f** — entrambi flippano segno allo stesso punto (f=0.6-0.8 →
negativo). Due sopravvissuti = **un solo grado di libertà di rischio-modello** (il caveat "premio
MODELLATO su DVOL ATM" resta il collo di bottiglia dell'intera famiglia).
2. **⚠️ CONFLITTO DI UNITÀ sul "12%"** (il punto più pericoloso per la narrativa): il **12% di PESO
del book** (convenzione pnl/Ks di `sleeves.py`) = ~**0.6% margine/equity ≈ 0.014 Kelly**, mentre
il "FISSO 12%" del filone sizing = **12% margine/equity ≈ 0.27 Kelly** — **fattore 19x**. Entrambe
corrette internamente, ma non vanno confuse: worst-week −12.2% del conto (convenzione margine) vs
−0.64% (convenzione peso book).
3. **L'ensemble-7-fasi è ridondante con il tranching TP01** (matematica di diversificazione: corr fra
fasi ρ=0.355, boost teorico ×1.50 vs osservato ×1.53, residuo alpha ≈ 0) → **non promuovere a LEAD
autonomo**; la coda strutturale è invariata (worst = 7 tranche a full-loss simultaneo), il DD 4.7%
è campionario, non un cap.
**Effetto congiunto sul book 5-sleeve: ZERO** (entrambi propongono nessun cambio; controfattuale
|ΔSh| ≤ 0.04). Il book live Deribit (TP01+SKH01) non contiene VRP01 → impatto operativo nullo.
---
## Cosa entra nella narrativa (una sola voce, status = misura research)
- **Audit anchor-luck VRP01 CHIUSO** → i numeri di ammissione reggono e si citano con banda
(ShFULL [1.09,1.83], ShHOLD [−0.03,1.11], DD [5.7,11.8%]); l'edge OOS resta f-dipendente.
Con questo l'audit anchor è completo su 4/4 sleeve ancorati.
- **Sizing (conferma, con disambiguazione unità obbligatoria):** 12% deploy ≈ 0.27 Kelly onesto,
anti-rovina; NON confondere col 12% di peso book (0.014 Kelly, 19x).
- **VRP01 canonico resta lo sleeve giusto, INVARIATO** — non migliorabile per struttura, gate,
overlay o sizing; la protezione DD si compra con la size.
## Regole/candidati rafforzati
- **`implausible_sharpe` gate in altlib**: 3ª occorrenza del pattern "0-perdite = Sharpe
implausibile" (griglia struttura, dopo CC01 e ALB-A) → priorità alzata.
- **Nuova regola metodologica**: un gate che si correla con un errore di modello (term-structure vs
BS-flat) è indistinguibile da alpha finché non si corregge il modello — riprezzare
term-structure-consistent prima di credere a qualsiasi gate vol su strutture BS-flat.
- **Conferma (4ª): l'alpha del VRP è il gate IV-rank binario**, non struttura/sizing/overlay/gate
aggiuntivi.
**Stato:** book live INVARIATO, nessun nuovo sleeve, nessun forward-monitor. Test suite verde. 7
script committati.
@@ -0,0 +1,109 @@
# 2026-07-07 — Video-claim "CRT top-down multi-TF, 74% win rate": SCARTATO (il 74% è un knob, non un edge)
**Richiesta utente:** analizzare e testare una strategia da video, metodo ICT/SMC top-down
multi-timeframe con claim **74% win rate**:
1. **H1** — setup CRT: candela di displacement forte, poi candela che prende liquidità (spike oltre
il range di C1) ma richiude dentro → falso breakout → fade/reversal.
2. **M15** — struttura: swing (U a 3 candele) + imbalance che diventa inverse-imbalance (FVG mitigato).
3. **M5** — conferma: displacement direzionale + zona di protezione (order block / imbalance).
4. **M1** — entry: attende la correzione, entra con SL dietro la zona di protezione.
Uscita: **TP1 a fine zona CRT (RR ~1.5–2), chiude 70–80% lì → resto a break-even → runner 20–30%**
verso la "liquidità successiva" (previous daily high/low). Due esempi mostrati (gold, nasdaq), entrambi
vincenti. Metà finale del video = vendita academy → lead magnet.
La valutazione critica dell'utente ("occhio Milito") aveva già isolato le red flag giuste (74% non
dimostrato, cherry-picking di 2 esempi, concetti discrezionali non falsificabili, RR basso + WR alto =
fragile, funnel commerciale). Questo diario **meccanizza e falsifica** la parte testabile.
## Inventario preventivo (non rifare lavoro)
Il setup H1 CRT è **già stato meccanizzato e scartato 3 volte** nell'onda 2026-07-02:
- `r0702_crt_base` (864 trial, 1h/4h/12h/1d): **DSR 0.000**; short "smart-money" negativo perfino IS.
- `r0702_crt_mtf` (4h→15m, 1h→5m, ~10k trade): **expectancy netta negativa OVUNQUE**; refutazione
strutturale = **"il ritest è informazione negativa"** (pattern CON ritest −40bps, SENZA +52bps).
- `r0702_crt_context` (FVG/sessioni/livelli): FVG semmai peggiora; **FADE < FOLLOW ogni anno 2019-26**.
**Angolo NUOVO non coperto** = la **gestione d'uscita (parziale+BE+runner)** e il **claim 74% WR**.
È lì che ho concentrato il test: `scripts/research/r0707_crt_topdown.py` (non tocca src/config/live;
nessun file scritto). Riusa l'harness certificato (dati/atr/sharpe/DSR di `altlib`).
## Disegno
- Detection CRT C1-C2 su **H1** (causale, nota alla chiusura di C2). Direzione = fade dello sweep.
- Entry sul TF basso (**5m/15m**, proxy di M5/M1 — ⚠️ **M1 non è nel feed certificato**): ritest della
zona violata + close-back attraverso il livello ("displacement di conferma"), **SL = estremo dello
swing basso = zona di protezione**.
- Tre schemi d'uscita sugli **stessi ingressi**: `fix1.5` (full, TP 1.5R), `fix2.0` (full, TP 2.0R),
`managed` (75% a 1.5R → resto 25% a BE, runner target = prev-daily high/low o estremo opposto C1).
- Gate progetto: hold-out 2025-01-01, griglia (k, s, d, tf, scheme) con **selezione cella solo
in-sample** + **DSR su tutti i trial**, **fee sweep** 0/0.10/0.20% RT, executability $600.
- Metrica invariante = **expectancy in R netto fee** (non il win-rate).
## Esito — il 74% è un artefatto della distanza del target, non un edge
**1) Win-rate reale (fade, tutti gli schemi, pooled BTC+ETH):**
| schema | WR mediana | expectancy R (netto 10bps) |
|---|---|---|
| fix1.5 | **35.8%** | −2.38 |
| fix2.0 | 31.3% | −2.34 |
| managed | **35.8%** | −2.17 |
Il WR a RR 1.5 è **~35%**, cioè **SOTTO** il null gambler's-ruin di un random walk senza edge
(P(+1.5R prima di −1R) = 1/(1+1.5) = **40%**). Il setup tocca 1.5R **meno spesso di una moneta** →
conferma indipendente che *il ritest è informazione negativa*. Lo schema `managed` **non gonfia** il
WR sopra `fix1.5` (per costruzione: "vinci" solo se raggiungi il parziale a 1.5R, che è la stessa
condizione di `fix1.5`). **In nessuna cella si avvicina al 74%.**
**2) Il win-rate È un knob — sweep del target parziale `rr1` (managed, 5m, cella tipica):**
| rr1 | WR reale | null 1/(1+rr1) | expR (fee 10bps) | expR (fee 0) |
|------|----------|----------------|------------------|--------------|
| 0.50 | 51.4% | 66.7% | **−2.54** | +0.11 |
| 0.75 | 46.9% | 57.1% | −2.51 | +0.14 |
| 1.00 | 43.2% | 50.0% | −2.47 | +0.17 |
| 1.50 | 36.3% | 40.0% | −2.45 | +0.19 |
| 2.00 | 31.8% | 33.3% | −2.42 | +0.23 |
Avvicinando il target il WR sale (esattamente come previsto dalla formula gambler's-ruin): **un "74%"
si fabbrica scegliendo un parziale vicino** (~0.35R), NON perché il metodo indovina la direzione. Ma
l'**expectancy R è costante e negativa a ogni rr1**: il WR alto non porta soldi. NB anche a WR massimo
il setup resta *sotto* il null teorico ad ogni rr1 → è pure peggio di un random walk nel raggiungere
target vicini.
**3) Gate statistici (cella scelta in-sample = 15m, k1.5, s0.1, d0.15, fix2.0):**
- **DSR = 0.000** su 48 trial (null max-Sharpe atteso 4.35). FAIL.
- **Fee sweep:** a **0 bps** expR = −0.10 e Sharpe book −0.63 → **non è morte-per-fee: l'edge lordo
non esiste** (il residuo lordo marginalmente positivo su 5m è la beta di trend dei time-exit, la
stessa autopsia del CRT base). A 10bps expR −1.26; a 20bps −2.43. Stop stretti (0.13–0.24%) →
la fee 0.10% pesa 0.75–2.6 R per trade → qualunque micro-edge lordo è polverizzato.
- **Hold-out 2025-26:** WR 32%, expR −1.56 (peggio dell'IS). Nessuna reggenza fuori campione.
**4) Executability $600:** SL sul TF basso = 0.13% (5m) / 0.24% (15m). Lo schema parziale+BE+runner
richiede **3–4 ordini per trade**, alcuni **sotto il min-order $5** a nozionale $1200 → non eseguibile
pulito al capitale reale.
## Verdetto
**SCARTATO.** Il claim "74% win rate" è **coerente con ZERO edge**: è la scelta di un parziale vicino
(gambler's ruin), non capacità direzionale. Smontato lo schema d'uscita, resta il setup H1 CRT che
questo progetto ha già triplo-refutato (DSR 0.000, ritest = informazione negativa, fade < follow).
Sul feed certificato BTC/ETH il metodo ha **win-rate reale ~30–37% e expectancy R negativa a ogni
schema, fee, finestra e asset**; lordo di fee non c'è edge; a $600 non è nemmeno eseguibile pulito.
La parte *utile* del video è il framework di lettura (CRT + imbalance + parziali), non il numero — come
aveva già concluso la valutazione dell'utente. Da trattare come lettura del mercato, non come sistema.
## Lezione codificabile (candidata)
**Il win-rate di uno schema parziale+BE non è un parametro di merito: è ~P(tocca il primo target prima
dello stop) = 1/(1+rr1) per un processo senza drift.** Ogni claim "WR X%" da schema SMC va convertito
in **expectancy R netto fee** prima di crederci; il WR alto si compra con un target vicino a costo di
un'expectancy identica (o peggiore). Prossimo giro di gate: un helper `winrate_is_a_knob()` che, dato
un book a schema parziale, riporta expectancy-R vs WR al variare del target (rende esplicito l'artefatto).
## File
- `scripts/research/r0707_crt_topdown.py` — il test (griglia + 74%-check + knob-sweep + DSR + fee + exec).
- Prior: `r0702_crt_{base,mtf,context}.py`, diario `2026-07-02-timing-crt-wave.md`.
- Nessuna modifica a src/, config/, scripts/live/, tests/. Book live e pesi INVARIATI.
@@ -0,0 +1,108 @@
# 2026-07-09 — Incident infra: "BOOK LIVE conto offline" = cert Traefik di default (non un problema del conto)
**Tipo:** incident operativo (infra VPS), non ricerca. Nessun edge, nessun cambio a strategie/pesi/config
di trading. Documentato qui perché ha **bloccato la lettura del conto del book live** e ha prodotto
l'alert Telegram `⚠️ BOOK LIVE — conto offline`.
## Sintomo
Alert dal `cron_book` orario (`scripts/live/book_execute.py --execute`):
```
⚠️ BOOK LIVE — conto offline
nota: salto l'esecuzione, non opero a cieco
```
Nel log (`logs/cron_book.log`) le run recenti mostravano `conto non leggibile (offline) -> stop, non
eseguo a cieco`. 10 run offline su 382 totali → **regressione recente**, non uno stato storico.
## Diagnosi (catena completa)
Il book legge il conto Deribit mainnet in sola lettura via **Cerbero MCP** (`DeribitRead`,
`src/live/deribit.py` → `https://cerbero-mcp.tielogic.xyz`). `book_report` marca `online=False` quando
`DeribitRead.mark_price(BTC)` lancia. Riproduzione diretta:
```
mark_price BTC: FAIL -> SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] self-signed certificate
```
Il proxy presentava il **cert self-signed di default di Traefik** (`CN = TRAEFIK DEFAULT CERT`,
`notBefore Jul 9 19:55 2026`) al posto del vero Let's Encrypt. `curl -k` → HTTP 401 (backend
`cerbero-mcp` healthy, routing OK): **solo la presentazione del cert TLS era rotta**. `requests`
verifica il cert → fallisce → `online=False` → il book salta l'esecuzione (comportamento di sicurezza
**corretto**: non opera a cieco).
**Causa a monte** (log di avvio Traefik, 11:37:16Z, container `traefik-traefik-1`):
```
ERR The ACME resolve is skipped from the resolvers list
error="unable to get ACME account: permissions 660 for /acme.json are too open, please use 600"
resolver=mytlschallenge
→ (a cascata) Router uses a nonexistent certificate resolver certificateResolver=mytlschallenge
routerName=cerbero-mcp@docker [+ ~14 altri router: git, vault, portfolio, budget, cerbero-bite, ...]
```
Sequenza:
1. Immagine `traefik:latest` + **Watchtower** (`com.centurylinklabs.watchtower.enable=true`) →
auto-upgrade a **Traefik 3.7.7** con restart alle 11:37 di oggi.
2. Traefik 3.x **rifiuta** `acme.json` con permessi più larghi di `600`; il file era `660`
(`-rw-rw---- root:adriano`) → **resolver `mytlschallenge` scartato**.
3. Tutti i ~15 router che lo referenziano → "nonexistent certificate resolver" → Traefik serve il
**cert di default self-signed** a ogni host HTTPS del VPS (non solo cerbero-mcp).
4. I cert veri erano **già dentro `acme.json`** (14 domini, incl. `cerbero-mcp.tielogic.xyz`) → nessuna
ri-emissione necessaria, **zero rischio rate-limit** Let's Encrypt.
## Impatto
- **VPS-wide:** ogni servizio HTTPS dietro Traefik serviva un cert invalido (warning browser, fallimento
di ogni client che verifica il TLS). Non solo il trading.
- **Trading:** **nessun trade perso.** Target del book **flat** (TP01/SKH01 risk-off) + conto reale
~$598 (non finanziato al livello nominale): anche online il book avrebbe fatto HOLD. Il doppio gate
di sicurezza ha lavorato come previsto.
## Fix
**Immediato** (eseguito dall'utente):
```bash
sudo chmod 600 /opt/docker/traefik/acme.json
docker restart traefik-traefik-1
```
Il resolver ricarica i cert già presenti in `acme.json` e li ripresenta subito.
**Durevole** (pin dell'immagine, `/opt/docker/traefik/docker-compose.yml`):
```yaml
- image: "traefik" # = traefik:latest → Watchtower salta ai major (causa dell'incident)
+ image: "traefik:3.7" # Watchtower resta su 3.7.x: patch sì, salto a 3.8+ breaking no
```
Applicato con `docker compose up -d` (container ricreato su `traefik:3.7`, 20:05:05Z).
## Verifica (end-to-end, post-fix)
| Check | Risultato |
|---|---|
| `acme.json` perms | `600` |
| Cert `cerbero-mcp.tielogic.xyz` | issuer **Let's Encrypt** (fino 2026-09-27) |
| Traefik log | nessun `ACME resolve is skipped` / `too open` |
| Container image | `traefik:3.7` (running) |
| `DeribitRead.mark_price` | BTC 63.193 / ETH 1.746 |
| `book_report.online` | **True** · `eq_basis=mainnet USDC` · `real_equity=$598.06` · `pos_error=None` |
## Lezioni
- **`traefik:latest` + Watchtower = auto-upgrade non deterministico.** Un bump di major (qui il giro
di vite sui permessi di `acme.json`) diventa un'interruzione TLS di tutto il VPS senza intervento
umano. Pinnare la minor (`3.7`) rende i restart prevedibili pur ricevendo le patch.
- **Traefik 3.x pretende `acme.json` a `600`** (non solo warning: **scarta il resolver**). Se il file
è group/other-readable, tutti i router cadono sul cert di default.
- **Il gate `online` del book ha fatto il suo lavoro:** un problema *infra di lettura* non ha prodotto
ordini a cieco. L'alert "conto offline" va letto prima come possibile problema di **connettività/cert
al Cerbero MCP**, non del conto Deribit.
- **Runbook rapido** per "BOOK LIVE conto offline":
1. `python -c "from src.live.deribit import DeribitRead; DeribitRead().mark_price('BTC-PERPETUAL')"`
→ se `SSLError`/`CERTIFICATE_VERIFY_FAILED` è il cert del proxy, non il conto.
2. `openssl s_client -connect cerbero-mcp.tielogic.xyz:443 -servername cerbero-mcp.tielogic.xyz | openssl x509 -noout -issuer`
→ se `TRAEFIK DEFAULT CERT`, Traefik non serve il cert reale.
3. `docker logs traefik-traefik-1 | grep -iE "ACME resolve is skipped|too open|nonexistent"`
→ conferma resolver scartato; controlla `stat -c %a /opt/docker/traefik/acme.json` (deve essere `600`).
Nessun file di trading toccato; `config/live.json`, sleeve e pesi **invariati**.
@@ -0,0 +1,126 @@
# 2026-07-15 — Incident ops: feed BTC/ETH del book congelato 7 giorni (`copy2`→`copystat` EPERM)
**Tipo:** incident operativo (pipeline dati), non ricerca. Nessun edge, nessun cambio a
strategie/pesi/config di trading. Documentato qui perché ha **congelato il segnale del book live**
per una settimana: il book ha ri-girato ogni ora ma su una barra vecchia (`ultima barra 2026-07-08`),
senza ri-valutare TP01. Trovato durante un check di `stato`, non da un alert (il fallimento era
silenzioso — vedi Lezioni).
## Sintomo
Nel log del `cron_book` orario, ogni run dal 2026-07-08 in poi mostrava:
```
ultima barra : 2026-07-08 # <-- oggi e' 2026-07-15
...
ETH TP +0.000 · SKH +1(LONG@1868.9) -> net $+75 | pos $+77 -> HOLD (a target)
=> Nessuna azione: conto gia' al target netto del book.
```
Conto **online** e sano ($600.5), esecuzione armata, cron regolari — ma il segnale TP01 (1d) fermo
al 8 luglio. SKH01 meno colpito: prende il 5m fresco **in memoria** via `livefeed.fresh_5m`, non da
disco. Il congelamento riguardava il **feed certificato su disco** (`data/raw/{btc,eth}_*.parquet`),
mtime fermo a **Jul 8 00:32**.
## Diagnosi (catena completa)
Il `cron_daily` (00:30) ricostruisce il feed Deribit con `rebuild_history.py --asset BTC ETH`. Nel
`logs/cron_daily.log`, **ogni notte dal 9 luglio**:
```
REBUILD STORICO da DERIBIT MAINNET — FULL (scrive data/raw, backup)
Traceback (most recent call last):
File "scripts/analysis/rebuild_history.py", line 189, in build
shutil.copy2(path, BACKUP / f"{asset.lower()}_{tf}.parquet.prebuild.bak")
PermissionError: [Errno 1] Operation not permitted
```
Il resto del daily (Hyperliquid, DVOL, ETF, paper trader) proseguiva regolare — solo il **primo**
step, il rebuild BTC/ETH, moriva. Sequenza dentro `build()`:
```python
if path.exists():
shutil.copy2(path, BACKUP / f"...prebuild.bak") # <-- crash QUI
tmp = path.with_suffix(".parquet.tmp")
d.to_parquet(tmp, index=False) # <-- mai raggiunto
tmp.replace(path) # <-- il feed non viene mai scritto
```
**Causa radice:** `shutil.copy2` = `copyfile` **+ `copystat`**. `copystat` fa `os.utime`/`chmod`/
`chflags` sulla destinazione con valori espliciti → richiede la **proprietà** del file (o `CAP_FOWNER`),
**non basta il group-write**. I file erano `root:adriano 660`; il cron gira come **adriano** (uid 1001,
membro del gruppo `adriano`). adriano può *scrivere* nel `.bak` (group-write) ma non `utime`-arlo →
`EPERM`.
Firma diagnostica coerente: `btc_5m.parquet.prebuild.bak` aveva mtime **odierno** mentre gli altri
`.bak` erano fermi al 7 luglio. Ovvero il `copyfile` interno riusciva (scriveva contenuto + mtime),
poi `copystat` lanciava → l'eccezione abortiva il loop **prima** di scrivere `data/raw/btc_5m.parquet`.
Perché ha iniziato il 9 luglio e non prima: l'ownership `root:*` dei file di `data/raw` è residuo di
run/manutenzione eseguiti come root (l'incidente Traefik del 9 luglio è nella stessa finestra). Finché
il processo era root, `copystat` sui file root riusciva; passato a run come adriano, EPERM. La causa
prossima non è *chi* ha creato i file, ma che **un backup difensivo poteva abortire il feed live**.
## Impatto
- **7 giorni (2026-07-08 → 07-15)** di feed Deribit BTC/ETH fermo → TP01 (1d) del book non ha
ri-valutato. Il book ha tenuto un ETH long SKH01 (@1868.9) impostato il 8 luglio.
- **Nessuna perdita né ordine errato:** il segnale ricalcolato sul feed fresco **coincide** con quello
tenuto (BTC flat, ETH long $75, già a target → 0 ordini di divergenza). Rischio evitato per fortuna
di regime, non per design — il book è comunque stato **cieco** a una settimana di segnale TP01.
- Paper trader e dashboard **non impattati**: usano feed diversi (HL/DVOL/ETF, aggiornati regolarmente).
## Fix
`scripts/analysis/rebuild_history.py` — backup reso **best-effort e non fatale**:
```python
if path.exists():
# copyfile (solo contenuto, NO copystat) dentro try/except: un .bak difensivo
# non deve MAI poter bloccare la scrittura del feed live.
try:
shutil.copyfile(path, BACKUP / f"{asset.lower()}_{tf}.parquet.prebuild.bak")
except OSError as e:
print(f" WARN backup {path.name} saltato (non fatale): {e}")
```
Due cambi: (1) `copy2` → `copyfile` — un `.bak` non ha bisogno dei metadati originali, e `copystat`
era l'unica fonte dell'EPERM; (2) `try/except OSError` con warning — anche un futuro errore di backup
(disco pieno, permessi) non blocca più il feed.
**Verifica end-to-end:**
- rebuild rigirato a mano → `scritto {btc,eth}_{5m,15m,1h}.parquet`, feed fresco a **2026-07-15**,
audit cross-venue **BTC 1.9 bps / ETH 2.0 bps** (pulito).
- i file di `data/raw` ora sono **`adriano:adriano`** (`tmp.replace` li rigenera con l'owner del
processo) → l'ownership si auto-sana, il problema non si ripresenta anche con `copy2`.
- `book_execute.py` in dry-run legge **`ultima barra 2026-07-15`** e ricalcola → BTC flat / ETH long
$75 → HOLD. Pipeline sbloccata.
## Lezioni
1. **Un backup difensivo non deve mai poter uccidere l'operazione che protegge.** Il `.bak` è una
rete di sicurezza; il suo fallimento (metadati, permessi, disco) va isolato in `try/except`, mai
propagato allo scrittore del feed live.
2. **`shutil.copy2` è insidioso in ambienti multi-utente:** `copystat` richiede *ownership*, non
group-write. In una dir a proprietà mista (`root:adriano`) un cron non-root ci sbatte. Per un
backup, `copyfile` è la scelta giusta (i metadati del `.bak` non servono).
3. **Fallimento silenzioso = il peggiore.** Il conto era online, i cron giravano, gli alert tacevano:
solo la barra vecchia nel log tradiva il congelamento. Il gate `online` del book protegge dai
problemi di *conto*, non da un feed *stale*. **Follow-up raccomandato:** alert se
`ultima_barra < today − 2g` in `book_execute` (staleness-gate esplicito).
4. **La sicurezza del book ha retto a metà:** non ha operato a cieco su un conto irraggiungibile, ma
*ha* operato (HOLD) su un segnale stantio. La coincidenza segnale-vecchio == segnale-nuovo è
fortuna di regime; un mercato in movimento avrebbe lasciato il book fuori posizione.
## Runbook (feed BTC/ETH stantio)
1. **Rilevare:** `stat -c '%y %n' data/raw/btc_1h.parquet` → se mtime > 1-2g fa, il feed è fermo.
Conferma incrociata: `ultima barra` nel `logs/cron_book.log`.
2. **Diagnosi:** `grep -A3 "REBUILD STORICO" logs/cron_daily.log | tail` → cercare Traceback nello
step rebuild.
3. **Sbloccare:** `uv run python scripts/analysis/rebuild_history.py --asset BTC ETH` → deve stampare
`scritto ..._5m/15m/1h.parquet` e l'audit cross-venue (atteso < ~10 bps mediana).
4. **Verificare il book:** `uv run python scripts/live/book_execute.py` (senza `--execute`) → `ultima
barra` deve essere la data odierna.
Nessun file di trading (strategie/pesi/config) toccato. Solo `rebuild_history.py`.
+111
View File
@@ -0,0 +1,111 @@
# 2026-07-17 — Ondata WEEKEND (ven→lun, timing multipli, 4 agenti): 0 edge, 1 fatto strutturale sul book
**Goal:** "cerca strategie che con diversi timing lavorino solo tra venerdì e lunedì, usa diversi
agenti." Quattro filoni in parallelo su BTC/ETH 1h/15m certificati, harness `altlib` condiviso,
metodologia onesta piena (selezione in-sample-only pre-2025, banda di timing mai la best-cell,
deflated-Sharpe sull'intera famiglia, `day_boundary_robust`, fee nette 0.10% RT + sweep,
`causality_ok`, realismo small-cap $600). Prior vincolante: day-of-week già morto (SEA 2026-07-02),
anchor timing-luck su 3/3 sleeve ancorati, CRT triplo-refutato.
**Esito: SCARTATO 4/4. Nessun LEAD, nessun forward-monitor, book/pesi INVARIATI.**
Il fatto nuovo utile è *difensivo*: il weekend è leggermente sovra-denso per TP01 (38% del gross
nel 31% del tempo) → togliere esposizione weekend al book è attivamente dannoso.
---
## Filone 1 — WK-DRIFT: drift puro ven→lun (`r0717_wk_drift.py`)
Griglia 6 H_in (ven) × 6 H_out (lun) × long/short × BTC/ETH = **144 trial**.
- Cella scelta in-sample (LONG ETH ven08→lun16): IS +1.07 → FULL +0.84 → **HOLD −0.14**
(ret hold-out −23%), maxDD 69%. Banda long: FULL med +0.57, HOLD med **−0.21**.
- **DSR 0.001/144** (max atteso sotto il null: 1.97 ≫ 0.84 osservato).
- **Null weekday: il venerdì NON è speciale** — mediana IS della famiglia long per ancora:
Fri +0.74 = 71° percentile, sotto Mon (+0.78) e Sun (+0.78). Qualsiasi finestra ~3g long fa lo
stesso = beta di buy&hold a esposizione ridotta (B&H daily Sh FULL: BTC 0.79 / ETH 0.86 ≈ il max
della griglia).
- A fee ZERO l'hold-out resta negativo (−0.03) → non è morte-per-fee, l'edge OOS non esiste.
- `day_boundary_robust`: ARTIFACT-RISK (uplift flippa spostando il confine UTC, spread 0.43).
**SCARTATO** — il "weekend drift" è B&H diluito nel tempo (vive del toro 2019-21, −58% nel 2022,
−33% nel 2025).
## Filone 2 — WK-COND: weekend condizionato da gate causali (`r0717_wk_cond.py`)
5 gate causali noti all'ingresso del venerdì × 9 timing × direzioni = **99 combo** (198 stream):
(a) TSMOM concorde, (b) FOLLOW/FADE del venerdì, (c) follow/fade della settimana, (d) regime vol
RV30 (percentile espandente causale), (e) breakout dei livelli del giovedì.
- **5/5 gate: earns_slot=False, DSR ≤0.30, `day_boundary_robust` = ARTIFACT-RISK 5/5** (la stessa
firma che uccise `open_drive`: l'etichetta "weekend" non è dove vive alcun segnale).
- (a) TSMOM-gate = **TP01-in-weekend per costruzione** (β 0.67, uplift hold −0.015, jackknife
−0.18): re-timing del trend, non alpha. Lo short weekend perde perfino col trend a favore
(mediana IS −0.15).
- (b) FOLLOW>FADE regge in-sample ma **si inverte in hold-out** → rumore; il lead prevday-FOLLOW
non si trasferisce alla finestra weekend. Unico is_hedge=True dell'ondata, ma con HOLD −0.92.
- (d) l'unica variante con HOLD positivo (HIGH70 +0.19) è **non selezionabile in-sample**
(IS +0.22): crederle sarebbe selection-on-holdout da manuale.
- A fee zero l'hold-out resta negativo per 4/5 gate → non è morte-per-fee.
**SCARTATO** — e con questo (99 trial qui + SEA + expiry-calendar 2026-07-02) **la famiglia
calendario su BTC/ETH è satura**: riaprirla solo con un meccanismo nuovo non-calendario.
## Filone 3 — WK-INTRA: intraday dentro la finestra (`r0717_wk_intra.py`)
**132 celle** su 1h+15m, tre sotto-filoni: (A) Donchian weekend-only follow/fade,
(B) gap dom 22:00 vs close ven 21:00 (meccanizzazione onesta del claim "CME gap"),
(C) livelli H/L/C del venerdì come magnete.
- Quadro: celle IS **lorde** positive = 64/132 ≈ 50% = **moneta simmetrica** (rumore prima ancora
delle fee); IS nette >0: 18/132. DSR famiglia 0.068 → 0.001 per filone.
- (A) la cella IS (Donchian 48h follow) è trend-2022 su ETH travestito (2022 +96%; BTC per-anno
negativo nel toro); su BTC muore di fee E il lordo è sotto soglia.
- (B) **il claim "CME gap" è morto**: nessuna config ha IS netto >0; la best (revert 2%) fa IS
−0.09 *lordo +0.03* → l'edge non esiste nemmeno lordo; il suo HOLD +0.5 è la firma esatta del
selection-on-holdout. Nessuna centratura reale sulle 22:00 (shift-test).
- (C) il "magnete del venerdì" non esiste in nessuna direzione (L-fade: IS lordo +0.12 →
HOLD −0.97/−0.77; DSR 0.001). FOLLOW>FADE riconfermato (le celle fade sono le peggiori ovunque).
- Eseguibilità $600 NON è il vincolo (0% ordini sotto min-order, haircut 0.00): manca l'edge.
**SCARTATO 3/3.**
## Filone 4 — WK-OVERLAY: esposizione weekend di TP01 sul book (`r0717_wk_overlay.py`)
Il lato eseguibile: conviene uscire/dimezzare/aumentare TP01 nel weekend? Griglia timing + null
de-levering (lezione DVOL 2026-06-26) + bootstrap settimanale appaiato + placebo rotazioni + smallcap.
- **Fatto strutturale (attribuzione gross):** la finestra ven20→lun00 è il 30.9% del tempo e porta
il **38% del gross di TP01** (+44.2pp su +117.8pp, positivo ogni anno) — il weekend non è tempo
morto per uno slow-trend crypto 24/7, è sovra-denso.
- **WK-FLAT: REFUTED, attivamente dannoso** — ΔSh FULL −0.46 (banda 6/6 negativa),
**P(danno)=1.000** al bootstrap; a fee zero resta −0.41; il de-levering k=0.88 compra lo stesso
DD a Sharpe pieno (1.29 vs 0.83). Placebo: il weekend è tra i giorni *peggiori* da flattare (5/7).
- **WK-HALF: REFUTED** — solo de-levering pagato con fee (k=0.755 a pari DD: +0.20 Sh in più).
- **WK-BOOST ×1.5: neutro** — coerente col controllo simmetrico ma non significativo (P=0.12) e a
pari DD la leva uniforme rende di più sul CAGR → nessuna azione.
- **WK-ONLY**: Sh 1.04 da solo, ma k=0.54 uniforme lo domina → diagnostica, non strategia.
- Small-cap $600: haircut ≈0 su tutte — l'overlay si eseguirebbe fedelmente; non conviene e basta.
**REFUTED/nessuna azione — book e pesi INVARIATI.**
---
## Lezioni codificabili
1. **Famiglia calendario BTC/ETH = SATURA.** SEA (day-of-week) + expiry-calendar + event-clock
(2026-07-02) + 144+99+132 trial weekend (oggi) convergono: su BTC/ETH non vive alcun edge di
calendario/finestra-oraria. Prossimi claim di questa famiglia partono da prior ~0: esigere il
pacchetto completo (null weekday-ancora + day_boundary + DSR famiglia) prima ancora di guardare
l'hold-out.
2. **"~50% di celle lorde positive" = rumore simmetrico**: diagnostica rapida di famiglia morta
prima ancora del netting fee (WK-INTRA).
3. **Il gate condizionato non salva una finestra morta**: un gate causale su una finestra senza
edge o replica il trend (TP01 travestito) o seleziona rumore che flippa OOS (5/5 in WK-COND).
4. **Non de-esporre il weekend del book**: il 38%-in-31%-del-tempo di TP01 è la ragione
quantificata per cui il libro resta 24/7. Qualsiasi futura proposta "risk-off weekend" parte
REFUTED salvo nuovo evidence (null de-levering obbligatorio).
5. Riconferme indipendenti: FOLLOW>FADE (3ª volta); "CME gap" e "magnete del venerdì" =
folklore che non sopravvive alla meccanizzazione onesta.
**Script:** `scripts/research/r0717_wk_{drift,cond,intra,overlay}.py` (standalone, `uv run python`,
nessun file esistente toccato). **Nessun cambiamento a strategie, config, pesi o esecuzione live.**
@@ -0,0 +1,76 @@
# 2026-07-24 — Dossier 0DTE: economia LIVE delle daily options Deribit (BTC/ETH)
**Goal.** Quantificare stanotte, da quote pubbliche LIVE Deribit, l'economia del premio a
scadenza DAILY (0-1DTE) — il dossier 0DTE parcheggiato. VRP01 resta deploy-bloccato dalla regola
"niente short-vol da modello"; le daily (365 expiry/anno) accumulerebbero una serie di premi
REALI 7x più in fretta delle weekly. Domanda: il tenor daily è quotato/eseguibile/conveniente,
o muore di fee (lezione Albimarini)?
**Misura (3 snapshot ~22:35 UTC, ven 24 lug):** catena 0DTE (settle 25JUL 08:00, DTE 9.4h),
daily "fresca" (26JUL, DTE 33.4h), weekly (31JUL, DTE 153h). Fee verificate: taker=maker
0.0003 base/contratto, **cap 12.5% del premio**, daily ESENTI da delivery fee. Min size:
BTC 0.1 contratto, ETH 1.0. Spot 64.1k / 1859.
## Numeri chiave (put credit spread -0.28d/-0.10d, prezzi al tocco, fee taker 2 gambe)
| tenor | credito lordo | cross-spread (vs mid) | fee (% credito) | NETTO (% width) | %width/giorno |
|---|---|---|---|---|---|
| BTC 9.4h | $38.5 | 25% | 25.0% | 5.8% | — |
| BTC 33h | $96.2 (0.1 lot: $9.6) | 12% | 20.8% | 7.6% | 5.5%/g |
| BTC weekly | $224.6 | 16% | 17.1% | 9.3% | 1.5%/g |
| ETH 9.4h | $1.12 | 29% | 29.2% | 3.2% | — |
| ETH 33h | $3.53 | 14% | 23.0% | 10.9% | 7.8%/g |
| ETH weekly | $13.39 | 8% | **8.3%** | 12.3% | 1.9%/g |
- **Il cap 12.5% è quasi sempre BINDING a tenor daily** (premi < 0.0024 base) → fee ≈ 10-12.5%
del premio PER GAMBA, sempre. A weekly la fissa 0.0003 = 3-5% del premio. Il drag fee del
daily è **2-3x** quello weekly per unità di premio: la legge di scala Albimarini vista live
(premio ~ √T, fee ~ costante).
- **Haircut totale mid→netto**: daily 33h ≈ 30-35% del credito mid; 0DTE 9.4h ≈ 45-50%;
weekly ETH ≈ 16%. Richezza di pareggio a tenor daily ≈ **IV/RV ~1.4x**; a weekly ~1.1x.
- **IV vs RV stanotte**: ATM daily mark_iv BTC **12.8%** / ETH **21.5%** ann. contro RV20
29.6% / 39.8% → **IV_daily/RV20 = 0.43x / 0.54x: il premio daily era SOTTO la realized**
(VRP negativo al front). Weekly: 33.9% / 44.9% = 1.13-1.14x RV (il VRP vive lì, coerente
con VRP01). DVOL-30d 37.0 / 50.2. Caveat onesto: 1 snapshot, finestra weekend (ven→dom) =
IV bassa in parte razionale; NON generalizzabile — esattamente il perché della cattura.
- **EV check ETH 33h**: credito netto $2.72 < fair-value mid ~$4.1 e < E[payout] alla STESSA
IV implicita (~$4.9) → EV negativo *anche al pricing del mercato*, prima di ogni view di vol.
- **Quote sulle ali**: sì, 2-sided su tutto il ladder anche a 9h; depth MM ETH 400-1150
contratti al tocco, BTC più sottile (0.4-49). MA la griglia strike daily è GROSSA (step
1.3% ETH): i delta -0.28/-0.10 non esistono, si salta da -0.36 a -0.12; smile ripidissimo
(vendi bid_iv 13-20, compri ask_iv 22-38); le ali <5d hanno spread mediano 200% del mid =
di fatto non prezzate. Tick 0.0001 base = 3-10% del premio daily: anche la granularità quota.
## Margine = la realtà che uccide la taglia
Default Deribit = **standard margin SENZA netting fra gambe** (verificato docs): lo spread
"defined-risk" è margginato come naked short + long pagata intera. Il netting (margine ≈ width)
richiede Portfolio Margin, **min equity ~0.5 BTC ≈ $32k**. Quindi:
- ETH 1-lot PCS daily: margine SM ~$276, credito netto $2.72, max loss ~$22 → *meccanicamente*
eseguibile a $600 (1-2 lot), rendimento su margine ~1%/g SE zero perdite (e l'EV è negativo).
- BTC 0.1-lot: margine SM ~$963 → FUORI a $600, dentro a $2.6k.
- La soglia "$2.6k ETH" vale per strutture long/covered; per credit spread le soglie oneste
sono: $600 = ETH 1-lot (SM), $2.6k = entrambi sottili, **$32k = defined-risk vero (PM)**.
## Pipeline di cattura — FATTA (non in cron)
`scripts/research/r0724_daily_opt_snapshot.py`: pubblico/read-only, appende 1 riga JSON per
strumento (+1 meta con spot e DVOL) a `data/options_daily/snapshots.jsonl`; scadenze ≤50h,
moneyness 75-125%, ~160 righe/run, ~40 MB/anno a 2 run/g. Cadenza raccomandata quando la si
cabla: **08:05 UTC** (daily appena listata, ~24h DTE = premio vendibile) + **07:55 UTC**
(pre-settle = chiude il ciclo payoff). Primo snapshot già nel file. Esisteva solo
`options_real_quote_check.py` (weekly, one-shot, dipende da EXT path) e `fetch_dvol.py` (IV
30d, non quote): nessuna cattura daily preesistente.
## Verdetto: **CAPTURE-AND-WAIT con prior negativo sul daily**
Il tenor daily NON è morto-di-quotazione (mercato 2-sided, depth reale) ma stanotte era
**morto-di-economia**: haircut fee+spread 2-3x il weekly E IV<RV al front → servono entrambe
le gambe della condizione (IV/RV>~1.4x al daily) che oggi non c'è. Nessun deploy, nessun
cambio a book/pesi. Regola di decisione futura: dopo **≥90 giorni di cattura 2x/g**, calcolare
mediana(credito_netto/fair_mid) e mediana(IV_daily/RV_forward); il dossier si riapre SOLO se
il VRP daily mediano netto-haircut > 0 (e poi passa i gate standard). Il f di stress reale
arriva gratis se un crash cade nella finestra di cattura — lo stesso prerequisito che sblocca
VRP01. Fino ad allora: le daily servono da **strumento di misura**, non da strategia.
Script: `scripts/research/r0724_daily_opt_snapshot.py`. Dati: `data/options_daily/snapshots.jsonl`.
+293
View File
@@ -0,0 +1,293 @@
# 2026-07-24 — Goal "50 EUR/giorno in qualche mese": analisi onesta e roadmap
**Contesto.** Goal dichiarato: rendita aggiuntiva che arrivi a **50 EUR/giorno entro qualche
mese**, senza precludere alcuna modalità. Branch `goal/50eur-day`. Questo diario è la sintesi
di: matematica del target sui ritorni reali del book, Monte Carlo prop-firm, 3 ricerche web
parallele (prop firm 2026, yield/basis a piccola scala, monetizzazione del track record),
e audit delle migliorie interne possibili.
**Verdetto in una riga:** 50 EUR/g = **EUR 18.250/anno**; ai CAGR onesti del book (10-20%)
servono **EUR 73k-183k di capitale**. Da $600 in "qualche mese" per via di trading sul
capitale proprio **non esiste** — l'unica famiglia di vie compatibile con "mesi" è
**moltiplicare il nozionale gestito** (conto funded / capitale di terzi), ognuna con
probabilità e rischi quantificati sotto.
---
## A) Il muro del capitale (script `r0724_goal50_math.py`, parte A)
| CAGR netto | capitale per 50 EUR/g |
|---|---|
| 8% | ~EUR 228k |
| 10% | ~EUR 182k |
| 15% | ~EUR 122k |
| 20% | ~EUR 91k |
| 25% | ~EUR 73k |
Tempo da $600 (CAGR 15%, compounding + depositi mensili): **0/mese → 38.7 anni; 500/mese →
9.6 anni; 1.000/mese → 6.3 anni; 2.000/mese → 3.8 anni; 5.000/mese → 1.8 anni.**
## B) La leva non è la scorciatoia (parte B)
Book Deribit live (TP01 .75 + SKH01 .25, modellato): Sharpe 1.77, **vol nativa ~11%**,
CAGR 20.5%, maxDD 9.4%. Il target su capitale piccolo implica: $600 → 3.315%/anno
(leva ~160x); $5k → 398%/anno (~19x, vol ~212%); $20k → 99%/anno (~4.8x, vol ~53%).
Tutte fuori dalla zona di sopravvivenza (Kelly documentato: il book gira a ~0.01-0.27 Kelly).
La frontiera 2026-07-03 ha già stabilito che il book gira alla sua vol nativa — alzare
`target_vol` scala DD in proporzione, non crea rendimento.
## C) Prop-firm / conto funded — l'unica via "da mesi" quantificabile (parte C)
Monte Carlo (block bootstrap 20g dei ritorni giornalieri reali del book, 20k path,
regole tipiche: target 8-10%, maxDD 10% statico/trailing, daily loss 4-5%):
| scenario | leva eval | P(pass entro 1a) | mediana giorni |
|---|---|---|---|
| book modellato | 1.0x | 81-86% | 111-132 g |
| book modellato | 1.5x | 78-85% | **72-89 g** |
| book modellato | 2.0x | 72-81% | 46-62 g |
| de-luck ×0.6 | 1.0x | 63-72% | 113-137 g |
| de-luck ×0.6 | 1.5x | 62-71% | **70-87 g** |
| de-luck ×0.6 | 2.0x | 56-65% | 43-58 g |
Fase funded ($100k nozionale, split 80%, 1 anno): **modellato** P(conto vivo) 88.9%,
payout p10/p50/p90 = EUR 8.9/42.3/93.4 al giorno; **de-luck ×0.6** P(vivo) 67.7%,
p10/p50/p90 = EUR 1.3/**31.1**/77.9 al giorno. A $200k nozionale i payout raddoppiano
(mediana de-luck ~EUR 62/g) — il target dei 50 EUR/g sta tra $150k e $200k funded.
**Caveat onesti:** (1) daily-loss simulato su barre daily → i wick intraday rendono le
P(pass) OTTIMISTE; (2) le regole reali (consistency, min trading days, divieto bot/API,
weekend) possono uccidere lo stile low-frequency → vedi ricerca firm 2026 sotto;
(3) payout = reddito VOLATILE, non "rendita" (p10 de-luck ≈ EUR 1/g).
## D) Vault / copy-trading (parte D)
A perf-share 10% sopra HWM servono **$1-2M di TVL altrui** per 50 EUR/g → richiede anni
di track record pubblico, non mesi. Vincolo legale per residente italiano (gestione di
capitale altrui = art. 166 TUF) approfondito nella ricerca dedicata sotto.
---
## Migliorie interne implementate/decise oggi
1. **Gate di deploy PRE-REGISTRATO per STATARB-RESID** (`r0724_statarb_deploy_gate.py`).
Forward a oggi: 25 barre, +4.42%, Sharpe fwd +5.84 (caldissimo → regredirà), DD 1.4%,
haircut 0.01pp. Regola fissata OGGI (day 25) per evitare selection-on-forward:
**decisione il 2026-09-27 (90g)**; Sh≥0.5 → candidato deploy (pesi {10,15,20}% via
`weights_tilt_null`, maxDD combinato <15%); 0≤Sh<0.5 → UNA proroga di 90g; Sh<0 → ritiro.
Guardie: haircut <0.5pp, config congelata (W=45, sgn=+1), DD fwd <10%.
2. **Audit infra:** i messaggi "open/completed orders request timed out" nel cron daily sono
warning benigni di `ib_async` al connect col Gateway IB (conto paper DU) — cosmetici,
nessuna azione. Book live 743/743 giri completati; errori cerbero-mcp solo storici.
3. **Conferme di sistema (non ri-litigate):** soffitto direzionale ~1.3 (10+ ondate);
book già quasi-risk-parity; alzare vol = de-levering inverso (frontiera 2026-07-03);
il vincolo binding è il CAPITALE, non la ricerca. Il cap dinamico equity/2 è già
pronto ad assorbire depositi.
## Ricerche web (3 agenti paralleli) — RISULTATI
### R1 — Yield / basis / carry a $600-20k (luglio 2026): NIENTE di rilevante ora
- **Il carry è al fondo del ciclo, CC01 confermato live**: funding BTC annualizzato
+70% (gen 2026, euforia) → **−3.4%** (mag) → **+4.2%** (metà lug); spot 22-24 lug ≈ 0.
**ETH funding NEGATIVO** (flip 3-4 giu). CME basis −2.35% dic 2025 (peggior
backwardation post-FTX). Carry netto BTC oggi: **0-2%/anno < Aave**, con più tail risk.
- **Menu onesto**: Aave v3 USDC **4-5%** = pavimento income reale; sUSDe 4-7% in
compressione (= il premio CC01 tokenizzato, riserva 1.18% del TVL, TVL fuggito
$14B→$5.9B, DeFi-only per EEA); **HLP ~15-25%** ma è inventory di market-making
travestito da yield (tail plausibile −20/−50%, cooldown sui prelievi; nel crash
ott 2025 fece +10% in un weekend — profitta nei cascade, sanguina nei trend).
- **Tier di capitale**: $600 → ~€0.07/g; $5k → ~€0.6-0.8/g; $20k → **€2.5-4/g**
(aggressivo HLP-heavy ~€5-6 con la sua coda). Nessuno step-change tra 5k e 20k;
quelli veri sono ~$20k (basis multi-leg eseguibile QUANDO il funding torna) e $100k+
(fee tier). 50 EUR/g a 5-8% onesto = **€250-350k** — peggio del muro trading.
- **Regola operativa cablabile**: CC01 resta LEAD **regime-triggered** — riaprire il
dossier solo con **funding medio 1-mese > 10-15% annualizzato sostenuto** (la serie
funding HL ce l'abbiamo già). Gli spike stile gen-2026 (70% ann., spariti in
settimane) NON sono income raccoglibile.
- **MiCA day-one 2026-07-01 — mappa venue per residenti IT**: **Binance OUT** (no
licenza, restrizioni dal 1/7); Bybit globale bloccato EEA, bybit.eu senza perp;
**Deribit OK** (Coinbase ha licenza MiCA Luxembourg) ma perp-EU-retail in zona grigia
MiFID-II da monitorare; **Hyperliquid ancora accessibile** senza KYC ma è il
test-case del perimetro EU → rischio geoblock futuro reale. In pratica: i nostri
due venue sono esattamente ciò che resta.
- ⚠️ **FISCO ITALIA 2026**: capital gain crypto **33% dal 1/1/2026** (~~L.199/2025~~ →
**L. 207/2024 art. 1 c.23-29**, corretto il 2026-08-07: la L.199/2025 fa altro, vedi CLAUDE.md),
esenzione €2.000 ABOLITA (dal 2025), IVAFE 0.2%, DAC8 auto-reporting, crypto nell'ISEE.
→ ogni numero di questo diario è LORDO: **50 EUR/g netti ≈ 75 EUR/g lordi**, il
muro di capitale sale di ~1.5x (~EUR 180k a CAGR 15%). Da verificare col
commercialista il trattamento di yield/staking.
_(FX: i rendimenti sono USD-denominati; ~2pp del 4.5% stable è solo il differenziale
tassi USD-EUR — hedged in EUR il "4.5%" reale è ~2.5%.)_
### R2 — Prop firm crypto 2026: via CREDIBILE ma payoff modesto — €8-15/g a $100k, cap $200k
- **Vincolo vero = geometria del drawdown**: le eval crypto-native danno **DD max 3-6%
statico** (non 10%) contro il maxDD storico 9.4% del book → si gira a 0.5-1.0x vol.
FTMO Swing è l'unica con DD 10% ma è crypto-via-CFD (swap ~10-25%/anno).
- **Ranking per QUESTO stile** (verificato su fonti primarie, non affiliate-SEO):
1. **HyroTrader** 1-step $100k ($579): unica con **API reale** (sub-account Bybit) da
funded, funding = mercato (stessa economia del book Deribit), no time limit, weekend
ok, consistency 40% solo in eval, fee rimborsata al pass, payout ~12h. Cap $200k.
2. **Breakout/Kraken Prop** ($800): miglior reputazione (Trustpilot 4.8, Kraken-backed),
regole pulite, MA **carry nascosto 0.033%/giorno ≈ 12%/anno sul nozionale** = ostile
ai multi-week hold; niente API supportata (a cadenza 1d l'esecuzione manuale è ~5
min/g, non-blocker). Evitare 2-step (DD trailing = veleno per un trend book) e Turbo (DD 3%).
3. **FTMO Swing** (~€540): controparte più solvibile del settore ($450M+ pagati),
DD 10%, EA propri su MT5; ma crypto non è il suo core.
- **Crypto Fund Trader: EVITARE** (Trustpilot soppresso per manipolazione, pattern di
payout negati, SL obbligatorio che rompe la meccanica TSMOM).
- **Monte Carlo aggiornato alle regole VERE** (parte C di `r0724_goal50_math.py`, bootstrap
dei ritorni reali del book): de-luck ×0.6 a leva 1.0-1.5x → **P(pass) 55-68%, mediana
68-137 giorni**; funded $100k HYRO de-luck → P(vivo 1a) 69%, payout mediano €31/g SE
vivo. La MC dell'agente (Sharpe 0.5-1.0, code t(4)) converge: P(pass) 40-72%.
⚠️ **SUPERATO da C-bis (MC intraday, sera stessa)**: questi numeri sono close-only e
OTTIMISTI — coi wick intraday P(pass) de-luck ~44% a 1.0x, funded a 1.0x P(vivo) crolla
a 20.5% (leva ottima funded = 0.75x). Vedi sezione C-bis sotto.
- **Attriti fuori dal MC** (che tagliano l'atteso): carry/swap, recycling dei bust
(~40-55%/anno di P(bust) al limite 6%), consistency in eval, **controparte non regolata**
(il settore ha perso il 13% delle firm nel solo 2024, $50M+ di payout stranded; profitti
non ritirati = credito chirografario) → **atteso blended onesto: €250-450/MESE a $100k
funded; €15-30/g al cap $200k nei buoni scenari.** Consob/ESMA stanno tirando il
modello verso MiFID II → rischio regolatorio EU 2026-27.
- **Disciplina se si apre il fronte**: entry sensata = $25k ($249) o $50k ($379) come
test economico che può autofinanziare il tentativo $100k; prelievi SETTIMANALI
(mai lasciare credito alla firm); è un side-bet EV+ ~10-50x il rendimento della stessa
strategia sui nostri $600 — **non** la soluzione del capitale.
### R3 — Monetizzazione track record / vault / legale IT: NIENTE in mesi, stack lento legale in 18-36 mesi
- **Aritmetica sovrana**: ogni canale profit-share paga ~10-15% dei profitti generati sul
capitale altrui → a CAGR onesto 15-20%, 50 EUR/g richiede **€600k-1.2M di capitale
follower**. Nessun meccanismo sposta quel capitale su un track record di mesi con $600
di skin-in-the-game.
- **Hyperliquid vault: MORTO a $600** — creazione ora costa **$10k** + leader deve tenere
≥5% del vault; TVL mediano dei vault utente ≈ $0 (solo ~$35M su 2.400 vault non-HLP);
la discovery è ordinata per APR → un 15-20% difensivo è carta da parati.
- **Copy trading post-MiCA (1/7/2026)**: Binance/Bybit/Bitget CHIUSI per residenti EEA.
Restano: **OKX EU** (Malta MiCA+MiFID II, lead trader legale con KYC, 8-13% profit
share) e **eToro Popular Investor** (Champion: $400-800/mese FISSI = €13-26/g, ma
servono $50k di copier AUM + $5k equity propri + 6 mesi risk-score ≤7 → 12-24 mesi).
- **Darwinex Zero = miglior fit strutturale**: l'engine normalizza tutti alla stessa vol
→ **l'allocazione si vince con lo SHARPE, non col CAGR flashy** — l'unico canale dove
la virtù del book è la metrica classificata. FCA-regolato, 15% perf fee sopra HWM,
~$35-50/mese di costo. Primi fee piccoli a 3-6 mesi, >€10/g a 18-36 mesi con
qualche centinaio di k€ di allocazione cumulata. Caveat: crypto solo via MT5 CFD →
conto parallelo, non monetizza direttamente il book Deribit.
- **Collective2**: mediana ≈ $0 lifetime, C2 trattiene ~50%, il retail compra emozioni
non Sharpe difensivi → non vale il listing fee.
- ⚠️ **LEGALE (pattern regolatorio, non parere)**: gestione remunerata di conti di
amici/famiglia = **art. 166 TUF, 1-8 anni** (+ D.Lgs. 129/2024 art. 30 per i
crypto-asset, 6m-4a) — è l'unico canale "veloce" ed è esattamente quello penale;
la denuncia arriva con le perdite. Safe harbor = lead trader su venue licenziata
(la licenza è della piattaforma). Newsletter GENERICA con disclaimer = lecita;
personalizzazione/auto-esecuzione/soldi in mano = attività riservata.
- **Stack realistico a 24 mesi** (Darwinex + eToro/OKX): top-decile **€15-45/g**,
mediana €5-15/g. In "qualche mese": ~€0. Il vincolo non è la strategia, è il
**trust-capital** — e si accumula sullo stesso orologio del capitale.
### C-bis — MC INTRADAY wick-aware (addendum serale): chiuso il caveat n.1 — i wick
### tagliano 6-37pp di P(pass) e RIBALTANO la config consigliata
Script `scripts/research/r0724_goal50_intraday_mc.py`. Il MC di parte C applicava le
regole alle CHIUSURE daily; le regole vere scattano sull'equity intraday. Qui l'equity
del book è ricostruita MTM a 1h sul feed certificato: TP01 = pesi daily (fee di
ribilanciamento incluse), SKH01 = trade 230m con exit AL LIVELLO SL/TP nell'ora del
trigger (SL prioritario, stessa convenzione di `backtest_signals`), wick per-barra
firmati col segno del peso.
**Validazione della ricostruzione** (obbligatoria prima di credere ai numeri):
leg TP01 corr daily 0.9997 e log-total +0.833 vs sleeve×0.75 +0.827 (esatto); leg SKH
log-total +0.548 vs sleeve×0.25 +0.513 (Δ≈0.5%/anno, bordi orari); book Sharpe MTM 1.62
vs 1.77 dello sleeve — il delta è l'ATTRIBUZIONE: lo sleeve SKH è equity-a-scalino
per-trade (P&L intero sulla barra d'ingresso), mentre un conto prop è marcato MTM →
la lens MTM è quella giusta per questo uso. ⚠️ Bug catturato dalla sanity al primo run:
`reindex` con indice tz-naive contro tz-aware → NaN→0 SILENZIOSI, TP01 sparito dal recon
(corr 0.43) — ennesima conferma della famiglia di lezioni pandas-tz del progetto.
**Geometria dei wick del book**: gap (min intraday − chiusura) p50 −0.17pp, p10 −1.03pp,
p1 −2.7pp, worst −6pp; 2.6% dei giorni con wick oltre −2pp. Piccolo in mediana, ma le
regole prop sono sensibili proprio alla coda.
**Eval (de-luck ×0.6, P(pass) close→intraday):** a leva 1.0x HYRO 58.8%→**44.7%**,
BREAKOUT 57.1%→**26.6%**, FTMO Swing 65.7%→**59.9%**. Tre conseguenze:
1. **La leva 1.5x consigliata dal MC close-only è REFUTATA**: intraday fa PEGGIO di 1.0x
(HYRO 36.0% vs 44.7%) — i wick amplificati bruciano il daily-loss prima che il drift
paghi. Config onesta: **eval a leva 1.0x**, mediana pass ~99g (HYRO) / ~125g (FTMO).
2. **Breakout Classic declassata**: il daily-loss 3% coi wick del book è una tagliola
(P(pass) 26.6%) — fuori dalla shortlist.
3. **FTMO Swing riabilitata dal lato regole**: il DD 10% assorbe i wick (haircut solo
−5.8pp) → miglior P(pass); resta il caveat swap CFD ~10-25%/anno NON nel MC, che
colpisce esattamente i multi-week hold del book.
**Fase funded — sweep di leva (novità decisiva): la leva ottima è 0.75x, non 1x.**
A 1.0x col max-loss 6% HYRO l'account de-luck sopravvive 1 anno solo il **20.5%** delle
volte (il close-only diceva 69% — era il numero più gonfiato di tutta la parte C).
A **0.75x**: HYRO P(vivo) 58.1%, E[payout] $5.8k/anno (~€14.5/g ATTESO, mediana €20.6/g
se vivo); FTMO 0.75x P(vivo) 82.2%, E[payout] $7.4k lordo swap. Equivalente operativo:
girare il funded a target_vol ~15% invece del 20% canonico.
**EV del biglietto aggiornato (eval 1.0x, funded 0.75x, de-luck):** P(pass) ~44%,
**P(perdere la fee) ~56%** (peggio del 35-45% stimato close-only), EV a 1 anno
+$491/$1.048/$2.197 per i conti 25/50/100k → il fronte prop resta EV-positivo ma più
sottile; il costo atteso per arrivare funded è ~$570-1.325 a seconda della taglia.
Limiti dichiarati: wick a risoluzione 1h (i 5m sarebbero più severi → le P(pass) restano
un TETTO); leva applicata linearmente al giorno; bust funded = payout 0 (i prelievi
settimanali reali migliorano l'atteso). Test suite invariata (172 pass).
## Roadmap — sintesi e decision tree
### Verdetto finale (nessuna modalità esclusa, tutte quantificate)
**50 EUR/giorno entro "qualche mese": NON esiste via legale che ci arrivi.** I massimi
onesti per canale nell'orizzonte di mesi: prop funded ~€8-15/g (a $100k, P~55-68%,
3-6 mesi); yield ~€0-4/g (vincolato dal capitale, e il carry è al fondo del ciclo);
monetizzazione del track record ~€0 (i canali pagano in anni). L'unico canale "veloce"
è gestire a compenso i soldi di terzi senza autorizzazione = **reato** (art. 166 TUF,
1-8 anni) → chiuso. Il fisco 2026 (33%) alza ogni muro di un ulteriore ~1.5x.
**50 EUR/g resta raggiungibile solo come STACK su 18-36 mesi**, con esecuzione buona e
un po' di fortuna: prop al cap $200k (€15-30/g) + Darwinex/eToro (€5-20/g) + capitale
proprio cresciuto con depositi (a €20k il book fa ~€5-8/g). Top-decile ≈ €30-60/g a
24 mesi; mediana ≈ €10-25/g. Senza depositi sostanziosi, il target scivola oltre.
### Cosa è stato cablato oggi (branch `goal/50eur-day`)
| # | Cosa | File |
|---|---|---|
| 1 | Matematica del target + MC prop con regole vere | `scripts/research/r0724_goal50_math.py` |
| 2 | Gate deploy PRE-REGISTRATO statarb (decisione 27/09) | `scripts/research/r0724_statarb_deploy_gate.py` |
| 3 | Trigger regime CC01 (funding 30g, WARN 10%/ALERT 15%) | `scripts/live/cc01_regime_watch.py` |
| 4 | Fix test latente paper-advance (pre-esistente su main) | `tests/test_trend_portfolio.py` |
| 5 | Questo diario | `docs/diary/2026-07-24-goal-50eur-roadmap.md` |
| 6 | MC prop INTRADAY wick-aware (recon MTM 1h del book) | `scripts/research/r0724_goal50_intraday_mc.py` |
### Decisioni che spettano all'operatore (non automatizzabili)
1. **Fronte prop** (l'unico che cambia la scala in mesi): sì/no. Se sì (numeri C-bis,
MC intraday): HyroTrader $25-50k come test (€230-350), poi $100k; **eval a leva 1.0x
(NON 1.5x — refutata dai wick), funded a 0.75x** (≈ target_vol 15%); prelievi
settimanali; budget mentale = perdere l'intera fee con **P~56%** de-luck; atteso
funded ~€14.5/g a $100k. Alternativa con P(pass) migliore: FTMO Swing (DD 10%
assorbe i wick) MA swap CFD 10-25%/anno sui multi-week hold. Breakout Classic NO
(daily-loss 3% + wick = P(pass) 27%). Il book si esegue a mano (5 min/g)
dal segnale di `paper_portfolio` finché non c'è l'API funded.
2. **Track record pubblico** (canale 18-36 mesi): aprire Darwinex Zero (~€40-50/mese,
l'unico venue dove lo Sharpe difensivo compete sul merito) e/o candidarsi lead trader
OKX EU / eToro PI. Costo basso, payoff lento ma legale e cumulativo.
3. **Depositi**: il moltiplicatore più affidabile resta il capitale proprio — il sistema
è già pronto (cap dinamico equity/2, aspettativa onesta ~€0.6-0.8/g a 2k,
~€1.4-2/g a 5k, ~€5-8/g a 20k lordi).
4. **Alla merge in main**: aggiungere `cc01_regime_watch.py` a `cron_daily.sh` (riga
read-only) così il trigger CC01 lavora da solo.
### Cosa NON fare (confermato da questa ondata)
- Niente leva per "accelerare" (parte B: rovina quasi certa a ogni tier di capitale).
- Niente gestione remunerata di conti altrui, nemmeno family&friends (penale).
- Niente yield-chasing sopra il pavimento Aave 4-5% (HLP = trading risk travestito).
- Niente vault HL a questo capitale ($10k di creazione + 5% skin + discovery per APR).
- Il book live Deribit resta INVARIATO (pesi, config, esecuzione) — questa ondata non
ha toccato nulla del path live.
@@ -0,0 +1,72 @@
# 2026-07-24 — Ondata ON-CHAIN / SENTIMENT: la famiglia era vergine, il verdetto è 0/6 slot
**Goal**: "trova altre strategie, sfruttiamo anche internet". Prima parte (questa): la
famiglia on-chain/sentiment — l'unica grande famiglia di INFORMAZIONE (non di prezzo)
mai testata dal progetto — meccanizzata onestamente su dati gratuiti scaricati stasera.
Script `scripts/research/r0724_onchain_wave.py`. In parallelo girano 3 agenti di ricerca
web (letteratura accademica, segnali on-chain/fonti dati, pratica non convenzionale) —
sintesi in un diario/addendum separato quando completano.
## Setup
- **Segnali**: CoinMetrics Community (CSV daily dal genesis, gratuito, tokenless:
AdrActCnt, TxTfrCnt, CapMVRVCur, SplyExNtv, HashRate) + Fear&Greed alternative.me
(2018-02→oggi) + supply stablecoin totale DefiLlama (2017-11→oggi). Staging in
`data/external/coinmetrics/` (gitignored — NON certificato, mai usato come prezzo).
- **Ritorni**: SOLO feed Deribit certificato (lezione v2.0.0). Harness: `altlib`,
`study_family_honest` (selezione cella IN-SAMPLE, deflated-Sharpe sull'intera griglia,
marginal scorer indurito vs TP01). 32 celle totali su 6 famiglie, tutte contate.
- **Causalità**: doppio lag — segnale by-day shiftato di 1 giorno (la riga CM del giorno
d si completa a EOD d + processing) + lo shift di 1 barra di `eval_weights` ⇒ lag
attività→posizione = 2 giorni. tz-aware su entrambi i lati del reindex (la trappola
naive/aware ha già colpito stasera nel MC intraday).
## Verdetti (0/6 earns_slot_honest)
| Famiglia | Cella IS | DSR | Marginale | Perché muore |
|---|---|---|---|---|
| **STABLE**-supply-growth | L=30 LF thr=10% | **0.998** | **ADDS** | robust_oos=False (uplift concentrato, 2026 domina) |
| **NET**-growth (Liu-Tsyvinski) | TxTfrCnt L=30 LF | 0.916 | ADDS | DSR<0.95 E jackknife −0.12 |
| **MVRV**-valuation | long-salvo-top p90 | 0.968 | DILUTES | hold-out −0.08, blend peggiora sempre |
| **EXS**-exchange-supply | L=90 LF | 0.903 | NEUTRAL | hold-out **−0.58**: il claim "outflow=bullish" è DECADUTO |
| **HASH**-ribbons (BTC-only) | 30/60 hold120 | 0.984 | **HEDGE** | paga solo quando TP01 è debole (corr −0.67) |
| **FNG**-fear-greed | regime media7>50 | 0.955 | NEUTRAL | corr→TP01 **0.82**: è trend travestito |
## Il finding strutturale
**L'on-chain tradabile è in larga parte PREZZO TRAVESTITO**: corr→TP01 0.50-0.82 su
tutte le famiglie. L'attività di rete, il sentiment e la supply su exchange *seguono*
il prezzo; quando ne estrai un segnale direzionale daily ottieni un trend-follower
peggiore di TP01 con un vocabolario diverso. È la stessa firma delle onde macro-gate
(corr 0.989) e funding: la barra per un nuovo sleeve non è "informazione nuova" ma
"informazione nuova NON già incorporata nel prezzo che TP01 segue".
## Il lead (debole): STABLE-supply-growth
L'unico sopra la linea su quasi tutti i gate: la crescita 30g della supply stablecoin
totale (soglia 10% annualizzato) come gate risk-on. Standalone FULL 1.25/HOLD 0.42,
DSR 0.998, ADDS persistente multi-cut, non-hedge, blend w25 hold +0.12. Muore SOLO su
robust_oos (drop-best-month −0.06; l'uplift 2026 = 1.32 domina la persistenza).
⚠️ **Caveat VINTAGE che declassa il lead a WATCH**: la storia DefiLlama è RICOSTRUITA
retroattivamente (chain e coin aggiunte nel tempo) — il "totale supply" visto oggi per
il 2019-2021 NON era osservabile allora. Un backtest su serie vintage-contaminate può
inventare edge. Idem (più mite) per le metriche exchange-flow CM (labeling dei wallet
rivisto ex-post). **Regola nuova da questa ondata: ogni segnale da aggregatori esterni
va classificato per rischio-vintage prima del backtest; un PASS su serie ricostruita
vale al massimo WATCH.**
Decisione: **WATCH, niente paper-monitor** (corr 0.61-0.67 a TP01 = il beneficio
marginale reale è piccolo; il vintage-risk non è sanabile retroattivamente). Criterio
di rivisita: se una fonte point-in-time della supply stablecoin (snapshot propri da
oggi, o fonte con vintage garantito) accumula ≥12 mesi, ritestare il gate thr=10%.
## Note dati (per il futuro)
- CM community: fermo al **2026-05-24** (~2 mesi di lag) → inutilizzabile live senza
fonte fresca; per backtest ok.
- ETH HashRate muore al Merge (2022-09) → hash-famiglia solo BTC.
- F&G è DERIVATO da vol+momentum di prezzo → la ridondanza col trend era attesa e
lo scorer l'ha confermata.
Book/pesi INVARIATI. Test suite invariata (172 pass).
+132
View File
@@ -0,0 +1,132 @@
# 2026-07-24 — SKH01 sul PATH LIVE: peso del book Deribit a 2 sleeve + valore della cadenza 230m
**Chiude il follow-up aperto dall'audit anchor 2026-07-02** (`2026-07-02-anchor-audit-xs01-skh01.md`:
"cadenza 230m, peso live da rivedere"). Il book live Deribit è TP01 0.75 + SKH01 0.25
(`sleeves.deribit_book_sleeves`); l'audit aveva mostrato che il path live reale (cron ORARIO
`0 * * * *` + exit software, non on-book al livello) degrada SKH01 (50/50: FULL 1.46→1.19,
HOLD 1.64→1.15, DD 18→25%) e che l'offset 0 della griglia 230m/690m è best-of-23. Domanda:
**dato il path live vero, qual è il peso SKH ottimale, e quanto vale allineare il cron a 230m?**
**Script:** `scripts/research/r0724_skh_live_weight.py` — riusa la macchineria di
`r0702_anchor_skh01.py` (import diretto di `run_asset`/`sim_equity`/`get5m`/`sanity`, non
riscritta). Nessun file di produzione toccato (config/sleeves/live/cron INVARIATI).
## Verdetto in una riga
**INVARIATO su entrambi i fronti**: il peso SKH ottimale sul path live, scelto onestamente
(mediana de-luckata sui 23 offset, IN-SAMPLE, mai su hold-out), è **0.25 = il peso corrente**
(plateau 0.20–0.30); e **allineare il cron ai confini 230m non vale nulla** (Δmediana di banda
~+0.01/+0.02 Sharpe): il degrado live è quasi tutto **fill-al-livello vs exit software**,
che nessuna cadenza recupera.
## Setup (onestà dichiarata a priori)
- **Serie SKH live-path**: tutti i **23 offset** a priori della griglia (ogni 30m su [0,690)) ×
3 modi di `sim_equity`: `canonical` (fill al livello sl/tp = backtest), `barclose` (fill al
close della barra 230m = ciò che otterrebbe un cron allineato ai confini), `hourly` (fill al
close 5m del prossimo multiplo orario = **path del cron reale**). Sanity replica bit-exact
del canonico prima di ogni numero.
- **Sweep peso**: book = (1−w)·TP01 + w·SKH_live, w ∈ {0, .10, .15, .20, .25, .30, .40, .50}
(**8 valori = multiple-testing leggero, dichiarato**; nel gate k_seen=8). TP01 =
`al.tp01_baseline_daily()` canonico (come nell'audit).
- **Regola di selezione dichiarata PRIMA di vedere i numeri**: w* = argmax della **mediana
sui 23 offset dello Sharpe IN-SAMPLE** (pre-2025), lente `hourly`; a parità (<0.03) vince
il w più vicino al corrente 0.25. **L'hold-out serve solo a verificare, mai a scegliere.**
- **Gate**: `weights_tilt_null` (src/portfolio/portfolio.py) adattato al book a 2 sleeve
(null = 500 tilt casuali floor 0.05 / cap SKH 0.50 attorno al 75/25, sui daily del path
live hourly).
## Sanity — riconciliazione con l'audit r0702
Off0 == `_skyhook_returns()` **bit-exact** (max|Δ|=0.0 su 2688 giorni; l'audit ne aveva 2666 —
22 giorni di feed in più, deriva-dati attesa). DD harness BTC 21.4% / ETH 27.4% e n. trade
identici al diario di ammissione. Book 50/50 off0:
| modo | ShFULL | ShIS | ShHOLD | maxDD | audit r0702 |
|---|---|---|---|---|---|
| canonical | 1.447 | 1.418 | 1.578 | 18.1% | 1.46 / — / 1.64 / 18.1% |
| barclose | 1.100 | 1.080 | 1.228 | 23.0% | (non riportato) |
| hourly | 1.179 | 1.201 | 1.103 | 24.6% | 1.19 / — / 1.15 / 24.6% |
TP01 baseline: FULL 1.290 / IS 1.488 / HOLD 0.297 / DD 14.3% (audit ~1.30/~0.31). Blend 75/25
canonical off0 HOLD 1.125 (audit ~1.16). **Riconcilia** (Δ ≈ deriva-dati).
## Sweep peso — lente HOURLY (path live, quella della decisione)
| w | off0 FULL/IS/HOLD/DD | mediana banda FULL/IS/HOLD/DD | HOLD min..max | DD min..max |
|---|---|---|---|---|
| 0.00 | 1.29 / 1.49 / 0.30 / 14.3% | 1.29 / 1.49 / 0.30 / 14.3% | — | — |
| 0.10 | 1.48 / 1.67 / 0.54 / 11.8% | 1.42 / 1.63 / 0.43 / 11.9% | 0.33..0.56 | 11.3..13.1% |
| 0.15 | 1.56 / 1.74 / 0.66 / 11.6% | 1.47 / 1.68 / 0.50 / 11.6% | 0.35..0.70 | 10.7..12.6% |
| 0.20 | 1.61 / 1.79 / 0.77 / 11.3% | 1.51 / 1.71 / 0.56 / 11.3% | 0.36..0.82 | 10.1..12.7% |
| **0.25** | **1.65 / 1.82 / 0.86 / 11.1%** | **1.53 / 1.72 / 0.62 / 11.2%** | 0.36..0.94 | 9.6..13.6% |
| 0.30 | 1.67 / 1.82 / 0.94 / 11.0% | 1.53 / 1.71 / 0.67 / 11.0% | 0.37..1.05 | 9.4..14.6% |
| 0.40 | 1.65 / 1.78 / 1.04 / 11.9% | 1.48 / 1.65 / 0.73 / 11.9% | 0.35..1.20 | 10.4..17.3% |
| 0.50 | 1.58 / 1.69 / 1.09 / 12.9% | 1.39 / 1.53 / 0.76 / 13.4% | 0.33..1.30 | 11.2..19.9% |
(La tabella `canonical` di riferimento è nell'output dello script: stessa forma, picco a
0.30–0.40 su off0 — l'off0 canonico resta la lente gonfiata già nota.)
- **Mediana-IS (hourly) per w**: 0.00:1.488 · 0.10:1.627 · 0.15:1.678 · 0.20:1.710 ·
**0.25:1.721** · 0.30:1.712 · 0.40:1.645 · 0.50:1.534 → argmax = **0.25**, plateau
{0.20, 0.25, 0.30} dentro la tolleranza 0.03 → **w\* = 0.25 = corrente**.
- Anche sul path live onesto la gamba SKH **paga**: a w=0.25 la mediana di banda migliora
TP01-solo su tutto (FULL 1.29→1.53, IS 1.49→1.72, HOLD 0.30→0.62, DD 14.3%→11.2%) —
la diversificazione sopravvive al path orario. Il sizing 25%, deciso a suo tempo su numeri
best-of-23, **risulta a posteriori difendibile anche de-luckato sul path vero**.
- **Tentazione rifiutata per regola**: su off0 l'HOLD cresce monotono fino a w=0.50 (1.09).
Sceglierlo sarebbe selezione-sull'hold-out + fortuna d'ancora (off0 = 98° pctl HOLD
nell'audit). La banda IS dice 0.25 e il DD di banda peggiora oltre 0.30.
## Gate `weights_tilt_null`
w\* == corrente → **nessun cambio proposto: INVARIATO** (gate non necessario). Eseguito
comunque, a titolo informativo, sul miglior w ≠ corrente (0.30):
- **off0 (griglia live)**: delta_insample +0.007, delta_hold +0.076, pctl_hold 53.6 (<88.9
best-of-8) → gate_pass **True ma marginale** (frac_random_beat_hold 0.562: più di metà dei
tilt casuali batte il 75/25 sull'hold-out — il claim "SKH aiuta l'hold-out" è generico,
non specifico di 0.30).
- **off30 (offset IS-mediano)**: delta_insample **−0.009** → gate_pass **False**. Il pass di
off0 è (di nuovo) figlio dell'ancora fortunata: il tick +0.01 IS a 0.30 non è robusto
alla banda. → 0.30 NON supera la barra onesta; **75/25 resta**.
## Cadenza 230m — barclose vs hourly (a w=0.25)
- off0: ΔShFULL **−0.040**, ΔShHOLD +0.068, ΔDD −0.9pt. Banda 23 offset: ΔShFULL med
**+0.010** [−0.042,+0.105], ΔShHOLD med **+0.020** [−0.109,+0.162], ΔDD med −0.3pt.
- SKH standalone 50/50: barclose−hourly ΔShFULL off0 −0.080 (med +0.015), ΔShHOLD off0
+0.125 (med +0.041), ΔDD off0 −1.5pt (med −1.3pt).
- **Sorpresa onesta**: a off0 il barclose è perfino PEGGIO dell'hourly su FULL — il ritardo
0–50 min del cron orario è **rumore, non un costo sistematico**. Il vero gap è il
**fill-al-livello** (canonical−barclose: ΔShFULL off0 +0.347, ΔShHOLD +0.350, ΔDD −4.9pt),
cioè l'assunzione del backtest che l'exit avvenga esattamente a sl/tp — e quello **nessun
cron lo recupera** (l'exit software in una barra che gappa prende il gap comunque; già
misurato dall'audit: sl2% → −11/−23% realizzato nei crash).
- Fattibilità (SOLO stima, non cablata): 230=23×10 → i confini 230m cadono sempre su multipli
di 10 min dall'epoch, quindi un cron `*/10` che esegue solo quando `now % 230min == 0`
colpirebbe ogni confine con ritardo ~0. **Ma non vale la pena**: guadagno mediano ~+0.01/+0.02
Sharpe, dentro il rumore, contro 6× invocazioni cron e complessità sul path live certificato.
## Caveat
- Exit software nei crash = gap reale (la sim `hourly` è già la stima pessimistica giusta);
niente slippage/parziali modellati; equity daily-step (lens Sharpe) come canonico e audit.
- 8 valori di w provati e dichiarati (k_seen=8 nel gate); selezione mai sull'hold-out.
- La banda 23-offset è la lente de-luckata; live gira UNA sola griglia (off 0).
- Deriva-dati vs audit (22 giorni di feed in più): riconciliazione "circa", riportata sopra.
- A $600 la granularità del peso non vincola (gamba SKH a w=0.10 ≈ $60/trade ≫ min-order $5).
## Raccomandazione finale (decisione utente per ogni cambio config)
1. **Peso SKH del book live Deribit: INVARIATO a 0.25.** È l'ottimo di banda sul path live
(plateau 0.20–0.30); nessun w alternativo passa il gate in modo robusto.
2. **Cadenza cron: INVARIATA (oraria).** L'allineamento 230m vale ~+0.01/+0.02 Sharpe mediano
(rumore); il degrado live è strutturale (fill-al-livello), non di cadenza. Non cablare il
cron `*/10`.
3. L'aspettativa onesta della gamba SKH live resta quella dell'audit: blend ~fase-mediana +
path orario (HOLD di banda ~0.62 a w=0.25, non 1.17), con gap-through-stop nei crash.
Il **follow-up dell'audit 2026-07-02 è CHIUSO** (entrambi i punti, esito nullo).
**Stato:** config/live.json, sleeves.py, scripts/live, cron **INVARIATI** — questo è ricerca;
ogni eventuale cambio resta una decisione esplicita dell'utente. Script committabile dopo review.
+42
View File
@@ -0,0 +1,42 @@
# 2026-07-24 — Snapshot stato paper book (chiusura sessione goal/50eur-day)
Fotografia dello stato dei libri paper al 2026-07-24 00:00 UTC, presa alla chiusura della
sessione (merge di `goal/50eur-day` in main a `05d069f`, branch cancellato, cron cablati:
cc01_regime_watch + stable_snapshot in cron_daily, opzioni 0DTE 2x/g 07:55+08:05 UTC).
Serve da riferimento per le decisioni pre-registrate (gate STATARB 2026-09-27 in primis).
## Book attivo 5-sleeve (`paper_portfolio`, €2000 nominali dal 2026-06-19)
- **Equity €2018,80 → +0,94% in 35g** (≈+10% ann.), **maxDD 0,3%**, picco €2018,89 (22/07).
- Posizioni: **risk-off quasi totale sul crypto** — TP01 0.0x/0.0x, XS01 flat (gate
dispersione chiuso), VRP01 nessuno spread (gate IV-rank chiuso), SKH01 flat.
Unica gamba investita: **GTAA01** (IB, 23/07) SPY 15,5 / HYG 16,7 / IWM 8,2 / QQQ 6,2 /
TLT 5,7 / GLD 2,1 / cash 45,8%.
- Lettura onesta: il rendimento del mese viene dalla gamba equity difensiva + i pochi
giorni crypto di fine giugno; i gate tengono il book fuori dal crypto da settimane —
comportamento atteso (il valore è il taglio del DD, non il ritorno). Coerente col book
live Deribit, anch'esso flat.
## Forward monitor
| Libro | Equity | Da inizio | maxDD | Posizione |
|---|---|---|---|---|
| Combo TP01+GTAA (dal 22/06) | €1991,20 | −0,44% | 0,6% | segue gli sleeve sopra |
| **STATARB-RESID** (dal 29/06) | €2088 mod. / €626 reale-$600 | **+4,4%** | 1,4% | long residuo 0.22x |
| Prevday-breakout (dal 21/06) | €1904 mod. / €572 reale | −4,8% | 6,4% | short BTC −0,47 / ETH −0,37 |
- **STATARB è il monitor messo meglio** (+4,4% in ~4 settimane, modellato E reale-$600
quasi identici, DD 1,4%): se la finestra forward regge, il gate pre-registrato
`r0724_statarb_deploy_gate.py` (2026-09-27) ha una chance concreta di promozione a
sleeve eseguibile (2 gambe BTC/ETH perp).
- Prevday −4,8%: lead in osservazione, nessuna azione.
## Promemoria trigger attivi a questa data
- Gate deploy STATARB: **2026-09-27**.
- Dossier 0DTE: riapertura solo dopo **≥90g** di snapshot (serie partita 24/07) con
mediana IV_daily/RV_forward netto-haircut > 0.
- WATCH STABLE: ritest a **≥12 mesi** di snapshot point-in-time (serie partita 24/07).
- CC01: riapertura a funding 30g **≥15% ann.** (watch in cron; oggi QUIET, BTC +8,4%).
Book live Deribit e pesi INVARIATI in tutta la sessione.
+161
View File
@@ -0,0 +1,161 @@
# 2026-07-24 — Caccia strategie via web (3 agenti + 3 ondate empiriche): 0 slot, 2 lead operativi, 1 pista infrastrutturale
**Goal**: "trova altre strategie, sfruttiamo anche internet". Seconda metà della serata
(la prima è l'ondata on-chain, diario `2026-07-24-onchain-sentiment-wave.md`). Tre agenti
di ricerca web in parallelo (accademia 2022-26, on-chain/fonti dati, pratica non
convenzionale) + meccanizzazione immediata di tutto ciò che era testabile stanotte.
## Convergenza ricerca ↔ empirica (il quadro)
La letteratura di replicazione 2024-26 dice: dei 36 fattori crypto pubblicati ne
sopravvivono **2-3** (tutti liquidity/momentum — Mercik/Zaremba IRFA 2026); le anomalie
sono micro-cap e bull-conditional (Fieberg IRFA 2024); attention/volume falliscono OOS;
i flussi opzioni predicono la VOL, non la direzione (Alexander JFM 2022). Le prime 5
raccomandazioni degli agenti (MVRV, stablecoin, exchange-flow, F&G, hash ribbons)
**coincidono con le famiglie uccise stanotte dall'ondata on-chain** — la convergenza
indipendente ricerca/empirica è essa stessa il finding: il soffitto ~1.3 direzionale
BTC/ETH non si aggira con "informazione nuova" che è funzione del prezzo.
## Ondata PREMI CROSS-VENUE (empirica, stanotte) — 0/2, con lezione
`scripts/research/r0724_premium_wave.py` — unica famiglia flow con dati 100%
auto-calcolati da candele raw (zero rischio-vintage): Coinbase premium (2015→) e
kimchi premium Upbit/ECB (2017→), allineamento 00:00 UTC verificato (le daily Upbit
ancorano a 09:00 KST = mezzanotte UTC).
- **CBPREM**: medio −1bp (il feed certificato è un indice che include Coinbase →
premio smorzato, strutturale); miglior cella = HEDGE, hold −0.46 → MORTO.
- **KIMCHI d30-follow**: il candidato più forte della serata — **EARNS_SLOT=True al
marginal scorer** (ADDS, robust_oos, uplift positivo OGNI anno 2020-26, non-hedge,
hold standalone 0.74) ma DSR 0.891<0.95. Lo scettico (`r0724_kimchi_skeptic.py`) lo
uccide in due mosse: **niente plateau** (d15 0.44 / d30 1.07 / d45 0.51 / d60 0.24 =
spike isolato) e **lag +1g lo azzera** (hold 0.74→0.14, uplift blend negativo).
→ SCARTATO, parameter-luck. **Lezione: un EARNS_SLOT con DSR<0.95 va SEMPRE allo
scettico plateau+lag prima di qualsiasi entusiasmo** — il DSR aveva ragione.
## Probe HLP vault (dati reali API HL, 89 periodi ~14g, 2023-05→oggi)
L'unico stream **crash-long** mai visto dal progetto: corr col book **−0.19**, nei
periodi in cui il book perde HLP fa in media **+2.5%**; crash ott-2025 **+10.4%**,
liquidazione feb-2026 +7.0%. Sharpe grezzo 1.98 (su barre 14g — il daily vero è più
brutto), maxDD 5.8%. MA: **decay netto** (+60%/+79% 2023/24 → +19% 2025 → ~+12%
run-rate 2026, TVL diluisce) e la coda di protocollo (JELLY mar-2025, −$12M
quasi-socializzati; contract/bridge risk) NON è nella serie → lo Sharpe è
event-luck + short-tail-risk travestito da income. **Verdetto: ALLOCATION-WATCH**
(non è una strategia: è un deposito USDC con lockup 4g). A $600 la materialità è
~€10-30/anno → decisione operatore, non urgente. Dati: `data/external/hlp_vault.json`.
## LEAD infrastrutturale nuovo: Polymarket ↔ Deribit (probabilità implicite)
Il best-find dell'agente pratica: le binarie BTC/ETH su Polymarket vs le probabilità
implicite della chain opzioni Deribit — **gap medio 11pp vs Deribit** (arXiv 2606.19517),
half-life ~4h (= retail-compatible), delta-hedge col perp che già tradiamo. Unico
candidato 2026 che è insieme: meccanismo NUOVO (non prezzo), eseguibile a $600 (PM min
$1, no fee), e costruibile su infra ESISTENTE (motore BS/DVOL di VRP01 + cerbero-bite).
Scettici seri dichiarati: campione accademico piccolo e clusterizzato; parte del gap è
probabile **spec-mismatch** (fonte/orario di risoluzione PM vs settle Deribit) da
riconciliare contratto-per-contratto PRIMA di credere a un bp; book PM sottili vicino a
risoluzione; l'arb veloce è dei bot (73% sub-100ms) — l'angolo onesto è la convergenza
lenta a limit-order. **→ Prossima ondata di ricerca: studio di riconciliazione** (dati:
PM CLOB API gratuita + DB storico pubblicato arXiv 2606.04217). Nessun codice stasera.
## Altre azioni a costo zero raccomandate dagli agenti (per l'operatore)
1. **Puntare cerbero-bite anche sulle scadenze DAILY Deribit** da subito: 365 expiry/anno
= una serie di premi REALI si accumula 7× più veloce delle weekly → in 6 mesi decide
il dossier 0DTE/calendar (che resta bloccato dalla regola no-short-vol-da-modello).
2. Dataset Reservoir S3 (tape completo HL: fill, liquidazioni, ADL, L2) = primo dataset
non-di-prezzo del progetto, requester-pays (serve account AWS) → abilita studio
liquidation-exhaustion + listing-effects. Parcheggiato: richiede setup infra.
3. ETF flows: storia 2.6 anni → NON testabile onestamente fino al ~2028 (parcheggiato
con data di rivisita).
## Test cross-sectional su HL (lead-lag JEDC 2024 + salience/MAX) — DEAD 2/2
`scripts/research/r0724_xs_leadlag_max.py` (agente, 19 major HL, 2024→2026-07, 936g,
0 backfill verificato a runtime, convenzioni XS01: fee 0.10% RT/gamba, vol-target 20%,
holdout 2025).
- **LEAD-LAG (Guo et al. JEDC 2024)**: finding strutturale — con predictor equal-weight
"all-others", S_i = (Σr − r_i)/(A−1) è affine DECRESCENTE nel ritorno proprio
(rank-corr empirica **−1.000**): il "lead-lag accademico" sull'universo È lo
short-term reversal, già morto (3ª conferma FOLLOW>FADE). Le 8 celle hanno IS Sharpe
TUTTE negative (best −0.11); le celle large5 "buone" in hold-out (1.18) non sono
selezionabili in-sample (trappola selection-on-holdout) E sono degenerate (14/19
asset a segnale identico). DSR 0.237. **DEAD.**
- **MAX/lottery (Cai&Zhao JBF 2024)**: cella IS L30/H10 FULL 0.59 / HOLD 0.47,
DSR **0.412**, il segno si INVERTE tra L7 e L30 (plateau assente), 34 ribilanci IS
(small-n), fee-zero non salva (edge lordo piccolo, non morte-per-fee). Sotto lo
standard STATARB (0.84/DSR 0.929) → **DEAD**, non lead. Direzione coerente con la
letteratura ma indistinguibile dal rumore su ~2.5 anni.
Nota metodologica in omaggio: la degenerazione "predictor affine nel ritorno proprio"
è un check di 3 righe (rank-corr segnale↔momentum proprio) che smaschera i lead-lag
cross-section travestiti — da riusare su ogni futura proposta XS.
## Bilancio del goal "trova altre strategie"
Su tutta la serata: **10 famiglie nuove meccanizzate e giudicate coi gate completi + 1
probe** (6 on-chain/sentiment + 2 premi cross-venue + 2 cross-sectional HL + probe HLP),
3 report di ricerca web con ~50 fonti primarie, **0 slot nuovi** — coerente con la
storia del progetto (il book attuale resta il massimo onesto raggiunto) — ma:
1 pista genuinamente nuova con meccanismo non-di-prezzo (Polymarket↔Deribit, prossima
ondata), 1 allocation-watch crash-long (HLP), 2 azioni a costo zero (daily options
capture, rivisita ETF 2028), e 2 regole metodologiche nuove a diario (vintage-risk
delle fonti esterne; scettico plateau+lag obbligatorio sugli EARNS_SLOT con DSR<0.95).
Book/pesi INVARIATI.
---
## Addendum (sera, goal "un agente per ogni case") — i 3 verdetti
Tre agenti dedicati, uno per case, tutti su DATI LIVE (nessun claim di seconda mano).
Script: `r0724_pm_deribit_probe.py`, `r0724_hlp_deepdive.py`, `r0724_daily_opt_snapshot.py`.
### 1. Polymarket ↔ Deribit (con opzioni in copertura) — **SKIP come trade; il lead "11pp" è REFUTATO dalla misura**
34 binarie PM matchate alle daily options Deribit, spec verificata su 66 mercati (PM
risolve su candela 1m Binance USDT alle 16:00 UTC; Deribit TWAP 30m indice USD alle
08:00). Il gap si decompone in: **fonte USDT +9,3bps di basis = +4-5pp di probabilità
ATM**, tempo 8h ∓5pp, e replica ingenua su book ITM morti (la banda sub/super-replica
ATM è [39%,91%] con strike ogni $500 su orizzonti a 1σ≈$350). Residuo spec-adjusted:
ATM −5…+6pp a segno instabile DENTRO la banda di replica; tail +1,8-3,1pp
(favorite-longshot) sotto i costi. Trade coperto reale a size minima: lock netto
$0,1-5, capitale $200-1.000 (il margine SM del leg corto domina: Deribit non netta i
vertical), **P(gambe in conflitto 08→16 UTC) 2-22%** → non è un arb. Più geoblock/ToS
PM per residenti IT. Facoltativo: WATCH a costo zero (cron dello script per la serie
del gap tail). Lezione: anche il "best lead" accademico muore alla riconciliazione di
spec — la parte vera del gap era spec, non alpha.
### 2. HLP vault — **SKIP come income, WATCH con trigger meccanici; il carry 2026 ex-evento è +0,2%/anno**
Trovata la serie daily vera (wrapper wHLP via CoinGecko, 364 giorni + thunderhead per
i tail di marzo 2025): il daily smaschera la lens 14g — Sharpe 0,69 (non ~2), maxDD
−7,9%, worst day −5,96%; e l'uscita-in-stress via wrapper costa ~5% di sconto NAV.
**Il finding killer: il +12% headline 2026 è UN SOLO periodo evento (feb-2026 +7%);
gli altri 15 periodi sommano +0,10%** → carry ex-evento ~0,2%/anno, PnL-$ piatto vs
TVL (ritorno ∝ 1/TVL, e i depositanti lo sanno: TVL −59% dal picco). Coda JELLY
ricostruita: −4,7% MtM su inventario EREDITATO illimitato, troncato SOLO da un voto
discrezionale dei validator in 2 minuti — il crash-long può morire NEL crash
(pattern is_hedge-che-fallisce). Kelly onesto con code: **f*=0 al carry corrente**.
Trigger di ri-arma meccanici: 90g return-on-AUM ≥8% ann. AND TVL<$350M AND nessun
evento di socializzazione in 180g. Legale: HL accessibile dall'IT ma non autorizzato
MiCA → rischio geoblock non copribile con lock 4g.
### 3. Opzioni DAILY Deribit (0DTE) — **CAPTURE-AND-WAIT con prior negativo; cattura AVVIATA**
Misura live (22:35 UTC): mercato 2-sided reale anche sulle ali, MA il cap fee 12,5%
è quasi sempre binding a tenor daily → **drag fee 2-3× il weekly** (legge Albimarini
dal vivo: premio ~√T, fee ~costante; haircut mid→netto 0DTE ~45-50%) e stanotte
**IV_daily/RV = 0,43-0,54× (VRP NEGATIVO al front)** mentre il weekly fa 1,13×
(coerente con VRP01: il premio vive lì). Capitale minimo per defined-risk vero
(Portfolio Margin) ≈ $32k; a $600 = 1 lotto ETH a EV negativo. **Pipeline scritta e
attiva**: `r0724_daily_opt_snapshot.py` → `data/options_daily/snapshots.jsonl`
(primo snapshot 160 righe già su disco; raccomandate 2 run/g 08:05+07:55 UTC — da
cablare in cron alla merge, read-only). Regola pre-registrata: riaprire il dossier
solo dopo ≥90g di serie E mediana(IV_daily/RV_forward) netto-haircut > 0.
Diario dedicato: `2026-07-24-daily-options-0dte.md`.
### Bilancio dei 3 case
0 trade nuovi (ed è il punto: due lead famosi refutati coi numeri, non con le
opinioni), 1 pipeline di cattura reale avviata che tra 90 giorni decide da sola,
regole di ri-arma meccaniche per HLP, e il metodo confermato: ogni claim muore o
sopravvive alla RICONCILIAZIONE DI SPEC prima che al backtest. Book/pesi INVARIATI.
@@ -0,0 +1,295 @@
# 2026-07-25 — Caccia a strategie nuove: MAT01 (trend multi-asset) + generalizzazione di STATARB, e uno SPLIT non aggiustato nel feed equity
Goal di sessione: **trovare nuove strategie**. Tre filoni scelti cercando i vuoti reali nella
mappa (89 diari, famiglie calendario/funding/VRP/CRT gia' dichiarate sature). Esito: **0 sleeve
nuovi**, 2 refutazioni pulite, 1 **difetto di dato che tocca il libro live** trovato e riparato,
1 addendum pre-registrato al gate STATARB del 27/09.
Book e pesi **INVARIATI**.
---
## (1) MAT01 — trend difensivo su 18 ETF multi-asset-class invece di 6 → **SCARTATO**
Script: `scripts/research/r0725_mat01_multiasset_trend.py`, `r0725_mat01b_regime.py`.
**Il vuoto.** GTAA01 gira su 6 ETF (SPY QQQ IWM TLT GLD HYG), 4 su 6 azionari US. I 12 ETF
multi-classe (DIA EFA EEM FXI EWJ AGG LQD IEF USO SLV DBC VNQ) sono su disco certificati dal
2026-06-22 con 9-30 anni di storia, ma erano stati usati SOLO per il test lead-lag crypto→X
(diario 2026-06-23-crossmarket-beyond-sp500), mai per un programma di trend. Il TSMOM
multi-asset-class e' l'anomalia meglio replicata della finanza quantitativa: valeva il test.
**Disciplina.** Meccanismo CONGELATO (import di `_exposure` da `src/portfolio/gtaa.py`: orizzonti
21/63/126/252, vol-target 12%, long-flat, EW, fee 2bps/lato). Cambia SOLO l'universo. L'universo
ALL18 e' definito a priori per classe d'attivo: **a k=18 la liberta' di selezione e' zero**
(esiste un solo sottoinsieme di 18 su 18), quindi il confronto ALL18-vs-GTAA6 non e' selezionabile.
**Risultati.**
| | Sh FULL | Sh IS<2015 | Sh OOS2015+ | maxDD OOS | vol |
|---|---|---|---|---|---|
| GTAA6 (incumbent) | 0.62 | 0.49 | **0.89** | −8.2% | 6.05% |
| MAT18 (candidato) | 0.56 | 0.43 | 0.80 | −6.9% | 4.62% |
| MAT18-CLS (per classe) | 0.57 | — | 0.73 | — | 4.38% |
corr(GTAA6, MAT18) = 0.91. Sostituzione nel book a peso invariato 20%: Sharpe FULL 2.22→2.19,
HOLD 2.36→2.38, DD 6.2%→6.6%. Corr→crypto praticamente identica (0.110 vs 0.116): **nessun
guadagno di diversificazione**, che era l'unica ragione plausibile per farlo.
**Perche' scartato — quattro ragioni indipendenti:**
1. **Finestre disgiunte: MAT18 perde 3/4** (1998-2004 0.28 vs 0.40; 2005-2011 0.63 vs 0.54 —
unica vittoria; 2012-2018 0.55 vs 0.72; 2019-2026 0.99 vs 1.13). Non e' regime-luck
dell'incumbent: GTAA6 vince anche nella finestra che contiene dot-com e GFC.
2. **A PARI VOLATILITA' il vantaggio di DD sparisce e si inverte**: MAT18 va scalato ×1.31 per
eguagliare la vol di GTAA6, e a quel punto maxDD −20.6% contro −15.4%. Il suo DD piu' basso
era **solo de-levering** — replicabile meglio abbassando `target_vol`.
→ **3ª occorrenza della stessa lezione** (overlay DD del VRP01 2026-07-03: 4/4 refutati dal
null de-levering; TP01×DVOL 2026-06-26: il taglio di DD era de-levering). Il null de-levering
e' ormai il primo test da fare su ogni claim di "meno drawdown".
3. Beta azionario e alpha quasi identici (GTAA6 beta 0.19 / alpha 1.56%; MAT18 0.14 / 0.97%):
MAT18 non e' meno "equity travestito", e' solo piu' piccolo.
4. Nei bear MAT18 e' migliore (GFC −3.0% vs −5.1%, 2022 −3.2% vs −6.1%) ma paga quel conforto
con Sharpe piu' basso in ogni altro regime.
**Il risultato POSITIVO da conservare — l'ampiezza funziona, ma il soffitto e' gia' raggiunto.**
La curva di ampiezza (400 sottoinsiemi casuali per k, Sharpe OOS) e' monotona in 13/17 passi:
mediana **0.44 a k=1 → 0.80 a k=18**, DD mediano **−16.0% → −6.9%**, satura verso k≈10-12.
Cioe': allargare l'universo di un trend difensivo *e' un meccanismo reale*. Ma GTAA6 sta al
**95° percentile dei 6-subset casuali** — e non perche' sia un best-of cherry-picked (contiene
TLT, il PEGGIORE dei 18 con Sh OOS 0.03): e' la sua composizione (equity US + oro + credito HY)
a stare sopra il soffitto d'ampiezza. **Non c'e' piu' ampiezza da raccogliere su questo sleeve.**
---
## (2) STATARB-MULTI — il meccanismo generalizza fuori da ETH/BTC? → **si', debolmente; nessuno sleeve nuovo**
Script: `scripts/research/r0725_statarb_multi.py`.
**Perche'.** STATARB-RESID e' il miglior lead del progetto e ha un gate di deploy al **2026-09-27**,
ma e' stato scoperto su UNA coppia dentro uno sweep. Test out-of-pair-sample: meccanismo congelato
(W=45, sgn=+1) su tutte le **50 coppie alt/BTC** di Hyperliquid, che non hanno partecipato alla
scoperta.
**Cosa regge:**
- **82% delle 50 coppie ha Sharpe netta > 0** (media 0.38, mediana 0.32).
- **0/50 coppie degeneri**: il segno del segnale e' quasi bilanciato (mono medio 53%) → NON e' la
scommessa statica "short alt vs BTC" travestita, che era il modo di fallire pre-registrato.
- p-permutazione a blocchi < 0.05 nel **18%** delle coppie (atteso 5% per caso).
- **ETH/BTC e' al rango 22/50, 58° percentile: la coppia scopritrice NON e' un outlier.** E'
l'informazione piu' utile per il gate del 27/09: l'ipotesi "fortuna di una coppia" non regge.
- Paniere EW delle 50 coppie: Sharpe 0.82, maxDD −6.0%, **corr a XS01 solo 0.207** (non ridondante).
**Cosa NON regge — e perche' non e' uno sleeve:**
- **Ampiezza effettiva ~4.5, non 50** (corr media fra coppie 0.204: condividono la gamba BTC).
- **Block-bootstrap sul paniere: IC95% [−0.12, +1.72], t ≈ 1.31** → non distinguibile da zero su
2.6 anni. Il t cross-coppie apparente di 5.05 e' gonfiato dalla dipendenza.
- Contro il null **"sempre short alt vs BTC"** (a priori, nessun parametro stimato) l'uplift medio
e' **−0.11** e solo il 40% delle coppie lo batte: una parte del rendimento e' beta di regime
2024-2026, non timing.
- Eseguibilita': 50 coppie = 51 gambe → STAT-MODE come XS01, fuori portata a $600.
⚠ **Correzione a un mio errore di metodo, dentro questa stessa sessione.** La prima stesura del
null statico usava `sign(mean(segnale))` sull'INTERO campione: un null che conosce gia' la
direzione giusta, cioe' look-ahead. Rifatto in due versioni oneste — (a) causale con media
espandente, (b) a priori sempre-short. L'uplift vs la versione causale e' mediana +0.10 / 58%
positivo (debolmente favorevole); vs sempre-short e' negativo. Il numero pubblicabile e' questo,
non quello della prima stesura.
---
## (3) STATARB-EQ — lo stesso meccanismo su coppie ETF con 20-30 anni di storia → **SCARTATO, e il crypto non ne esce rafforzato**
Script: `scripts/research/r0725_statarb_eq.py`.
**Perche'.** La debolezza di STATARB-RESID non e' il segno dei numeri, e' la statistica: 2.6 anni,
ampiezza effettiva 4.5. Le coppie ETF la attaccano frontalmente — 12 coppie definite **a priori
dentro la stessa classe d'attivo** (DIA/SPY, IWM/SPY, QQQ/SPY, EEM/EFA, EWJ/EFA, FXI/EEM, EFA/SPY,
SLV/GLD, IEF/TLT, HYG/LQD, LQD/AGG, USO/DBC), **28.5 anni**, ampiezza effettiva **9.9**, 4 regimi
completi. Nessun data-mining di cointegrazione: cercare le coppie piu' cointegrate sugli stessi
dati sarebbe selezione.
**Esito: il meccanismo NON si trasferisce.**
| | valore |
|---|---|
| Sharpe LORDA media / mediana | −0.17 / −0.16 (25% positive) |
| Sharpe NETTA media / mediana | −0.50 / −0.51 (8% positive) |
| paniere EW, 28.5 anni | Sharpe **−1.00**, IC95% [−1.36, −0.64], **t −5.33** |
| per decade | −0.56 / −1.61 / −1.83 / −0.78 — **negativo in 4/4** |
| p-permutazione < 0.05 | **0%** delle coppie |
| turnover | 0.40/giorno → drag di fee **0.33 Sharpe** |
| borrow 0 / 30 / 100 bps | −1.00 / −1.06 / −1.21 |
**La lettura corretta e' nella decomposizione lordo/netto, non nel netto.** La lorda e' −0.17, non
−1.00: due terzi del disastro sono drag di turnover. Quindi **non esiste una "strategia specchio"
da girare**: sgn=−1 avrebbe lorda ≈ +0.17 e netta ≈ −0.16, morta anch'essa sui costi. Il segno
lordo dice pero' una cosa vera e interessante: **sulle coppie azionarie il residuo REVERTE
debolmente, mentre sul crypto CONTINUA** (sgn=+1 vince). Il meccanismo di STATARB e' quindi
plausibilmente specifico del crypto, non universale.
**Onesta' sull'inferenza:** che non funzioni sulle azioni NON dimostra che non funzioni sul crypto
— gli indici azionari sono efficienti e le coppie alt/BTC hanno microstruttura e flussi diversi.
Il punto e' negativo in modo preciso: il gate del 27/09 **non puo' appoggiarsi** all'argomento
"e' un fenomeno universale, quindi e' reale". Non lo e'.
---
## (4) ⚠ DIFETTO DI DATO: split NON aggiustati nel feed equity — trovato, riparato, gate chiuso
Emerso mentre diagnosticavo ritorni giornalieri impossibili in (3) (min −99.9%, max +112%).
**Il fatto.** `data/raw/eq_iwm_1d.parquet` e `eq_efa_1d.parquet` avevano uno **split non aggiustato
il 2005-06-09** (tornata di split iShares): IWM 94.13→47.53 (−49.5%, rapporto 1.981 ≈ **2:1**),
EFA 85.91→28.76 (−66.5%, rapporto 2.987 ≈ **3:1**). IB `ADJUSTED_LAST` non li aveva aggiustati.
**Perche' la certificazione non li vedeva — ed e' un punto cieco strutturale, non sfortuna.**
L'unica guardia sui salti era `maxret > 50% → SPIKE?`. Uno split 2:1 non aggiustato produce
**esattamente −50%**: cade sul filo della soglia. IWM passava a 49.5% con status **OK**. La soglia
era tarata precisamente sul valore che il difetto piu' comune genera.
**Perche' importa: IWM e' una delle 6 gambe di GTAA01, sleeve in PRODUZIONE.** Impatto misurato:
| GTAA6 | FULL Sh | IS<2015 Sh | OOS2015+ Sh | maxDD |
|---|---|---|---|---|
| con difetto | 0.61 | 0.49 | 0.86 | −15.38% |
| riparato | **0.64** | **0.54** | 0.86 | −15.38% |
Il difetto **sottostimava** lo sleeve (l'artefatto e' nel 2005, fuori dall'hold-out) → **nessuna
decisione presa va rivista**, ma il dato e' ora corretto.
**Il discriminante split-vs-crollo (la parte riusabile).** Non basta il rapporto: SLV il
2026-01-30 ha fatto −28.5% con rapporto **1.3994**, a 4 bps da 1.4. Il discriminante e' il **range
intraday**:
- **SPLIT**: la barra APRE gia' al nuovo livello, range intraday normale. IWM 2005-06-09: open
47.00, range 1.7%. Un crollo del 50% con range 1.7% non esiste.
- **CROLLO VERO**: il movimento avviene DENTRO la barra. SLV: open 89.33, low 69.12, range 33%,
volume raddoppiato, e **GLD −10.3% lo stesso giorno**. Stessa verifica su EEM 2008-10-28 (+26%,
reale).
**Cosa e' stato fatto:**
- Nuovo modulo `src/data/eq_splits.py` — `detect_unadjusted_splits()` (tre condizioni congiunte:
|ret|>20% AND rapporto entro 1.5% da un fattore comune AND range intraday <5%) e
`repair_splits()` (riscala i prezzi precedenti; split multipli si compongono; volume opposto).
- Riparazione **in lettura** in entrambi i loader: `src/portfolio/gtaa.py::_close` (produzione) e
`scripts/research/eqlib.py::load_eq` (ricerca).
- Certificazione indurita: `fetch_ib_equities.certify()` ha ora lo status **`SPLIT-NON-AGG`** e
riporta gli split rilevati.
- Test `tests/test_eq_splits.py` (8 casi): i due split reali, il falso positivo SLV, un crollo
−50% esatto con range grande, split multipli componibili, serie pulita invariata, ed end-to-end
sui parquet. **Suite completa: 180 passed.**
**Regola nuova:** ogni soglia di certificazione tarata su un valore tondo va controllata contro il
difetto che genera *esattamente* quel valore. Una soglia a 50% non puo' sorvegliare gli split 2:1.
---
## (5) Addendum PRE-REGISTRATO al gate STATARB del 27/09
Registrato **oggi, forward-day 26 di 90, 64 giorni prima della decisione** — pre-registrazione
vera, non selezione a posteriori. Motivo: il null "sempre short alt vs BTC" batte il segnale sul
60% delle coppie crypto, e su ETH/BTC (finestra HL 2024-2026) il pareggio e' quasi esatto
(segnale 0.46 vs statica 0.48).
`r0724_statarb_deploy_gate.py` ora calcola e riporta anche lo Sharpe della **statica sempre-short
a pari vol-target sulla stessa finestra forward**. **Le soglie pre-registrate il 2026-07-24
(Sharpe≥0.5, DD<10%, haircut<0.5pp) NON sono state toccate**: il benchmark e' una diagnostica
obbligatoria da leggere insieme, e la decisione se renderlo binding spetta all'operatore.
**Lettura di oggi (26 barre, da non sovrainterpretare):** STATARB **+5.70** contro benchmark
statico **−4.98**. La posizione forward corrente e' LONG lo spread (+0.61), cioe' **opposta** alla
scommessa statica → la finestra forward sta testando il segnale in un modo che il beta di regime
non spiega. Prima lettura favorevole.
---
## (6) ✅ XSR01 — il candidato che e' uscito dal filone (2): **CROSS-SECTIONAL RESIDUAL**
Script: `r0725_statarb_basket_gate.py` (gate), `r0725_statarb_demean_skeptic.py` (scettico),
monitor `scripts/live/paper_xsr.py`, gate `r0725_xsr_deploy_gate.py`, test `tests/test_paper_xsr.py`.
Il paniere di coppie del punto (2) non era uno sleeve per un motivo **diagnosticato, non subito**:
ampiezza effettiva 4.5 invece di 50, perche' le 50 coppie **condividono la gamba BTC**. Da qui una
variante **pre-registrata per ragione strutturale** (prima di guardare i risultati): demeanare le
posizioni cross-sezionalmente ogni giorno. L'algebra dice cosa succede:
sum_i (p_i − p̄)(r_i − r_btc) = sum_i (p_i − p̄) r_i perche' sum_i (p_i − p̄) = 0
**la gamba BTC si annulla**, e con essa il fattore comune. Il risultato non e' piu' un paniere di
coppie: e' una strategia **cross-sectional dollar-neutral sui 50 alt** con pesi (p_i − p̄)/N.
| | V1 ALL50 | V2 MAJ19 | **V3 DEMEAN** |
|---|---|---|---|
| Sharpe netta | 0.82 | 0.75 | **1.82** |
| maxDD | −6.0% | −8.1% | **−2.6%** |
| ampiezza effettiva | 4.5 | 4.0 | **37.4** |
| marginale vs TP01 | ADDS | NOISE | **ADDS** |
| deflated-Sharpe | 0.701 | 0.660 | **0.985 PASS** |
**Gate superati.** Marginale **ADDS** con `robust_oos`, `beats_noise_null`, `is_hedge=False`,
`has_insample_edge=True`. **Deflated-Sharpe 0.985** (soglia 0.95) su 3 varianti pre-registrate — e
la config W=45/sgn=+1 viene da un altro studio, su questi dati non e' stata cercata.
**Correlazione ~0 a TUTTI e 5 gli sleeve attivi**: TP01 0.060, XS01 −0.019, VRP01 −0.001,
SKH01 0.001, GTAA01 0.071. Book a w=15%: HOLD 2.36 → **2.51**, DD invariato.
**Verifica avversariale** (`r0725_statarb_demean_skeptic.py`) — numeri cosi' puliti sono, in questo
progetto, il momento in cui di solito si trova l'artefatto. Quattro attacchi:
- **Tre null a fee-neutrale** (permutazione cross-sezionale delle etichette-asset; posizioni
casuali; permutazione temporale a blocchi 20g): tutti centrati a **~0.01** con p95 1.0-1.3, e il
candidato **LORDO 2.70 sopra il massimo di 300 estrazioni** → p < 0.004 su tutti e tre.
⚠ Correzione di metodo: la prima stesura confrontava a fee piene, e i null uscivano a −3.7/−4.2
perche' permutare **fa esplodere il turnover** → il null perdeva per COSTO, non per assenza di
segnale, dando un p-value trionfale e falso. A fee zero il confronto isola l'informazione.
- **Lag**: 1.82 → 1.19 → 0.81 → 0.51 a +0/1/2/3 giorni. **Decadimento dolce = segnale lento reale;**
un look-ahead crollerebbe a zero al primo giorno di ritardo.
- **Ridondanza**: contro un momentum cross-sectional semplice sugli stessi 50 (che fa Sharpe
0.03/0.17/−0.79 a L=30/45/90) la correlazione e' 0.29/0.17/−0.10 → **non e' XS01 travestito**.
- **Struttura**: netto 2e−17 (dollar-neutral esatto), 23.8 gambe long su 50 (bilanciato), lordo
14.4% del capitale.
**Le tre debolezze, dichiarate — e' per queste che va in MONITOR e non nel book:**
1. **Storia 2.6 anni, un regime solo**, e il rendimento e' **crescente** (Sharpe 2024 1.03 / 2025
1.98 / 2026 3.11): la maggior parte dell'edge e' recente.
2. **`weights_tilt_null` NON passa** (gate_pass=False a w=10% e 15%, delta_insample −0.004/−0.007).
E' un effetto strutturale della storia corta — ma un gate fallito resta fallito.
3. **Margine di costo sottile**: 1.82 a 0.05%/gamba, **0.93 a 0.10%, NEGATIVA a 0.20%**. Turnover
38.5% del lordo al giorno su 50 alt fra cui illiquidi (GALA, BLUR, JTO, ORDI, WIF) e **slippage
non modellato**: e' il rischio numero uno.
**Eseguibilita' — il numero che serve davvero:** ticket medio per gamba $1.73 a $600 (**sotto il
min-order $5: STAT-MODE al capitale attuale**), $5.76 a $2000, **$14.41 a $5000**. Cioe' XSR01
diventa reale intorno ai **$5.000**, non ai $20.000 di XS01.
**Cablato come ogni lead del progetto:** `scripts/live/paper_xsr.py` (config CONGELATA, **tre**
libri paralleli MODELED $2000 / REAL $600 / REAL $5000 con min-order per gamba, stato append-only),
inserito in `cron_daily.sh`, test a 7 casi che bloccano config, dollar-neutralita', causalita' dello
step, min-order e la trappola dei timestamp. Gate di decisione pre-registrato oggi a forward-day 0:
**2026-10-23**, con soglia Sharpe ≥ 1.0 **E** una guardia di costo esplicita (haircut di
eseguibilita' a $5000 ≤ 40%, altrimenti RITIRO a prescindere dallo Sharpe).
⚠ Trappola pandas ri-pagata e ri-documentata: `astype("int64")` su `DatetimeIndex` tz-aware dava
epoche 1970 nel monitor. E' la gemella di quella dell'ondata 2026-07-01. Ora c'e' un test.
---
## Bilancio
- **1 candidato nuovo: XSR01**, il primo da molte ondate a superare marginale-ADDS, deflated-Sharpe
0.95, tre null avversariali e il test di lag, con corr ~0 a tutti e 5 gli sleeve. In
forward-monitor (NON nel book) per tre ragioni dichiarate: storia 2.6 anni, `weights_tilt_null`
fallito, margine di costo sottile. Gate pre-registrato al **2026-10-23**.
**Nota di onesta' su come e' nato:** non e' uscito da un'idea nuova, e' uscito dalla
DIAGNOSI di un fallimento — l'ampiezza effettiva 4.5 del paniere di coppie indicava un fattore
comune da togliere, e toglierlo era una mossa algebrica obbligata, non una ricerca di parametri.
- 2 refutazioni pulite con diagnostica riusabile: il soffitto d'ampiezza di GTAA01 e' gia'
raggiunto; STATARB non e' un fenomeno universale (non si trasferisce alle azioni).
- 1 difetto di dato sul **libro live** trovato, quantificato, riparato, testato e chiuso alla fonte.
- Il gate del 27/09 arriva alla decisione con **un'ipotesi alternativa in meno** (fortuna di una
coppia: refutata, 58° percentile) e **un benchmark in piu'** (beta statico, gia' favorevole).
- Due errori di metodo miei, trovati e corretti dentro la sessione: null statico con look-ahead
(STATARB-MULTI) e null a fee piene contro un segnale permutato ad alto turnover (scettico XSR01).
Entrambi avrebbero prodotto numeri piu' belli e sbagliati.
Script: `r0725_mat01_multiasset_trend.py`, `r0725_mat01b_regime.py`, `r0725_statarb_multi.py`,
`r0725_statarb_eq.py`, `r0725_statarb_basket_gate.py`, `r0725_statarb_demean_skeptic.py`,
`r0725_xsr_deploy_gate.py`; monitor `scripts/live/paper_xsr.py`; modulo `src/data/eq_splits.py`;
test `tests/test_eq_splits.py`, `tests/test_paper_xsr.py`.
@@ -0,0 +1,234 @@
# 2026-07-25 — La lente wick ACCOPPIATA: chiusura del follow-up dichiarato
**Script:** `scripts/research/r0725_prop_coupled.py` · **Test:** `tests/test_prop_coupled.py` (13 casi)
**Segue:** `2026-07-25-rendita-capcurve-prop.md` §5 (scala prop) e §7 (HyroTrader)
**Book / pesi / cron: INVARIATI.** Nessuna decisione di portafoglio dipende da questo lavoro.
---
## 1. Cosa era rimasto aperto, e perché contava
La scala di conti funded (§5 del diario di stamattina) era stata giudicata con **due lenti** che
differiscono di un **ordine di grandezza** su P(≥50 €/g in 3 anni):
| lente | P(≥50/g) | com'era descritta |
|---|---|---|
| close-only | **20.7%** | tetto ottimista — le regole prop scattano sull'equity intraday, non sulla chiusura |
| wick indipendente | **1.6-2.5%** | pavimento pessimista — gap lognormale estratto **indipendente** dal rendimento del giorno |
Una banda 1.6%-20.7% non decide niente: è la differenza fra "scommessa a coda destra che vale i
600 euro" e "non vale la pena". E il difetto del pavimento era **già dichiarato** nel docstring:
> *«nella realtà i wick profondi stanno sulle giornate brutte (sono ACCOPPIATI): estrarli
> indipendenti aggiunge finti tuffi anche nelle giornate buone → breach spuri → stima troppo
> severa. Il modo giusto è il bootstrap delle TUPLE (ritorno, gap) come in
> r0724_goal50_intraday_mc.py, che però ha il recon solo per TP01+SKH01 → FOLLOW-UP dichiarato.»*
Questo lavoro chiude quel follow-up.
## 2. Metodo
Tre pezzi, tutti verificati contro qualcosa di indipendente:
1. **Recon per-sleeve a risoluzione oraria.** `r0724` calcola il minimo intraday del book Deribit
con i pesi 75/25 **cablati dentro**. Qui i pesi si dividono via per ottenere gli sleeve nudi
(ret, wick) di TP01 e SKH01 — così il minimo si compone **esattamente** sul path orario per
**qualsiasi** vettore di pesi. Logica invariata: exit-al-livello, SL prioritario, fee.
2. **Lente accoppiata per XS01**, che su Hyperliquid è 1d nativo. L'escursione intraday si
ricostruisce dagli **OHLC giornalieri** dei 19 alt: il book si valuta ai 4 checkpoint
O / primo estremo / secondo estremo / C, con **ordinamento condiviso** fra le gambe (le alt
co-muovono) preso nell'ordine **avverso**. Non è path-exact, ma è **accoppiato al giorno vero**,
che è tutto il punto.
*Sanity:* il recon riproduce lo sleeve ufficiale con `max|Δ| = 0.0` esatto.
3. **Le tre lenti sulla stessa macchina di simulazione** (close / indipendente / accoppiata), così
il confronto non mescola differenze di modello con differenze di lente.
---
## 3. Il risultato principale: la calibrazione era giusta, l'**indipendenza** era l'errore
Confronto delle distribuzioni **marginali** del gap (book live TP01/SKH01, 2691 giorni):
| | p50 | p90 | p99 | peggiore |
|---|---|---|---|---|
| **accoppiato (recon)** | −0.17pp | −1.03pp | −2.70pp | −5.96pp |
| indipendente (calibrazione 25/07) | −0.17pp | −0.90pp | −3.50pp | — |
**Sono quasi identiche.** La calibrazione lognormale di stamattina era buona. Quello che era
sbagliato non è *quanto* sono profondi i tuffi, ma **su quali giorni cadono**.
### 3.1 E la dipendenza va nel verso inatteso
Mi aspettavo — e lo avevo scritto — che i gap profondi stessero sui giorni brutti. **È il
contrario:**
| book | giorni | m==R | gap medio | gap \| decile PEGGIORE | gap \| decile MIGLIORE |
|---|---|---|---|---|---|
| A TP01/SKH01 (live) | 2691 | 26% | −0.38pp | **−0.48pp** | **−1.58pp** |
| B +XS01 (diversif.) | 937 | 20% | −0.36pp | −0.39pp | −1.30pp |
| TP01 solo | 2691 | 33% | −0.39pp | −0.59pp | −1.57pp |
| SKH01 solo | 2691 | 76% | −0.39pp | −0.40pp | −2.97pp |
| XS01 solo | 937 | 53% | −0.44pp | −0.22pp | −2.32pp |
L'escursione intraday è **~3× più profonda nei giorni che finiscono BENE** che in quelli che
finiscono male. Il meccanismo, una volta visto, è ovvio: un giorno brutto **scende tutto il
giorno e chiude sul minimo** (`m == R` nel 26% dei giorni: la chiusura *è* il peggio), mentre
un recupero a V ha un minimo profondo e una chiusura alta.
Il breach però si valuta **sul minimo**. Quindi ciò che conta è quanto gap si aggiunge **nei
giorni brutti** — e lì il gap vero è ~1/3 di quello dei giorni buoni. Un'estrazione indipendente
usa la stessa distribuzione ovunque, e così **carica i giorni brutti con la coda che nella realtà
appartiene ai giorni buoni**.
### 3.2 Quanto costa, misurato sui giorni storici (nessun bootstrap)
Frazione di giorni che sfondano la regola di daily-loss:
| book | leva | regola | close-only | **ACCOPPIATO** | indipendente | gonfiaggio |
|---|---|---|---|---|---|---|
| A (live) | 0.75 | daily 4% (HYRO) | 0.00% | 0.21% | 0.40% | **1.9×** |
| A (live) | 1.00 | daily 4% (HYRO) | 0.00% | 0.32% | 0.78% | **2.4×** |
| B (+XS01) | 0.75 | daily 4% (HYRO) | 0.00% | 0.11% | 0.25% | **2.4×** |
| B (+XS01) | 1.00 | daily 5% (FTMO) | 0.00% | 0.11% | 0.31% | **2.9×** |
Due letture:
- la lente indipendente **raddoppia** i breach da daily-loss (2.0-2.9×);
- **close-only non è "leggermente ottimista": è strutturalmente cieca.** Fa `0.00%` su ogni riga —
la regola di daily-loss **non scatta mai** sulle chiusure. Non è una lente approssimata, è una
lente che non vede affatto quel vincolo.
---
## 4. Tre verifiche — perché un "nessuna differenza" va provato, non assunto
### (1) Risoluzione: l'1h basta? — **sì, misurato**
TP01 tiene peso costante nel giorno, quindi il suo minimo intraday si può calcolare **anche a 5m**
ed è un confronto pulito:
| | p50 | p90 | p99 | peggiore |
|---|---|---|---|---|
| gamba TP01 @1h | −0.337pp | −1.358pp | −3.056pp | −5.34pp |
| gamba TP01 @5m | −0.336pp | −1.366pp | −3.136pp | −5.33pp |
Identici. **Il caveat "i wick a 1h sono un tetto, i 5m sarebbero più profondi" — portato avanti dal
24/07 — è quantificato e trascurabile.** L'ora cattura già il minimo del giorno: i 5m aggiungono
solo rumore dentro un'ora di minimo già individuata.
*Nota di metodo:* entrambe le righe riportavano `n=1865` e la cosa sembrava un errore (stessa
serie confrontata due volte). Non lo era: il filtro scarta i giorni in cui TP01 è **flat** (~30%),
che sono gli stessi a qualsiasi risoluzione. Verificato prima di accettare il risultato.
### (2) Riconciliazione col 24/07 — **la discrepanza dichiarata è risolta**
CLAUDE.md portava un ⚠ aperto: *«Discrepanza col 24/07 (P(vivo) A@0.75x 58% vs 10% mio)»*, con
l'ipotesi che fosse un effetto-finestra. **Non era la finestra, era la lente:**
| finestra | lente | P(pass) | P(vivo 1a) | E[payout/a] |
|---|---|---|---|---|
| 2019-03+ FULL | close | 53.8% | 79.7% | $2.085 |
| **2019-03+ FULL** | **accoppiato** | 48.1% | **63.2%** | $1.618 |
| 2024+ comune | close | 47.0% | 74.8% | $1.632 |
| 2024+ comune | accoppiato | 35.6% | 39.4% | $770 |
Sulla **stessa finestra piena** del 24/07 (recon MTM indipendente, che dava **58%**) la mia lente
accoppiata dà **63.2%** — accordo entro 5pp, con due implementazioni scritte separatamente. Il
**10%** del 25/07 era l'artefatto della lente indipendente. La finestra spiega il resto
(63.2% full → 39.4% sul 2024+, dove config A è debole).
### (3) Bound severo su XS01 — **non ribalta niente**
È XS01 a reggere il vantaggio della config diversificata, e il suo gap dipende da una convenzione
(ordinamento condiviso). Girato anche il bound opposto — ogni gamba al **proprio** peggio nello
stesso istante, fisicamente impossibile su 10 gambe co-moventi ma utile a delimitare l'errore:
| convenzione | gap p90 | peggiore | P(pass) | P(vivo 1a) | E[payout/a] |
|---|---|---|---|---|---|
| ordine condiviso (base) | −0.86pp | −4.81pp | 42.9% | **76.0%** | $1.144 |
| per-gamba (bound severo) | −1.83pp | −15.56pp | 32.3% | **57.6%** | $814 |
| *config A, per confronto* | — | — | 35.6% | **39.4%** | $770 |
Anche al bound severo **config B resta sopra config A** (57.6% vs 39.4%, $814 vs $770). La
conclusione non dipende dalla convenzione.
---
## 5. Cosa cambia nelle decisioni
### 5.1 La raccomandazione HyroTrader si sposta da 0.50x a **0.75x**
Config B (book diversificato, +XS01), lente accoppiata, finestra 2024+:
| leva | P(pass eval) | P(vivo 1a) | E[payout/a] | **E[payout] su 3 anni** |
|---|---|---|---|---|
| 0.50x | 28.6% | 99.5% | $412 | ~$1.230 |
| **0.75x** | 42.9% | 76.0% | $1.144 | **~$2.674** |
| 1.00x | 46.6% | 42.1% | $1.246 | ~$1.992 |
Stamattina la scelta era **0.50x**, perché la lente indipendente dava a 0.75x una sopravvivenza
del 55%. Con la lente onesta la sopravvivenza a 0.75x è **76%**, e 0.75x **massimizza il payout
atteso su 3 anni** — batte 0.50x di 2,2× e 1.00x di 1,3× (a 1.00x la sopravvivenza crolla e
l'effetto composto la punisce). L'argomento del 25/07 — *"la sopravvivenza compone su più anni"* —
resta valido; è il punto in cui morde che si sposta.
### 5.2 La scala di conti: il ranking regge, i livelli no
| lente | leva | MISTO EUR/g med | P(≥10/g) | P(≥50/g) | P(zero) |
|---|---|---|---|---|---|
| close-only | 1.00x | 11.11 | 50.8% | **22.0%** | 33.9% |
| **accoppiata** | **0.75x** | 0.00 | **29.7%** | 5.6% | **52.2%** |
| **accoppiata** | **1.00x** | 0.00 | 20.8% | **6.5%** | 65.5% |
| indipendente | 1.00x | 0.00 | 5.2% | 1.0% | 81.5% |
- **L'ordinamento fra politiche SOPRAVVIVE a tutte e tre le lenti**: MISTO ≥ CONC-DIV >
CONC-2SL ≈ SPARSO. L'affermazione di stamattina — *«il confronto fra POLITICHE è robusto:
è la stessa lente applicata a tutte»* — è confermata su una lente che allora non esisteva.
**CONC-2SL (= il book live attuale su ogni conto) resta la peggiore o penultima ovunque.**
- **I livelli si spostano parecchio.** La stima onesta di P(≥50/g) in 3 anni è **~5,6-6,5%**, non
1,6-2,5% e non 20,7%. La scala è **~3-4× più probabile** di quanto diceva il pavimento e
**~3,4× meno** di quanto diceva il tetto.
- **P(≥10/g) è massima a 0.75x (29,7%)**, non alla leva piena: l'ottimo di leva della scala
coincide con quello del conto singolo.
- Il prezzo resta alto: **P(bruciare i €600) = 52% a 0.75x, 65% a 1.00x.**
### 5.3 Il verdetto sul goal, ristretto
Il 25/07 concludeva: *«una via da €600 a €50/g ESISTE con P ~2-21% in 3 anni e P(bruciare i €600)
~33-78% → scommessa a coda destra, NON una rendita»*. Con la lente onesta la banda si stringe:
> **P(≥50 €/g entro 3 anni) ≈ 6%, con P(perdere i €600) ≈ 52-65%.**
> Resta una scommessa a coda destra. Ma è una scommessa con una probabilità **conoscibile**,
> non un intervallo di un ordine di grandezza.
---
## 6. Cosa NON cambia
- **Book, pesi, cron: invariati.** Niente qui tocca il portafoglio.
- Il fronte prop **non è aperto**: questo lavoro dice *cosa costerebbe e con quale probabilità*,
non che vada fatto.
- Resta il caveat di finestra del 25/07: il **2024+** è la finestra in cui XS01 è stato scoperto e
affinato → la **taglia** del vantaggio di config B è ottimista; il **meccanismo** (correlazione
bassa → meno DD → più sopravvivenza sotto vincolo di DD) è robusto. La verifica (2) qui sopra
quantifica per la prima volta quanto pesa la finestra da sola (63.2% → 39.4% su config A).
- XS01 resta **STAT-MODE sul capitale proprio** (serve ~$20k). Su un conto funded da $100k è
eseguibile: è esattamente l'asimmetria capitale-proprio vs funded del §4 di stamattina.
---
## 7. Lezione da portare avanti
> **Un modello di rischio intraday non si valida sulla distribuzione marginale del wick, ma sul suo
> ACCOPPIAMENTO al rendimento del giorno.** Qui la marginale era calibrata quasi perfettamente
> (p50 −0.17pp identico) e ciò nonostante il modello sbagliava di 2-3× sui breach, perché metteva
> i tuffi sui giorni sbagliati. Un test "i percentili del mio wick sintetico coincidono con quelli
> del recon" sarebbe **passato**, e la stima sarebbe rimasta sbagliata.
Corollario controintuitivo, da ricordare perché è il contrario dell'intuizione: **l'escursione
intraday è più profonda nei giorni che chiudono bene**. I giorni che chiudono male chiudono *sul*
minimo. Ogni regola valutata sul minimo (daily-loss, trailing DD, stop di conto) va misurata su
tuple accoppiate, mai su un wick estratto a parte.
Terzo: **close-only non è una lente conservativa, è una lente cieca** per le regole intraday —
0.00% di breach da daily-loss su ogni configurazione testata. Va usata come controllo, mai come
stima.
@@ -0,0 +1,408 @@
# 2026-07-25 — Rendita passiva: la curva capitale→book, il muro vero, e l'asimmetria del funded
**Contesto.** Goal: "altra sessione di ricerca per arrivare allo scopo (rendita passiva, 50 EUR/g),
i 600 euro si possono usare come si vuole". La roadmap del 24/07 aveva già chiuso i *canali*
(prop / vault / copy / legale). Questa ondata attacca i due punti che quella roadmap **assumeva**
invece di calcolare: (a) il tasso di crescita del book è preso come **CAGR fisso 15%**, (b) il
capitale-rendita è calcolato come **target/CAGR**, cioè ignorando il rischio di sequenza.
Entrambe le assunzioni sono risultate sbagliate, e nella stessa direzione: ottimista.
Script: `scripts/research/r0725_capcurve.py`, `scripts/research/r0725_prop_config.py`.
Test: `tests/test_capcurve.py` (10 casi). **Book live, pesi e config: INVARIATI.**
---
## 1) Difetto di eseguibilità su GTAA01 — il 5° sleeve del book attivo
`src/portfolio/gtaa.py` modella il costo come **2bps proporzionali** e lo sleeve è documentato
come *"eseguibile su IB a basso capitale (ETF frazionabili, switch mensile/basso turnover)"*.
Entrambe le cose sono false come codificate:
- il segnale è un vol-target **continuo**: l'esposizione cambia **ogni giorno** su **6 gambe**;
- IB non ha una fee proporzionale ma un **pavimento FISSO per ordine**:
`min(max($0.35, $0.0035/azione), 1% del controvalore)` → ~**$530/anno di commissioni
indipendenti dal capitale**.
| capitale allocato a GTAA | CAGR reale | Sharpe reale | drag commissioni |
|---|---|---|---|
| $600 | **−3.5%** | **−0.55** | 7.2%/anno |
| $2.000 | −0.7% | −0.09 | 4.4%/anno |
| $5.000 | +1.5% | 0.28 | 2.2%/anno |
| $50.000 | +3.4% | 0.59 | 0.2%/anno |
| *modello vecchio (2bps propor.)* | *+3.8%* | *0.64* | — |
⚠️ **Correzione a un errore MIO, trovata implementando il fix.** La prima stesura di questa
sezione citava il modello vecchio a *Sharpe 0.77 / CAGR 5.5%*: era un **artefatto di
annualizzazione** del mio script di analisi — metricavo la serie GTAA grezza (solo giorni di
borsa, ~252/anno) con `metrics()`, che annualizza a 365 e calcola `years = n/365.25` → Sharpe
gonfiato di √(365/252) = 1.20× e CAGR di ~1.45×. Le righe per-capitale erano già su calendario
365 (reindex + weekend a zero), quindi **il confronto era falsato solo sulla riga di riferimento**.
Valore corretto del modello vecchio: **0.64 / 3.8%**.
**La formulazione giusta del difetto cambia di conseguenza.** Non è "il modello sovrastimava lo
Sharpe di 0.13": alla taglia grande il modello vecchio era sostanzialmente **giusto** (0.64 contro
0.59-0.66 reali). Il difetto è che era **CIECO AL CAPITALE** — dava 0.64 sia a $50.000 sia a $600,
mentre a $600 la realtà è **−0.55**. Un modello di costo proporzionale non può descrivere un
pavimento fisso, e l'errore è tutto concentrato dove lo sleeve verrebbe realmente deployato.
**La banda lo salva.** Con costo fisso la banda ottimale non è il minimo eseguibile (come su
Deribit) ma un valore molto più alto. Plateau robusto = **cadenza settimanale × banda $25-100**
→ Sharpe 0.45-0.64 a *ogni* capitale; a $600 la config scelta sul plateau (banda $50, weekly)
dà **Sh 0.52 / CAGR 3.0%** invece di −0.55/−3.5%. (La cella argmax a $600 era banda $50 *daily*
a 0.57, ma è isolata — crolla a 0.28 a banda 100 → scartata: il parametro è di costo, si sceglie
sul plateau, non sull'argmax in-sample.)
**Conseguenza operativa: CABLATO** (stessa sessione, `src/portfolio/gtaa.py`). Il modulo ora
modella il costo IB reale (`ib_commission`), esegue a **banda + cadenza** (settimanale, $50/gamba),
prende il **capitale allocato** come parametro (`gtaa_returns(capital=...)`), dichiara la soglia
di deployabilità (`GTAA_MIN_CAPITAL = $3.000`, `gtaa_is_deployable`) ed espone
**`gtaa_rebalance_plan(held, capital)`** — il piano che l'esecutore deve usare per non ribilanciare
ogni giorno per pochi dollari. `sleeves.py` dichiara esplicitamente il capitale assunto
(`GTAA_DEFAULT_CAPITAL = $10.000` allocati ≈ book $50k al peso 20%) invece di nasconderlo.
**Impatto sul book, misurato prima/dopo** (non citato: ricalcolato sostituendo la sola gamba GTAA):
| | GTAA01 standalone | book 5 sleeve FULL | HOLD | maxDD |
|---|---|---|---|---|
| prima (2bps, continuo) | Sh 0.64 / CAGR 3.76% | 2.22 | 2.36 | 6.2% |
| dopo (IB reale + banda) | Sh 0.61 / CAGR 3.65% | 2.22 | **2.38** | **6.0%** |
Alla taglia assunta l'impatto sul book è **trascurabile** — il fix non è cosmetico per i numeri
storici, lo è per il **deploy**: è a $600-2.000 che cambia tutto (da −3.5%/anno a +3.0%/anno).
Pesi **invariati** (nessun cambio pesi → nessun `weights_tilt_null` richiesto).
**Regola nuova (generale): il costo di un venue va modellato nella sua FORMA — fisso vs
proporzionale — non solo nel suo livello.** Due venue con lo stesso "costo medio" danno
risultati **opposti** al variare del capitale: la fee proporzionale è neutrale alla taglia, il
pavimento fisso è una tassa regressiva che si mangia i piccoli. Ogni sleeve nuovo va incrociato
col modello di costo del suo venue *prima* di dichiararlo eseguibile.
**Controprova su Deribit (fee proporzionale, nessun pavimento):** lo Sharpe realistico di TP01
coincide col modellato da ~$500 in su (1.29 a $1k = 1.29 a $50k) → conferma indipendente della
lezione già a libro *"a $600 il min-order $5 è già la banda ottimale"*.
---
## 2) La rendita NON è `capitale × CAGR` — il muro del 24/07 era ottimista di 2-4×
Una rendita passiva si preleva **mentre** il book è in drawdown: è rischio di sequenza, e
`target/CAGR` non lo vede. Calcolato col bootstrap a blocchi (20g) dei ritorni **reali** del book
(TP01 75 / SKH01 25, SKH01 sul **path live** orario, non sul backtest):
| lente | Sharpe | CAGR | SWR 20a (95% sopravv.) | **rendita perpetua** | capitale per 50 EUR/g |
|---|---|---|---|---|---|
| modellato (backtest) | 1.75 | 20.5% | 13.10% | 13.57% | $219k |
| path live | 1.64 | 19.7% | 12.48% | 12.78% | $232k |
| **path live de-luck ×0.6** | **0.98** | **11.1%** | **7.31%** | **5.98%** | **$497k** |
*"Rendita perpetua"* = prelievo massimo con **P(capitale a 20 anni ≥ capitale iniziale) ≥ 90%**.
È il criterio giusto: "sopravvivere 20 anni" non è una rendita, è un piano di consumo del capitale.
**Il muro vero per 50 EUR/g perpetui è $300k-$500k**, non i €122k del diario 24/07. L'errore si
componeva di due fattori nella stessa direzione: (a) `capital×CAGR` ignora la sequenza (−45%
circa sul tasso), (b) CAGR 15% invece del de-luckato 11%.
⚠️ **Sul de-luck, onestà metodologica:** il ×0.6 sul drift è la convenzione ereditata dal 24/07,
ma qui è applicato **sopra** il path live orario, che *già* incorpora la degradazione di SKH01
(fill al livello → fill orario). C'è quindi un rischio concreto di **doppio conteggio** della
stessa penalità. Il muro va perciò letto come una **banda**, non come un punto:
**$232k (path live, nessun de-luck ulteriore) — $497k (path live + de-luck ×0.6)**, con la stima
centrale ragionevolmente attorno a **$300-400k**. Ciò che NON dipende dal de-luck è il risultato
strutturale: la rendita perpetua vale ~**45-55% del CAGR**, non il 100% — quindi qualunque muro
calcolato come `target/CAGR` è sbagliato per un fattore ~2, indipendentemente dalla lente.
Al capitale attuale: **$600 → ~€0.11/giorno** di rendimento atteso, ~€0.06/g come rendita perpetua.
*(Fisco incluso: 50 EUR/g netti = €18.250/anno netti = **$29.690/anno lordi** al 33%.)*
**Validazione della macchineria** (obbligatoria, 3 casi a risposta nota): asset deterministico
al 10%/anno → rendita perpetua fra 9% e 10% ✓; random walk a drift zero → rendita 0 ✓; book a
prelievo nullo → P(rovina)=0 e mediana 37.6× in 20 anni ≈ 1.197²⁰ ✓.
---
## 3) La diversificazione non crea reddito a pari nozionale — libera budget di rischio
Il test che conta, per tier di sblocco (tutti de-luck ×0.6, GTAA01 a costo IB reale con banda):
| tier | Sharpe | vol | rendita @iso-nozionale | capitale | @ISO-RISCHIO (vol 15%) | capitale |
|---|---|---|---|---|---|---|
| $600 — 2 sleeve | 0.98 | 11.4% | 5.98% | $497k | 1.32× → **7.51%** | $395k |
| $2k — + GTAA01 | 1.02 | 9.2% | 5.39% | $551k | 1.64× → 7.92% | $375k |
| $20k — + XS01 | 1.11 | 9.3% | 6.28% | $472k | 1.61× → **9.25%** | **$321k** |
| $20k — + XS01 + VRP01 (contro-fattuale) | 1.15 | 8.8% | 6.35% | $467k | 1.70× → 9.82% | $302k |
**A pari nozionale il muro NON si abbassa** (5.98% → 6.35%: nulla). Un diversificatore a basso
CAGR toglie vol e ritorno insieme. **A iso-rischio sì**: −19% di muro ($395k → $321k).
**Regola: un diversificatore a basso CAGR si giudica a ISO-RISCHIO, mai a iso-nozionale.** È il
"null de-levering" del progetto applicato al contrario — lì si smascherava un finto taglio di DD
comprato con la size, qui si smaschera un finto *mancato* guadagno per non aver rilevato la size.
*(L'ipotesi di partenza — "più capitale → più sleeve → CAGR super-lineare" — è quindi **refutata**
nella forma forte: la curva Sharpe del book eseguibile è **piatta** da $600 a $200k, perché TP01 su
Deribit non ha pavimento di costo e SKH01 nemmeno. Sopravvive solo nella forma debole, via iso-rischio.)*
---
## 4) Traiettoria onesta (bootstrap, de-luck, target $497k)
| deposito | p10 | mediana | p90 | P(entro 10a) | P(entro 20a) |
|---|---|---|---|---|---|
| €0/mese | — | — | — | 0% | **0%** |
| €250/mese | 18.9a | 22.4a | 24.6a | 0% | 8% |
| €500/mese | 15.6a | 19.6a | 23.4a | 0% | 48% |
| €1.000/mese | 11.6a | 14.8a | 18.7a | 2% | 95% |
| €2.000/mese | 8.1a | 10.1a | 12.8a | 48% | 100% |
Senza depositi, da $600, la rendita da 50 EUR/g **non arriva mai** (0% dei path in 20 anni).
Il moltiplicatore è il deposito, non il rendimento: è la stessa conclusione del 24/07, ma su un
target 4× più alto e quindi con tempi ~2× più lunghi.
---
## 5) L'ASIMMETRIA — il risultato strategico della sessione
Il 24/07 ha valutato il fronte prop **solo col book a 2 sleeve** (quello eseguibile a $600). Ma su
un conto funded il capitale non è $600, è **$100k** — e gli sleeve che a casa nostra sono STAT-MODE
*per taglia* (XS01 serve ~$20k) **diventano eseguibili**. Le regole prop, inoltre, passano sul
**drawdown**, non sul CAGR: premiano esattamente ciò che la diversificazione produce.
Finestra comune 2024+, de-luck ×0.6, crypto-only (niente GTAA01 che è equity su IB, niente VRP01):
| | P(pass) HYRO 1.0× | P(pass) FTMO 1.5× | **funded HYRO 1.0×: P(vivo 1a)** | funded FTMO 1.0×: P(vivo) | E[payout] FTMO | EUR/g atteso |
|---|---|---|---|---|---|---|
| A: TP01/SKH01 (live oggi) | 44.4% | 51.9% | **18.9%** | 58.8% | $8.655 | 14.58 |
| B: + XS01 (19 alt perp) | **54.7%** | **70.0%** | **57.6%** | **92.0%** | **$9.333** | **15.72** |
**Il salto è nella sopravvivenza: 18.9% → 57.6% (3×) sul conto funded HYRO a leva 1.0×.** E la
raccomandazione del 24/07 ("funded a 0.75×, mai 1.0×") si **ribalta** col book diversificato: su
FTMO a 1.0× la sopravvivenza è 92%.
**L'asimmetria in una riga:** sul **capitale proprio** diversificare non aumenta il reddito (il
reddito è `C × tasso`, e il tasso sale poco); su un **conto funded** lo aumenta molto, perché lì
il vincolo binding non è il capitale ma la **regola di drawdown**. → **Gli sleeve "inutili a $600
perché STAT-MODE" sono esattamente gli asset di maggior valore sull'unico canale che scala in mesi.**
Questo inverte la priorità implicita di dieci ondate di ricerca.
**Caveat forte, dichiarato.** (1) Il MC è **close-only**: C-bis del 24/07 ha dimostrato che i wick
intraday tagliano 6-37pp → **i livelli assoluti qui sono un TETTO**. Il ricostruttore MTM intraday
esiste solo per TP01+SKH01 (feed 5m); XS01 è 1d nativo su Hyperliquid e il suo intraday non è
ricostruibile dai nostri dati → non l'ho inventato. Il **delta** fra config è la misura onesta ed
è **conservativo** (B ha vol minore → wick minori → haircut minore). (2) La finestra comune 2024+
è **quella in cui XS01 è stato scoperto e affinato** → la *taglia* del guadagno è ottimista; sulla
finestra piena il delta si riduce (P(pass) 56.9%→58.5%, P(vivo) 14.9%→21.8%) ma quella è
sfavorevole a B per costruzione (pre-2024 B degenera in A). Il **meccanismo** (corr bassa → meno
DD → più sopravvivenza sotto vincolo di DD) è robusto; la sua taglia no.
---
## 6) LA VIA — i 600 euro come BIGLIETTO, non come capitale (`r0725_prop_ladder.py`)
Se i €600 come *capitale* sono refutati (§2, §4), restano i €600 come **biglietto**: si compra
un'evaluation, il conto funded moltiplica il **nozionale** senza possedere capitale, i payout
comprano altri biglietti. È l'unica leva che non richiede depositi. Il 24/07 si era fermato a
**un** conto ($100k → ~€14.5/g, cap $200k/firm). Ma €50/g richiede **più conti in parallelo** —
e qui c'è il problema che nessuno aveva studiato:
> **N conti che girano lo stesso book bustano INSIEME.** La diversificazione fra conti è
> illusoria salvo assegnare **sleeve diversi a conti diversi**.
È un problema di costruzione di portafoglio sotto **barriera di rovina per-conto**, e non è ovvio
quale verso vinca: concentrare alza lo Sharpe *per conto* (sopravvivenza individuale) ma rende le
morti perfettamente correlate; sparpagliare decorrela le morti ma ogni conto ha Sharpe più basso
e quindi buca più spesso la propria barriera.
Simulazione: 36 mesi, cassa iniziale €600, max 6 conti, 2 firm (cap $200k/$400k), regole vere,
payout mensile 80% prelevato subito, fisco 33%, **rischio-morte firm 10%/anno**, bootstrap a
blocchi **congiunto** dei 3 sleeve (la correlazione fra conti è quella *reale*: TP01–SKH01 +0.10,
TP01–XS01 −0.12, SKH01–XS01 −0.00).
| politica (leva 1.0×) | EUR/g mediano | p90 | P(≥10/g) | **P(≥50/g)** | P(zero) |
|---|---|---|---|---|---|
| CONC-2SL — ogni conto = book live attuale | 0.00 | 63.2 | 26.1% | 13.1% | 55.6% |
| CONC-DIV — ogni conto = book diversificato | 5.70 | 70.6 | 44.9% | 17.8% | 33.4% |
| SPARSO — 1 sleeve per conto | 0.00 | 76.3 | 26.2% | 16.8% | **66.0%** |
| **MISTO — metà diversificati, metà single** | **10.70** | 75.1 | **50.6%** | **20.7%** | 33.4% |
*(lente close-only)*
**Risultato non ovvio: vince il MISTO, non gli estremi.** Ogni conto ha bisogno di abbastanza
Sharpe per sopravvivere alla *propria* barriera (questo uccide SPARSO: P(zero) 66%), ma i conti
hanno anche bisogno di essere decorrelati fra loro (questo penalizza CONC). E il **book live
attuale a 2 sleeve è la politica peggiore** di tutte.
**La lente onesta però è più dura.** Le regole prop scattano sull'equity *intraday*. Con i wick
(lognormale calibrato sui percentili del recon MTM 1h del 24/07: p50 −0.17pp, p90 −0.90pp,
p99 −3.50pp, scalati sulla vol di ogni config):
| politica (leva 1.0×, INTRADAY) | EUR/g mediano | p90 | P(≥10/g) | **P(≥50/g)** | P(zero) |
|---|---|---|---|---|---|
| CONC-2SL | 0.00 | 2.18 | 4.8% | 1.7% | 85.1% |
| CONC-DIV | 0.00 | 7.34 | 9.0% | **2.5%** | 78.1% |
| SPARSO | 0.00 | 0.02 | 1.3% | 0.3% | 89.9% |
| MISTO | 0.00 | 4.89 | 6.6% | 1.6% | 78.1% |
⚠️ **Il mio modello di wick è un PAVIMENTO, non una stima puntuale**: il gap è estratto
**indipendente dal rendimento del giorno**, mentre i wick veri sono *accoppiati* alle giornate
brutte → estrarli indipendenti aggiunge finti tuffi anche nelle giornate buone, cioè breach spuri.
Il modo corretto è il bootstrap delle **tuple (ritorno, gap)** come in `r0724_goal50_intraday_mc.py`,
che però ha il recon solo per TP01+SKH01 (XS01 è 1d nativo su Hyperliquid, intraday non
ricostruibile dai nostri dati) → **follow-up dichiarato, non simulato**.
**Verdetto in banda (ed è la risposta al goal):**
> Una via da €600 a €50/giorno **esiste** ed è la scala di conti funded. In 3 anni ha una
> probabilità **fra il 2% e il 21%** di arrivarci, e una probabilità **fra il 33% e il 78%** di
> bruciare interamente i €600. Il valore atteso è positivo rispetto ai €600 tenuti come capitale
> (~€0.11/g ⇒ ~€120 in 3 anni), ma è una **scommessa a coda destra, non una rendita**.
Il confronto fra *politiche* è invece robusto (stessa lente per tutte) e ha un'implicazione
diretta: **se si apre il fronte prop, non mandarci il book live attuale** — è l'ultima delle
quattro politiche in entrambe le lenti.
---
## 7) ADDENDUM — "e se metto 10K su IB?" (`r0725_ib10k.py`)
Domanda dell'operatore a valle dell'ondata. Non è una domanda su GTAA01: è **allocazione fra due
venue** con profili opposti — Deribit (TP01+SKH01) è il **motore** (CAGR ~11% de-luck, vol 11.3%),
IB (GTAA01) è un **diversificatore** (CAGR ~3.9%, vol ~5%, corr ~+0.10). Tre effetti da contare
insieme: (a) il deposito **sblocca** GTAA01 (il pavimento di commissione passa dall'1-3% per ordine
a ~0.02% → §1 risolto); (b) sposta il baricentro su un venue a CAGR basso; (c) cambia l'**aliquota**
(ETF 26% vs crypto 33%, assunzione dichiarata).
Capitale totale $11.500 ($600 Deribit + €10k), de-luck ×0.6, SKH01 path live:
| quota su IB | Sharpe | CAGR | maxDD | €/g atteso | rendita perpetua |
|---|---|---|---|---|---|
| 0% (tutto Deribit) | 0.99 | 11.2% | 15.3% | **2.16** | €1.16/g |
| 25% | 1.06 | 9.3% | 12.0% | 1.85 | €1.08/g |
| 50% | **1.13** | 7.5% | 11.2% | 1.54 | €0.98/g |
| 94% (= i 10k su IB) | 0.84 | 4.4% | 10.5% | **0.93** | €0.61/g |
**Mettere i 10k su IB più che dimezza il reddito** (€0.93 vs €2.16/g): è la §3 di questo stesso
diario vista dal lato pratico — un diversificatore a basso CAGR diluisce l'income a pari nozionale.
**E la via d'uscita (levare) è chiusa dai costi.** Lo Sharpe migliore (1.13 a 50/50) si converte in
reddito solo con leva; ma su ETF a IB con €10k c'è la **Reg-T (2× max**, il portfolio margin parte
da ~$110k) e il margine costa **~5.5%/anno**. Contando il finanziamento:
| quota IB | leva attuabile | CAGR lordo | costo leva | CAGR netto | rendita |
|---|---|---|---|---|---|
| **0%** | 1.33× | 14.8% | 0.7% | **14.1%** | **€1.33/g** |
| 25% | 1.71× | 15.9% | 2.0% | 13.9% | €1.25/g |
| 50% | 2.27× | 17.1% | 4.8% | 12.4% | €0.92/g |
| 94% | 2.06× | 9.0% | 5.6% | 3.4% | €0.00/g |
→ **con leva attuabile E costo del margine, vince tutto-Deribit a 1.33×.** Il diversificatore
permetterebbe di levare di più, ma il finanziamento costa più di quanto aggiunge.
**Regola: l'argomento iso-rischio (§3) vale solo se la leva è (a) disponibile e (b) a costo
inferiore all'uplift — su un conto retail da €10k su ETF non lo è.**
**Il confronto che ridimensiona GTAA01:** €10k in GTAA01 = **€0.93/g con maxDD 10.5%**; gli stessi
€10k **fermi** a interesse ~2% = **€0.54/g con maxDD ~0%**. Il premio dello sleeve sopra la
liquidità è **~€0.50/g pagato con un drawdown del 10%** — in isolamento un cattivo affare (e un
monetario/BTP EUR renderebbe più del 2% assunto).
**Raccomandazione:** se arrivano €10k, il posto produttivo è **Deribit**. Chi vuole meno drawdown
può tenere **25% su IB**: costa ~€0.08/g di rendita e taglia il maxDD dal 15.3% al 12.0% — è
l'unico split che regge anche coi costi di finanziamento. Il 94% su IB no.
⚠️ **Caveat che rende il confronto meno netto di come appare:** il CAGR crypto (11%) viene da ~7
anni che contengono **due bull market**; il 3.9% di GTAA01 da ~30 anni con dentro più orsi. Il
confronto **favorisce il crypto per costruzione** — il numero crypto ha più probabilità di deludere.
Tassi (margine 5.5%, liquidità 2%) e aliquote (26%/33%) sono assunzioni dichiarate; le aliquote
vanno confermate col commercialista (**non è un parere fiscale**).
---
## 8) HYROTRADER nello specifico (`r0725_hyro.py`)
La firm che il 24/07 aveva messo prima in classifica per *questo* book: unica con **API reale** da
funded (sub-account Bybit) → il book gira automatico; **nessun limite di tempo** sull'eval (una
strategia lenta non è penalizzata); **weekend consentito** — non banale, l'ondata 2026-07-17 ha
misurato che il weekend porta il **38% del gross di TP01**. Biglietti $25k/$249, $50k/$379,
$100k/$579, cap $200k, split 80%, fee rimborsata al pass.
Due regole mordono proprio noi, e nessuna analisi le aveva modellate: **maxDD 6% STATICO** e
**consistency 40%** (nessun giorno > 40% del profitto totale, in eval).
**Ipotesi refutata: la consistency NON morde.** Avevo previsto una tagliola (SKH01 ha P&L a
scalino, TP01 fa strappi di trend). Misurato: **costo ≈ 0pp** a ogni leva e in entrambe le lenti.
Ragione strutturale: il book accumula il 10% in **130-300 giorni**, quindi nessun singolo giorno
si avvicina al 40% del cumulato. ⚠️ Prima di dichiararlo ho dovuto **provare che il controllo
funziona** (un "costo 0" può essere un bug): `test_consistency_MORDE_su_un_book_grumoso` mostra
che su un book con profitto concentrato in 1-2 giorni la regola porta P(pass) da >90% a <5%. Il
meccanismo c'è; è il book a non essere grumoso abbastanza. *(Il primo probe era sbagliato — strappi
ripetuti si diluiscono a vicenda, e sim_eval fa block-bootstrap, non replay: due iterazioni di test
prima di avere un discriminante valido.)*
**Il vincolo vero è il DD 6% statico.** Finestra comune 2024+, de-luck ×0.6:
| | Sharpe | CAGR | vol | maxDD |
|---|---|---|---|---|
| A — book live (TP01/SKH01) | 0.74 | 7.2% | 10.1% | 9.5% |
| B — + XS01 | **1.13** | 10.0% | 8.8% | **6.2%** |
Config A ha maxDD 9.5% contro un limite di 6%: **strutturalmente incompatibile a leva piena**.
**Funded $100k, P(vivo 1 anno) / €-giorno:**
| config | leva | close-only (tetto) | intraday (pavimento) |
|---|---|---|---|
| A | 0.50× | 80.2% / €8.33 | 44.0% / €6.86 |
| A | 0.75× | 51.1% / €12.21 | **10.1%** / — |
| A | 1.00× | 27.1% / €13.89 | **1.4%** / — |
| B | 0.50× | 98.5% / €8.69 | **71.0%** / €7.69 |
| B | 0.75× | 85.4% / €12.78 | 31.6% / €8.66 |
| B | 1.00× | 66.0% / €16.20 | 9.9% / — |
**EV del biglietto** (config B, eval 1.0×, funded a leva ottima, 1 anno): close-only P(pass) 73.0%
→ EV **+$6.789** sul biglietto $100k; intraday P(pass) 31.1% → EV **+$1.166**. **Positivo in
entrambe le lenti** — ma con ~69% di probabilità di perdere la fee nella lente pessimista.
**Raccomandazione operativa:**
1. **Config B (con XS01), non il book live attuale.** A 1.0× intraday config A sopravvive l'1.4%:
mandarci il book a 2 sleeve a leva piena è morte quasi certa.
2. **Funded a 0.50×** (non 0.75× come indicava il 24/07 per la config A): E[payout] scende poco
(€7.69 vs €8.66/g) ma la sopravvivenza raddoppia (71% vs 32%) — e su orizzonti pluriennali la
sopravvivenza **compone**, un conto bustato smette di produrre per sempre.
3. Eval a 0.75-1.0×; biglietto $25-50k come test economico — l'EV scala **linearmente** con la
taglia, quindi la ragione per partire piccoli è varianza e apprendimento, non EV.
4. **Cap $200k/trader ⇒ ~€15-30/g anche negli scenari buoni.** Per €50/g servono più firm → §6.
⚠️ **Discrepanza dichiarata col 24/07:** lì il funded di config A a 0.75× dava P(vivo) 58%, qui
10%. Due cause note: (a) il mio wick è a estrazione indipendente (più severo — §6); (b) finestra
2024+, dove config A è debole (Sharpe 0.74 vs 0.99 sulla finestra piena). **La direzione concorda
(meno leva è meglio), il livello no** — e il numero del 24/07 usa il recon MTM vero, quindi sul
livello è più affidabile del mio.
---
## Bug catturato in sessione
**Modello funded, base di prelievo aggiornata ogni giorno come un HWM mobile** → al checkpoint
mensile `eq > hwm` è quasi sempre falso → guadagno misurato ≈ 0 → **payout $230/anno invece di
~$7.000**. Le regole vere sono a max-loss **statico dal saldo iniziale**, con la base ripristinata
dopo ogni prelievo. Corretto e bloccato da `test_funded_payout_non_e_zero_regressione_hwm`.
Famiglia nota: numero plausibile, meccanismo sbagliato — si prende solo con una sanity a risposta nota.
---
## Decisioni e non-decisioni
**Cablato:** nulla sul path live. Book, pesi, config, cron: **invariati**.
**Raccomandazioni all'operatore (non automatizzabili):**
1. **Se si apre il fronte prop** (l'unico canale che scala in mesi): mandarci il book
**diversificato** TP01+SKH01+XS01, non il book a 2 sleeve. È la differenza fra P(vivo) 19% e
58% a leva 1.0×. Richiede una venue con i 19 alt perp (Bybit sub-account HyroTrader li ha).
E se si arriva a più conti, **politica MISTA** (§6): metà conti col book diversificato, metà
con singoli sleeve decorrelati. Budget mentale onesto: **P(perdere tutto) 33-78%**.
2. **GTAA01 su IB**: non andare live senza banda+cadenza (weekly, banda ~$50/gamba). È un cambio
al modello dello sleeve → passa dai gate, non lo cablo in questa sessione.
3. **Aspettativa onesta ricalibrata**: rendita perpetua da 50 EUR/g = **$300k-$500k** di capitale
(non €122k). A $600 il book rende ~**€0.11/giorno**.
**Cosa NON fare (confermato):** niente cambio pesi senza `weights_tilt_null`; niente leva "per
accelerare" sul capitale proprio (il muro si sposta del 20%, non dell'ordine di grandezza).
+112
View File
@@ -0,0 +1,112 @@
# 2026-07-26 — "come faccio a capire se l'edge è morto?"
Domanda dell'operatore dopo la misura del decadimento. 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 vedrà" — cioè esattamente ciò che
il progetto non accetta dai candidati.
**Script:** `r0726_edge_death.py` (taratura) + `scripts/live/edge_watch.py` (sorveglianza, cablata
in `cron_daily.sh`). **Test:** `tests/test_edge_watch.py` (11). **Book/pesi/config INVARIATI.**
---
## 1. La risposta scomoda: non puoi saperlo in fretta
Con Sharpe ~1.6 e vol ~8%, un anno di risultati non distingue nulla. Distribuzione dello Sharpe
rolling su 4.000 percorsi bootstrap, con edge **vivo** e con edge **morto** (drift a zero, stessa vol):
```
finestra VIVO (p5..p50..p95) MORTO (p5..p50..p95) sovrapposizione
6m -1.06 1.60 4.15 -3.24 -0.10 2.71 67.8%
12m -0.24 1.62 3.43 -2.20 -0.04 1.99 56.0%
24m 0.34 1.64 2.92 -1.51 -0.02 1.44 34.6%
36m 0.57 1.62 2.68 -1.22 -0.03 1.19 21.1%
```
**A 12 mesi il 56% dei casi "morto" è indistinguibile da uno vivo.** Un anno brutto non è
informazione, è rumore.
## 2. La taratura: falsi kill contro velocità
*"Sharpe rolling a N mesi scende sotto S almeno una volta in 10 anni"*, con edge **intatto** —
cioè quanto spesso la regola ucciderebbe una strategia che funziona:
```
finestra S<-0.5 S<0.0 S<+0.5
6m 100.0% 100.0% 100.0%
12m 80.5% 95.9% 99.5%
24m 14.1% 43.7% 78.8%
36m 1.8% 12.3% 43.2%
```
Con il controllo positivo (edge davvero morto) accanto:
| finestra | soglia | falso kill | lo prende | rilevamento mediano |
|---|---|---|---|---|
| 12m | −0.5 | 80.5% | 100% | 1.1 anni |
| 24m | −0.5 | 14.1% | 98.5% | 2.5 anni |
| **36m** | **−0.5** | **1.8%** | **90.8%** | **3.8 anni** |
**→ CRITERIO A: Sharpe rolling 36 mesi sotto −0.5.** Falso kill 1.8% in 10 anni, riconosce l'edge
morto nel 91% dei casi, in **3.8 anni** mediani.
⚠️ **La lentezza non è un difetto della regola: è statistica.** Una versione a 12 mesi ucciderebbe
un edge vivo nell'80% dei casi. **Non esiste una versione veloce e onesta.**
## 3. TP01 non si giudica così — e questo è il punto
Il leave-one-out del 26/07 ha misurato il contributo hold-out di TP01 **negativo nel 99.1% delle
configurazioni d'ancora**. È la firma dell'assicurazione: paga premio negli anni senza incendio.
**"Non ha guadagnato" non è evidenza di morte per uno sleeve difensivo** — la sua morte è *non
proteggere quando serve*.
```
anno DD buy&hold DD TP01 protezione
2019 56.4% 10.3% 5.5x
2020 59.2% 8.4% 7.0x
2021 52.0% 6.8% 7.6x
2022 68.4% 2.8% 24.2x
2023 22.0% 12.3% 1.8x <- il peggiore, e passa comunque
2024 35.6% 7.1% 5.0x
2025 45.1% 6.8% 6.6x
2026 46.6% 1.4% 34.4x
```
**→ CRITERIO B: in un anno con DD buy&hold > 10%, il DD di TP01 deve restare sotto il 75% di
quello.** Storico: **8 anni di sinistro, 8/8 superati**. Negli anni **senza** sinistro il criterio
non si valuta: non c'è informazione.
Questo criterio è **veloce** dove l'altro è lento — si pronuncia a ogni anno con un crash, che nel
campione è ogni anno.
## 4. Cosa succede se scattano
Dichiarato ora per non doverlo decidere nel momento sbagliato:
* **(A) scatta** → il book **non si spegne da solo**. Si apre una revisione: `weights_tilt_null` +
deflated-Sharpe ricalcolato sui dati nuovi. Spegnere è una decisione dell'operatore.
* **(B) fallito in due anni di sinistro consecutivi** → TP01 non assicura più, e il suo peso (75%)
va rimesso in discussione: proteggere è **l'unico motivo** per cui sta lì.
Cablato in `cron_daily.sh`, allerta Telegram, non tocca l'esecuzione. Stato al 2026-07-26:
**Sharpe 36m +1.51**, protezione **8/8**.
## 5. Il limite, di nuovo
Il criterio A misura se l'edge è morto **dopo** che è morto, con ~4 anni di ritardo. Questo non è
riparabile con una regola migliore — è il contenuto informativo dei dati. La difesa vera non è la
rilevazione: è che **il piano regge a un edge dimezzato** (misurato: traguardo da 11.6 a 15.8 anni,
P(entro 20a) ancora 77%) e che i rischi *veloci* — venue, esecuzione, feed — hanno sorveglianze
proprie che scattano in ore.
## 6. Regole trasferibili
1. **Se si pretende un gate di kill dai candidati, se ne deve avere uno per ciò che gira.**
L'asimmetria era invisibile finché non è stata nominata.
2. **Un criterio di kill si tara sul nullo e si valida su un controllo positivo** — identico al
tripwire di venue costruito lo stesso giorno. "Non è mai scattato" non è una buona notizia
finché non si è provato che sa scattare.
3. **Uno sleeve difensivo richiede un criterio DIVERSO**, o lo si uccide per aver fatto il suo
mestiere. Il criterio giusto guarda il sinistro, e negli anni senza sinistro **non si valuta**.
4. **Quando la rilevazione è strutturalmente lenta, dirlo e spostare la difesa altrove** invece di
accorciare la finestra fino a ottenere una risposta veloce e falsa.
+123
View File
@@ -0,0 +1,123 @@
# 2026-07-26 — Nuovo schema fee Deribit (dal 1 agosto 2026): la curva, non il numero
**Input:** annuncio Deribit di un nuovo schema fee **effettivo 2026-08-01** — taker piu' bassi e
maker rebate piu' bassi su futures/perpetual, soglie VIP abbassate, nuovo tier VIP7,
**liquidation fee 1% su tutti i prodotti** (opzioni: cap premio 25%), fee spot temporaneamente
azzerate fino al collegamento coi mercati spot Coinbase.
**Script:** `r0726_fee_sensitivity.py`. **Test:** `tests/test_fee_sensitivity.py` (6).
**Book, pesi, cron, config: INVARIATI.**
---
## 0. Perche' non ho aspettato la tabella
La fee e' un **vincolo di prim'ordine** dichiarato di questo progetto ("0.10% RT baseline; molte
operazioni = morte per fee"). Ma l'annuncio non contiene un solo numero, e **la tabella numerica
nell'articolo Insights e' un'IMMAGINE**: non l'ho letta da fonte primaria.
⚠️ I valori che cito del nuovo schema vengono da un **riassunto testuale secondario**, non dalla
tabella di Deribit: tier base ~**5 bps taker / 2 bps maker**, VIP7 **2/0 bps**. Vanno trattati come
indicativi finche' non si legge il tier reale in Account Settings.
Quindi invece di assumere un numero ho misurato la **curva**: quando la tabella e' leggibile si
prende il valore giusto da qui, senza rifare l'analisi.
Il progetto modella ovunque **5 bps/lato = 0.10% RT (taker)**: `trend_portfolio.CANONICAL
.fee_side = 0.0005`, `sleeves._skyhook_returns fee_rt=0.001`, paper monitor `FEE_SIDE = 0.0005`.
Le repliche parametrizzate riproducono **bit-exact** gli sleeve di produzione alla fee canonica
(`max|dif| = 0.0`, test permanenti) — altrimenti la curva descriverebbe un'altra strategia.
---
## 1. La curva
```
bps/lato %RT | TP01 Sh CAGR | SKH01 Sh CAGR | BOOK Sh CAGR maxDD
0.0 0.00% | 1.322 16.60% | 1.567 35.66% | 1.849 21.69% 8.92%
1.0 0.02% | 1.316 16.51% | 1.543 34.95% | 1.833 21.46% 9.02%
2.0 0.04% | 1.309 16.42% | 1.519 34.24% | 1.816 21.22% 9.12%
3.0 0.06% | 1.303 16.33% | 1.495 33.53% | 1.799 20.99% 9.22%
5.0 0.10% | 1.290 16.15% | 1.446 32.14% | 1.766 20.53% 9.42% <- oggi
7.5 0.15% | 1.274 15.92% | 1.385 30.41% | 1.724 19.96% 9.67%
10.0 0.20% | 1.258 15.69% | 1.324 28.70% | 1.682 19.39% 9.92%
15.0 0.30% | 1.226 15.24% | 1.200 25.36% | 1.597 18.26% 10.59%
drag della fee attuale vs fee zero: TP01 -0.032 Sh / -0.46% CAGR
SKH01 -0.121 Sh / -3.52% CAGR
BOOK -0.084 Sh / -1.15% CAGR
sensibilita' marginale: BOOK -0.017 Sharpe/bps -0.23% CAGR/bps
```
**Il book e' poco sensibile.** Anche un raddoppio del taker a 10 bps costerebbe 0.08 di Sharpe —
**meno della banda d'ancora misurata oggi stesso** (book FULL canonico 2.222 vs mediana 1.946).
Mettere la fee nella giusta scala di grandezza: e' un effetto piu' piccolo dell'ancora.
### I due sleeve NON sono uguali
**SKH01 e' ~4x piu' sensibile di TP01** (−0.69% vs −0.09% di CAGR per bps/lato). Il motivo e'
strutturale: SKH01 fa round-trip **discreti** (~500 trade sui 7 anni per asset), TP01 e' una
posizione **continua vol-targeted** che ribilancia poco. Conseguenza operativa: **se il taker
salisse in modo serio, il primo parametro da rivedere e' il peso 75/25, non il resto**; se scende,
SKH01 e' quello che guadagna di piu'.
---
## 2. I quattro punti dell'annuncio, uno per uno
| punto | ci tocca? |
|---|---|
| **Taker piu' basso** | bene o neutro: a 3 bps il book va 1.766 → 1.799 di Sharpe. Nessuna decisione cambia. |
| **Maker rebate piu' basso** | **non oggi**: il book manda ordini **market** (taker). |
| **Liquidation fee 1%** | **irrilevante** — vedi sotto. |
| **Soglie VIP piu' basse + VIP7** | **irrilevante a $600**: volume 30g trascurabile, restiamo al tier base a qualunque soglia. |
### Il maker tocca una raccomandazione non implementata
L'idea **T1 del 26/07** — TP di SKH01 come **limit resting** per incassare il maker — perderebbe
parte della sua convenienza se il maker passa da rebate a **+2 bps**. Ma: (a) **non e'
implementata** (lo blocca il fatto che TP01 e SKH01 tradano lo stesso strumento con una sola
posizione netta), e (b) il beneficio misurato era quasi tutto *"convertire una lotteria in
certezza"*, non la fee. Quindi il cambio maker **non riapre** quella decisione, la rende solo
meno appetibile se un giorno si riaprisse.
### Liquidation fee 1%: perche' e' irrilevante
`live.json` impone `max_notional_per_asset_frac = 0.5` su **2 asset** → nozionale lordo massimo
**1.00x l'equity**, con `disaster_sl_pct = 0.30`. A leva ≤1x la liquidazione richiederebbe un
movimento avverso ~100%, e il disaster-SL interviene a −30%.
⚠️ Questa conclusione **poggia sul cap**, non sulla strategia. Se il cap sale, decade. Per non
lasciarla valida per inerzia c'e' una **guardia di decisione** cablata
(`test_leva_massima_da_config_resta_sotto_o_uguale_a_1x`): alzare il cap **rompe il test** e
rimanda qui.
---
## 3. Azione
**Nessuna adesso.** Il 1 agosto: leggere il tier reale in Account Settings e confrontarlo con la
curva. Regola decisa in anticipo, per non decidere col numero davanti:
* taker **≤5 bps/lato** → non si tocca nulla (il modello e' gia' giusto o conservativo);
* taker **>10 bps/lato** → rivedere per primo il peso di SKH01 (e' li' che morde 4x).
**Cio' che il cambio NON puo' rompere:** tutti i backtest del progetto sono a 0.10% RT, quindi se
la fee scende diventano **conservativi** — la direzione dell'errore e' quella giusta.
---
## 4. Regole trasferibili
1. **Quando arriva un annuncio senza numeri, misurare la CURVA invece di aspettare il numero.**
Il risultato vale per qualunque valore esca, e sposta la decisione da "aspettiamo" a "sappiamo
gia' cosa fare in ogni caso".
2. **Dichiarare la qualita' della fonte.** Qui la tabella e' un'immagine non letta: i numeri del
nuovo schema sono **secondari** e vanno etichettati come tali, non usati come se fossero il
listino.
3. **Una conclusione che poggia su un parametro di config va legata a un test su quel parametro.**
"Liquidation fee irrilevante" e' vera *perche'* la leva e' ≤1x; senza guardia sopravviverebbe
al cambio di cap che la rende falsa.
4. **Mettere ogni effetto nella sua scala di grandezza.** Un raddoppio della fee vale meno della
fortuna d'ancora dello stesso book: senza il confronto si rischia di dedicare a una fee un
allarme che merita altro.
+613
View File
@@ -0,0 +1,613 @@
# 2026-07-26 — GTAA01 sugli UCITS: la via d'uscita dal blocco PRIIPs è aperta, e il broker non è la variabile
**Domanda dell'operatore:** *"usiamo revolut o degiro"* — dopo che il conto reale ha rifiutato
l'ordine sui 6 ETF USA di GTAA01 con `Trading limitato — Questo prodotto non dispone di un KID`.
**Risposta breve:** cambiare broker non sblocca niente (il PRIIPs è una norma, non una politica di
IB). Ciò che sblocca è cambiare **veicolo**. Misurato: il cambio di veicolo costa **~0**, e con la
scelta giusta delle linee lo sleeve è eseguibile **senza frazionamento** già a $3.000.
**Book, pesi, cron, config: INVARIATI.** GTAA01 non entra nel book live (resta la decisione venue
del 26/07: 100% Deribit fino a $20k).
Script: `scripts/research/fetch_ib_ucits.py`, `scripts/research/r0726_gtaa_ucits.py`.
Modulo nuovo: `src/data/eq_crosscheck.py`. Test: `tests/test_eq_crosscheck.py` (14),
`tests/test_gtaa_ucits.py` (10).
---
## 0. La premessa che era falsa, ed è la ragione per cui il problema è piccolo
La nota che avevo scritto in `src/portfolio/gtaa.py` diceva:
> storia più CORTA (diversi nati dopo il 2010) → si perde la validazione a 30 anni che è ciò che
> rendeva credibile questo sleeve
**È falsa, per un motivo strutturale: il PRIIPs vieta di COMPRARE, non di GUARDARE.** I prezzi di
SPY/QQQ/IWM/TLT/GLD/HYG restano leggibili — l'operatore li aveva sotto gli occhi sul terminale
*mentre* l'ordine veniva rifiutato. Quindi il **segnale** di GTAA01 può continuare a girare sui 30
anni di serie USA per sempre; cambia solo il **veicolo** su cui si incassa il rendimento.
La storia corta degli UCITS non serve a validare la strategia. Serve a misurare una cosa sola: la
**deviazione del veicolo**, che è un drift lento e si stima bene anche su pochi anni.
> **Regola:** prima di dichiarare che un vincolo esterno distrugge un risultato, chiedersi
> *esattamente cosa* vincola. Qui la differenza fra "non posso comprare" e "non posso vedere"
> separa uno sleeve morto da uno sleeve con un problema di esecuzione.
---
## 1. Il dato, prima della strategia — e il feed equity non aveva un cross-check
Estratti 12 veicoli UCITS da IB (`LSEETF`, **tutti in USD**: quotare in USD elimina un livello di
costo, la conversione per ordine). Alla prima certificazione, **7 su 10 con gap lunghi** e CSPX con
un **+27.8% giornaliero** su un tracker S&P 500.
I gap sono tutti **al lancio** della linea USD (ultimo gap lungo: CSPX 2014-04, XRSU 2016-10,
IGLN/IHYU 2011); negli ultimi 3 anni tutti i veicoli fanno 253 barre/anno. Non è un problema
corrente.
Il +27.8% invece è un difetto vero. La barra CSPX 2012-01-13:
```
open 112.740 high 112.740 low 88.010 close 88.010
```
**`open`/`high` in USD, `low`/`close` in EUR** — fattore dai close adiacenti **1.2797**, cioè
l'EURUSD di quel giorno (reale 1.266-1.282). Andata e ritorno: 112.63 → 88.01 → 112.47 mentre SPY
faceva −0.39% e +0.23%.
**La certificazione esistente non lo vedeva.** L'unica guardia sui movimenti era
`maxret > 50% → SPIKE?`, e una contaminazione EUR/USD vale ~22-28%. È lo **stesso schema** dello
split 2:1 non aggiustato del 25/07 (che valeva *esattamente* −50%): una soglia tarata su una classe
di difetto non sorveglia le altre.
### Perché serviva il gemello e non una regola locale
Il discriminante del 25/07 (**range intraday**) qui non funziona: una barra contaminata ha un range
enorme, ma anche un crollo vero (SLV 2026-01-30 aveva 33% di range). Ciò che separa i due casi è che
**un evento di mercato lo fa anche il gemello**: nel *rapporto* veicolo/gemello i movimenti veri si
cancellano.
Controprova su dati reali: la stessa scansione fatta sui **prezzi** segnalava IDTL 2020-03
(liquidazione dei treasury) e IGLN 2013-04 (crollo dell'oro) — andate-e-ritorni identiche nella
forma. Sul **rapporto** spariscono, e resta la sola CSPX 2012-01-13.
Questo è il buco che il feed equity aveva: nel crypto la certificazione incrocia sempre più venue
(`certify_feed.py` vs Coinbase USD); il feed equity aveva **solo controlli locali**.
### La soglia non è tarabile sulla deviazione, ed è il punto interessante
| statistica | rumore massimo misurato | difetto CSPX | margine |
|---|---|---|---|
| deviazione dal gemello | **9.90%** (2025-04-09) | 21.4% | 2.2× ❌ |
| **|dev| / movimento del gemello** | **8.1** | **42.7** | **5.3×** ✅ |
Il 9.90% è **legittimo**: Londra chiude alle 11:30 di New York, quindi in un giorno violento le due
chiusure sono davvero lontane. Ma **un disallineamento d'orario non può superare il movimento del
mercato**: se il gemello si è mosso dello 0.4% e il veicolo se ne va del 21%, non c'è orario che lo
spieghi. La statistica adimensionale porta il margine da 2.2× a 5.3× — sopra il 3× che questo
progetto richiede a un rilevatore.
Tre condizioni congiunte (come il rilevatore di split, e per la stessa ragione): deviazione oltre
`MIN_DEV`, non-spiegato oltre `MIN_UNEXPLAINED=18.0`, e **rientro** entro 5 barre (una divergenza di
NAV vera persiste, una stampa sbagliata no).
**Riparazione = scartare la barra, non ricostruirla.** Del prezzo vero non sappiamo niente;
sappiamo che quello scritto è sbagliato. Scartarla rende corretto il rendimento 12/01→17/01
(−0.14%); "ripararla" con un fattore stimato inventerebbe un dato.
### ⚠️ Limite dichiarato, e come è stato chiuso
GBPUSD ~1.27 → 21% di deviazione = **sempre rilevata**. EURUSD ~1.09 → 8.3% = **dentro il rumore**
dei giorni violenti. Non è tappabile abbassando la soglia (sotto 12 si segnalano i giorni veri).
Invece di inseguire la rilevabilità ho misurato il **danno** di una contaminazione non vista:
iniettando 60 contaminazioni casuali, **dSharpe mediano −0.003, peggiore −0.056, |Δ|>0.05 nel 2%
dei casi**. Il limite resta, ma è quantificato e irrilevante.
> **Regola:** quando un rilevatore ha un buco che non si può chiudere senza generare falsi positivi,
> si misura il **danno** del caso non rilevato, non la sua probabilità. Un buco quantificato e
> innocuo è un risultato; un buco taciuto è un debito.
---
## 2. Quanto costa il veicolo: ~zero — ma lo stimatore ovvio dà la risposta sbagliata
Prima stesura: media delle differenze giornaliere → **CSPX −0.47%/anno**. Sbagliato.
Le due serie seguono lo **stesso indice** ma sono campionate a orari diversi. La differenza
giornaliera è dominata da uno sfasamento che si **inverte il giorno dopo**: volatilità 17-22%
annualizzata, **errore standard ~7%/anno** sulla stima del drag — cioè **15 volte più grande del
drag stesso**. In più la media delle differenze *semplici* è contaminata dal drag di varianza.
Il rapporto veicolo/gemello invece è **stazionario**: il suo drift *è* il drag.
| gamba | UCITS | drag misurato | atteso da TER | + ritenuta USA | banda annua |
|---|---|---|---|---|---|
| SPY | CSPX | **−0.06%** | +0.02% | +0.20% | [−0.52,+0.63] |
| QQQ | EQQQ | **−0.00%** | −0.10% | −0.03% | [−0.13,+1.29] |
| IWM | XRSU | **−0.15%** | −0.11% | +0.07% | [−0.91,+0.37] |
| TLT | IDTL | **+0.18%** | +0.08% | +0.68% | [−0.45,+1.60] |
| GLD | IGLN | **+0.36%** | +0.28% | +0.28% | [−0.56,+0.99] |
| HYG | IHYU | **+0.28%** | −0.01% | +0.89% | [−0.83,+1.88] |
| **media EW** | | **+0.10%/anno** | +0.03% | **+0.35%** | |
Controllo di plausibilità: **segno concorde in 4/6, scarto < 30bps in 6/6**. Il caso più netto è
l'oro (GLD 0.40% vs IGLN 0.12% → atteso +0.28%, misurato +0.36%): è un controllo indipendente che la
misura sta cogliendo il TER e non rumore. Le due gambe discordi restano entro 30bps, e su una banda
annua larga [−0.9%,+1.9%] il segno di uno scarto così piccolo non è informativo. **Ciò che il
controllo stabilisce è la scala: decine di bps, non punti.**
⚠️ La colonna "ritenuta" è **a favore dell'UCITS e non è nel drag misurato**: `ADJUSTED_LAST` sulle
serie USA è al **lordo** della ritenuta USA del 15% che un residente italiano paga davvero sui
dividendi. Comprando SPY quella ritenuta la paghi e nella serie non c'è; un UCITS irlandese la
subisce una volta a livello di fondo e non una seconda all'incasso. *(Ipotesi fiscale dichiarata,
fonte secondaria, da confermare col commercialista — non è un parere fiscale.)*
### Le tre lenti
| lente | Sharpe | CAGR | maxDD | vol |
|---|---|---|---|---|
| L0 segnale USA + rend. USA (pubblicato) | 0.81 | 3.96% | −7.9% | 5.0% |
| L1 segnale USA + rend. UCITS (veicolo) | 0.89 | 4.22% | −7.0% | 4.8% |
| L2 segnale UCITS + rend. UCITS (+orologio) | **0.84** | **4.08%** | −7.5% | 4.9% |
**Totale L2−L0: dSharpe +0.03, dCAGR +0.12%/anno.** Il cambio di veicolo *non costa*.
⚠️ `corr(L0,L2) = 0.65`, bassa per due serie sullo stesso indice — ed è l'**orologio**, non un
difetto: le due chiusure condividono la notte e la mattina americana ma non il pomeriggio.
Verificato che non sia uno sfasamento di date: la correlazione veicolo/gemello è **massima a lag 0
su 6/6 coppie** (0.46-0.78). Conseguenza: le statistiche *giornaliere* delle due lenti non sono
confrontabili una a una, mentre il **drift** sì — che è esattamente perché la sezione 2 usa il
rapporto cumulato.
---
## 3. Il vincolo vero non è il broker: è il prezzo di UNA azione
Senza frazionamento un ordine è almeno una azione. **Il prezzo unitario è una scelta
dell'emittente, non una proprietà dell'indice**: CSPX costa $802 e VUAA $144 sullo *stesso* S&P 500.
| gamba | STORIA | prezzo | DEPLOY | prezzo | a $3.000 | a $10.000 |
|---|---|---|---|---|---|---|
| SPY | CSPX | $801.86 | **VUAA** | $143.80 | 29% | 9% |
| QQQ | EQQQ | $692.67 | **XNAS** | $65.74 | 13% | 4% |
| IWM | XRSU | $437.80 | **R2US** | $86.35 | 17% | 5% |
| TLT | IDTL | $3.09 | IDTL | $3.09 | 1% | 0% |
| GLD | IGLN | $79.06 | IGLN | $79.06 | 16% | 5% |
| HYG | IHYU | $94.12 | IHYU | $94.12 | 19% | 6% |
*(% = quanto pesa una azione sull'allocazione di quella gamba)*
Danno misurato dell'esecuzione a numero **intero** di azioni, stessa finestra per entrambi:
| insieme | capitale | Sh fraz. | Sh intero | Δ | vol fraz. | vol intero | **gambe vive** | esposta |
|---|---|---|---|---|---|---|---|---|
| STORIA | $3.000 | 0.84 | 0.80 | −0.04 | 5.1% | **2.2%** | **4/6** | **33%** |
| STORIA | $10.000 | 1.08 | 1.02 | −0.06 | 5.1% | 4.2% | 6/6 | 63% |
| **DEPLOY** | **$3.000** | 0.88 | 0.84 | −0.04 | 5.1% | **4.5%** | **6/6** | **65%** |
| DEPLOY | $10.000 | 1.10 | 1.09 | −0.02 | 5.1% | 4.9% | 6/6 | 66% |
**Con i veicoli giusti il frazionamento non serve.** Con quelli sbagliati, a $3.000 lo sleeve perde
due gambe su sei ed è a mercato un terzo del tempo: non è GTAA01 con un vincolo, è un'altra cosa.
⚠️ **Si legge `gambe vive` e `vol`, non `Sharpe`.** Un vincolo che alza lo Sharpe non è un
miglioramento: arrotondando in giù riduce l'esposizione e paga meno commissioni. È il **null
de-levering** (4ª occorrenza dopo VRP-DD, TP01×DVOL, MAT01). Qui il controllo è stato eseguito e
il verdetto è che con l'insieme DEPLOY il de-levering **non c'è**.
⚠️ Scartati di proposito, benché con più storia: **RTWO** (Russell 2000 *quality* = fattore),
**CSUSS** (MSCI USA Small Cap *ESG*), **IDP6** (S&P 600, indice diverso). Equivalenza dell'indice
prima della storia.
---
## 4. Il costo del venue, per FORMA — la sola cosa su cui i broker differiscono davvero
**Ordini/anno** (dipendono da banda e cadenza, non dal listino): **77 a $3.000, 102 a $10.000, 149 a
$50.000**. Con questo numero ogni listino è calcolabile a mano.
| costo fisso/ordine | $3.000 Sh | CAGR | $10.000 Sh | CAGR | $50.000 Sh | CAGR |
|---|---|---|---|---|---|---|
| $0.00 | 0.92 | 4.45% | 0.92 | 4.48% | 0.92 | 4.48% |
| $0.35 (IB US) | 0.73 | 3.52% | 0.84 | 4.11% | 0.90 | 4.37% |
| $1.00 | 0.39 | 1.80% | 0.71 | 3.42% | 0.86 | 4.17% |
| $2.00 | −0.13 | −0.79% | 0.50 | 2.37% | 0.79 | 3.86% |
| $5.00 | −1.51 | −8.17% | −0.12 | −0.71% | 0.61 | 2.93% |
| costo proporzionale | $3.000 | $10.000 | $50.000 |
|---|---|---|---|
| 5 bps/ordine | 0.89 | 0.89 | 0.88 |
| 25 bps/ordine | 0.77 | 0.76 | 0.75 |
| 50 bps/ordine | 0.62 | 0.60 | 0.59 |
**Le soglie da verificare presso il broker:**
| capitale allocato | CAGR = 0 | Sharpe = 0.45 |
|---|---|---|
| $3.000 | $1.68/ordine | **$0.90/ordine** |
| $10.000 | $4.34/ordine | **$2.23/ordine** |
| $50.000 | $14.65/ordine | **$7.62/ordine** |
Un listino **proporzionale** è quasi indifferente al capitale (0.75-0.89 di Sharpe a ogni taglia);
uno **fisso** è una tassa regressiva. È la regola del 25/07 riconfermata su un venue diverso.
---
## 5. Risposta operativa alla domanda
**Revolut o Degiro non sbloccano gli ETF USA**: il PRIIPs vale per ogni intermediario che serve
retail UE. IB è anzi fra i più permissivi. Aprire un terzo conto per lo stesso rifiuto aggiunge
rischio di venue senza guadagno.
Ciò che si compra su *qualunque* dei tre sono gli **UCITS**, e a quel punto la scelta si gioca su
**una sola dimensione misurabile**: il costo per ordine, contro le soglie della tabella sopra, con
77-149 ordini l'anno.
**Raccomandazione: restare su IB**, perché (a) il conto esiste già, (b) i dati per il segnale
arrivano dallo stesso gateway, (c) è l'unico dei tre di cui la forma di costo è già modellata in
`gtaa.py`. La verifica che resta da fare è **una sola**: la tariffa IB per ordine su LSEETF in USD,
contro $2.23 (a $10.000) o $0.90 (a $3.000).
**Nessuna azione oggi**: la decisione venue del 26/07 tiene tutto su Deribit fino a $20k, cioè
~2028 col piano di versamenti corrente.
---
## Lezioni
1. **Prima di dichiarare che un vincolo esterno distrugge un risultato, chiedersi cosa vincola
esattamente.** "Non posso comprare" ≠ "non posso vedere": tutta la validazione a 30 anni era
salva, e la nota che diceva il contrario era mia.
2. **Un feed senza secondo parere non è certificato**, e la regola valeva già nel crypto. Il feed
equity ha vissuto 5 settimane con soli controlli locali, e il primo veicolo estero ha trovato
il buco alla prima estrazione.
3. **Una soglia tarata su una classe di difetto non sorveglia le altre** — 2ª conferma dopo lo
split 2:1 del 25/07. E quando la taratura non regge il margine richiesto, la risposta non è
accettarla ma **cambiare statistica**: qui il passaggio da assoluta ad adimensionale
(deviazione / movimento del gemello) porta il margine da 2.2× a 5.3×.
4. **La media delle differenze giornaliere non è la deviazione fra due veicoli sullo stesso
indice.** Errore standard 15× più grande della quantità stimata, più il drag di varianza. La
domanda "quanto mi costa il veicolo" è una domanda sul **drift**, quindi si misura sul rapporto
cumulato.
5. **Il prezzo unitario di un ETF è un parametro di progetto, non un dato.** Sceglierlo cambia la
soglia di capitale di uno sleeve più di qualunque negoziazione con un broker.
6. **Il grado d'accordo si conta, non si dichiara.** La prima stesura stampava "stesso segno su 6/6
gambe"; i dati dicevano 4/6. Scriverlo a mano nel `print` è il modo più facile di pubblicare una
conclusione che i propri dati smentiscono — 3ª occorrenza in questa sessione.
---
# Addendum 2026-07-27 — "io ho già Revolut e Degiro, IB sono solo iscritto"
L'informazione ribalta la raccomandazione di ieri. L'argomento principale per IB era **"il conto
esiste già"**, e non è vero: i conti reali sono Revolut e Degiro, IB è una registrazione.
Cosa **non** cambia: il gateway IB serve per i **dati** del segnale (ADJUSTED_LAST sui 6 ETF USA),
e per quello basta il paper — non serve eseguire lì. La scelta del broker di **esecuzione** è
quindi libera, e si gioca su una sola dimensione misurabile: il **costo per ordine**.
Script: `scripts/research/r0727_gtaa_broker.py`. Test: `tests/test_gtaa_broker.py` (9).
**Book, pesi, cron, config: INVARIATI.**
## Il numero di ordini è un parametro, non un dato
I 77-149 ordini/anno del 26/07 sono la conseguenza di `REBAL_EVERY=5` e `REBAL_BAND_USD=50`,
scelti il 25/07 sul plateau **per il listino IB su azioni USA e a una taglia sola**.
| cadenza | banda | ord/anno | Sh @ $0 | Sh @ $1 | Sh @ $2 |
|---|---|---|---|---|---|
| settimanale | $25 | 102 | 1.28 | 1.08 | 0.87 |
| settimanale | **$50** (canonico) | 84 | 1.27 | 1.10 | 0.94 |
| settimanale | $400 | **23** | **1.27** | 1.22 | 1.18 |
| mensile | $50 | 33 | **1.12** | 1.06 | 1.00 |
| bimestrale | $400 | 10 | 1.10 | 1.08 | 1.06 |
**Si legge `Sh @ $0` per prima**: è il prezzo della banda *in assenza di commissioni*. Allargare la
banda a cadenza settimanale **non lo tocca** (1.27 → 1.27), rallentare la cadenza sì (1.27 → 1.12).
Il meccanismo è interpretabile: `_exposure` è la media di 4 indicatori binari, quindi si muove a
scatti di 0.25 ≈ $417 su una gamba da $1.667. **La banda filtra la deriva del vol-target, non il
segnale di trend.**
### Controllo su finestra lunga e veicoli diversi
Sui **veicoli USA**, finestra comune ai 6 (10 anni, limitata dalla cache TLT dal 2016):
| banda | ord/anno | Sh @ $0 | Sh @ $1 |
|---|---|---|---|
| $25 | 133 | 0.98 | 0.72 |
| $400 | **35** | **0.96** | **0.89** |
✅ Lo Sharpe a costo zero perde **0.02** mentre gli ordini calano del **74%**. Non è un artefatto
della finestra corta.
## ⚠️ Ma la banda in dollari assoluti è la parametrizzazione sbagliata
| capitale | banda | % della gamba | ord/anno | **esposta** | Sharpe | |
|---|---|---|---|---|---|---|
| $3.000 | $400 | **80%** | **3** | **45%** | 0.71 | ❌ congelato |
| $10.000 | $400 | 24% | 23 | 66% | 1.22 | OK |
| $50.000 | $400 | 5% | 75 | 66% | 1.25 | OK |
A $3.000 la banda da $400 è l'80% della gamba: **3 ordini l'anno**, a mercato il **45%** del tempo
invece del 66%. Lo Sharpe resta 0.71 — accettabile — **su una strategia che ha smesso di seguire il
proprio target**. È il null de-levering in una veste nuova: qui non travestito da "meno drawdown"
ma da "meno costi".
> **Regola: quando un parametro di esecuzione è espresso in valuta assoluta, il suo effetto dipende
> dal capitale — e il controllo non è lo Sharpe ma la QUOTA DI TEMPO A MERCATO.**
## La configurazione: banda = 25% della gamba
| capitale | banda | ord/anno | esposta | soglia $/ordine | budget/anno |
|---|---|---|---|---|---|
| $3.000 | $125 | **21** | 66% | **$5.65** | $120 |
| $6.000 | $250 | **21** | 66% | $11.34 | $240 |
| $10.000 | $417 | **21** | 66% | $18.90 | $400 |
| $25.000 | $1.042 | **21** | 66% | $47.26 | $1.000 |
| $50.000 | $2.083 | **21** | 66% | >$60 | — |
**21 ordini l'anno a ogni capitale**, esposizione 66% ovunque. Contro il canonico: a $3.000 la
soglia passa da **$2.08 a $5.65 per ordine** — cioè dalla differenza fra *"serve un broker
economico"* e *"va bene qualunque broker europeo"*.
⚠️ **Non è un cambio di produzione.** È una configurazione **proposta**, tarata su questa finestra,
non passata per `study_family_honest` né per un deflated-Sharpe. Regge il controllo su 10 anni e
veicoli diversi, ma GTAA01 non è deployabile prima dei $20k (decisione venue 26/07): c'è tempo per
validarla come si deve.
## Cosa cercare sul proprio conto — per ISIN, non per ticker
| gamba | ticker | ISIN | prezzo | descrizione |
|---|---|---|---|---|
| SPY | VUAA | `IE00BFMXXD54` | $143.80 | Vanguard S&P 500 UCITS (Acc, USD) |
| QQQ | XNAS | `IE00BMFKG444` | $65.74 | Xtrackers Nasdaq 100 UCITS 1C |
| IWM | R2US | `IE00BJ38QD84` | $86.35 | SPDR Russell 2000 US Small Cap UCITS |
| TLT | IDTL | `IE00BSKRJZ44` | $3.09 | iShares $ Treasury Bond 20+yr UCITS |
| GLD | IGLN | `IE00B4ND3602` | $79.06 | iShares Physical Gold ETC |
| HYG | IHYU | `IE00B4PY7Y77` | $94.12 | iShares $ High Yield Corp Bond UCITS |
*(ISIN da contract details IB: i ticker cambiano da borsa a borsa, le ISIN no. Tutti domiciliati in
Irlanda — è il motivo per cui sono acquistabili nell'UE.)*
Tutti quotati a **Londra in USD**. ⚠️ Le stesse ISIN esistono su altre borse e in altre valute: una
linea in **EUR** aggiunge la conversione per ordine, che a 25bps costa **~0.15 di Sharpe** — più del
costo per ordine di qualunque broker a questa cadenza. **La valuta della linea conta più del
broker.**
## Verdetto
Con 21 ordini l'anno e una tolleranza di $5.65/ordine già a $3.000, **il vincolo di costo smette di
essere binding su qualunque broker retail europeo**. La domanda "Revolut o Degiro" perde quindi la
sua parte quantitativa e resta solo la parte di disponibilità: quale dei due quota le sei ISIN sopra
sulla linea in USD.
Restano due criteri non misurabili da qui, entrambi a favore di Degiro su Revolut per questo uso
(universo ETF europeo tipicamente più ampio, e accesso diretto a LSE), **ma vanno verificati
guardando i due conti** — non sono cose che posso misurare da questo lato.
## Lezione
**Una raccomandazione poggiata su un fatto non verificato sul conto reale vale quanto quel fatto.**
Ieri ho consigliato IB in parte perché "il conto esiste già": era un'assunzione, e per la seconda
volta in due giorni un'assunzione sul conto reale ha cambiato la conclusione. La prima volta era la
negoziabilità (PRIIPs), questa volta quale conto è davvero operativo.
---
# Addendum 2026-07-27 (2) — "degiro ha api?"
**Fatto:** DEGIRO **non** espone una API di trading ufficiale per il retail. Revolut nemmeno (la sua
API è per pagamenti, non per il portafoglio titoli). IB sì, documentata e supportata — è quella che
il progetto già usa per i dati.
Esistono wrapper **non ufficiali** degli endpoint interni del web trader DEGIRO. Girano su
credenziali + seed 2FA depositati sulla macchina, sono fuori dai termini di servizio, e si rompono
**in silenzio** a ogni cambio di front-end. Questo progetto ha già pagato una volta il prezzo di un
guasto silenzioso (`fresh_5m`, 26/07: fallimento muto → latenza d'uscita di SKH01 da ~1h a ~1 giorno
senza che nulla lo segnalasse). **Un esecutore automatico che può rompersi senza dirlo è peggio
dell'esecuzione manuale.**
Quindi la domanda utile non è "si può automatizzare" ma **"quanto costa non farlo"**.
## Carico operativo (banda 25%, controllo settimanale, $10.000)
| | |
|---|---|
| controlli/anno | 50 |
| **settimane con ≥1 ordine** | **15** (29% dei controlli) |
| ordini per settimana attiva | 1.4 (max 5) |
Nel 71% dei controlli non c'è nulla da fare.
## Costo del ritardo di esecuzione
Veicoli USA, 10 anni. ⚠️ Sulla finestra UCITS di 3.2 anni la curva **non risulta monotona** (5
giorni −0.26, 10 giorni −0.13): il campione corto non risolve differenze di questa taglia, quindi
il numero si legge sulla finestra lunga.
| ritardo | Sharpe | ΔSharpe | stabilità |
|---|---|---|---|
| 0 giorni | 0.90 | — | — |
| **1 giorno** | 0.89 | **−0.02** | peggiora in 6/11 anni = **moneta** |
| 2 giorni | 0.83 | −0.07 | 7/11 |
| 3 giorni | 0.78 | −0.13 | 7/11 |
| 5 giorni | 0.73 | −0.18 | 7/11 |
| **10 giorni** | 0.63 | **−0.27** | 6/11 |
**Il costo non è il ritardo tipico, è la coda.** Eseguire il giorno stesso o il giorno dopo costa
nulla; dieci giorni valgono quasi un terzo dello sleeve.
## Conseguenza
Il rischio dell'operatività manuale non è la lentezza, è la **dimenticanza** — e quella si compra
con un **allarme**, non con una API. `gtaa_rebalance_plan(held, capital)` esiste già in produzione
ed è nato esattamente per un esecutore; il progetto ha già l'allerta Telegram sul book live. Un cron
settimanale che calcola il piano e notifica quando c'è da agire copre il caso 15 volte l'anno.
⚠️ **L'altro lato, che resta vero:** il resto del book è automatico (TP01 e SKH01 mandano ordini
veri su cron). Aggiungere una gamba manuale introduce un modo di fallire che il sistema oggi non ha.
È un argomento reale a favore di IB — che l'API ce l'ha — ma richiede finanziare un secondo venue, e
la decisione venue del 26/07 tiene tutto su Deribit fino a $20k. **La scelta è quindi rimandata al
punto in cui la si riaprirebbe comunque.**
## Lezione
**Una capacità mancante si valuta sul costo di non averla, non sulla sua assenza.** Qui l'assenza di
API sembra squalificante e vale −0.02 di Sharpe se si esegue entro un giorno; ciò che vale davvero
(−0.27) è un rischio operativo che si copre con una notifica.
---
# Addendum 2026-07-27 (3) — "r2us in revolut non c'è, ma ho zprr e spy4"
## ZPRR **è** R2US
| ticker | borsa | valuta | ISIN |
|---|---|---|---|
| R2US | Londra | USD | `IE00BJ38QD84` |
| **ZPRR** | **Xetra** | **EUR** | **`IE00BJ38QD84`** |
Stessa ISIN = stessa classe di quote = **stesso fondo, stesso NAV**. Cambia solo dove e in che
valuta si negozia. La gamba small cap è risolta: **compra ZPRR**, non si perde niente.
> **Regola: si cerca per ISIN, non per ticker.** Lo stesso fondo ha ticker diversi su borse diverse,
> e un ticker copiato da una lista può essere un altro prodotto.
## ⚠️ SPY4 non è quello che sembra
`IE00B4YBJ215` = SPDR **S&P 400 US Mid Cap**. Non è small cap, e non è l'S&P 500 (quello è SPY5,
`IE00B6YX5C33`). Non serve, dato che ZPRR c'è — ma misurato come ripiego, su 6.5 anni:
| gamba small cap | Sharpe | CAGR | maxDD |
|---|---|---|---|
| R2US (small) | 0.86 | 4.20% | −8.2% |
| SPY4 (mid) | 0.86 | 4.26% | −8.3% |
Correlazione dei due sleeve **0.991**, SPY4 peggiore in **3/7 anni** = moneta. *(Sulla finestra
corta di 3.2 anni sembrava −0.15 di Sharpe: era rumore.)*
**Ripiego accettabile**, e il motivo è meccanico: small e mid cap USA hanno correlazione giornaliera
~0.95, e un TSMOM su due serie così vicine si accende quasi negli stessi giorni. ⚠️ Non è
"validato" — 6.5 anni non bastano a distinguere due gambe così simili, ed è **esattamente per
questo** che la scelta fra le due non conta.
## ⚠️ Correzione a un'indicazione data ieri: sulla valuta avevo ragionato al contrario
Ieri ho scritto che *"una linea in EUR aggiunge la conversione per ordine"*. È vero **solo per un
conto in USD**. Per un conto in **euro** — cioè un retail italiano su Revolut o Degiro — vale
l'opposto: comprare la linea in USD costringe a convertire a ogni ordine, la linea in EUR no.
L'esposizione economica è identica nei due casi: il fondo detiene attivi in USD e **nessuna delle
due linee è coperta**. La valuta di quotazione non copre niente — decide solo se serve una
conversione.
> **Regola giusta: prendere la linea nella valuta del proprio saldo.**
Quanto vale, misurato (turnover lordo **$13.655/anno** su $10.000, 21 ordini):
| bps FX per ordine | ΔSharpe | costo/anno |
|---|---|---|
| 15 bps | −0.04 | $20 |
| 25 bps | −0.07 | $34 |
| 50 bps | −0.14 | $68 |
A 25bps la conversione equivale a ~**$1.6 in più su ciascuno dei 21 ordini**: reale, ma piccolo
rispetto alla soglia di $18.90/ordine a $10.000. Quindi **ZPRR in EUR su un conto in euro è la
scelta migliore**, non un compromesso.
## Lezione
**Un costo di conversione non è una proprietà dello strumento ma della coppia strumento-conto.**
Avevo dedotto "linea in EUR = costo in più" da un caso (conto in USD) e l'avevo scritta come regola
generale; per il conto che l'operatore usa davvero il segno è invertito. È la terza volta in due
giorni che un'assunzione non verificata sul conto reale cambia la conclusione — dopo la
negoziabilità PRIIPs e quale conto è operativo.
---
# Addendum 2026-07-27 (4) — DEGIRO ha tutte e sei
Screenshot della watchlist "Pythagoras" su flatexDEGIRO: **le sei gambe ci sono tutte**, con i
ticker esatti raccomandati. (Era Revolut a non avere R2US.)
| gamba | ticker | borsa | valuta | prezzo Degiro |
|---|---|---|---|---|
| SPY | VUAA | TDG | **EUR** | € 126,795 |
| QQQ | XNAS | TDG | **EUR** | € 58,10 |
| IWM | R2US | LSE | USD | $ 86,66 |
| TLT | IDTL | LSE | USD | $ 3,09987 |
| GLD | IGLN | LSE | USD | $ 79,585 |
| HYG | IHYU | LSE | USD | $ 94,32 |
## Verifica indipendente che le linee in EUR siano gli stessi fondi
Non dallo screenshot ma dai dati: il rapporto fra il prezzo IB (Londra USD) e il prezzo Degiro deve
essere **un solo cambio** per entrambe le linee EUR.
| ticker | Degiro | IB (LSE USD) | rapporto |
|---|---|---|---|
| VUAA | 126,795 | 143,80 | **1.1341** |
| XNAS | 58,10 | 65,74 | **1.1315** |
| R2US / IDTL / IGLN / IHYU | — | — | 0.993-0.998 (già USD) |
EURUSD implicito **1.1341 vs 1.1315, scarto 0.23%**. Due fondi diversi non darebbero lo stesso
cambio: sono le stesse quote, quotate in euro.
## ⚠️ Un errore mio, dello stesso tipo che avevo appena codificato come regola
Per cercare le linee in euro delle altre quattro gambe ho interrogato IB **per ticker** sulle borse
tedesche: risultato "nessuna linea EUR" su 4/4. **Falso.** Il ticker cambia da borsa a borsa — R2US
su Xetra si chiama ZPRR. Cercando **per ISIN**:
| gamba | linea USD | **linea EUR** | ISIN |
|---|---|---|---|
| SPY | VUAA (LSE) | VUAA (Xetra/BIt) | `IE00BFMXXD54` |
| QQQ | XNAS (LSE) | XNAS (Xetra) | `IE00BMFKG444` |
| IWM | R2US (LSE) | **ZPRR** (Xetra) | `IE00BJ38QD84` |
| TLT | IDTL (LSE) | **IS04** (Xetra) | `IE00BSKRJZ44` |
| GLD | IGLN (LSE) | **EGLN** (Londra) | `IE00B4ND3602` |
| HYG | IHYU (LSE) | **IS0R** (Xetra) | `IE00B4PY7Y77` |
**Ogni gamba ha una linea in euro.** Avevo scritto la regola "si cerca per ISIN, non per ticker" un
messaggio prima e poi ho costruito la sonda per ticker. *Un "assente" da una ricerca per ticker su
una borsa dove quel ticker non esiste non significa "non esiste".*
## Quanto vale la conversione, e su quale gamba
Turnover per gamba a $10.000 (banda 25%, 21 ordini/anno):
| gamba | ticker | ordini/anno | turnover/anno | quota |
|---|---|---|---|---|
| **TLT** | **IDTL** | **9** | **$6.257** | **46%** |
| SPY | VUAA | 3 | $2.289 | 17% |
| GLD | IGLN | 3 | $1.695 | 12% |
| QQQ | XNAS | 3 | $1.614 | 12% |
| HYG | IHYU | 1 | $958 | 7% |
| IWM | R2US | 2 | $843 | 6% |
- turnover su gambe in **USD** (da convertire): **$9.752/anno = 71%**
- costo conversione: **$24/anno a 25bps**, $49 a 50bps (0.24-0.49% del capitale, ~6-12% del CAGR)
**IDTL da sola vale il 46% del turnover e 9 dei 21 ordini.** Se si vuole ridurre la conversione
senza cambiare sei strumenti, si sposta **quella** sulla linea in euro (IS04, `IE00BSKRJZ44`): da
sola copre il **64%** del turnover convertibile.
⚠️ Il risparmio non è netto: le linee di Xetra possono avere spread più larghi delle linee di Londra
(che sono le primarie), e Degiro storicamente addebita una tariffa di connettività per borsa. Su
$10.000 parliamo di decine di dollari l'anno in entrambe le direzioni — **non è una decisione
importante**, e dirlo è più utile che costruire una precisione finta.
## Cosa NON serve
Il messaggio in cima allo screenshot — *"Richiedi un'aliquota ridotta della ritenuta alla fonte sugli
investimenti statunitensi"* (il W-8BEN) — **non riguarda queste sei posizioni**: sono fondi
irlandesi, non titoli USA. La ritenuta del 15% la subisce il fondo al proprio interno e nessun
modulo dell'investitore la cambia. Va compilato se un giorno si detengono azioni USA dirette.
## Stato
Saldo Degiro €328,92: questa è **preparazione, non azione**. GTAA01 richiede ≥$3.000 per reggere i
costi, e la decisione venue del 26/07 tiene tutto su Deribit fino a $20k.
+225
View File
@@ -0,0 +1,225 @@
# 2026-07-26 — "Quale strategia terrei?" — leave-one-out del book DE-LUCKATO sulle ancore
**Richiesta:** *"dimmi qual strategia pensi di tenere"*.
**Script:** `scripts/research/r0726_loo_deluck.py` — **test:** `tests/test_loo_deluck.py` (9).
**Book, pesi, cron, config: INVARIATI.** Nessuna decisione di allocazione cambia.
Cambia invece un **numero documentato in CLAUDE.md** (§4) e cambiano **due giudizi che avevo
dato un'ora prima nella stessa sessione** (§3).
---
## 0. Perche' la risposta ovvia non vale
La domanda "quanto vale ogni sleeve al suo posto nel book" ha una misura ovvia: togli lo sleeve,
guarda quanto cala il book. L'ho fatta, e alla prima lettura diceva questo:
```
BOOK COMPLETO FULL +2.222 HOLD +2.364 maxDD 6.07%
tolto dFULL dHOLD dDD
TP01 (33%) +0.280 -0.219 +0.24pp
XS01 (15%) +0.142 +0.640 +0.25pp
VRP01 (12%) +0.087 +0.064 +1.08pp
SKH01 (20%) +0.432 +0.652 +1.64pp
GTAA01 (20%) +0.120 +0.244 +1.70pp
```
Letta cosi', SKH01 e' il motore del book e TP01 e' un peso morto sull'hold-out.
**Entrambe le letture sono sbagliate**, e il motivo era gia' scritto nel progetto il giorno prima:
> *se si de-lucka una strategia va de-luckato anche il suo DEGRADO* — ogni Δ fra due varianti
> misurato a un'ancora sola eredita la fortuna di quell'ancora.
> (lezione 26/07, codificata in `altlib.anchor_luck_delta`)
Un leave-one-out **e' esattamente un Δ fra due varianti**. E qui il problema e' al quadrato: 4
sleeve su 5 sono ancorati, e per 3 di loro l'ancora canonica era gia' stata misurata come
fortunata (TP01 92° pctl su 24 ancore, SKH01 93-98° su 23 offset, XS01 fase 0 al 15° pctl di DD).
VRP01 e' l'unico senza firma — la sua fase canonica e' la **peggiore** delle 7.
---
## 1. Il metodo: estrazioni CONGIUNTE, non una griglia per sleeve
Gli audit del 02/07 e del 03/07 hanno de-luckato **uno sleeve alla volta**, tenendo gli altri alla
loro ancora canonica. Va bene per giudicare quello sleeve; non basta per giudicare il **book**,
perche' i numeri del book sono calcolati con tutti e cinque alla canonica insieme.
Spazio di luck congiunto: **24 (TP01, ancore orarie) x 10 (XS01, fasi H=10) x 7 (VRP01, fasi
settimanali) x 23 (SKH01, offset di griglia 230m/690m) x 5 (GTAA01, fasi della cadenza
settimanale) = 193.200 configurazioni.** Non enumerabile: si campiona.
**2000 estrazioni uniformi e indipendenti** (seed 20260726). Uniformi-indipendenti e' il null
onesto: non avevamo nessuna ragione a priori di preferire un'ancora a un'altra — se ce l'avessimo
avuta, sarebbe stata parte della strategia.
Per ogni estrazione: book completo + i 5 leave-one-out, **tutti alla stessa configurazione
d'ancora**. La statistica e' la **mediana delle differenze appaiate**, mai la differenza delle
mediane (l'errore che il 26/07 aveva ribaltato il verdetto sul recupero on-book di SKH01: le due
mediane cadono su ancore diverse).
**Repliche riusate, non riscritte.** I quattro generatori ancorati vengono dagli audit che li
hanno gia' verificati bit-exact (`r0702_tp01_offset.daily_off`, `r0702_anchor_xs01.xs_phase`,
`r0703_vrpimp_anchor.combo_weekly`, `r0702_anchor_skh01.skh_port`). Riscriverli avrebbe voluto
dire rifare gli stessi errori di convenzione. L'unico pezzo nuovo e' la fase di GTAA01
(`i % REBAL_EVERY == ph` invece di `== 0`), ed e' l'unico coperto da test dedicato.
**Sanity obbligatorio prima di tutto** — ogni replica ancorata deve riprodurre lo sleeve di
**produzione** alla sua ancora canonica, altrimenti sto misurando un'altra strategia:
```
TP01 ancora 0 max|dif| = 0.0e+00 (n=2692) OK
XS01 ancora 0 max|dif| = 0.0e+00 (n=938) OK
VRP01 ancora 0 max|dif| = 0.0e+00 (n=1884) OK
SKH01 ancora 0 max|dif| = 0.0e+00 (n=2690) OK
GTAA01 ancora 0 max|dif| = 0.0e+00 (n=2690) OK
```
Costo totale: 69 serie, ~8s di precalcolo, 34s per le 2000 estrazioni.
---
## 2. Il livello del book: i numeri pubblicati stanno in cima alla banda
```
canonico pctl MEDIANA p10 p90 fortuna
Sharpe FULL +2.222 97.0% +1.946 +1.807 +2.116 +0.276
Sharpe HOLD-OUT +2.364 99.6% +1.542 +1.109 +1.910 +0.822
maxDD FULL 6.07% 12.0% 6.85% 5.99% 7.94% -0.78%
```
**L'hold-out canonico sta al 99.6° percentile dello spazio d'ancora: solo 9 estrazioni su 2000
fanno meglio.** La stima onesta e' **1.54**, con banda [1.11, 1.91].
⚠️ **Un "100%" che ho dovuto correggere.** La prima stampa dava `pctl 100%` — arrotondamento di
99.55% con un `%.0f`. In un artefatto di ricerca un 100% stampato significa "e' il massimo, punto"
e avrebbe fatto concludere a una sessione futura qualcosa di piu' forte del vero. Verificato a
mano (max fra le 2000 = +2.577, a `TP01=0 / XS01=7 / VRP01=1 / SKH01=0 / GTAA01=3`), formato
portato a 1 decimale. *Regola pratica: un percentile stampato senza decimali mente esattamente
agli estremi, che sono l'unico posto dove lo si legge.*
---
## 3. Il leave-one-out de-luckato — e due giudizi miei ribaltati
```
dSharpe FULL canonico pctl MEDIANA >0 in
TP01 33% +0.280 5.8% +0.390 100.0%
SKH01 20% +0.432 99.0% +0.142 90.8%
XS01 15% +0.142 76.8% +0.125 99.9%
VRP01 12% +0.087 1.8% +0.122 100.0%
GTAA01 20% +0.120 63.5% +0.115 100.0%
dSharpe HOLD-OUT canonico pctl MEDIANA >0 in
XS01 15% +0.640 63.4% +0.497 96.2%
GTAA01 20% +0.244 17.3% +0.267 100.0%
SKH01 20% +0.652 96.0% +0.190 85.5%
VRP01 12% +0.064 47.4% +0.065 84.2%
TP01 33% -0.219 39.5% -0.200 0.9%
dMaxDD (pp, >0 = protegge) pctl MEDIANA >0 in
GTAA01 20% +1.695pp 23.8% +1.999pp 100.0%
VRP01 12% +1.075pp 55.6% +1.056pp 88.3%
SKH01 20% +1.636pp 89.3% +0.322pp 64.0%
TP01 33% +0.236pp 48.4% +0.274pp 62.1%
XS01 15% +0.251pp 65.0% +0.000pp 43.0%
```
**SKH01 non e' il motore del book.** Del suo contributo apparente, l'ancora canonica regala **2/3
sul FULL** (+0.43 → +0.14), **70% sull'hold-out** (+0.65 → +0.19), **80% sulla protezione DD**
(+1.64pp → +0.32pp). De-luckato e' indistinguibile dagli altri sul FULL ed e' **il meno affidabile
dei cinque**: l'unico sotto il 91% di estrazioni positive su tutte e tre le metriche (91/86/64%).
**GTAA01 non e' il primo da tagliare** (lo avevo detto un'ora prima, sulla lente canonica). E'
**l'unico sleeve positivo nel 100% delle estrazioni su tutte e tre le metriche** e il miglior
protettore di DD del book, al doppio del secondo. Non ha fortuna da restituire: il suo canonico
sta *sotto* la mediana su FULL e DD. ⚠️ L'altra gamba di quel giudizio resta pero' intatta e
indipendente: a $10k comprare ~€0.50/giorno sopra il risk-free con un maxDD del 10% e' caro, e
sotto `GTAA_MIN_CAPITAL` = $3k lo sleeve non e' deployabile. **Attribuzione ≠ eseguibilita'.**
**TP01 e' il maggior contributore, e il canonico lo SOTTOSTIMAVA** (+0.280 al 5.8° pctl → +0.390
de-luckato, positivo in 2000/2000, quasi 3x il secondo). Il suo hold-out negativo **non e'
artefatto d'ancora**: e' negativo nel **99.1%** delle configurazioni. Le due cose insieme sono la
storia dell'assicurazione, finalmente misurata invece che asserita — sul campione pieno (che
contiene il 2022) e' il contributore piu' grande; nella finestra 2025-26 e' stato fermo mentre gli
altri guadagnavano, e questo costa −0.20. **Giudicarlo sulla finestra in cui non e' servito
significa venderlo esattamente prima che serva.**
**VRP01** conferma per la seconda volta di essere l'unico senza firma di fortuna: canonico al
**1.8° pctl** sul FULL, cioe' i numeri di ammissione erano *conservativi*. Secondo protettore di DD.
**XS01** tiene il primo posto sull'hold-out anche de-luckato (+0.497), ma la sua protezione di DD
e' **esattamente zero** (mediana 0.000, positiva nel 43% = moneta). E' un diversificatore di
**rendimento, non di rischio** — e conta, perche' sul canale funded il vincolo binding e' il DD,
non il CAGR (25/07 §4).
**Correlazioni:** stabili sotto de-luck, tutte quasi-nulle. La sola sopra 0.1 e' TP01-GTAA01
(mediana +0.189, canonica +0.242).
### Il contrappeso che SKH01 ha diritto ad avere
Questo de-luck penalizza SKH01 sul path **backtest** (chiusura di bin). Ma le due misure del 26/07
dicono che il **path live e' migliore del backtest su entrambi i lati**: ingressi +0.38 di Sharpe
mediano, uscite +0.081 di Sharpe FULL di book. Applicare il de-luck senza quel contrappeso lo
penalizzerebbe due volte. Verdetto onesto: **SKH01 vale meno dei suoi numeri di ammissione e piu'
di questa tabella.** Quanto esattamente resta il follow-up gia' dichiarato e bloccato (serve la
versione vol-targeted del path live di SKH01).
---
## 4. Correzione a CLAUDE.md
La stima del 02/07 era **a occhio** — sommava le fortune misurate sleeve-per-sleeve. Oggi e'
**misurata congiuntamente**, ed era ottimista su tutte e tre le metriche:
| | stimato 02/07 | misurato 26/07 |
|---|---|---|
| HOLD-OUT | ~1.9-2.1 | **1.54** [1.11, 1.91] |
| FULL | ~2.0-2.2 | **1.95** [1.81, 2.12] |
| maxDD | "~6% invariato" | **6.85%** [5.99, 7.94] |
L'errore non e' stato usare una stima: e' stato che una stima per somma di effetti marginali
**non e' la mediana congiunta**, e la differenza (+0.82 di hold-out) e' piu' grande di quasi
tutti gli uplift per cui in questo progetto si e' discusso se ammettere uno sleeve.
---
## 5. Cosa NON e' questa misura
- **Non e' evidenza out-of-sample.** Il book e' valutato sugli stessi anni in cui XS01 e SKH01
sono stati scelti e affinati. E' attribuzione, de-luckata.
- **Non e' un gate sui pesi.** Ogni proposta di cambio pesi passa da `weights_tilt_null`. Qui non
si propone nulla: i pesi restano 33/15/12/20/20.
- **Non e' una lente di eseguibilita'.** Dice quanto uno sleeve contribuisce al book modellato,
non se lo si puo' comprare a $600 (GTAA01 sotto $3k e XS01 sotto ~$20k non si possono).
---
## 6. Risposta alla domanda
**TP01**, se ne va tenuta una. Maggior contributore de-luckato (+0.390, 2000/2000), l'unico
eseguibile davvero oggi a $600 senza haircut, e l'unico il cui valore dichiarato — il taglio del
DD ~6x contro il buy&hold — **non e' ancorato** e regge a tutte le ancore testate. Tutto il resto
dei suoi numeri e' gia' stato declassato (hold-out 0.31 → ~0.05); quello no.
Le altre: **SKH01** si tiene al 25% e non un euro di piu'; **GTAA01** si tiene nel book modello
(miglior protettore di DD) ma non nel live finche' non ci sono $3k su IB; **VRP01** si tiene come
*metro* — e' l'unico i cui numeri sono onesti per costruzione; **XS01** non e' da tenere oggi, e'
da accendere quando arriva il capitale (~$20k, o un conto funded, dove vale piu' di tutte).
Il book live che gira — **TP01 75 / SKH01 25** — e' gia' questa risposta.
---
## 7. Regole trasferibili
1. **Un leave-one-out e' un Δ, quindi va de-luckato come ogni Δ.** L'attribuzione all'ancora
canonica ha invertito la classifica su 2 metriche su 3.
2. **De-luckare uno sleeve alla volta non de-lucka il book.** La fortuna del book e' un fenomeno
*congiunto*: la somma delle fortune marginali ha sbagliato di +0.82 di Sharpe hold-out. Quando
serve la banda di un aggregato, si campiona lo spazio congiunto.
3. **Un percentile stampato a 0 decimali mente agli estremi**, che sono l'unico posto dove serve.
4. **La frazione di estrazioni positive dice piu' della mediana.** Fra +0.142 (SKH01, positivo nel
91%) e +0.115 (GTAA01, positivo nel 100%) la mediana preferisce il primo e l'affidabilita' il
secondo — ed e' la seconda a decidere se ci si mette del capitale.
5. **Uno sleeve difensivo si giudica sul sinistro, non sul premio.** L'hold-out negativo di TP01 e'
robusto (99.1% delle ancore) e *non* e' un argomento per ridurlo.
+113
View File
@@ -0,0 +1,113 @@
# 2026-07-26 — Rivalutazione della strategia dopo le correzioni del giorno
**Richiesta:** *"in base a quanto definito rivalutiamo la strategia"*.
**Script:** `r0726_reeval_live_weight.py`. **Test:** `tests/test_reeval_live_weight.py` (6).
**Book, pesi, cron, config: INVARIATI.**
---
## 0. Cosa c'era da rivalutare davvero
La giornata ha prodotto sei misure che toccano la strategia. Solo **una** apriva una decisione:
| misura di oggi | cambia una decisione? |
|---|---|
| fattore de-luck ×0.6 → ×0.89 | no: cambia i *numeri* (muro −45%), non cosa si fa |
| muro come punto fisso ($273.900) | no: la mia previsione era sbagliata, il piano resta |
| LOO de-luckato (SKH01 il meno affidabile) | **forse**: e' un argomento per *ridurre* SKH01 |
| path live SKH01 migliore su entrambi i lati | **forse**: argomento opposto, per *aumentarlo* |
| curva fee (SKH01 4x piu' sensibile) | no oggi: regola gia' decisa per il 1 agosto |
| rischio venue + tripwire | no: decisione dell'operatore gia' registrata |
Le due righe "forse" puntano in **versi opposti** e nessuna delle due si puo' dedurre a tavolino.
Il peso 75/25 fu confermato il **24/07** con la lente *hourly* — la stessa che il 26/07 e' risultata
pessimistica su entrambi i lati di SKH01 (uscite **+0.081** Sharpe FULL di book, ingressi **+0.048**).
Quindi la domanda e' legittima: **se SKH01 vale piu' di come e' stato pesato, 0.25 e' ancora giusto?**
## 1. La misura
Path live vero (`intra_entry=True`), 8 offset del sottocampione a priori, statistica = mediana
delle differenze **appaiate** per offset.
```
peso SKH Sh FULL med banda p10-p90 Sh HOLD med d vs 0.25 (appaiata)
0.00 1.289 [1.289, 1.289] 0.296 -0.322 ( 12%)
0.15 1.523 [1.425, 1.714] 0.705 -0.091 ( 12%)
0.20 1.575 [1.450, 1.825] 0.825 -0.038 ( 12%)
0.25 1.611 [1.463, 1.915] 0.928 +0.000 ( 0%) <- LIVE
0.30 1.632 [1.465, 1.982] 1.012 +0.022 ( 88%)
0.35 1.639 [1.455, 2.028] 1.078 +0.030 ( 88%)
0.40 1.634 [1.435, 2.055] 1.127 +0.025 ( 88%)
0.50 1.595 [1.374, 2.064] 1.188 -0.013 ( 38%)
```
**Argmax a w=0.35**, e in **88% degli offset** 0.30-0.40 batte 0.25: il segnale c'e' ed e' nel verso
previsto dalla correzione di lente. Ma:
* **plateau entro 0.05 di Sharpe = [0.25, 0.30, 0.35, 0.40, 0.50]** — il peso live e' dentro, quindi
la differenza col massimo non e' distinguibile;
* **`weights_tilt_null` FALLISCE** (`delta_insample −0.0026`, `gate_pass False`);
* e soprattutto la lettura che la mediana da sola nasconde ⬇.
## 2. Il motivo vero per non toccarlo: il guadagno e' tutto nella coda ALTA
```
peso p10 mediana p90
0.25 1.463 1.611 1.915
0.30 1.465 1.632 1.982
0.35 1.455 1.639 2.028
0.40 1.435 1.634 2.055
0.50 1.374 1.595 2.064
```
Il **p10 e' piatto fino a 0.30 e poi SCENDE**, mentre il p90 sale monotono. Alzare il peso di SKH01
non compra Sharpe: compra **dipendenza da quale ancora ti e' capitata**. La banda si allarga da
0.45 (a w=0.25) a 0.69 (a w=0.50).
E' coerente con il leave-one-out de-luckato dello stesso giorno — SKH01 e' lo sleeve con la
frazione d'ancora piu' grande da restituire — e con la curva fee, dove SKH01 e' **4x** piu'
sensibile di TP01. Tre misure indipendenti dicono la stessa cosa: **SKH01 e' la gamba fragile del
book, e 0.25 sta all'estremo prudente della regione robusta.**
**→ Nessun cambio. Il 75/25 e' confermato per la terza volta** (24/07 lente hourly, 26/07 path live
intra-bin, e ora il gate sui pesi).
## 3. La rivalutazione che conta non e' sulla strategia
Messi in fila, gli ordini di grandezza di oggi:
| leva | effetto misurato |
|---|---|
| ottimizzare il peso SKH01 (0.25 → 0.35) | **+0.030 Sharpe**, gate fallito |
| versare €250/mese invece di €0 | da **mai** a **16.2 anni** (mediana), P(entro 20a) 92% |
| perdere il conto Deribit (p=1%, 20 anni) | **−18%** di probabilita' di arrivare, e si riparte da zero |
**L'esito del piano non e' piu' governato dalla strategia.** Il book e' dentro il suo plateau su
ogni asse misurato; il margine residuo di ricerca vale centesimi di Sharpe, mentre i versamenti
valgono la differenza fra "mai" e "16 anni" e il rischio di venue vale il 18% del risultato.
Questo **non** dice che la ricerca sia finita — dice che la ricerca ha smesso di essere il vincolo
binding. Il vincolo binding oggi e' **capitale che entra** e **conto che non sparisce**.
## 4. Cio' che la rivalutazione NON cambia
* **La strategia resta quella**: TP01 0.75 / SKH01 0.25 su Deribit, cron orario, cap 1.0x.
* **I gate pre-registrati restano alle loro date** (1 ago fee, 27 set STATARB, 23 ott XSR01,
24 ott kill DVOLSPREAD, 24 gen 2027 decisione DVOLSPREAD). Rivalutare non vuol dire anticiparli:
anticipare un gate e' selezione sull'hold-out.
* **La decisione venue resta $20k**, con il tripwire a coprire la parte di rischio che ha una
finestra.
## 5. Regole trasferibili
1. **Una rivalutazione onesta parte dall'elenco di cosa CAMBIA una decisione**, non dal riassunto
di cosa si e' scoperto. Sei misure, una sola apriva qualcosa.
2. **Quando due correzioni puntano in versi opposti, si misura**: qui l'una (lente pessimistica)
spingeva ad alzare SKH01, l'altra (LOO de-luckato) ad abbassarlo, e a occhio si sarebbe potuto
argomentare qualunque cosa.
3. **Un argmax dentro un plateau non e' una decisione.** E la mediana da sola nascondeva il fatto
decisivo: il guadagno stava tutto nel p90, il p10 peggiorava.
4. **Quando le leve hanno ordini di grandezza diversi, dirlo.** +0.030 di Sharpe e "da mai a 16
anni" non sono la stessa categoria di scelta, e trattarle come tali e' il modo piu' comune di
lavorare molto senza cambiare niente.
@@ -0,0 +1,215 @@
# 2026-07-26 — Follow-up SKH01 "vol-targeted": il blocco non esisteva. E il ×0.6 era troppo severo del 31-34%.
**Richiesta:** *"fai il follow-up SKH01 vol-targeted"*.
**Script:** `r0726_skh_sigcache.py` (cache), `r0726_skh_live_book.py` (misura),
`r0726_deluck_factor.py` (decomposizione), `r0726_capwall_refresh.py` (muri ricalcolati).
**Test:** `tests/test_skh_live_book.py` (8). **Book, pesi, cron, config: INVARIATI.**
---
## 0. Il follow-up era mal diagnosticato
Portato avanti come bloccante per tre sessioni, con questa motivazione registrata in CLAUDE.md:
> il book ricalcolato sul path live e' bloccato da una **incompatibilita' di lenti** — il
> simulatore SKH01 compone per-trade a nozionale unitario, **lo sleeve e' vol-targeted**;
> combinarle darebbe un numero preciso e falso.
**Lo sleeve SKH01 non e' vol-targeted.** Tre verifiche indipendenti:
1. `_skyhook_returns` chiama `backtest_signals(..., leverage=1.0, position_size=1.0)` — che nel
suo docstring dice *"ogni trade muove capital di position_size \* leverage \* ret_netto"*:
compounding per-trade a nozionale pieno, **la stessa lente del simulatore**;
2. nel sorgente dello sleeve non compare `target_vol` / `vol_target` / `realized_vol`;
3. `r0702_anchor_skh01.sim_equity(mode='canonical')` riproduce `backtest_signals` con
**max|diff| = 0.0**.
Vol annualizzata realizzata per sleeve: SKH01 **20.7%**, TP01 12.2%, XS01 20.9%, GTAA01 5.4%.
Il 20.7% e' probabilmente cio' che aveva suggerito "vol-target 20%" — ma e' un **prodotto** della
strategia (uscite % asimmetriche + poco tempo a mercato), non un parametro. **SKH01 e' l'unica
delle cinque a NON essere vol-targeted**, ed e' il contrario di quanto si credeva.
**Lezione:** un blocco dichiarato va ri-verificato prima di costruirci sopra, non ereditato. Qui
il costo e' stato tre sessioni di follow-up rimandato per un ostacolo inesistente, e la verifica
che lo ha smontato e' durata due minuti.
---
## 1. La misura: ingressi live vs backtest, de-luckata
Due path identici in tutto (livelli, uscite intra-barra, cap `max_per_day`, fee, non-overlap)
tranne **quando si valuta l'ingresso**: LIVE = a ogni confine orario dentro il bin 230m (cio' che
il cron fa), BACKTEST = solo a chiusura di bin.
Riusa la macchina a stati fedele del 26/07 (`r0726_skh_partial_entry.simulate`). ⚠️ Trovato per
strada: **`simulate` non e' mai chiamata da `main()` di quello script** — i numeri headline del suo
diario vennero da una corsa ad hoc mai committata. Qui il driver e' committato.
**Costo:** la ricostruzione del segnale a ogni osservazione oraria costa ~9 min per (asset,
offset). Su 2 core con il cron live da non affamare, la griglia piena (23 offset) era fuori
portata → **sottocampione uniforme dichiarato a priori: 8 offset**, uno ogni 90m su [0,690).
E' un sottocampione per costo, non una selezione; la banda che ne esce ha 8 punti invece di 23.
**Sanity superato prima di tutto** (campionato sugli EVENTI, non sulla popolazione — lezione del
26/07): **120/120** bin con ingresso ricostruiti su entrambi gli asset.
```
off CANON ShBT ShLIVE dSharpe trade LIVE trade BT falsi
0 +1.446 +1.174 +1.204 +0.029 534 447 68
90 +1.043 +1.182 +1.194 +0.011 538 472 67
180 +1.467 +1.505 +1.698 +0.193 544 469 60
270 +1.231 +1.199 +1.205 +0.006 605 477 179
360 +0.761 +1.069 +1.397 +0.328 570 478 109
450 +0.921 +0.917 +2.025 +1.108 530 484 36
540 +0.751 +0.374 +0.445 +0.071 531 411 138
630 +0.871 +0.991 +1.144 +0.154 460 412 47
SLEEVE (50/50) mediana appaiata +0.112 positive 8/8 banda [+0.006, +1.108]
PER-ASSET mediana appaiata +0.097 positive 13/16 banda [-0.170, +1.086]
```
**Il numero del 26/07 era ~4x troppo grande.** Confrontando like-with-like — quel diario citava la
mediana **per-asset** — si passa da **+0.38 su 3 offset** a **+0.097 su 8**, e da "6/6 non
negativi" a **13/16**. Il segno regge, la taglia no: ennesimo Δ misurato su poche ancore che ne
eredita la fortuna. L'outlier a offset 450 (+1.108) mostra perche' la statistica e' la mediana.
⚠️ Le due righe della tabella **non sono la stessa grandezza** e vanno tenute separate: nel BOOK
entra lo sleeve 50/50, dove la diversificazione BTC/ETH cambia il denominatore.
### A livello di book
```
dSharpe FULL mediana +0.048 p10 -0.015 p90 +0.677 >0 in 79.3%
dSharpe HOLD-OUT mediana +0.051 p10 -0.589 p90 +0.721 >0 in 51.2%
d drift annuo mediana +0.731pp p10 +0.044pp p90 +6.800pp >0 in 100.0%
```
Lo Sharpe e' quasi una monetina, **il drift e' positivo nel 100% delle estrazioni**. Meccanismo:
l'ingresso intra-bin prende un prezzo migliore (piu' drift) ma i falsi ingressi aggiungono churn
(530-605 trade live contro 411-484) → vol e ritorno salgono insieme e lo Sharpe non si muove.
Per la domanda del ×0.6, che e' **sul drift**, il numero rilevante e' +0.73pp.
---
## 2. Un'ipotesi mia, nata e morta nella stessa sessione
Guardando i primi **due** offset avevo notato che il canonico oscillava di 0.40 mentre i path del
simulatore stavano fermi, e ne avevo tratto un'ipotesi: la *grid timing-luck* di SKH01 (audit
02/07: 93-98° pctl, "spike non plateau", gate DD<30% che fallisce in 15/23 offset) sarebbe stata
in buona parte un **artefatto della lente a chiusura-di-bin**, non una fragilita' della strategia
live — che valuta ogni ora e non e' ancorata al confine del bin.
**Refutata.** Dispersione dello Sharpe fra gli 8 offset:
```
path min mediana max range std
CANONICO (chiusura bin) +0.751 +0.982 +1.467 0.716 0.289
BT-sim (chiusura bin) +0.374 +1.122 +1.505 1.131 0.325
LIVE-sim (intra-bin) +0.445 +1.204 +2.025 1.580 0.459
rapporto di dispersione LIVE/CANONICO: 1.59x
```
Il path live e' **piu'** disperso fra le fasi della griglia, non meno. **L'audit del 02/07 resta
valido com'e':** la timing-luck di SKH01 e' della strategia, non della lente. L'ipotesi e' nata su
2 offset, si e' incrinata a 4 (1.24x) e si e' chiusa a 8 (1.59x) — e la direzione dell'errore era
sempre la stessa, il che e' il motivo per cui 2 punti non bastano mai.
---
## 3. Il ×0.6 decomposto, misurato, corretto
Il fattore taglia il **drift** (`b - 0.4*mean(b)`) ed era applicato **sopra** la lente `hourly`,
cioe' sopra un modello del live gia' pessimistico. Mescolava due cose separabili.
**(a) Fortuna d'ancora sul drift** — misurata sullo spazio congiunto:
| | canonico | pctl | MEDIANA | p10-p90 |
|---|---|---|---|---|
| book 5-sleeve, drift | 17.33% | 96.0° | **15.15%** | [13.88, 16.49] |
| book 5-sleeve, CAGR | 18.56% | 96.0° | **16.00%** | [14.55, 17.56] |
| book LIVE 75/25, drift | 19.27% | 93.8° | **17.16%** | [15.75, 18.67] |
→ fattore d'ancora **×0.874** (5-sleeve) / **×0.890** (book live). La **vol e' invariata** fra le
ancore (7.80% → 7.76%): la fortuna sta tutta nel drift, non nel rischio.
**(b) Degradazione del path live** — non-negativa su tutto cio' che e' stato misurato:
uscite SKH01 **+0.081** Sharpe di book (23/23 offset); ingressi SKH01 **+0.73pp** di drift
(100% delle estrazioni); TP01 barra parziale trascurabile (24 ancore).
**Il ×0.6 implicava un residuo ×0.687 attribuito al live oltre l'ancora.** Nessuna misura del
progetto lo sostiene. Il sospetto gia' registrato in CLAUDE.md — *"il ×0.6 sopra il path live
rischia di contare DUE VOLTE la degradazione SKH01"* — e' **confermato quantitativamente**.
> **FATTORE ONESTO: ×0.87 – ×0.91** (5-sleeve) / **≥×0.89** (book live), contro il ×0.60 in uso.
> **Troppo severo del 31-34%.**
La componente uscite spingerebbe oltre, ma e' misurata in Sharpe e non in drift: non convertita,
per non inventare precisione. Quindi il limite superiore e' esso stesso conservativo.
---
## 4. Cosa cambia nei muri di capitale (`r0726_capwall_refresh.py`)
Stessa macchineria del 25/07 (`book_series`, `survival`, `_boot_paths` importati, non riscritti).
```
fattore leva SWR-20a PERPETUA capitale
×0.60 (25/07, a occhio) 1.00 7.36% 6.00% $494,758
×0.60 (25/07, a occhio) 1.50 8.16% 8.11% $366,300
×0.89 (26/07, ancora MISURATA) 1.00 10.94% 10.91% $272,061
×0.89 (26/07, ancora MISURATA) 1.50 13.72% 14.87% $199,625
×1.00 (nessun haircut) 1.00 12.48% 12.72% $233,330
```
**Il muro per 50 EUR/g scende del ~45%: da ~$495k a ~$272k** (leva 1.0), e il valore vero sta fra
la riga ×0.89 e la riga ×1.00 perche' ×0.89 e' un limite inferiore.
**Cio' che NON cambia:** $272k restano **~453x** il conto di oggi. La conclusione strutturale del
25/07 — *i 600 euro come CAPITALE sono refutati, come BIGLIETTO (prop) no* — regge intatta.
Cambia la taglia dell'errore, e cambia che il numero e' misurato invece che scelto.
Rendita sul conto attuale: EUR 0.12/g (×0.6) → **EUR 0.18/g** (×0.89). A questa taglia sono
centesimi: **il fattore conta per il MURO e per le soglie prop, non per il conto di oggi.**
### La traiettoria — il fattore agisce DUE volte
Correggere il fattore alza il drift (si accumula prima) **e** abbassa il bersaglio (serve meno
capitale). I due effetti pesano quasi uguale, quindi vanno separati invece che sommati alla cieca:
```
dep./mese ×0.60 muro $495k ×0.89 muro $495k ×0.89 muro $272k
(25/07) (solo drift) (26/07)
€0 mai mai mai
€250 22.4a (8% <20a) 19.6a (53%) 16.2a (91%)
€500 19.6a (48%) 15.7a (94%) 12.4a (100%)
€1000 14.8a (95%) 12.0a (100%) 9.0a (100%)
€2000 10.0a (100%) 8.5a (100%) 6.0a (100%)
```
✅ **Validazione indipendente:** la colonna ×0.60 riproduce **esattamente** i numeri pubblicati il
25/07 (€500/m → 19.6a, €1000/m → 14.8a). La replica e' fedele, quindi le altre due colonne sono
confrontabili con quelle.
A €500/mese: dei ~7 anni guadagnati, ~4 vengono dal drift e ~3 dal bersaglio piu' basso.
⚠️ **Cio' che il fattore NON cambia:** senza depositi il capitale-rendita **non si raggiunge mai**
(0% dei path a 20 anni, a ogni fattore). L'accumulo viene dai versamenti, non dal rendimento —
correggere il ×0.6 accorcia i tempi, non crea una via che non c'era. E la mediana e' una mediana:
meta' dei path arriva dopo, e una quota non arriva affatto.
---
## 5. Regole trasferibili
1. **Un blocco dichiarato e' un'ipotesi, non un fatto.** Ri-verificarlo prima di costruirci sopra
o di rimandare: qui tre sessioni di attesa contro due minuti di verifica.
2. **Un Δ su poche ancore eredita la loro fortuna, sempre** — terza occorrenza in due giorni
(recupero on-book, degrado d'esecuzione, e ora gli ingressi: +0.38 → +0.097).
3. **Quando un fattore correttivo e' scelto a occhio, decomporlo prima di rifiutarlo o accettarlo.**
Il ×0.6 non era "sbagliato": era due fattori moltiplicati insieme, uno dei quali contato due volte.
4. **Sharpe e drift rispondono a cose diverse.** L'effetto ingressi e' una monetina sullo Sharpe e
certo sul drift: chiedersi *quale* delle due grandezze entra nella decisione prima di misurare.
5. **Due punti non fanno una tendenza** — nemmeno quando la meccanica sembra spiegarla. L'ipotesi
sulla dispersione era plausibile e sbagliata, e il costo di verificarla era basso.
+202
View File
@@ -0,0 +1,202 @@
# 2026-07-26 — SKH01: gli INGRESSI su barra 230m PARZIALE. Misura dedicata.
**Richiesta:** *"fai la misura sugli ingressi con barra parziale"*.
**Follow-up dichiarato che chiude** (registrato in CLAUDE.md stamattina, misura T1):
> la stessa barra parziale tocca anche gli INGRESSI — `ent[n-1]` puo' venire da un breakout non
> confermato a fine barra → se evapora, il book apre e richiude. Su 112 bin campionati:
> disaccordo parziale-vs-completa in 1 (~1%), ma con sole 3 entry nel campione la taglia non e'
> stimabile … serve una misura dedicata prima di decidere il verso.
**Script:** `scripts/research/r0726_skh_partial_entry.py` — **test:** `tests/test_skh_partial_entry.py` (8).
**Book, pesi, cron: INVARIATI.** Nessuna decisione di allocazione cambia.
---
## 0. Il fatto meccanico da cui parte tutto
`resample_5m(..., origin="epoch")` **non scarta il bin in corso**. Il cron gira a ore piene; una
barra SKH01 dura 230 minuti. Quindi a ogni giro il live valuta il segnale su una barra 230m che, in
media, e' **completa a meta'**. Il backtest invece valuta solo alle chiusure dei bin.
Stamattina ho misurato il lato **uscite** di questo fatto (e ho scoperto che il live esce
gia' intra-barra, quindi le uscite erano modellate troppo pessimisticamente). Restava il lato
**ingressi**, che e' l'opposto: il live puo' entrare su un breakout che a fine barra **non c'e' piu'**.
La domanda non e' "succede?" (succede per costruzione). E' **di che segno e' il saldo**.
---
## 1. Come si misura senza misurare la propria aritmetica
Il rischio di questa misura non e' sbagliare un numero: e' costruire una ricostruzione rotta e non
accorgersene. `signal_at(obs_ms, ...)` ricostruisce il segnale che il live *avrebbe visto* a un
istante arbitrario: storia completa fino a li' + barra parziale, passata per i **veri**
`htf_features` / `merge_htf_to_ltf` / `atr` su una finestra di 200 barre HTF.
**Due errori catturati in sessione, entrambi del tipo che passa i test se i test sono pigri:**
**(a) Self-check vacuo + bug di confine.** La prima versione stampava "BTC 80/80 OK". Era falso su
due livelli insieme. `obs_ms // MS_LTF` a un'osservazione *alla chiusura* del bin cadeva nel bin
**successivo**, ancora vuoto → aggregato vuoto → `signal_at` ritornava `None` → segnale 0. E il
check campionava bin **a caso**: gli ingressi sono ~2% dei bin, quindi confrontava **zeri con zeri**
e passava comunque. Le uniche 2 divergenze su ETH erano gli unici 2 bin con un segnale vero — cioe'
il campione stava gia' dicendo che era rotto al 100%, non al 2.5%.
Fix: `((obs_ms - 1) // MS_LTF) * MS_LTF`, e `selfcheck` riscritta per testare **esplicitamente i bin
CON ingresso**. Esito corretto: **120/120 su BTC, 120/120 su ETH**. I "falsi allarmi" sui bin flat
(17 BTC / 22 ETH su 400) sono bin dove il segnale c'e' ma il backtest lo sopprime col cap
`max_per_day=1` — atteso, non un difetto.
> **Regola:** un self-check su eventi rari va campionato **sugli eventi**, non sulla popolazione.
> Un check che confronta zeri con zeri ha potenza zero e sembra un successo.
**(b) Sovrastima ~20× dei falsi ingressi.** La prima scansione contava **1361** falsi ingressi
(204% in piu' dei trade veri, costo stimato −3.03%/anno di sleeve). Numero **sbagliato**: `signal_at`
riporta il compositore **grezzo**, mentre il live applica anche il cap `max_per_day=1` e il
non-overlap. La spia era nella sezione D della stessa stampa — **305 giorni** con un falso ingresso a
fronte di 663 "eventi": con cap 1/giorno non possono essere eventi indipendenti. Riscritta come
**macchina a stati sequenziale** fedele al live: i falsi ingressi veri sono **~5/anno/asset**.
> **Regola:** un conteggio di eventi su un segnale grezzo non e' un conteggio di **trade**. Prima di
> monetizzare un evento, farlo passare per gli stessi filtri che ha il live.
---
## 2. Il risultato
Due path identici in tutto (stessi livelli SKH01_V2_DD pct-asimmetrici, stesse uscite intra-barra,
stesso cap, stesse fee 0.10% RT) tranne **quando si valuta l'ingresso**:
- **LIVE** — segnale valutato a ogni confine orario interno al bin (= cio' che fa il cron oggi);
- **BACKTEST** — segnale valutato solo alle chiusure dei bin (= cio' che il backtest assume).
| asset | offset | path | equity× | trade | falsi | Sharpe |
|---|---:|---|---:|---:|---:|---:|
| BTC | 0 | LIVE | 6.58 | 249 | 29 | **1.07** |
| BTC | 0 | BACKTEST | 6.28 | 211 | 0 | 1.08 |
| ETH | 0 | LIVE | 6.09 | 285 | 39 | **0.95** |
| ETH | 0 | BACKTEST | 5.44 | 236 | 0 | 0.91 |
| BTC | 230 | LIVE | 27.10 | 254 | 20 | **1.63** |
| BTC | 230 | BACKTEST | 8.32 | 226 | 0 | 1.19 |
| ETH | 230 | LIVE | 11.47 | 283 | 34 | **1.20** |
| ETH | 230 | BACKTEST | 5.08 | 241 | 0 | 0.88 |
| BTC | 460 | LIVE | 17.53 | 258 | 18 | **1.44** |
| BTC | 460 | BACKTEST | 4.29 | 236 | 0 | 0.85 |
| ETH | 460 | LIVE | 72.87 | 281 | 17 | **1.93** |
| ETH | 460 | BACKTEST | 6.12 | 253 | 0 | 0.95 |
**ΔSharpe (live − backtest): −0.01, +0.04, +0.44, +0.32, +0.59, +0.98 → 6/6 non negativi,
mediana +0.38.**
⚠️ **I multipli d'equity NON sono ritorni dello sleeve.** Questo simulatore compone per-trade senza
vol-target, senza pesi di book, a nozionale unitario. Servono solo a confrontare due path che
differiscono per una cosa sola. La lente onesta qui e' lo **Sharpe** (che non compone), e i multipli
sono la sua integrazione su 7 anni.
**Split in-sample / hold-out (offset 0, dove ho le serie):**
| asset | path | FULL | IS | HOLD |
|---|---|---:|---:|---:|
| BTC | LIVE | 1.07 | 1.07 | **1.12** |
| BTC | BACKTEST | 1.08 | 1.15 | 0.71 |
| ETH | LIVE | 0.95 | 0.93 | 1.03 |
| ETH | BACKTEST | 0.91 | 0.88 | 1.03 |
All'offset 0 il FULL e' un pareggio ma l'hold-out favorisce il live su BTC (**+0.41**) e pareggia su
ETH. Coerente col fatto noto che **offset 0 e' l'ancora fortunata del backtest** (93-98° pctl sui 23
offset a priori): e' esattamente l'ancora dove il path canonico ha meno da guadagnare.
---
## 2-bis. I due controlli che il risultato doveva superare
Un +0.98 di Sharpe e un 72.87× di equity sono il tipo di numero che va attaccato prima di crederci.
**(a) E' concentrato in pochi giorni?** No — e il controllo va nella direzione **opposta** al sospetto:
| offset 460 | ret/trade | win rate | top-5 gg = % del log-equity | equity senza i top-5 |
|---|---:|---:|---:|---:|
| ETH LIVE | +1.878% | 48.6% | **16.7%** | 35.64× |
| ETH BACKTEST | +0.946% | 40.6% | **39.5%** | 2.99× |
| BTC LIVE | +1.307% | 46.1% | **22.5%** | 9.20× |
| BTC BACKTEST | +0.801% | 44.0% | **38.3%** | 2.46× |
Togliendo i 5 giorni migliori il divario si **allarga** (ETH 35.6× vs 3.0×). E' il **backtest** il
path concentrato (~39% del log-equity in 5 giorni). La differenza vive nella **distribuzione**:
ret/trade circa doppio e win rate +8pp (ETH) / +2pp (BTC).
**(b) C'e' look-ahead intra-bin?** E' il rischio serio, perche' il self-check valida la ricostruzione
solo **a chiusura di bin** — un leak che esistesse solo intra-bin gli sarebbe **invisibile per
costruzione**. Test decisivo: ricalcolare ogni osservazione intra-bin con la serie 5m **troncata**
alle sole barre gia' chiuse a `obs_ms`. Se il futuro contasse, la risposta cambierebbe.
> **BTC 145/145 e ETH 144/144 osservazioni intra-bin: risposta identica dopo il troncamento**, e il
> prezzo d'ingresso coincide sempre con l'ultimo close 5m gia' chiuso (241/241).
Cablato come test permanente (`test_nessun_lookahead_intra_bin`).
---
## 3. Il meccanismo (perche' vince, e perche' non e' una sorpresa)
Sezione B della scansione: quando il segnale c'e' **anche** a fine bin, il live entra in anticipo di
**180 minuti mediani** a un prezzo **0.25-0.26% migliore** in media (0.11-0.12% mediano).
SKH01 e' un **Donchian breakout**. Aspettare fino a 230 minuti la chiusura del bin significa, sui
casi che confermano, **pagare il pezzo di movimento gia' avvenuto**. Il costo di quell'attesa e'
sistematico; il beneficio (evitare i breakout che evaporano) e' reale ma raro — **~5 eventi/anno/asset**
dopo i filtri del live, perche' il cap `max_per_day=1` e il non-overlap assorbono quasi tutto.
E l'effetto si amplifica sui **livelli**, che sono percentuali sull'ingresso (long sl4%/tp10%, short
sl2%/tp8%). Entrare 0.26% piu' avanti nella direzione del breakout sposta TP **e** SL dello stesso
0.26% — ma il TP e' a 4-10% e lo SL a 2-4%: la stessa quantita' assoluta vale il **6-13% della
distanza dallo SL** contro il 2.6-3.3% della distanza dal TP. Il vantaggio d'ingresso e' quindi
**asimmetrico a favore della sopravvivenza del trade**: e' il canale che spiega il win rate piu' alto,
non un giorno fortunato.
**La cannibalizzazione del cap non morde:** ingressi veri bloccati da un falso ingresso = **2 su BTC
(0.6%) e 3 su ETH (0.9%)**.
---
## 4. Verdetto
**L'ingresso su barra parziale NON e' un difetto da correggere. Il verso del follow-up e': lasciarlo.**
Ma la lettura che conta e' la seconda:
> **Il live e il backtest stanno girando due strategie diverse, e la differenza non e' neutra.**
Tutti i numeri di SKH01 nel progetto — Sharpe standalone, il peso 25% del book Deribit, l'audit
d'ancora del 02/07, la conferma di peso/cadenza del 24/07 — sono calcolati sul path **a chiusura di
bin**, che non e' quello che gira. La misura dice che il path reale e' **≥** in 6/6 coppie
asset×offset. Insieme alla misura di stamattina sulle uscite (il live esce gia' intra-barra, +0.081
Sharpe FULL di book sottostimato), **il path live di SKH01 e' stato modellato in modo
sistematicamente pessimistico su entrambi i lati**.
**Cosa NON concludo.** Che "l'ingresso intra-bin e' un miglioramento validato". Non ha passato
nessuno dei gate del progetto: e' stato *misurato* sugli stessi 7 anni su cui SKH01 e' stato
selezionato e affinato, non e' passato per `study_family_honest` ne' per un deflated-Sharpe, e la
taglia varia molto fra ancore (da −0.01 a +0.98). Promuoverlo a meccanismo canonico sarebbe
esattamente la selezione-sull'hold-out che il progetto ha gia' codificato come gate.
E non serve promuoverlo: **e' gia' cio' che il live fa**. L'azione richiesta e' l'opposta — smettere
di trattare il numero del backtest come l'aspettativa del live, e non "riparare" il live per farlo
somigliare a un backtest peggiore.
**Nessun cambio a book, pesi, cron, config.**
---
## 5. Regole nuove
1. **Un self-check su eventi rari si campiona sugli EVENTI.** Confrontare zeri con zeri ha potenza
zero e passa. (Costo: un "80/80 OK" completamente falso.)
2. **Un conteggio di eventi su segnale grezzo non e' un conteggio di trade.** I filtri del live
(cap giornaliero, non-overlap) vanno applicati prima di monetizzare qualsiasi evento. (Costo:
sovrastima 20× e un costo inventato di −3%/anno di sleeve.)
3. **Quando live e backtest differiscono, misurare il DELTA con machinery identica** — un solo grado
di liberta' cambiato — e quotarlo sulla **banda d'ancora**, non su un'ancora sola. All'ancora
canonica questo effetto vale ~0; sulla banda vale +0.38 mediano. Su un'ancora sola avrei
concluso "irrilevante".
@@ -0,0 +1,155 @@
# 2026-07-26 — T1 nel live: il fix richiesto NON va fatto, e il perché è una correzione di modello
**Richiesta:** implementare nel live il fix T1 (TP di SKH01 come limit resting on-book).
**Esito: NON implementato**, con i numeri sotto. **Implementato invece** ciò che le misure
sostengono: la sorveglianza della freschezza del feed 5m di SKH01, e la correzione dei docstring
che hanno causato tre settimane di misure sbagliate.
**File toccati (produzione):** `src/live/livefeed.py`, `src/live/book.py`, `src/portfolio/sleeves.py`
(solo docstring), `scripts/live/book_execute.py`, `config/live.json`.
**Test:** `tests/test_skh_feed_freshness.py` (11 casi) · suite **266 verdi**.
**Strategia, pesi, cadenza del cron: INVARIATI.** Nessun ordine inviato.
---
## 1. Cosa ho trovato leggendo il codice di produzione
Il fix T1 nasceva da una simulazione in cui SKH01 esce per conto suo. Il live non funziona così, e
il vincolo era scritto nel codice:
> `book.py`: *«gli exit sono SOFTWARE (no bracket on-book per SKH, sennò chiuderebbero anche la
> quota TP01)»*
TP01 e SKH01 tradano **lo stesso strumento** e Deribit tiene **una sola posizione netta**. Un
ordine on-book al livello di TP di SKH chiuderebbe una fetta della posizione netta, che è per il
75% di TP01. Ho quindi misurato i due ostacoli invece di assumerli:
**(A) Compatibilità di segno — risolvibile.** Un ordine reduce-only può muovere la posizione solo
verso lo zero. Se SKH è short mentre il netto è long (perché TP01 pesa di più), chiudere lo short
significa *aumentare* il netto: non esprimibile. Frequenza sui trade che escono in TP — gli unici
che il fix tocca: **97% compatibili** (SKH long 100%, SKH short 94%). Il 3% si sarebbe potuto
saltare con fallback all'uscita software.
**(B) Divergenza modello/live — sembrava bloccante.** Se il limit riempie a metà barra ma il
modello non "vede" l'uscita, il cron successivo ricalcola il target includendo ancora la quota SKH
e **ricompra ciò che il TP ha appena chiuso**. Misurato assumendo la rilevazione a fine barra 230m:
ritardo mediano **115 min**, p90 **210**, e nel **70% dei TP almeno un cron gira nella finestra**
(mediana 1.9 cron, p90 3.5).
## 2. …e poi ho scoperto che il problema (B) non esiste
Il problema (B) presuppone che il modello veda le uscite solo a barra 230m chiusa. È ciò che dicono
i docstring:
> `sleeves._skyhook_positions`: *«fino all'ultima barra 230m chiusa. Causale: usa solo barre chiuse»*
> `book.py`: *«latenza fino alla chiusura della barra 230m corrente»*
**Sono falsi.** `resample_5m` **non scarta il bin in corso** — aggrega le barre 5m che ci sono
finora — e il ciclo di `_skyhook_positions` itera fino a `n-1`, quindi valuta gli hit di SL/TP
anche sul bin **parziale**, col suo high/low corrente. Verificato sul feed reale: l'ultimo bin 230m
conteneva **21 barre 5m su 46** (105 minuti su 230).
Quindi il live rileva il tocco **entro il primo cron dopo il tocco (~1h)**, non a fine barra. E non
è look-ahead: il livello è fissato all'ingresso da barre chiuse, e osservare che il prezzo l'ha già
toccato è esattamente ciò che fa qualunque stop reale.
### La conseguenza: il path live era modellato male da tre settimane
La lente `hourly` — usata dall'audit del 02/07, dal follow-up del 24/07 e dal mio stesso T1 di
stamattina — assume la rilevazione a fine barra. Il modello fedele è un altro (`fastdetect`:
rilevazione intra-barra a 5m, uscita a mercato al primo cron successivo). Sulla banda appaiata dei
23 offset, **relativo al path live come veniva modellato**:
| modalità | ΔFULL mediana [min,max] | ΔHOLD mediana | offset migliorati (FULL) |
|---|---|---|---|
| **`fastdetect` = il live VERO** | **+0.081** [+0.00,+0.14] | +0.039 | **23/23** |
| `canonical` (tetto teorico del backtest) | +0.054 [−0.05,+0.12] | +0.099 | — |
| `onbook_tp` (**il fix richiesto**) | +0.054 [−0.03,+0.07] | +0.061 | 19/23 |
| `onbook` (TP+SL on-book) | +0.024 [−0.07,+0.11] | +0.031 | 17/23 |
Due letture, entrambe importanti:
1. **Il "−0.35 di degrado del path live" è in gran parte un artefatto di modello**, sopra
l'artefatto di ancora già trovato stamattina. Sul FULL il live vero sta **sopra** il canonical.
2. **Il fix richiesto sarebbe un declassamento**: +0.054 contro i +0.081 che il live già fa — e in
cambio si porterebbero in un percorso con soldi veri ordini parziali sul netto, un 3% di casi
non esprimibili, e la riconciliazione fra fill del broker e stato del modello.
**Per questo non l'ho implementato.** Non è una difficoltà tecnica: è che la misura, fatta sulla
lente giusta, dice che peggiorerebbe.
---
## 3. Il problema vero, trovato per strada
`fresh_5m` è il pezzo che tiene bassa la latenza d'uscita. E **fallisce in silenzio**:
```python
try:
tail = _fetch_recent_5m(sym, lookback_days)
except Exception:
return base # ← nessun log, nessun errore, nessuna traccia
```
`_fetch_recent_5m` inghiotte a sua volta le eccezioni (`except Exception: break`). Se il fetch
pubblico Deribit non risponde, il segnale SKH gira sul **feed certificato**, che il cron ricostruisce
**una volta al giorno**. La latenza d'uscita passa da **~1 ora a ~1 giorno**, e niente lo segnala:
il conto è online, la posizione è leggibile, il gate di staleness guarda il feed *di TP01* — nessuno
dei controlli esistenti scatta. È lo stesso schema del feed-freeze del 2026-07-14, su un altro feed.
E conta esattamente quanto il resto di questo lavoro: la latenza d'uscita **è** dove vive la qualità
del path live.
### Cosa ho cablato
- **`livefeed.feed_age_minutes(df5)`** — pura, testabile senza rete: età in minuti dell'ultima barra
5m, misurata dalla sua **chiusura**, con `None` per input non interpretabili (`None` = "non
misurata", da trattare come sospetta: se tornasse `0.0` sembrerebbe fresca) e clamp a zero sugli
skew d'orologio.
- **`book.book_report(live_feed=True)`** avvolge il loader per misurare la freschezza del feed
**effettivamente usato**, e la espone come `skh_feed_age_min` (massimo fra gli asset: se anche uno
solo è stantio, il netto è sospetto).
- **`book_execute`** stampa lo stato e **allerta su Telegram** sopra `skh_feed_max_age_min` (30 min,
in `config/live.json`).
**Scelta dichiarata: allerta, NON blocca.** Bloccare fermerebbe anche il ribilancio di TP01 — sono
nettati sullo stesso strumento — per un guasto di rete; e forzare SKH a flat chiuderebbe posizioni
buone su un glitch. Non ho evidenza su quale politica di blocco sia giusta, quindi la decisione
resta all'operatore, informato.
### Docstring corretti
I due docstring falsi sono stati corretti *sul posto*, con la misura e il perché. Erano loro a
sostenere la catena di ragionamenti sbagliata, ed erano la cosa più economica da riparare.
---
## 4. Follow-up dichiarato, non risolto
La stessa barra parziale che migliora le **uscite** tocca anche gli **ingressi**: `ent[n-1]` può
venire da un bin parziale, cioè da un breakout non ancora confermato a fine barra. Se il segnale
evapora, il book apre e richiude — churn puro.
Misurato su **112 bin campionati**: entry sulla barra completa in 3, sulla parziale in 2,
**disaccordo in 1 (~1% dei bin)**. Ma con sole 3 entry nel campione la **taglia dell'effetto non è
stimabile**: so che esiste, non so quanto pesa. Non l'ho toccato — a differenza delle uscite, qui
il comportamento del live **diverge dal backtest in modo sostanziale** (entra su un segnale che il
backtest non avrebbe visto), e sistemarlo è un cambio di strategia, non di strumentazione.
Serve una misura dedicata prima di decidere in che verso.
---
## 5. Lezioni
1. **Prima di implementare una raccomandazione, leggere il codice che dovrà ospitarla.** T1 era
corretto sul suo modello e inapplicabile sull'architettura reale — e leggendo quel codice è
saltato fuori che il modello stesso era sbagliato. La ricerca del mattino non lo poteva sapere:
simulava lo sleeve, non il book nettato.
2. **Un docstring falso costa più di un bug**, perché nessun test lo cattura e tutti ci ragionano
sopra. Questi due hanno guidato tre analisi (02/07, 24/07, T1) verso una latenza che il codice
non aveva.
3. **Un fallback silenzioso è un guasto silenzioso.** `fresh_5m` fa la cosa giusta (mai operare a
cieco) ma non dice di averla fatta: la scelta giusta è tenere il fallback **e** misurarlo.
4. Terzo caso in due giorni in cui **il numero di partenza era peggio di com'era stato scritto**:
la fortuna d'ancora sul degrado (stamattina), la lente `hourly` (qui), il wick indipendente
(ieri). Ogni volta il difetto stava nella **lente**, non nella strategia.
+187
View File
@@ -0,0 +1,187 @@
# 2026-07-26 — "Tutto su Deribit?" — il rischio di venue, mai prezzato in 2 mesi di progetto
**Richiesta:** *"tutto su deribit?"* (dopo il ricalcolo dei muri di capitale e della traiettoria).
**Script:** `r0726_venue_risk.py` + aggiunte a `r0726_capwall_refresh.py` (drill-down €250/mese,
`solve_deposit`). **Test:** `tests/test_venue_risk.py` (13). **Book, pesi, cron: INVARIATI.**
---
## 0. La domanda ha scoperto un buco, non un dettaglio
Il progetto ha prezzato con ossessione: fee a 0.10% RT, slippage, min-order $5, pavimento fisso
IB, haircut small-cap, fortuna d'ancora su 4 sleeve, degrado d'esecuzione su entrambi i lati di
SKH01, look-ahead, backfill sintetico, split non aggiustati.
**Non ha mai prezzato la probabilita' che l'exchange sparisca col saldo dentro.** Per un piano di
rendita a 10-20 anni su un exchange offshore e' un rischio di prim'ordine, e — punto che rende il
buco piu' grave — **non e' diversificabile con gli sleeve**: TP01, SKH01 e VRP01 stanno tutti
sullo stesso conto Deribit. Tre sleeve quasi-ortogonali sui ritorni, **perfettamente correlati sul
fallimento del venue**.
## 0-bis. E un limite nei muri che avevo appena pubblicato
`r0725_capcurve.book_series` gira a **`alloc=$600`** col book a **2 sleeve** (TP01+SKH01 75/25).
Portare quella serie fino a $272.061 assume due cose mai dichiarate:
(a) che a $272k si giri ancora il book da $600 — falso: a ~$3k si accende GTAA01, a ~$5k XSR01,
a ~$20k XS01, e il book a 5 sleeve ha Sharpe piu' alto → **il muro vero e' piu' basso**;
(b) che tutto il capitale stia su **un solo exchange** per 10-20 anni — cioe' i muri
**assumevano gia' "tutto su Deribit"**, senza dirlo.
---
## 1. La misura
Monte Carlo dell'accumulo (da $600, €250/mese, 20 anni, bersaglio $272.061, de-luck ×0.89) con
**jump di venue**: ogni venue fallisce indipendentemente con probabilita' annua `p`, e in quel caso
la sua quota di capitale va a **zero**; i depositi futuri si ripartiscono fra i superstiti.
* **CONC** = tutto su Deribit (TP01+SKH01) — l'ipotesi implicita dei muri
* **SPLIT** = Deribit 65% / Hyperliquid 15% (XS01) / IB 20% (GTAA01) — il book attivo mappato sui
venue dove gira davvero
Bersaglio **identico** nei due casi, per confrontabilita': lo SPLIT ha in realta' Sharpe piu' alto
e quindi muro piu' basso → **il confronto e' conservativo CONTRO lo split**.
```
p annua P(arrivare a $272k in 20a) P(perso TUTTO)
CONC SPLIT diff CONC SPLIT
0.0% 95% 96% +1% 0% 0%
0.5% 87% 90% +2% 10% 0%
1.0% 81% 83% +3% 18% 0%
2.0% 69% 71% +3% 34% 4%
5.0% 42% 45% +3% 64% 27%
```
Capitale mediano a 20 anni, CONC: $544k (p=0) → $475k (p=1%) → **$0 (p=5%)**.
### La colonna che conta non e' la prima
Sulla probabilita' di **arrivare** al bersaglio la concentrazione costa quasi nulla (1-3pp): se il
venue regge, ci arrivi. Il danno e' tutto sulla **rovina**: a p=1%/anno la concentrazione porta
**18% di probabilita' di perdere tutto** contro **0%**; a p=5% il capitale mediano e' azzerato.
Il motivo e' strutturale: **con un solo conto "almeno un fallimento" coincide con "perso tutto"**.
Nello split un fallimento costa una frazione.
⚠️ Controintuitivo ma corretto: **lo SPLIT viene colpito PIU' spesso** (26% vs 10% a p=0.5%: ha
tre venue che possono fallire) ed e' irrilevante. Conta quanto perdi, non quante volte sei toccato.
Una metrica "P(almeno un incidente)" avrebbe classificato lo split come il piu' rischioso.
---
## 2. Tre onesta' obbligatorie
1. **`p` NON e' stimato.** Il record degli exchange crypto dice che non e' trascurabile, ma
metterci una cifra precisa qui sarebbe inventarla. La tabella e' una **sensibilita'**: la scelta
di `p` resta dell'operatore e va dichiarata insieme al risultato.
2. **I fallimenti sono assunti INDIPENDENTI**, e per la coppia Deribit-Hyperliquid e' ottimistico:
in una crisi sistemica crypto possono andare insieme. **La parte solida dello split e' IB**, che
e' un'altra classe di rischio (broker regolamentato), non un terzo exchange crypto.
3. **Oggi lo split non e' una scelta.** GTAA01 richiede $3k (`GTAA_MIN_CAPITAL`), XS01 ~$20k. A
$600 la concentrazione e' **forzata**, non scelta.
---
## 3. Conclusione: la domanda ha una data, non una risposta secca
**No, non tutto su Deribit — ma non da oggi.**
| soglia | cosa si sblocca | effetto sul rischio di venue |
|---|---|---|
| oggi ($600) | niente | concentrazione **forzata** |
| **~$3k** | GTAA01 su IB | **prima riduzione vera**: 20-25% fuori dal rischio-exchange, su un broker regolamentato |
| ~$20k | XS01 su Hyperliquid | poco: e' ancora crypto, fallimenti plausibilmente correlati |
### La convergenza che rafforza una decisione gia' presa
Il 25/07 (`r0725_ib10k.py`) concludeva: **"al massimo 25% su IB, costa ~€0.08/g di rendita"** — su
basi puramente di **rendimento**, e con tono di concessione ("costa"). Questa misura dice che quel
25% compra una riduzione grande della probabilita' di **rovina**, che l'analisi di allora non
prezzava affatto.
**Stesso numero, ragione diversa, e molto piu' forte: €0.08/giorno non e' il prezzo di un
peggioramento, e' il premio di un'assicurazione contro il modo piu' probabile di perdere tutto.**
---
## 4. Regole trasferibili
1. **Un rischio non-diversificabile dagli sleeve va prezzato a parte.** Tre sleeve ortogonali sui
ritorni possono essere perfettamente correlati sul fallimento del venue: la matrice di
correlazione del book non lo vede, per costruzione.
2. **P(successo) puo' nascondere P(rovina).** Qui la concentrazione costa 1-3pp sulla prima e fino
a 64pp sulla seconda. Per un piano di rendita la metrica e' la seconda.
3. **"Quante volte vieni colpito" non e' una misura di rischio** — lo split viene colpito 2.5x piu'
spesso ed e' molto piu' sicuro.
4. **Quando una raccomandazione e' presa su un asse solo, ricontrollarla sugli altri prima di
considerarla stabile.** Il "25% su IB" era una concessione sul rendimento; sull'asse della
rovina e' la mossa principale.
---
## 5. Addendum — la decisione dell'operatore (stessa sessione)
**Domanda dell'operatore, in sequenza:** *"tutto su deribit?"* → *"quanto tengo su deribit
allora?"* → *"la protezione e' solo di 25%, conviene usarli in Deribit"* → **"resto tutto su
deribit fino a 20k"**.
**DECISIONE: concentrazione 100% Deribit fino a $20k.** Presa dopo aver visto la tabella della
rovina, non prima. Registrata qui perche' non venga ri-litigata alla soglia dei $3k.
### Cosa e' stato verificato per rispondere (e che ha corretto un mio suggerimento)
Avevo suggerito, genericamente, *"non lasciare su Deribit piu' di quanto serve a girare il book"*.
Letto il codice di produzione, e' **inerte** su questa architettura:
```python
# src/live/book.py:81
raw = weight * equity * (W_TP01 * max(tp_frac, 0.0) + W_SKH * skh_sign) # weight = 0.5
```
`equity` e' il **saldo reale letto dal conto**. Il sizing e' proporzionale: prelevare $100 non
mette al sicuro $100, **riduce il nozionale del book di $100**, 1:1. Non esiste capitale in
eccesso da spazzare via. L'unico modo di tenere meno saldo a pari nozionale sarebbe scollegare la
base di sizing dal conto e usare il margine — cioe' **scambiare rischio-venue con rischio di
liquidazione**, che oggi il cap a 1.0x esclude strutturalmente (e che ha una guardia cablata,
`test_leva_massima_da_config_resta_sotto_o_uguale_a_1x`). Cattivo affare: 10-18% ventennale contro
qualche punto **annuo**, per proteggere $500.
Correlato, da mettere agli atti: **"exchange FDIC" non esiste.** L'FDIC assicura depositi bancari
in USD, non crypto e non derivati; la "FDIC pass-through" pubblicizzata da alcuni exchange copre
solo il saldo USD in contanti. Le protezioni reali sono **SIPC** (IB, copre ETF/azioni — cioe'
GTAA01 — non le crypto, che passano da Paxos) e la **segregazione CFTC** (CME, ma la taglia dei
contratti la rende inaccessibile sotto le decine di migliaia).
### L'argomento dell'operatore regge sull'asse su cui ottimizza
Non e' una concessione: e' un fatto gia' nella tabella del §2. Sulla probabilita' di **arrivare**
al capitale-rendita lo split vale **+1-3pp** (81% → 83% a p=1%) e costa ~€0.08/g. Se il criterio
e' quello, la concentrazione e' quasi gratis.
### L'argomento contro, che resta vero e va lasciato scritto
**Zero e' assorbente.** In un piano di accumulo da 16 anni (€250/mese verso $272k), andare a zero
all'anno 10 significa **non arrivarci piu'**: si riparte da €0 + versamenti. Restare col 25%
significa aver perso ~4 anni. Il valore del non-andare-a-zero **non e' proporzionale alla frazione
salvata** — ed e' l'unico argomento vero a favore dello split.
### Termini registrati
| | |
|---|---|
| **Accettato** | P(perso TUTTO) resta 10/18/34/64% a p=0.5/1/2/5% invece di 0/0/4/27% |
| **In cambio di** | ~€0.08/g di rendita, commissione fissa IB, un secondo venue da gestire — per proteggere **$750** a $3k |
| **Non si ri-discute** | la soglia $3k |
| **Si riapre a** | **$20k** (dove lo split protegge ~$5k ed e' comunque richiesto dall'eseguibilita': XS01/HL, GTAA01/IB) |
| **Si riapre PRIMA se** | cambia il piano (orizzonte, importo dei versamenti) oppure `p` diventa **stimabile** invece che assunto |
⚠️ **Nota per il futuro-me:** decisione presa con l'informazione completa, non una svista da
correggere. Se a $3k qualcuno ripropone lo split "come da CLAUDE.md", la risposta e' che la data
e' $20k.
### Regola trasferibile (5ª)
5. **Quando una raccomandazione viene respinta con motivo, registrare COSA E' STATO ACCETTATO IN
CAMBIO.** Senza, la stessa analisi si ripresenta fra tre mesi come se fosse nuova — e l'operatore
deve ri-decidere una cosa gia' decisa, con meno contesto di adesso.
+182
View File
@@ -0,0 +1,182 @@
# 2026-07-26 — Un sistema di protezione dal fallimento exchange, a capitale concentrato
**Richiesta:** *"trova un sistema di protezione da fallimento exchange"* — subito dopo la decisione
di restare **100% su Deribit fino a $20k**.
Il vincolo e' quello che rende il problema interessante: **la riduzione dell'esposizione e' fuori
discussione**. Lo split di venue e' stato valutato e rifiutato con motivo (§5 del diario
`2026-07-26-venue-risk.md`). Quindi non si puo' ridurre *quanto* si perde: si puo' solo ridurre
**la probabilita' di essere ancora dentro quando succede**.
**Script:** `r0726_venue_tripwire.py` (il segnale), `r0726_venue_response.py` (il costo di
rispondere). **Produzione:** `src/live/venue_watch.py` + `scripts/live/venue_watch.py`, cablato in
`cron_book.sh`. **Test:** `tests/test_venue_watch.py` (23). **Book, pesi, config: INVARIATI.**
---
## 0. L'idea in una riga
Il modello di rischio del mattino assumeva il **salto a zero istantaneo**. I fallimenti reali non
lo sono: Mt.Gox gato' i prelievi per mesi, FTX ebbe ~72 ore, e — misurato qui — **Bitfinex nel
2018-19 resto' dislocato dal consenso per 2.324 ore consecutive**. Se dentro quella finestra il
saldo esce, la perdita non e' totale. Il sistema e' quindi un **rilevatore di finestra**, non una
riduzione di esposizione.
## 1. Il segnale, e perche' e' falsificabile
Quando un exchange gata i prelievi **l'arbitraggio si rompe**: non si puo' piu' comprare li' e
vendere altrove per chiudere lo scarto, quindi il suo prezzo si stacca dal consenso e ci resta.
Il segnale e' **|scarto|, non il segno** — su Mt.Gox il BTC andava a *premio* (si comprava BTC per
far uscire valore), su un venue in fuga si vede lo *sconto*. Dicono la stessa cosa.
Misurato su 8 anni di feed certificato, consenso = mediana di venue **USD indipendenti** (Coinbase,
Bitstamp; mai USDT — il depeg 2022 sposta BTC/USDT fino al 3% e genererebbe falsi allarmi giganti):
```
asset ore mediana p95 p99 p99.9 max >50bps >100bps
BTC 65,043 3.1 11.4 18.0 34.4 712.9 0.06% 0.018%
ETH 64,541 3.3 13.3 22.2 44.3 453.1 0.07% 0.017%
```
Deribit sta a **3 bps** dal consenso in mediana. E' un fondo di rumore bassissimo, ed e' cio' che
rende possibile una soglia con margine.
## 2. L'ipotesi meccanica era in parte SBAGLIATA
Avevo scritto, prima di misurare, che il discriminante sarebbe stato la **costanza del segno**:
un venue gated resta da un lato, un crash rimbalza fra i due. **Falso.** Gli episodi peggiori su
Deribit sono tutti a segno costante anche loro:
```
BTC 2020-03-13 10:00 12h picco 158 bps segno -1 (crash COVID)
ETH 2022-09-14 20:00 10h picco 97 bps segno -1 (Merge)
ETH 2020-03-12 23:00 3h picco 453 bps segno -1
BTC 2021-07-01 13:00 2h picco 150 bps segno +1
```
In un cascata di liquidazioni il perp sta **sotto** lo spot per ore di fila: e' un run a segno
costante come quello di un venue gated. Il segno costante resta nel rilevatore (toglie il rumore
simmetrico), ma **non e' lui a separare i due casi**: separano **ampiezza e durata**. Ipotesi
corretta nella conclusione, sbagliata nel meccanismo.
## 3. La taratura va DICHIARATA, perche' due criteri ovvi sbagliano in versi opposti
Provati entrambi in sessione:
| criterio ingenuo | esito | perche' e' sbagliato |
|---|---|---|
| **minimi bps** | 25 bps / 24h | consuma 24 delle ~72 ore che diede FTX |
| **minime ore** | 500 bps / 2h | **manca FTX** (300 bps): margine 0.6x |
Criterio adottato, in quest'ordine: **(1)** zero falsi allarmi su entrambi gli asset in 8 anni;
**(2)** margine ≥3x sul caso storico **piu' debole** (FTX ~300 bps) → soglia ≤100 bps; **(3)** a
quei vincoli, **minima latenza**.
```
2h -> 500 bps (scartata: 0.6x < 3x su FTX)
3h -> 150 bps (scartata: 2.0x < 3x su FTX)
4h -> 100 bps <- SCELTA
6h -> 75 bps
24h -> 25 bps
```
**→ 100 bps persistenti 4 ore a segno costante.** Margine 3x su FTX, 5x su QuadrigaCX, 10-20x su
Mt.Gox. Zero falsi allarmi in 8 anni, **crash COVID / maggio 2021 / LUNA / novembre 2022 inclusi**.
## 4. Il controllo positivo — senza, "non scatta mai" non e' una buona notizia
Un rilevatore tarato per non segnalare e' indistinguibile da uno rotto. Puntato su **Bitfinex
2018-19** (problemi bancari/Tether, premio persistente), consenso Coinbase+Bitstamp con Bitfinex
escluso dal proprio consenso:
```
BTC: 33.000 ore, scarto mediano 11 bps, max 1136 bps -> 22 EPISODI a 100bps/4h
2018-12-26 2324h picco 447 bps segno +1
2018-11-08 1151h picco 663 bps segno +1
2018-10-10 496h picco 1136 bps segno +1
2019-04-25 363h picco 734 bps segno +1
```
**22 scatti su un venue realmente in stress, zero su Deribit in 8 anni.** E la *durata* di quegli
episodi risponde alla domanda che conta davvero: un venue gated resta dislocato per **settimane**,
quindi 4 ore di latenza di rilevamento costano una frazione trascurabile del preavviso.
## 5. Il lato risposta: quanto costa sbagliarsi
Un allarme senza il costo della risposta non e' un sistema. Misurato sul book Deribit reale
(TP01+SKH01 75/25) forzando flat una finestra a **ogni** data d'inizio possibile:
```
giorni costo medio mediana p5 (peggio) p95 (meglio) % dannosi
1 -0.149% -0.100% -1.093% 0.590% 76.4%
3 -0.248% -0.100% -2.065% 1.006% 67.9%
7 -0.442% -0.100% -4.072% 1.505% 62.4%
30 -1.537% -0.455% -9.236% 2.993% 57.3%
```
⚠️ **Errore mio, corretto:** avevo impostato il break-even sul **p5** (la coda). Per un valore
atteso ripetuto nel tempo si usa la **media** — con la coda il numero esce 8.3x piu' severo e la
conclusione si ribalta. Il p5 serve a sapere quanto puo' bruciare *una* volta, non a decidere.
```
Il tripwire conviene se p_annua > (falsi allarmi/anno) x 0.00248:
1 ogni 8 anni -> p > 0.031% conviene per ogni p del ventaglio
1/anno -> p > 0.248% conviene per ogni p del ventaglio
4/anno -> p > 0.991% conviene da p=1%
12/anno -> p > 2.974% conviene solo a p=5%
52/anno -> p > 12.889% NON conviene mai
```
**Il valore del sistema sta tutto nella SPECIFICITA', non nella sensibilita'.** Un tripwire che
strilla 12 volte l'anno sarebbe dannoso; questo, a zero falsi allarmi misurati su 8 anni, ha un
break-even di **p > 0.031%** — un ordine di grandezza sotto l'ipotesi piu' ottimistica del
venue-risk (0.5%).
## 6. Cosa e' stato cablato
`src/live/venue_watch.py` (nucleo puro, testabile) + `scripts/live/venue_watch.py` (runner), 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, e il terzo non e' il primo:** `OK` (misurato, sotto soglia) / `ALERT` (misurato,
sopra soglia e persistente → Telegram) / **`BLIND`** (non misurabile: referenze irraggiungibili o
in disaccordo fra loro). *"Non vedo" non e' "va tutto bene"*: dopo 12 ore di cecita' scatta un
allarme suo. Stessa lezione della contabilita' a 3 stati di `paper_dvolspread`.
**Allerta, non blocca.** L'azione giusta a un vero positivo e' *prelevare*, che richiede comunque
un intervento manuale — una chiave API con permesso di prelievo sarebbe essa stessa un rischio.
E bloccare l'esecuzione non protegge il saldo: il saldo e' a rischio anche stando flat.
**Runbook pre-deciso** (nel docstring del modulo, per non doverlo decidere nel momento sbagliato):
1. escludere il guasto delle referenze (`n_refs`, `ref_spread_bps`);
2. `public/status` (`platform_locked`) e canali ufficiali;
3. **prelievo di prova piccolo** — l'unica evidenza DIRETTA; se non passa in tempi normali
l'allarme e' vero qualunque altra spiegazione esista;
4. se non passa: flat + prelievo totale. Sbagliarsi costa **0.248%**, aver ragione salva il 100%.
## 7. Cio' che questo sistema NON copre — e va detto
Il tripwire prezza la finestra, non la sua esistenza. **Un fallimento senza finestra non lo prende
nessuno**: furto di chiavi, sequestro, exit-scam notturno. Quella parte di `p` resta scoperta, e la
sola difesa e' quella che l'operatore ha rifiutato fino a $20k — lo split. Il sistema **riduce** il
rischio di venue, non lo elimina, e non e' un argomento per cambiare la decisione del 26/07.
Secondo limite dichiarato: il preavviso storico di 200-2300 ore viene da **un** caso osservato
(Bitfinex). E' un'ancora, non una distribuzione.
## 8. Regole trasferibili
1. **Un rilevatore tarato per non segnalare va validato su un controllo positivo**, o "non e' mai
scattato" e' indistinguibile da "e' rotto". Qui: 22 scatti su Bitfinex, zero su Deribit.
2. **Una soglia si sceglie con un criterio dichiarato PRIMA**, perche' i criteri ovvi sbagliano in
versi opposti: "minimi bps" perde preavviso, "minime ore" perde il caso da prendere.
3. **La persistenza richiesta e' latenza, e la latenza va sottratta al preavviso.** Va confrontata
con la durata del fenomeno da rilevare, non scelta in astratto.
4. **Un break-even si calcola sulla media, non sulla coda.** La coda dice quanto fa male una volta;
la media dice se conviene ripeterlo.
5. **Un outer-join con una referenza corta e' una trappola** (2ª volta oggi, dopo GTAA01): la
prima corsa tronco' il campione da 8 anni a 29 giorni *in silenzio*, e la diagnostica di
copertura era gia' stampata. **Una diagnostica stampata non e' un controllo** — ora c'e' una
guardia che ferma lo script.
6. **Un controllo positivo dentro il ramo `else` non gira mai.** Trovato in sessione: era finito
nel ramo di fallimento, cioe' esattamente il difetto che doveva prevenire.
+421
View File
@@ -0,0 +1,421 @@
# 2026-07-26 — I versamenti: le quattro ipotesi che il piano non aveva mai fatto
**Richiesta:** *"allora concentriamoci sui versamenti"* — dopo la rivalutazione che ha misurato il
book dentro il suo plateau (ottimizzare il peso = +0.030 Sharpe, gate fallito) mentre i versamenti
valgono la differenza fra **mai** e **16 anni**.
**Script:** `r0726_deposits.py`. **Test:** `tests/test_deposits.py` (12).
**Book, pesi, cron, config: INVARIATI.** (Questo filone non tocca il codice di produzione.)
---
## 0. Cosa mancava
Tutte le traiettorie calcolate finora (25/07 e 26/07) assumono la stessa cosa: **versamento
piatto, ininterrotto, per sempre**. E' l'ipotesi meno realistica dell'intero piano. Qui si misurano
le deviazioni che succedono davvero, con la stessa macchineria (block bootstrap sui ritorni reali
del book live, fattore d'ancora ×0.89 **misurato**).
## 1. Smettere di versare — il costo non e' proporzionale ai soldi mancanti
€250/mese per K anni, poi stop, orizzonte 20 anni:
```
versi per totale versato cap. mediano a 20a P(muro entro 20a) rendita mediana
3a $10,410 $202,771 32.7% 37.27 €/g
5a $16,950 $287,081 53.3% 52.76 €/g
10a $33,572 $410,220 77.9% 75.39 €/g
20a $66,818 $496,778 90.0% 91.30 €/g
```
**I primi 5 anni sono il 25% dei soldi e il 58% del risultato.** Chi versa 5 anni e poi smette
arriva comunque alla rendita bersaglio nel 53% dei casi; chi versa gli ultimi 10 anni (piu' soldi)
arriva nell'11% (§3). **La variabile non e' quanto versi: e' quanto presto.**
Corollario pratico: un'interruzione al 12° anno costa poco; una al 3° costa quasi tutto. Se il
piano deve rompersi, e' meglio che si rompa tardi — il che e' un argomento per **partire con un
importo sostenibile** invece che con uno ambizioso.
## 2. Un piano crescente e' peggiore di uno piatto, a pari soldi
```
piano totale versato cap. mediano P(muro) $ finale / $ versato
piatto €250 $66,818 $496,778 90.0% 7.43x
€150 +5%/anno $67,998 $401,889 80.8% 5.91x
```
**Stessi soldi (€67-68k), 24% di risultato in meno.** Il piano crescente versa gli stessi euro
piu' **tardi**, e quegli euro compongono meno. L'ultima colonna e' la metrica giusta per
confrontare piani di taglia diversa: quanto capitale finale compra ogni dollaro versato — e i
piani crescenti stanno tutti a 5.1-5.9x contro 7.4x dei piatti.
E' contro-intuitivo perche' "i versamenti crescono col reddito" suona prudente. Lo e' dal punto di
vista del bilancio familiare; **non** lo e' dal punto di vista del capitale.
## 3. Stesso totale, calendario diverso — il tempo vale 2.2x
€60.000 in totale (= €250/mese per 20 anni), distribuiti diversamente:
```
calendario cap. mediano P(muro) vs piatto
piatto su 20 anni $496,778 90.0% 1.00x
tutto nei primi 10 anni $806,285 98.3% 1.62x
tutto nei primi 5 anni $1,104,587 99.4% 2.22x
solo negli ultimi 10 anni $178,494 11.0% 0.36x
```
**Gli stessi €60.000 valgono da $178k a $1.104k — un fattore 6 — a seconda di QUANDO entrano.**
⚠️ Questo **non** dice "versa tutto subito": dice quanto vale il tempo. Un piano che non si
sostiene non e' un piano, e il confronto serve a scegliere fra calendari **sostenibili**.
### E regge al rischio di venue?
Il vantaggio del front-loading e' calcolato mettendo **piu' capitale sull'exchange prima** — cioe'
proprio il rischio misurato stamattina. Andava verificato, non assunto:
```
calendario p=0.5% p=2.0% p=5.0%
piatto su 20 anni $463,413 $359,251 $0
tutto nei primi 10 anni $765,178 $555,904 $0
tutto nei primi 5 anni $1,015,491 $752,367 $0
solo negli ultimi 10 anni $172,228 $147,203 $0
```
Il vantaggio **regge** (2.22x → 2.09x a p=2%): il rischio di venue colpisce il **tempo**, non il
calendario dei versamenti. Anticipare non aumenta la probabilita' di essere colpiti, aumenta solo
quanto c'e' dentro quando succede — e nel frattempo ha composto di piu'.
⚠️ **Ma guardare la colonna p=5%: il capitale mediano e' $0 per OGNI calendario.** A quel tasso di
rischio la meta' dei percorsi finisce a zero (64% di rovina su 20 anni, come misurato stamattina) e
**come versi diventa irrilevante**. E' la formulazione piu' netta del rischio di venue trovata
finora: non erode il piano, lo **cancella**.
## 4. La domanda inversa — che rendita compra quello che posso permettermi
Rendita **netta** mediana in €/giorno:
```
€/mese 5a 10a 15a 20a P(€50/g a 20a)
100 2.08€ 6.54€ 16.40€ 38.07€ 31.0%
150 3.00€ 9.55€ 23.96€ 55.80€ 58.7%
250 4.83€ 15.53€ 39.11€ 91.30€ 90.0%
400 7.59€ 24.52€ 61.85€ 144.23€ 98.9%
600 11.26€ 36.52€ 92.17€ 215.07€ 100.0%
```
E' la tabella che **riformula l'obiettivo**. €50/g e' un punto su questa griglia, non l'unico
risultato che conta: €150/mese porta a ~€24/g in 15 anni, che non e' un fallimento del piano da
€50 — e' un risultato diverso, e ora si sa quanto costa il salto.
Da notare la **non-linearita' temporale**: da 15 a 20 anni la rendita piu' che raddoppia a ogni
livello. Gli ultimi anni del piano contano piu' dei primi *in rendita*, esattamente come i primi
contano piu' degli ultimi *in versamenti*.
## 5. Ogni quanto versare — la decisione meno importante
```
costo/tras. mensile bimestrale trimestrale semestrale
$0.00 *$490,149 $486,725 $482,587 $473,908
$2.00 *$486,597 $484,964 $481,446 $473,342
$5.00 $481,270 *$482,323 $479,727 $472,495
$25.00 $445,984 $464,692 *$468,226 $466,817
```
**Mensile fino a ~$2 di costo per trasferimento, bimestrale sopra.** Ma le differenze sono
**1-3%** del capitale finale: e' la meno importante delle cinque decisioni di questo diario, e non
merita ottimizzazione oltre la regola in una riga.
Verificato che un deposito **non resta strozzato**: col cap dinamico attivo (`_cap`), cap =
equity/2 = esattamente il nozionale massimo che il book puo' chiedere per asset.
## 6. Le cinque decisioni, in ordine di quanto pesano
| decisione | effetto misurato |
|---|---|
| **versare o no** | da **mai** a 16 anni |
| **quando** (front vs back, stesso totale) | **6x** sul capitale finale |
| **quanto presto smettere** | 5 anni = 25% dei soldi, 58% del risultato |
| piatto vs crescente | 24% a pari soldi |
| frequenza | 1-3% |
E sopra tutte, fuori scala: **a p=5% di rischio venue il risultato mediano e' zero comunque.**
## 7. Regole trasferibili
1. **Un piano di accumulo si giudica sulle sue deviazioni, non sul caso nominale.** Piatto,
ininterrotto e per sempre e' l'unico scenario che non succede.
2. **Confrontare piani di taglia diversa richiede una metrica normalizzata** (`$ finale / $
versato`), altrimenti "versa di piu'" vince sempre e non si impara niente.
3. **Un vantaggio calcolato ignorando un rischio noto va ri-misurato con quel rischio dentro**,
anche quando ci si aspetta che regga — qui reggeva, ma la colonna p=5% ha prodotto il risultato
piu' importante del filone.
4. **Quando l'obiettivo dichiarato non e' raggiungibile, la tabella utile e' quella inversa**:
non "quando arrivo a X" ma "cosa compro con quello che ho".
---
# Addendum — il piano dichiarato: €5.000 subito + €500/mese
L'operatore ha dato i numeri veri. Cambiano la scala: €5.000 portano il conto da **$597 a $6.047
(10.1x)** e €500/mese e' il doppio del livello tabulato sopra. Ricalcolato in dedicata
(`r0726_piano_5k500.py`), non estrapolato.
## Quando
```
traguardo ($272.061): p10 9.4a MEDIANA 11.6a p90 14.4a
P(entro 10a) 18% P(entro 12a) 57% P(entro 15a) 94% P(entro 20a) 100%
```
```
anno capitale p10 MEDIANO p90 rendita mediana
1$ 12,408$ 14,057$ 16,405 2.58 €/g
3$ 28,401$ 34,674$ 44,000 6.37 €/g
5$ 48,306$ 62,952$ 86,121 11.57 €/g
10$ 130,089$ 191,398$ 299,555 35.18 €/g
15$ 288,993$ 476,825$ 847,266 87.63 €/g
```
✅ **Validazione incrociata:** la variante "solo €500/mese da $600" da' **12.4 anni**, che e'
*esattamente* il numero pubblicato il 25/07 con macchineria diversa. Replica indipendente.
## Quanto vale il versamento iniziale: 0.8 anni
```
€5.000 subito (il piano) 11.6a
€5.000 spalmati sul 1° anno 11.7a
€5.000 al 5° anno 12.1a
niente lump, solo €500/mese 12.4a
```
⚠️ **Meno di quanto suggerisse il "fattore 6" del §3**, e la ragione e' aritmetica: €5.000 sono
**~10 mesi** di versamenti a €500, quindi comprano ~10 mesi. Il fattore 6 riguardava lo spostamento
di €60.000 su vent'anni. **Anticipare vale in proporzione a quanto si anticipa** — ovvio a
posteriori, ma la mia aspettativa era piu' alta e va corretta.
## Le soglie, e la data che compare
```
$ 3,000 GIA' SUPERATA il giorno 1 GTAA01 eseguibile
$ 5,000 GIA' SUPERATA il giorno 1 XSR01 eseguibile (gate pre-registrato 23/10)
$ 13,000 ~0.9 anni GTAA01 entra nel book deployable
$ 20,000 ~1.6 anni SOGLIA DELLA DECISIONE VENUE
$117,000 ~7.6 anni XS01 eseguibile
```
**La decisione "niente split fino a $20k" smette di essere un'ipotesi e diventa una data: ~19
mesi.** E le soglie $3k/$5k sono superate il primo giorno — il che NON autorizza ad anticipare il
gate XSR01 del 23/10 (anticiparlo e' selezione sull'hold-out), ma rende viva la sua domanda di
eseguibilita'.
## Con il rischio di venue dentro
```
p annua P(traguardo) P(perso TUTTO) cap. mediano 25a
0.0% 100.0% 0.0% $2,540,508
0.5% 94.3% 11.7% $2,304,596
1.0% 88.0% 23.2% $2,018,727
2.0% 78.8% 39.6% $1,464,013
5.0% 55.4% 72.0% $0
```
Il piano regge bene fino a p=2%. A p=5% il capitale mediano e' **zero**: e' la stessa conclusione
del §3, e vale a maggior ragione ora che il capitale in gioco e' 10x.
## ⚠️ AZIONE OPERATIVA PRIMA DEL VERSAMENTO — il cap fisso diventa una strozzatura
`src/live/book._cap` usa il cap **dinamico** (equity/2) solo quando l'equity reale e' leggibile;
altrimenti ripiega su `max_notional_per_asset_usd = $300`. **A $597 il fallback era INERTE**
(equity/2 = $298 ≈ $300). **Dopo il versamento l'equity/2 vale ~$3.023**, quindi un fallback
strozzerebbe il book a **~10% del target** — silenziosamente, con la sola allerta `eq_fallback`.
E' esattamente 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`: **fallisce** se
si deposita senza adeguare `max_notional_per_asset_usd`.
**Non eseguita**: e' un cambio di config su soldi veri, decisione dell'operatore.
---
## Il cap: alzato a $3.000, ma il modo conta piu' del numero
L'operatore ha autorizzato *"si alza il cap a 3000"*. Verificato prima di eseguire: **il deposito
non era ancora arrivato** (equity reale letta dal conto: $596.92). Alzare il cap in quel momento
sarebbe stato **pericoloso nel verso opposto**.
### Perche' alzarlo prima del deposito e' pericoloso
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 × 2000 × (...)` = fino a $1.000/asset,
e **il cap fisso e' l'unica cosa che impedisce a quel nominale di diventare leva reale**:
| cap fisso | fallback su conto da $597 | leva reale |
|---|---|---|
| $300 (prima) | $300/asset = $600 lordi | **1.00x** ✅ |
| $3.000 (alzato a mano) | $1.000/asset = $2.000 lordi | **3.35x** ❌ |
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: il fallback segue l'ultima equity osservata
Invece di alzare un numero da ricordare, il cap di fallback e' stato **legato al conto**:
```python
cap_fallback = min(cap_fisso_di_config, ultima_equity_reale_osservata * frac)
```
con un 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 quello che dovrebbe: un **tetto dichiarato**.
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**, e senza dipendere da un'azione manuale al momento del
deposito. Senza watermark (primo avvio, file cancellato) si usa `CAP_UNKNOWN_USD` = $300: non si sa
niente del conto, si usa la taglia storicamente sicura.
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**.
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).
### Regola trasferibile
**Un parametro di sicurezza che va aggiornato a mano a ogni cambio di scala e' un difetto, non una
configurazione.** Qui 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**. Il segnale che serviva questa correzione era gia' visibile: l'azione manuale era stata
pre-registrata 24 giorni prima e non era mai stata eseguita.
---
# Addendum 2 — "dai per scontato che non perdiamo mai con i trade?"
Obiezione dell'operatore. Si divide in due parti che hanno risposte **opposte**:
la prima e' infondata, la seconda coglie l'ipotesi piu' fragile di tutto il piano.
Script `r0726_decadimento.py`.
## Parte 1 — no: le perdite sono nel modello
Il block bootstrap ricampiona i ritorni **reali** del book a blocchi di 20 giorni, quindi conserva
autocorrelazione e forma dei drawdown.
```
serie reale (2.692 giorni): in perdita 35.6% · flat 27.5% · in guadagno 36.9%
giorno peggiore -3.94% · peggior mese -5.76%
5.000 percorsi simulati (20a): maxDD mediano 14.4% · p90 19.8% · PEGGIORE 44.2%
anni-calendario in perdita 5.8% (su 95.000 anni)
```
⚠️ **Errore mio catturato scrivendo questo**: la prima stesura riportava **63.9%** di giorni in
perdita. Artefatto: il de-luck sottrae una costante a *ogni* giorno (e' cosi' che riduce il drift
lasciando la vol invariata, come prescrive la misura d'ancora), quindi **trasforma il 27.5% di
giorni flat in piccoli negativi**. Corretto per il drift, fuorviante per la forma.
**REGOLA: una correzione uniforme sul drift e' giusta per le domande sul drift e sbagliata per le
domande sulla distribuzione** — la stessa serie dice 36% o 64% di giorni in perdita a seconda di
quale delle due si guarda, senza che sia cambiato niente.
## Parte 2 — si', ma l'assunzione e' un'altra: che l'edge continui a esistere
Il bootstrap assume che **il futuro sia il passato rimescolato**. Nessuna parte del progetto misura
il decadimento dell'alpha. Quanto costa se e' falso (piano €5.000 + €500/mese):
```
scenario mediana traguardo P(entro 20a) cap. mediano 20a
edge intatto (cio' che ho mostrato finora) 11.6a 99.9% $1,115,643
edge DIMEZZATO da subito 15.8a 76.6% $342,224
edge che decade a zero in 20 anni 14.3a 65.5% $269,970
edge che decade a zero in 10 anni oltre 20a 18.4% $157,856
edge MORTO dall'anno 10 (rende 0) oltre 20a 42.0% $259,553
edge MORTO dall'anno 5 oltre 20a 0.0% $163,377
```
**Il piano NON e' fragile a un dimezzamento dell'edge** (11.6 → 15.8 anni, P ancora 77%). **Lo e'
alla morte dell'edge.** E la differenza fra i due casi non e' distinguibile in anticipo — e' la
ragione per cui il progetto ha gate pre-registrati con date e soglie invece di aspettarsi che le
cose continuino a funzionare.
## Il limite strutturale del metodo
```
Peggior BIENNIO dell'intero campione: +3.0%
Se tutti i 20 anni fossero fatti cosi': P(traguardo) 2.9%, capitale mediano $149.014
(a fronte di $136.847 versati)
```
**Il peggior biennio della storia del book e' POSITIVO.** Sette anni di storia crypto contengono
due mercati toro: un decennio davvero brutto **non e' mai successo**, quindi il bootstrap non lo
puo' estrarre. Non e' un parametro da alzare, e' il limite del ricampionamento: **non si puo'
simulare un regime peggiore di qualunque cosa ci sia nel campione.**
Se i prossimi 20 anni somigliassero al peggior biennio gia' visto, il capitale finirebbe **appena
sopra i soldi versati**: il piano non fallirebbe, semplicemente non renderebbe.
## Cosa se ne fa
Nessun cambio a book, pesi o piano. Cambia **cosa si sorveglia**: la domanda "l'edge c'e' ancora?"
non ha una risposta nel backtest, ce l'ha solo nel forward — che e' esattamente cio' che i monitor
paper e i gate pre-registrati esistono per misurare.
---
## Addendum 3 — "+184% sembra alto, da dove arriva?"
Obiezione dell'operatore su un numero che avevo citato io. **Aveva ragione, e l'errore era di
metodo, non di calcolo.**
### Il numero e' vero
Non e' un bug. Tracciato l'anno estremo: e' composto da 18 blocchi da 20 giorni, e **nessuno di
essi e' negativo in modo significativo**:
```
+20% +15% +12% +10% +8% +8% +8% +7% +6% +6% +5% +5% +2% +1% +0% -0% -0% -1%
```
La popolazione da cui pesca lo consente: blocchi 20g reali con mediana **−0.1%**, p95 **+8.5%**,
max **+22.4%**, **skew +2.15** — la firma classica di un trend-follower (molte perdite piccole,
poche vincite grandi). E la materia prima esiste davvero: **la miglior finestra 365g della storia
reale e' +89.8%** (il 2020 fece +58% come anno di calendario).
### Ma citarlo era sbagliato
```
su 1.000 anni simulati: max +96.0%
su 5.000 anni simulati: max +135.2%
su 20.000 anni simulati: max +135.2%
su 114.000 anni simulati: max +184.3%
```
**Il massimo di N estrazioni cresce con N: descrive la taglia della mia simulazione, non la
strategia.** Con 1.000 percorsi avrei scritto "+96%" e sarebbe stata la stessa strategia. Il numero
che avevo dato all'operatore parlava del mio `N_PATHS`, non del book.
I numeri corretti sono i **percentili**, che non dipendono dal campione:
| p0.1 | p1 | p5 | p50 | p95 | p99 | p99.9 |
|---|---|---|---|---|---|---|
| −17.6% | −11.9% | −5.5% | **+16.0%** | +51.2% | +71.8% | +99.9% |
Vale simmetricamente per il "peggiore": il **−27.4%** che avevo citato e' anch'esso un minimo
campionario (a 1.000 percorsi era −19.1%). Il numero onesto per la coda sinistra e' **p1 = −11.9%**.
### Cablato
Corretto anche `r0726_decadimento.py`, che riportava "drawdown PEGGIORE 44.2%" con lo stesso
difetto: ora stampa **p99 = 26.0%** e dichiara esplicitamente che il 44.2% e' un massimo
campionario da non citare come "il caso peggiore".
### Regola trasferibile
**Il massimo (o il minimo) di una simulazione non e' una statistica della strategia: e' una
statistica del numero di simulazioni.** Si citano i percentili. E' la stessa famiglia dell'errore
gia' codificato oggi ("un percentile stampato a 0 decimali mente esattamente agli estremi"): gli
estremi sono il posto dove i numeri sembrano piu' informativi e lo sono meno.
+132
View File
@@ -0,0 +1,132 @@
# 2026-07-26 — Il muro come PUNTO FISSO: la mia previsione era sbagliata, e il numero pubblicato era giusto per caso
**Richiesta:** *"fai follow up"* — il follow-up dichiarato poche ore prima:
> I muri assumono il book a 2 sleeve da $600 fino a $272k. Il book a 5 sleeve ha Sharpe piu' alto,
> quindi **il muro vero e' piu' basso di $272k**.
**Script:** `r0726_wall_fixedpoint.py`. **Test:** `tests/test_wall_fixedpoint.py` (11).
**Book, pesi, cron, config: INVARIATI.**
---
## 0. Esito in una riga
**La previsione era sbagliata: il muro NON scende.** A pari nozionale e' **$273.900** contro i
**$272.061** pubblicati — **+1%**, cioe' l'estrapolazione col book a 2 sleeve era **giusta per
caso**. Solo a **iso-rischio** scende, a **$222.406 (−18%)**, e li' serve leva a costo minore
dell'uplift, che non e' gratis.
---
## 1. La struttura giusta: il muro e' un punto fisso
Il difetto era reale: `book_series(alloc=$600)` e' il book a **2 sleeve**, estrapolato fino a
$272k. A quella taglia gireresti un altro book — a ~$13k si accende GTAA01 (IB), a ~$118k XS01
(Hyperliquid, 19 gambe).
E la correzione ha una forma: **serve capitale C per girare il book che determina il muro C**.
Si itera `C_{n+1} = muro(book(C_n))`.
```
iter capitale ipotesi sleeve Sharpe rendita -> muro
0 $272,061 TP01+SKH01+GTAA01+XS01 1.94 10.84% $273,900
CONVERGE a $273,900 (variazione < 2%)
```
Converge in **una** iterazione, e il motivo e' istruttivo: il muro cade **sopra** la soglia di
XS01 ($117k), quindi la composizione del book non cambia fra un'iterazione e l'altra. La struttura
a punto fisso conta solo se il muro atterra **vicino a una soglia** — qui non succede, ma non si
poteva sapere prima di iterare.
**Regole di ammissione rispettate** (e' il book *deployable*, non il *migliore*): **VRP01 escluso**
(regola permanente: niente short-vol da modello in deploy), **XSR01 escluso** (gate pre-registrato
23/10), pesi = book attivo rinormalizzato, costi **capital-aware** (TP01 haircut min-order, GTAA01
commissione IB reale a banda+cadenza, SKH01 sul path live), fattore d'ancora **misurato su questo
book** (×0.860) e non ereditato.
---
## 2. Perche' il muro non scende
```
sleeve peso drift/a vol/a Sharpe
TP01 38% 15.7% 12.2% 1.29
SKH01 23% 27.6% 23.4% 1.18
GTAA01 23% 6.1% 5.4% 1.12
XS01 17% 28.0% 20.9% 1.34
book 2-sleeve (riferimento) drift 18.6% vol 11.4% Sharpe 1.64
book deployable al p.fisso CAGR 18.3% vol 8.9% Sharpe 1.94
```
Diversificare **alza lo Sharpe** (1.64 → 1.94) ma abbassa **drift e vol insieme**. La rendita
perpetua vive sul drift: 10.91% → 10.84%, cioe' **invariata**. Il guadagno di Sharpe finisce tutto
in **meno rischio**, non in piu' reddito.
E' esattamente il fatto gia' misurato il 25/07 (§3): *"Diversificare NON crea reddito a pari
nozionale — libera BUDGET DI RISCHIO"*. Non me ne ero ricordato scrivendo il follow-up.
## 3. Il confronto onesto e' a ISO-RISCHIO — e stavo violando una regola del progetto
CLAUDE.md ha una regola codificata il 25/07:
> **Un diversificatore a basso CAGR si giudica a ISO-RISCHIO, mai a iso-nozionale** (e' il null
> de-levering al contrario).
Il confronto che avevo impostato era **iso-nozionale**: quello sbagliato secondo la regola del
progetto stesso.
```
lente rendita muro
2 sleeve, ×0.89 (pubblicato) 10.91% $272,061
deployable, ISO-NOZIONALE (leva 1.00x) 10.84% $273,900 (+1%)
deployable, ISO-RISCHIO (leva 1.28x) 13.35% $222,406 (-18%)
```
✅ **Replica indipendente:** il 25/07 misurava, con macchineria diversa e su un book diverso,
iso-rischio → **−19% di muro**. Qui esce **−18%**. Due implementazioni separate, stesso numero.
⚠️ L'iso-rischio vale **solo se la leva e' (a) disponibile e (b) a costo minore dell'uplift** —
addendum IB del 25/07: su ETF a IB c'e' Reg-T 2x (portfolio margin da ~$110k) e il margine costa
~5.5%/anno. **Il $222k NON sconta il costo del margine: e' un tetto, non una stima.**
---
## 4. Il bug che ha quasi prodotto un titolo grottesco
La prima corsa dava: Sharpe **0.95**, CAGR 6.7%, muro **$854.013** — cioe' *"diversificare triplica
il muro"*, un risultato spettacolare e falso. Il numero era plausibile abbastanza da poter essere
pubblicato.
**Causa:** `CC.gtaa_banded` ritorna la storia GTAA **dal 1996**, mentre lo sleeve di produzione
(`sleeves._gtaa_daily_returns`) la tronca a `GTAA_BOOK_ACTIVATION` (2019-03). Con la
rinormalizzazione per-riga di `combine_outer`, per il **75% del campione** (1996-2019) il "book a
4 sleeve" era **GTAA01 da solo al 100%** — uno sleeve al 4% di drift.
**Come l'ho preso:** non da un test, ma perche' **la somma pesata dei componenti (~18%) non
tornava col drift del combinato (6.8%)**. Una discrepanza di 11 punti che non sapevo spiegare.
**Diagnostica decisiva:** la copertura per colonna — `TP01 24.6% / SKH01 24.6% / GTAA01 100.0% /
XS01 8.6%`. Un 100% accanto a tre valori bassi dice tutto in una riga.
**Cablato:** `test_gtaa_e_troncato_all_era_book` (la causa), `test_il_book_deployable_non_parte_dal_1996`
(l'effetto, per prendere una gamba futura che reintroducesse storia antecedente) e
`test_il_book_a_4_sleeve_ha_sharpe_superiore_al_singolo_gtaa` (plausibilita').
---
## 5. Regole trasferibili
1. **Un follow-up dichiarato contiene una PREVISIONE, e la previsione va misurata, non assunta.**
Avevo scritto in CLAUDE.md "il muro vero e' piu' basso": era una deduzione ragionevole
(piu' Sharpe → piu' rendita) e sbagliata, perche' la rendita vive sul **drift**.
2. **Prima di misurare, rileggere le regole gia' codificate.** La risposta ("diversificare non
crea reddito a pari nozionale, si giudica a iso-rischio") era gia' in CLAUDE.md dal 25/07 e ho
impostato comunque il confronto sbagliato.
3. **Quando un aggregato non torna con la somma dei suoi pezzi, fermarsi.** L'11% di discrepanza
era l'unico segnale del bug: nessun test lo copriva, nessuna eccezione, output plausibile.
4. **La copertura per colonna e' la prima diagnostica di un outer-join.** Un 100% accanto a valori
bassi = una gamba con storia diversa che domina la rinormalizzazione.
5. **Un punto fisso converge subito se non e' vicino a una soglia** — ma va iterato lo stesso per
saperlo.
@@ -0,0 +1,255 @@
# 2026-07-26 — Ondata a 3 filoni: esecuzione SKH01, DVOLSPREAD, XSR01 fuori dal crypto
**Script:** `r0726_skh_onbook.py` · `r0726_dvolspread_gate.py` · `r0726_xsr_equity.py`
**Test:** `tests/test_wave_0726.py` (11 casi) · suite completa **245 verdi**
**Book / pesi / cron: INVARIATI.** Una raccomandazione operativa aperta (T1), nessuna modifica fatta.
Tre filoni scelti non per esplorare aree nuove — quelle sono in gran parte sature — ma perché
il progetto stesso aveva lasciato **tre questioni aperte e decidibili oggi**:
| filone | questione aperta | esito |
|---|---|---|
| **T1** | il degrado del path live di SKH01 (~−0.35 Sh) è recuperabile? | ⚠️ **il degrado era a sua volta fortuna d'ancora**; metà del fix funziona, l'altra metà no |
| **T2** | DVOLSPREAD, in limbo dal 21/06, è sleeve o falso positivo? | ✅ **regge i gate che non esistevano allora** — promosso a forward-monitor con parametri onesti |
| **T3** | XSR01 regge fuori dal crypto e da 2.6 anni monoregime? | ❌ **no** — e si scopre *perché* |
---
## T1 — Il degrado d'esecuzione di SKH01 era anch'esso un artefatto d'ancora
### La domanda
Il book live gira SKH01 con cron orario e uscite **software**. Costo misurato (audit 02/07,
riconfermato il 24/07): sleeve FULL 1.46→1.19, HOLD 1.64→1.15, DD 18%→25%. È il buco singolo più
grande del progetto, e il 24/07 aveva già stabilito che **un cron più veloce non lo recupera**.
L'angolo mai testato è l'unico meccanismo che non è un cron: gli **ordini resting on-book**, dove
esiste un'asimmetria che nessuno aveva sfruttato:
- il **TP è un limit order**: se il prezzo ci arriva, il fill è al livello **per costruzione**
(sei il maker), e per giunta a fee maker invece che taker;
- lo **SL è uno stop-market**: al trigger diventa un ordine a mercato, e in un gap riempie peggio.
Ipotesi: il grosso del degrado sta sul lato TP, quindi è recuperabile senza rischio nuovo.
### Il risultato, e la trappola che ha nascosto
A **offset 0** — la griglia che gira davvero — il quadro sembrava trionfale: l'on-book completo
recupera il **94%** del degrado. Ma l'offset 0 è già noto essere al 93-98° percentile dei 23
offset a priori, quindi la lente onesta è la banda.
E qui c'è stato un mio errore di statistica, corretto in corso: avevo confrontato
**mediana(canonical) − mediana(hourly)**, che confronta offset *diversi* fra loro. Gli offset sono
**coppie appaiate**: la statistica giusta è la **mediana delle differenze**. Con quella:
| modalità | ΔFULL mediana [min,max] | ΔHOLD mediana | migliora in |
|---|---|---|---|
| canonical (tetto teorico) | **+0.054** [−0.05,+0.12] | +0.099 | — |
| **solo TP a limite** | **+0.054** [−0.03,+0.07] | **+0.061** | **FULL 19/23 · HOLD 21/23 · DD 19/23** |
| TP + SL on-book | +0.024 [−0.07,+0.11] | +0.031 | FULL 17/23 · HOLD 14/23 |
| *contributo del solo lato SL* | **−0.010** [−0.13,+0.08] | — | **11/23 = una moneta** |
**Due conclusioni, entrambe diverse da quella che cercavo.**
**(1) Il "−0.35 del path live" è a sua volta un artefatto dell'offset 0.** L'audit del 02/07 aveva
de-luckato i numeri *headline* di SKH01 ma aveva misurato il **degrado** solo a offset 0. Sulla
banda appaiata il degrado massimo recuperabile è **+0.054 di Sharpe sul book**, non +0.35 sullo
sleeve. Il buco più grande del progetto era in buona parte fortuna d'ancora anche lui.
**(2) Lo stop on-book PEGGIORA.** Mettere lo SL sul book cristallizza la perdita al livello,
mentre l'uscita software ritardata a volte incassa il rimbalzo: contributo mediano **−0.010**,
positivo in **11/23** offset = indistinguibile da una moneta. La sensibilità lo conferma: sopra
lo **0.50%** di slippage sullo stop l'on-book è **peggio del live di oggi**.
Il meccanismo è misurato, non ipotizzato: sulle uscite TP il fill orario batte il livello nel
**42%** dei casi (vantaggio medio −0.035%) — è quasi una moneta, quindi il limit TP **converte una
lotteria in una certezza** più che aggiungere ritorno. E solo l'**1% degli SL** gappa davvero
dentro la barra 5m: il gap-through dei crash è reale ma raro.
### Raccomandazione (NON eseguita)
> **Appoggiare il TP come limit resting reduce-only; NON mettere lo SL strategico sul book.**
> Guadagno atteso **+0.054 FULL / +0.061 HOLD** sul book, positivo in **19-21 offset su 23**,
> più il risparmio taker→maker su un quarto dei trade.
È un cambio di **esecuzione**, non di strategia, quindi non passa da `weights_tilt_null`. Ma è
piccolo, e va pesato contro il costo operativo vero: ordini orfani se il cron muore, gestione
del reduce-only, doppio fill. **Non l'ho implementato**: è una decisione dell'operatore, non un
fatto compiuto. Il disaster-SL on-book a −30% resta com'è (è un'altra cosa: protezione, non exit).
---
## T2 — DVOLSPREAD regge i gate che nel giugno non esistevano ✅
### Chi è, e perché era in limbo
`agent_14_dvol_spread` (onda ortho, 21/06) è **l'unico sopravvissuto** al marginal scorer
indurito: dei 18 book relative-value che facevano ADDS con lo scorer vecchio, l'indurito ne lasciò
in piedi **uno**, questo. Da allora non è mai stato ripreso — non è nel book, non è in un monitor,
non è stato rifiutato. Era semplicemente lì.
Il segnale: `log(DVOL_btc) − log(DVOL_eth)`, tilt verso la gamba con **vol implicita più ricca**
(tesi VRP / fear-reversal), market-neutral per costruzione, eseguibile a $600.
Nel frattempo il progetto ha codificato **due gate che il 21/06 non c'erano**, ed erano proprio
quelli che colpivano le sue riserve dichiarate:
1. **`deflated_sharpe`** (29/06) — l'agente dichiara *da sé* uno sweep di celle. Nel giugno
"72/72 celle ADDS" si leggeva come robustezza; il DSR dice che sono anche 72 tentativi.
2. **`select_cell_insample`** (29/06) — il plateau dell'agente è descritto in termini di
**`uplift_hold`**, cioè la cella è stata guardata **sull'hold-out**. È la firma esatta che il
gate selection-on-holdout fu scritto per catturare.
### Esito
⚠️ **Prima osservazione: la griglia dichiarata è sbagliata.** Il docstring dice "72-cell sweep", ma
il plateau che descrive è 6 assi × 3 valori = **729** combinazioni. Le ho valutate tutte e 729 —
scelta **conservativa**, perché più trial abbassano il DSR.
**Il plateau è reale e larghissimo:** FULL in [0.60, 0.71], HOLD in [0.68, 0.97], e
**729/729 celle con hold-out positivo**. Non è una cella fortunata.
**La selection-on-holdout c'è, ma è mite.** La cella pubblicata è **83ª/729 sull'hold-out** ma
**471ª/729 in-sample** — la firma è inequivocabile. Solo che, essendo il plateau così piatto,
scegliere onestamente la cella in-sample costa poco:
| cella | FULL | IS | HOLD | DSR (729 trial) |
|---|---|---|---|---|
| scelta **IN-SAMPLE** (onesta) | 0.68 | 0.70 | **0.69** | **0.953 PASS** |
| scelta sull'hold-out (proibita) | 0.68 | 0.58 | 0.97 | — |
| **pubblicata dall'agente** | 0.66 | 0.57 | 0.93 | 0.947 **FAIL** |
Cioè: **l'hold-out onesto è 0.69, non il 0.93 pubblicato** — un haircut reale — ma resta
chiaramente positivo. E la cella onesta **passa il deflated-Sharpe (0.953)** mentre quella
pubblicata lo **fallisce (0.947)**, il che è di per sé una conferma che il gate fa il suo lavoro.
Marginale vs TP01 sulla cella onesta: **ADDS**, `robust_oos` ✓, `multicut_persistent` ✓,
`is_hedge` ✗, `has_insample_edge` ✓, `beats_noise_null` ✓; corr +0.11, alpha annua **+7.4%**,
beta a TP01 +0.117, jackknife_min_uplift **+0.069**; dSharpe sul book **+0.08 FULL / +0.17 HOLD**
a w=15%, **+0.11 / +0.25** a w=25%.
### Verdetto: promosso, ma non nel book
**DVOLSPREAD esce dal limbo e diventa un candidato in forward-monitor con parametri ONESTI**
(`zwin=180, k=2.0, lw=0.6, zw=1.1, tgt=0.17, svw=60` — la cella in-sample), non quelli pubblicati.
### ✅ Monitor CABLATO (stessa sessione)
`scripts/live/paper_dvolspread.py`, in `cron_daily.sh` dopo `fetch_dvol.py` (quindi con DVOL
fresco), stato in `data/paper_dvolspread/` (gitignored), test `tests/test_paper_dvolspread.py`
(10 casi). Inception **2026-07-25**, posizione d'apertura +0.184 → **$111/gamba** (cap $300).
**Strumentazione specifica di questo lead** — la ragione per cui non bastava copiare
`paper_statarb`: il book va **flat quando il DVOL manca**, quindi un feed rotto produrrebbe una
fila di zeri che, contati come evidenza, direbbero *"nessuna perdita"* invece di *"nessuna
misura"*. Il monitor tiene una contabilità a **tre stati** — ATTIVE / flat-da-segnale /
**flat-senza-dato** — e la finestra forward si misura in **barre attive**, non in giorni di
calendario. C'è anche una **guardia sulla config**: se `FROZEN` diverge dallo stato salvato il
monitor esce con codice 1 invece di continuare su una finestra non più valida (verificato; nel
cron non c'è `set -e`, quindi segnala senza rompere la catena).
**Gate pre-registrato (scritto oggi, prima di vedere qualsiasi barra forward):**
- **kill anticipato 2026-10-24 (~90g):** Sharpe forward < −0.50 → ritiro;
- **decisione 2027-01-24 (~180g):** promozione solo se *tutte e quattro* — (a) Sharpe > 0,
(b) marginale ancora ADDS + robust_oos + has_insample_edge, (c) deflated-Sharpe ricalcolato
sul campione esteso ≥ 0.95, (d) `weights_tilt_null` superato;
- **veto d'integrità:** barre attive < 80% → la finestra non conta, si **estende** invece di
decidere su dati mancanti.
⚠️ La soglia (a) è deliberatamente debole — **necessaria, non sufficiente**. Con ~180 barre attive
l'errore standard dello Sharpe è ≈1.4: una soglia più alta sarebbe finta precisione. Il peso della
decisione sta su (c) — se il margine 0.953, già sul filo, **non migliora** con più dati, l'edge
non c'è.
**Perché NON entra nel book, dichiarato:**
- **campione ATTIVO 1949 giorni su 2691** (72%): prima del 2021-03 non esiste DVOL e il book è
correttamente flat. L'**hold-out attivo è 1.6 anni**;
- **margine DSR sul filo** (0.953 vs soglia 0.95) — un passaggio, non un'assoluzione;
- non ha ancora affrontato `weights_tilt_null`, che ogni cambio di pesi deve superare;
- il numero headline che circolava (HOLD 0.93) era gonfiato dalla selezione: **va citato 0.69**.
---
## T3 — XSR01 non generalizza fuori dal crypto ❌ (e si capisce perché)
### La domanda
XSR01 ha superato tutto ciò che gli è stato chiesto, ma la sua debolezza numero uno è dichiarata:
**2.6 anni monoregime, con l'edge crescente nel tempo** (Sharpe 2024 1.03 / 2025 1.98 / 2026 3.11).
Con 2.6 anni non si distingue un meccanismo da un regime fortunato. L'unico modo di guadagnare
potenza senza aspettare è portare il meccanismo **congelato** su un pannello lungo decenni.
**Non è il test del 25/07.** `r0725_statarb_eq.py` aveva già scartato le azioni, ma testava il
meccanismo a **coppie**. XSR01 è la versione **DEMEANATA cross-sezionalmente**, ed è proprio il
demeaning ad aver creato l'edge (ampiezza effettiva 4.5 → 37.4). Testare il demean sulle azioni è
una domanda diversa, mai posta.
### Esito
Meccanismo congelato (W=45, sgn=+1, residuo OLS causale vs **SPY**, z-score, tanh, vol-target 20%,
demean giornaliero), split IWM/EFA riparati in lettura, annualizzazione a **√252** (giorni di borsa):
| universo | variante | ampiezza eff. | Sharpe **LORDA** | Sharpe netta | maxDD |
|---|---|---|---|---|---|
| **SECT9** (9 settoriali, 1998+, 26 anni) | coppie | 5.3 | −0.05 | −1.67 | −91% |
| **SECT9** | **DEMEAN (= XSR01)** | **6.2** | **+0.24** | −1.61 | −89% |
| **ALL28** (tutti gli ETF, 30 anni) | coppie | 8.4 | −0.20 | −1.61 | −92% |
| **ALL28** | **DEMEAN** | **11.3** | **−0.14** | −1.82 | −91% |
| *XSR01 crypto (25/07, riferimento)* | *DEMEAN* | ***37.4*** | ***+2.70*** | *+1.82* | *−2.6%* |
Null di permutazione cross-sezionale **a fee zero** (la lezione XSR01: permutare un segnale ne fa
esplodere il turnover, quindi a fee piena il null perderebbe per *costo* e regalerebbe un p-value
trionfale e falso): SECT9 candidato +0.24 vs null medio 0.00, **p = 0.193**; ALL28 −0.14, **p = 0.747**.
Per decennio (DEMEAN, lordo): SECT9 −0.88 / +0.49 / +0.29 / +0.74 · ALL28 −0.88 / +0.46 / +0.38 / +0.05.
Stesso profilo nei due universi: fortemente negativo 1998-2005, debolmente positivo poi — il che
somiglia più a un cambio di regime che a un edge.
### Il risultato più interessante non è il Sharpe, è l'ampiezza
**Il demeaning non fa sulle azioni quello che fa sul crypto.** Sul crypto porta l'ampiezza
effettiva da 4.5 a 37.4 (**8×**); sulle azioni da 5.3 a 6.2 e da 8.4 a 11.3 (**1.2-1.35×**).
Il perché è strutturale, e spiega XSR01 meglio di quanto lo spiegasse la sua scoperta: il residuo
OLS **rimuove già** il beta al fattore comune. Sul crypto, dopo aver residualizzato su BTC, alle
gambe **resta** un enorme fattore comune (ampiezza 4.5 su 50 gambe = quasi una gamba sola) — ed è
quello che il demeaning toglie. Sulle azioni il residuo-vs-SPY è **già** quasi indipendente
(5.3 su 9 gambe), quindi il demeaning non ha molto da togliere e non c'è guadagno.
### Cosa significa per il gate del 2026-10-23
Il 25/07 aveva già scritto che *«il gate non può appoggiarsi all'argomento fenomeno universale»*.
Questo test **lo conferma e chiude la scappatoia** che il test a coppie lasciava aperta: nemmeno
la versione demeanata — quella vera di XSR01 — funziona sulle azioni.
**Onestà su cosa NON prova:** non prova che XSR01 sia falso. Prova che è **crypto-specifico**, e
suggerisce quale sia il meccanismo (l'esistenza di un fattore comune residuo che sopravvive alla
residualizzazione, cosa che le azioni non hanno). Il gate del 23/10 resta **interamente** appoggiato
sulla finestra forward e sull'haircut di eseguibilità a $5.000, come pre-registrato.
Nessuna soglia toccata.
---
## Lezioni da portare avanti
1. **Se si de-lucka una strategia, va de-luckato anche il suo DEGRADO.** L'audit del 02/07 ha
corretto i numeri headline di SKH01 per la fortuna d'ancora ma ha misurato il costo
d'esecuzione a offset 0 — e quel costo si è rivelato **fortunato quanto i numeri che
correggeva**. Ogni Δ fra due varianti misurato su una griglia ancorata eredita la fortuna
dell'ancora.
2. **Su una griglia di offset appaiati, la statistica è la mediana delle DIFFERENZE, non la
differenza delle mediane.** La seconda confronta offset diversi fra loro e qui ribaltava il
verdetto (faceva sembrare l'on-book completo migliore del solo TP, mentre è il contrario).
3. **Un lead lasciato "in forward-monitor" senza monitor e senza data di scadenza è un lead
perso.** DVOLSPREAD è stato in limbo 35 giorni. La disciplina che il progetto applica ai
candidati nuovi (config congelata + gate pre-registrato + cron) non era stata applicata a lui.
4. **Il claim di multiple-testing di un agente va ricontato, non creduto.** Il docstring diceva
72 celle; la griglia descritta ne contiene 729. Ricontare è conservativo e costa poco.
5. **Quando un meccanismo non generalizza, chiedersi PERCHÉ vale più del fatto che non generalizzi.**
Il fallimento di XSR01 sulle azioni ha prodotto la spiegazione migliore di come funziona sul
crypto: il demeaning vale quanto vale il fattore comune **residuo** dopo la residualizzazione,
ed è una proprietà dell'asset class, non del segnale.
@@ -0,0 +1,172 @@
# 2026-07-26-bis — Ondata: TP01 su barra parziale + i due gate mai costruiti
**Richiesta:** *"fai un'altra ondata di ricerca"*.
**Esito: 0 sleeve nuovi, 1 audit sul libro live, 2 gate codificati, 1 falso positivo del mio
stesso gate su uno sleeve in produzione (catturato e corretto), 1 replica indipendente di un
finding di tre settimane fa.**
**Book, pesi, cron, config: INVARIATI.**
Script: `scripts/research/r0726_tp01_partial_day.py`, `scripts/research/r0726_gates_retro.py`.
Test: `tests/test_gates_implausible_anchor.py` (13). Gate in `scripts/research/alt/altlib.py`.
Da dove nasce: il 26/07 ho misurato che il path live di SKH01 divergeva dal modello su entrambi
i lati (uscite e ingressi) e che **il modello era pessimistico**. Due domande restavano aperte, ed
erano piu' interessanti di un'ennesima caccia al segnale: *lo stesso difetto esiste sullo sleeve
che pesa il 75% del book?* e *perche' i gate che il progetto si e' raccomandato tre volte non
esistono ancora?*
---
## T1 — TP01 nel live legge una barra giornaliera fatta di UN'ORA
**Il fatto, verificato non dedotto.** `resample_tf(..., label="left", closed="left")` non scarta il
giorno in corso; `TrendPortfolio.current_target` prende `target_series(df)[-1]`. Il feed certificato
si ricostruisce alle 00:30 UTC, quindi per tutta la giornata il book vede il giorno corrente come
**1 barra oraria su 24** (misurato: `barre1h=1/24`). Il docstring diceva "ultima barra CHIUSA":
**falso nel live**, ed e' la terza volta in due giorni che un docstring di produzione afferma una
causalita' che il codice non ha.
**Due canali con segno atteso opposto**, quindi vanno separati:
- *esecuzione ritardata* — il modello ribilancia al confine 00:00, il live al primo cron dopo il
rebuild (~01:00);
- *barra parziale* — `c[t]` e' il prezzo delle 01:00 e `r[t]` e' un rendimento di **un'ora** contato
come giornaliero nella finestra di vol a 30 barre → vol sottostimata → **sovra-leva sistematica**.
**Tre path, un grado di liberta' per volta**, su griglia oraria (i confini sono diversi: solo
l'orario li rende confrontabili):
| offset 0 (ancora canonica) | FULL | HOLD | maxDD |
|---|---:|---:|---:|
| MODEL — `tgt[t-1]` dal confine 00:00 | 1.30 | 0.24 | 16.7% |
| CLOSED@+1h — scarta la parziale, ora del live | 1.27 | 0.16 | 17.5% |
| LIVE — `tgt[t]` da barra parziale, +1h | 1.25 | −0.07 | 17.5% |
**Banda delle 24 ancore, mediana delle DIFFERENZE APPAIATE:**
| effetto | FULL | HOLD |
|---|---|---|
| barra parziale (LIVE − CLOSED) | **−0.031** [−0.135,+0.065], pos. 7/24 | **+0.118** [−0.230,+0.277], pos. 19/24 |
| ritardo 1h (CLOSED − MODEL) | −0.004 [−0.053,+0.034], pos. 11/24 | −0.007, pos. 9/24 |
| totale (LIVE − MODEL) | −0.046, pos. 7/24 | +0.128, pos. 18/24 |
Leva LIVE/MODEL: **1.004** (mediana, invariata su tutta la banda).
**Verdetto: trascurabile.** Il ritardo d'esecuzione e' letteralmente una moneta (11/24). La barra
parziale muove ±0.03 su FULL e la sua "vittoria" su HOLD (+0.118) e' su una finestra sola e con
segno opposto su FULL — cioe' esattamente il profilo che il progetto ha gia' codificato come
sospetto. La sovra-leva prevista esiste ma vale **0.4%**. Nessun cambio al live.
**⚠️ Da notare: all'ancora canonica il quadro sembra peggiore del vero.** A offset 0 la barra
parziale costa **−0.230** sull'hold-out, che e' il **minimo dell'intera banda** — mentre la mediana
e' +0.118. Guardando solo l'ancora canonica avrei concluso "il live degrada TP01 di 0.23 sull'hold-out"
e sarebbe stato l'artefatto di un'ancora. E' la stessa lezione del 26/07 in versione speculare
(li' l'ancora canonica *nascondeva* un vantaggio, qui *inventa* un danno).
**Il risultato trasferibile non e' il numero, e' il perche'.** La parzialita' dell'ultima barra conta
in proporzione a **quanto il segnale pesa la barra piu' recente**:
> SKH01 e' un Donchian breakout su barra 230m: **la barra corrente E' il segnale** → stesso difetto,
> **+0.38** di Sharpe mediano. TP01 e' un TSMOM 30/90/180 giorni: l'ora mancante e' 1/24 di **una**
> osservazione su 30-180 → **±0.03**.
Corollario operativo: la conclusione di uno sleeve su questo tema **non si trasferisce** all'altro,
e la domanda "il mio live legge barre parziali?" ha una risposta diversa per ogni sleeve a seconda
della lunghezza del lookback. Cablato nei docstring di `current_target` e `resample_tf`.
---
## T2 — I due gate raccomandati tre volte e mai scritti
Debito dichiarato: `implausible_sharpe` (raccomandato il 26/06 su CC01, ri-raccomandato "con piu'
forza" il 02/07 su Albimarini) e `anchor_luck_band` (dichiarato "candidato gate futuro" il 02/07,
dopo il timing-luck trovato su 4/4 sleeve ancorati). Tre occorrenze, tre diagnosi a mano, zero codice.
### `implausible_sharpe`
Uno Sharpe/track troppo bello significa che **il rischio e' fuori dal dataset**, non che la strategia
sia buona. Trigger: Sharpe > 3, frazione di barre attive in perdita < 2%, Calmar > 20 o maxDD ~0, e
la **regola del tre** (0 perdite su N trade lascia un tasso vero fino a ~3/N — su un payoff deep-OTM
basta a ribaltare l'expectancy: e' il motivo per cui "0/142" non si legge come "senza rischio").
### `anchor_luck_band` + `anchor_luck_delta`
La griglia di ancore **non e' una griglia di parametri**, quindi il deflated-Sharpe non la conta: e'
multiple-testing invisibile. Il gate riporta la stima onesta (**mediana della banda**) e la fortuna
(canonica − mediana). `anchor_luck_delta` codifica l'errore che ho commesso stamattina: fra offset
appaiati la statistica e' la **mediana delle differenze**, non la differenza delle mediane — le due
mediane cadono su offset diversi e il verdetto puo' ribaltarsi.
### ⚠️ Il gate ha segnalato VRP01. Il difetto era MIO.
Prima stesura: perdite contate su **tutte** le barre. VRP01 e' settimanale su griglia giornaliera →
**94.2% di zeri** → "0.96% di perdite, coda sinistra assente" su uno sleeve **in produzione al 12%**.
Sulle barre **ATTIVE** le perdite sono **16.5%**, che e' esattamente la forma attesa di un credit
spread a rischio definito.
Verifica: zeri per sleeve — VRP01 94.2%, SKH01 87.6%, XS01 39.6%, GTAA01 31.9%, TP01 30.7%. Un gate
che conta gli zeri come "non perdite" avrebbe finito per segnalare mezzo book.
Ed e' la parte che vale la pena ricordare: **avevo gia' imparato questa lezione ieri**, cablando la
contabilita' a 3 stati del monitor DVOLSPREAD ("finestra misurata in barre attive, non giorni di
calendario"), e l'ho ripetuta il giorno dopo in un contesto diverso. Ora e' un test.
### Esito dell'applicazione retroattiva — copertura 7/7
| | Sharpe | maxDD | perdite/attive | esito |
|---|---:|---:|---:|---|
| TP01 | 1.29 | 14.3% | 48.7% (1865) | ok |
| XS01 | 1.36 | 10.9% | 46.6% (566) | ok |
| VRP01 | 1.08 | 11.9% | 16.5% (109) | ok |
| SKH01 | 1.45 | 18.1% | 55.6% (333) | ok |
| GTAA01 | 1.01 | 8.9% | 45.2% (1831) | ok |
| XSR01 (monitor) | 1.79 | 2.5% | 47.8% (892) | ok |
| DVOLSPREAD (monitor) | 0.68 | 25.5% | 50.8% (1949) | ok |
Controlli positivi (obbligatori: un gate che non segnala nulla puo' essere semplicemente rotto):
firma CC01 e firma deep-OTM **segnalate** con le motivazioni giuste; rumore a Sharpe 0.62 **non**
segnalato.
**Nota che vale per XSR01**, il cui gate di deploy scade il 23/10: il suo maxDD del 2.5% *non* e'
una coda mancante — il **47.8%** delle barre attive e' in perdita. Il DD basso viene da vol bassa
(2.3%) e dollar-neutrality. Il rischio #1 di XSR01 resta lo slippage non modellato, non un modo di
perdita nascosto.
### Replica indipendente del finding d'ancora del 02/07
Il gate, applicato alla cieca a TP01 sulle 24 ancore orarie, ritrova da solo cio' che il 02/07 era
stato diagnosticato a mano:
> canonica (00:00) **+0.237** = **92° percentile** delle 24 | mediana onesta **+0.056** |
> banda [−0.087, +0.247] | fortuna **+0.182**
Il 02/07 riportava mediana 0.04 e banda [−0.13, +0.30] con un'implementazione **separata**. Accordo
buono. **Il numero onesto dell'hold-out di TP01 e' ~+0.05, non 0.31.** (Il valore del sleeve resta
quello gia' stabilito e non ancorato: il taglio del drawdown ~6× vs buy&hold.)
---
## Cosa NON e' stato fatto, e perche'
**Il book ricalcolato sul path LIVE.** Sarebbe la sintesi naturale (SKH01 live > modello su entrambi
i lati; TP01 live ≈ modello) e cambierebbe la stima de-luckata del book, che oggi applica un ×0.6
assunto. Non l'ho fatto perche' le due misure vivono su **lenti diverse**: il simulatore di SKH01
compone per-trade a nozionale unitario, lo sleeve di `sleeves.py` e' vol-targeted. Combinarle
produrrebbe un numero che sembra preciso e non lo e'. **Follow-up dichiarato con l'ostacolo nominato:**
serve una versione vol-targeted del path live di SKH01 prima di toccare il fattore di de-luck.
Resta pero' una conseguenza qualitativa gia' solida: il ×0.6 fu scelto assumendo che il live
**degradi**. Su SKH01 e' misurato il contrario, su TP01 e' ~zero. **Il ×0.6 e' probabilmente
conservativo**, e la nota gia' presente in CLAUDE.md ("il ×0.6 sopra il path live rischia di contare
due volte la degradazione SKH01") va letta come confermata, non come cautela ipotetica.
---
## Regole nuove
1. **La parzialita' dell'ultima barra conta in proporzione a quanto il segnale pesa la barra piu'
recente.** Breakout/livelli: massima. Momentum a lookback lungo: ~nulla. Non trasferire la
conclusione fra sleeve.
2. **Ogni statistica di "frazione in perdita" si calcola sulle barre ATTIVE.** Uno sleeve flat la
maggior parte del tempo non ha una coda assente, ha meno osservazioni. (E: una lezione imparata
in un contesto non si applica da sola in un altro — questa era gia' cablata nel monitor
DVOLSPREAD il giorno prima.)
3. **Un gate nuovo si valida su un controllo positivo prima di credere ai suoi "ok".** Un gate rotto
e un gate soddisfatto producono lo stesso output.
4. **Anche un DANNO misurato a un'ancora sola e' fortuna d'ancora.** A offset 0 la barra parziale
sembrava costare −0.23 di hold-out: era il minimo della banda, mediana +0.12.
@@ -0,0 +1,337 @@
# 2026-07-27 — Il capitale già fermo, due sorveglianze mancanti, e la banda GTAA validata
Richiesta dell'operatore: *"proposte"*. Delle cinque proposte messe sul tavolo ne sono state
scelte quattro; questo diario le chiude tutte. **Book, pesi, cron-strategia, config: INVARIATI.**
Il cron guadagna due sorveglianze (non toccano l'esecuzione).
Script: `r0727_lumpsum_split.py`, `r0727_gtaa_band_gate.py`, `scripts/live/fee_watch.py`,
`scripts/live/monitor_health.py` + `src/live/monitor_health.py`.
Test: `test_lumpsum_split.py` (14), `test_gtaa_band_gate.py` (13), `test_fee_watch.py` (13),
`test_monitor_health.py` (16) = **56 nuovi**.
---
## 1. Il capitale già fermo — la leva mai misurata
### Il buco
Tutte le traiettorie pubblicate il 25 e 26/07 hanno `START = 600.0` **cablato**. Il progetto ha
misurato con grande cura il *calendario* dei versamenti (fattore 6 fra front e back loading) e
non ha mai misurato un **versamento iniziale** — mentre sul conto Revolut ci sono ~€10.000, di
cui €6.043 in XEON che rende ~0% reale netto. Il conto che gira ne ha 600.
### Validazione prima dei numeri
La macchineria è una generalizzazione di `r0726_venue_risk.simulate` (capitale iniziale e
deposito diventano parametri, tutto il resto identico incluso l'ordine di consumo dell'RNG).
Con lump=0 e €250/mese deve riprodurre **esattamente** i numeri del 26/07:
```
p=0.0% P(arrivare) 0.9487 vs 0.9487 · P(perso tutto) 0.0000 vs 0.0000 -> IDENTICO
p=1.0% P(arrivare) 0.8080 vs 0.8080 · P(perso tutto) 0.1842 vs 0.1842 -> IDENTICO
```
### Cosa compra un versamento iniziale (p=0, 100% Deribit, 20 anni)
| lump | dep/mese | totale versato | anni al muro | P(entro 20a) | cap. mediano | rendita a 20a |
|---|---|---|---|---|---|---|
| €0 | €0 | $600 | **mai** | 0.0% | $16.354 | €3.21/g |
| €2.000 | €0 | $2.780 | 19.0a | 2.5% | $75.773 | €14.89/g |
| €5.000 | €0 | $6.050 | 18.5a | 22.9% | $164.901 | €32.39/g |
| **€10.000** | **€0** | **$11.500** | **17.2a** | **61.7%** | **$313.448** | **€61.58/g** |
| €0 | €250 | $66.818 | 15.7a | 94.9% | $544.645 | €106.99/g |
| €2.000 | €250 | $68.998 | 15.1a | 96.8% | $605.454 | €118.94/g |
| €5.000 | €250 | $72.268 | 14.4a | 98.2% | $695.475 | €136.62/g |
| €10.000 | €250 | $77.718 | **13.3a** | 99.5% | $844.022 | €165.80/g |
La riga che sorprende è la quarta: **€10.000 fermi oggi, senza versare mai più nulla,** portano
al capitale-rendita in 17.2 anni mediani con P=62%. Il piano da €250/mese senza lump ci arriva in
15.7 anni con P=95%: più affidabile, ma costa $66.818 di versamenti contro $10.900 una volta sola.
### L'equivalenza — e la metrica che sbagliavo
Prima stesura: *"€10.000 subito risparmiano 30 mesi = €7.414 di versamenti futuri, cioè 0.7x"*.
Numero giusto, domanda sbagliata, e la conclusione che invita è l'opposto di quella corretta: il
valore di un lump-sum non è versare *meno*, è arrivare *prima*. La formulazione onesta è a quale
versamento mensile permanente equivale:
| lump | traguardo | equivale a versare | cioè |
|---|---|---|---|
| €2.000 | 15.1a (da 15.7a) | €281/mese | +€31/mese per 15 anni (€5.666) |
| €5.000 | 14.4a | €327/mese | +€77/mese per 14 anni (€13.241) |
| **€10.000** | **13.3a** | **€404/mese** | **+€154/mese per 13 anni (€24.523)** |
**€10.000 oggi valgono €24.500 di versamenti futuri: 2.45×.** È lo stesso meccanismo del
front-loading misurato il 26/07, portato al suo estremo.
### E il rischio di venue, che è la metà scomoda della domanda
Il 26/07 aveva già osservato che il front-loading mette più capitale sull'exchange *prima*.
Un lump-sum è il front-loading estremo, quindi va misurato col rischio dentro. A €10.000 il conto
sarebbe $11.500 e lo split diventa **possibile** — a quota IB **26%**, non il 25% preferito: sotto
$3.000 sulla gamba equity non c'è uno sleeve, c'è cash su un secondo conto.
| p annua | P(arrivare) CONC | SPLIT | SPLIT+costi | **P(perso tutto) CONC** | **SPLIT** |
|---|---|---|---|---|---|
| 0.0% | 99.5% | 98.2% | 98.0% | 0.0% | 0.0% |
| 0.5% | 93.2% | 91.4% | 91.2% | **9.7%** | **0.9%** |
| 1.0% | 87.1% | 85.2% | 85.0% | **18.4%** | **3.5%** |
| 2.0% | 76.2% | 73.2% | 73.1% | **33.7%** | **11.2%** |
| 5.0% | 50.5% | 47.9% | 47.8% | **64.1%** | **40.7%** |
Lo split costa **1.9-2.6pp** di P(arrivare) e taglia P(perso tutto) da 18.4% a 3.5% (a p=1%).
La colonna "SPLIT+costi" applica alla gamba IB il haircut dichiarato (0.8pp/anno di costi a
taglia piccola + 0.1pp di drag UCITS): **cambia lo 0.1-0.2pp**, cioè niente. Il costo della
gamba equity non è ciò che decide.
⚠️ **P(perso tutto) sotto CONC non dipende dal lump** (9.7/18.4/33.7/64.1% a qualunque taglia):
con un conto solo *"almeno un fallimento"* **coincide** con *"perso tutto"*, e quella probabilità
è una proprietà del tempo di esposizione. Il lump non la peggiora — moltiplica ciò che porta via.
### La sezione che serviva davvero: e se la seconda gamba fosse solo liquidità?
GTAA01 **oggi non è deployabile** (blocco PRIIPs; la via UCITS su Degiro è verificata ma in
preparazione). Quindi lo split disponibile *subito* è Deribit + un conto fermo.
| p annua | P(arrivare) CONC | SPLIT-GTAA | **SPLIT-CASSA** | P(perso tutto) CONC | SPLIT |
|---|---|---|---|---|---|
| 0.5% | 93.2% | 91.4% | **90.7%** | 9.7% | 0.9% |
| 1.0% | 87.1% | 85.2% | **84.5%** | 18.4% | 3.5% |
| 2.0% | 76.2% | 73.2% | **72.6%** | 33.7% | 11.2% |
**Tenere ferma la seconda gamba invece di investirla costa 0.6-0.8pp di P(arrivare) e non toglie
NULLA alla protezione** — che è identica, perché dipende da *quanti conti* falliscono, non da cosa
ci sta sopra. **La protezione dalla rovina non è bloccata dal PRIIPs, non aspetta la validazione
della banda, non richiede che GTAA01 esista: richiede un secondo conto.**
### Soglie
* split a quota **raccomandata** (25%): da **$12.000**
* split forzando la quota fino al 35%: da **$8.571**
* con un lump da €10.000 il conto sarebbe **$11.500** → possibile, ma a quota 26%.
La riapertura della decisione di venue è fissata a $20.000. Un lump da €10k porta il conto sotto
quella soglia ma sopra la fattibilità tecnica — ed è **un cambiamento del piano**, il caso in cui
CLAUDE.md dice esplicitamente di riaprire prima. Questa tabella è il materiale per farlo; la
decisione resta dell'operatore, come il 26/07.
⚠️ **Cosa questo filone NON decide:** quanto dei €6.043 in XEON sia un vero fondo d'emergenza.
Un fondo d'emergenza non è capitale disponibile, e la tabella qui sopra misura *cosa compra ogni
euro che entra*, non *quali euro debbano entrare*.
---
## 2. Fee Deribit — un sorvegliante invece di un promemoria
Il nuovo schema entra in vigore il **1° agosto** e l'annuncio non contiene numeri. La regola era
già decisa in anticipo (≤5bps/lato → nulla; >10bps → rivedere il peso di SKH01, 4× più
fee-sensibile di TP01). Mancava solo il modo di accorgersene.
`public/get_instrument` espone il tier **base** — che è quello che paga un conto da $600, dove
ogni soglia VIP è fuori portata — senza chiavi:
```
strumento taker maker liquidaz.
BTC-PERPETUAL 5.00 0.00 75.00
ETH-PERPETUAL 5.00 0.00 90.00
verdetto: [OK] taker 5.0bps <= 5: non si tocca nulla
```
`scripts/live/fee_watch.py` (in `cron_daily.sh`) confronta con l'ultima lettura, allerta su
**qualsiasi** cambiamento — taker, maker e liquidation fee, che l'annuncio tocca tutti e tre — e
applica la regola congelata. Cross-check best-effort sulla fee **realmente pagata** dai trade del
conto, con `{}` che significa *non misurata* e non *zero*.
`test_baseline_e_quella_dei_backtest` lega `BASELINE_TAKER_BPS` al default `fee_rt=0.001` di
`backtest_signals`: se un giorno le due divergessero, il confronto smetterebbe di avere senso.
---
## 3. I forward-monitor non erano sorvegliati
**Tre gate pre-registrati** — STATARB **27/09**, XSR01 **23/10**, DVOLSPREAD kill **24/10** — si
decideranno leggendo serie forward. Di quelle serie **una sola** aveva una guardia d'integrità
(`paper_dvolspread`, contabilità a 3 stati + veto sotto l'80%). Le altre nessuna: `paper_xsr`,
`paper_statarb`, `paper_prevday`, `paper_portfolio`, `paper_combo` → 0 controlli.
Un monitor fermo produce silenzio, e **il silenzio in una serie di ritorni si legge come zero**,
cioè come una misura. È lo stesso schema già pagato con `fresh_5m` (26/07) e col feed-freeze del
14/07.
`src/live/monitor_health.py` misura **due guasti diversi**, perché una sola misura non basta:
* **coda** — l'ultima barra è vecchia (il monitor si è fermato adesso);
* **buchi interni** — la serie è più corta del proprio arco temporale. *Una guardia di sola
freschezza lascerebbe passare un monitor che ha perso il 30% delle barre di mezzo e ha scritto
stanotte* — ed è esattamente il guasto che falsifica un gate senza farsi notare.
Cadenze dichiarate per monitor, perché sbagliarle significa un falso allarme a settimana:
`paper_prevday` registra a barra **oraria** (864 barre in 36 giorni); `paper_combo` vive sul
calendario di **borsa** (venerdì è l'ultima barra fino a lunedì). Soglia di copertura **0.80**,
riusata di proposito dal veto DVOLSPREAD: una soglia diversa per monitor renderebbe i gate non
confrontabili.
Stati: `OK` / `FERMO` / `BUCATO` / `ASSENTE` / **`NUOVO`** — quest'ultimo per i monitor troppo
giovani per un giudizio (XSR01 e DVOLSPREAD hanno 2 barre): non allerta, ma **non risulta sano**.
Stato al 27/07: 6/6 monitor giudicati, tutti OK; `paper_combo` al 96% per il 3 luglio — festività
di borsa che `np.busday_count` non conosce. È un **limite dichiarato** e conservativo (segnala di
più, non di meno).
I test includono i **controlli positivi** obbligatori (un rilevatore che non ha mai segnalato
nulla è indistinguibile da uno rotto): monitor fermo → FERMO, serie bucata e fresca → BUCATO,
stato assente → ASSENTE.
---
## 4. La banda GTAA01 al 25% — validata
La proposta del 27/07 (banda = 25% della gamba invece di $50 assoluti) era dichiarata
esplicitamente non validata. Griglia **30 celle** (5 cadenze × 6 bande) su **29.9 anni** di path
di produzione, annualizzazione **√252** (una serie su giorni di borsa passata a 365 esce con lo
Sharpe ×1.20: l'errore del 25/07).
**(A) Selezione in-sample** (cella scelta sui soli dati pre-2015, letta sul 2015+, l'hold-out
equity documentato di GTAA01):
```
cella scelta al buio : cadenza 1, banda 25% -> IS 0.66 · OOS 0.90 · FULL 0.74
cella proposta 27/07 : cadenza 5, banda 25% -> IS 0.62 · OOS 0.86 · FULL 0.70
rango della proposta : 4/30 in-sample · 5/30 sull'hold-out
```
Il rango **non migliora** passando all'hold-out → non è selezione-sull'hold-out (la firma sarebbe
il contrario). La cella scelta al buio preferisce il controllo **giornaliero**, che vale +0.04 di
Sharpe e costa **42 ordini/anno con 250 controlli manuali**: il conto d'esecuzione non ha API
(misurato il 27/07), quindi non è una configurazione, è un'ipotesi. La cadenza settimanale costa
−0.04 e compra l'eseguibilità a mano.
**(B) Deflated Sharpe** sulle 30 celle, dpy=252: **0.999 PASS** (massimo atteso sotto il nullo
0.14), sia per la proposta sia per la cella scelta al buio.
**(C) Null de-levering** — e qui il modo di fallire **non è quello atteso**:
| banda | corr col riferimento | vol/rif | Sh FULL | |
|---|---|---|---|---|
| 0% | 0.983 | 1.03 | 0.59 | OK |
| 10% | 0.980 | 1.02 | 0.64 | OK |
| **25%** | **0.951** | **0.99** | **0.70** | OK (al bordo) |
| 40% | 0.907 | 1.04 | 0.67 | fuori traccia |
| 60% | 0.859 | 1.10 | 0.59 | fuori traccia |
Allargando la banda **la volatilità non scende**: il null de-levering classico non morde. Ciò che
si rompe è il **tracking** — lo sleeve tiene posizioni vecchie e smette di somigliare a sé stesso.
E i due segnali concordano: oltre il 25% la correlazione cala *e* lo Sharpe smette di migliorare,
quindi non esiste una zona in cui il numero premia il congelamento. ⚠️ Ma **il 25% è al bordo**
(corr 0.951 contro una soglia di 0.95), non al centro di un plateau: va citato così.
**Invarianza al capitale** — la ragione per cui la proposta esiste:
| capitale | banda 25% | ord/anno | Sharpe | | banda $50 fissa | ord/anno | Sharpe |
|---|---|---|---|---|---|---|---|
| $3.000 | $125 | 25 | **0.66** | | $50 | 65 | 0.52 |
| $10.000 | $417 | 25 | **0.70** | | $50 | 92 | 0.62 |
| $50.000 | $2.083 | 25 | **0.71** | | $50 | 134 | 0.66 |
⚠️ **25 ordini/anno, non i 21 citati il 27/07**: stimatore diverso (qui il gate contato sulla
griglia dei controlli, 30 anni, veicoli USA; lì i cambi di posizione sulla finestra UCITS di 3.2
anni). L'*invarianza* — che è la proprietà sotto esame — regge in entrambi.
**Impatto sul book: Sharpe FULL 2.221 → 2.221, maxDD 6.08% → 5.94%.** Zero. Il book modella
GTAA01 a $10.000, dove la banda fissa già funziona: **il valore della proposta è tutto al capitale
piccolo** (0.52 → 0.66 a $3k), cioè al deploy.
**Verdetto: la proposta passa i tre gate.** Produzione **NON toccata**: cambiare
`REBAL_BAND_USD` non sposta un solo numero pubblicato, e lo sleeve non è deployabile prima dei
$20k. Il cambio si applica **al deploy**, insieme alla scelta del broker, con questo diario come
giustificazione.
---
## 5. Il debito chiuso di straforo
`edge_watch.py` — i criteri di kill del book **live** — è in cron dal 26/07 e **non era in
CLAUDE.md** (zero occorrenze). Il criterio di morte di ciò che gira con soldi veri non stava nella
memoria operativa del progetto: la sessione successiva avrebbe ragionato come se non esistesse.
Aggiunto.
---
## 6. Regole
1. **Un parametro d'esecuzione scelto guardando il risultato è selezione come ogni altra**, e va
passato per gli stessi gate — anche quando "è solo esecuzione" e non tocca l'allocazione.
2. **Quando si misura l'effetto di un vincolo, si misura anche il vincolo del vincolo.** Lo split
di venue a $11.500 non è "25% su IB": è 26%, perché sotto $3.000 la gamba equity non esiste.
È il capitale a scegliere la quota, non la preferenza.
3. **Il valore di un versamento iniziale non si misura in versamenti risparmiati** (domanda
sbagliata, rapporto 0.7×) ma in **versamento mensile equivalente** (2.45×). La prima
formulazione invita alla conclusione opposta.
4. **Una guardia di freschezza non è una guardia d'integrità.** Il guasto che conta — la serie
bucata e fresca — passa la prima e fallisce la seconda.
5. **Il verdetto pre-scritto va confrontato coi numeri prima di stamparlo.** Il testo di (C)
diceva "il numero migliora perché esce dal mercato": la vol misurata *non scendeva*, quindi era
falso. Il fallimento vero era un altro (tracking), e dirlo giusto vale più che avere ragione.
6. **Un rischio non-diversificabile si compra con un secondo conto, non con un secondo sleeve.**
La protezione dalla rovina è identica con GTAA01 o con liquidità: dipende da quanti conti
falliscono, non da cosa ci sta sopra.
---
## 7. Addendum — "€5k messi dove" (stessa sessione)
Domanda diretta dell'operatore dopo il riassunto. Ha richiesto una misura nuova, perché €5.000
cade in una zona che la tabella §1 non copriva: a **$6.050** lo split *con GTAA01* è impossibile
(servirebbe il 50% del conto per fare i $3.000 di gamba minima), ma lo split in **liquidità** non
ha soglie di eseguibilità.
Due correzioni al volo prima dei numeri:
1. **La configurazione vera non è quella che avevo tabulato.** `config/live.json` è stato alzato
il 26/07 *"in previsione del versamento (EUR 5.000 + 500/mese → equity ~$6.050)"*: il piano
dell'operatore è **€500/mese**, non i €250 di tutte le tabelle. Rimisurato su quella.
Conseguenza operativa: **nessuna azione di config al deposito** — il cap è già `min($3.000,
equity_osservata × 0.5)`, quindi a $6.050 vale $3.000/asset = leva lorda ≤1x, ed è protetto dal
watermark contro il caso "cap alto su conto piccolo".
2. **Niente si sblocca a $6.050.** GTAA01 richiede $3.000 *sulla gamba* (50% del conto) e non è
comunque deployabile (PRIIPs); XS01 ~$20.000; XSR01 è sotto gate fino al 23/10. Il book resta
TP01+SKH01 → **l'unica domanda è quanta parte non sta sull'exchange.**
Seconda gamba = liquidità ferma, due letture del suo rischio ([A] rischiosa come Deribit,
conservativa; [B] conto bancario con tutela dei depositi, realistica):
| fuori exchange | P(arrivare) | anni | P(perso tutto) [A] | [B] | salvato se cade |
|---|---|---|---|---|---|
| 0% | 89.4% | 11.4a | 18.4% | 18.4% | $0 |
| 10% | 89.0% | 11.8a | 3.5% | **0.0%** | $6.818 |
| **25%** | **88.5%** | **12.4a** | 3.5% | **0.0%** | **$17.045** |
| 40% | 87.8% | 13.3a | 3.5% | 0.0% | $27.272 |
*(p exchange = 1%; €5.000 + €500/mese, 20 anni)*
⚠️ **Due letture che il tavolo nasconde, e senza le quali si sceglie male.**
**(a) P(perso tutto) SATURA a qualunque quota > 0** (3.5% al 10, 25 e 40%): la protezione binaria
si compra col semplice fatto di *avere* un secondo conto, non con quanto ci si mette. Ciò che
distingue le quote è la colonna del salvataggio.
**(b) ⚠️ Errore mio, corretto in sessione.** La prima versione di quella colonna riportava il
capitale a 20 anni *condizionato al fallimento*, e dava $77k al 10% — undici volte il valore
vero. Artefatto della convenzione ereditata dal 26/07: **alla morte di un venue i versamenti
successivi vengono dirottati ai superstiti, e scartati se non ne resta nessuno.** Quel numero
attribuiva quindi allo split il valore di *continuare a versare*, che si ottiene comunque
aprendo un altro conto dopo il guasto. La misura onesta è il **salvataggio istantaneo**: quanto
resta nel momento in cui l'exchange cade. Congelato in
`test_il_salvataggio_e_istantaneo_non_a_scadenza`.
**Il prezzo, in chiaro:** tenere fuori il 25% costa **0.9pp** di probabilità di arrivare e **circa
un anno** di ritardo mediano (11.4 → 12.4), e compra ~$17k mediani nel 18% di percorsi in cui
l'exchange sparisce (a p=1%), più P(perso tutto) → 0 nella lettura realistica.
**E la parte che non costa nulla:** quei soldi sono *già* fuori dall'exchange, in XEON. Lo split
non si costruisce spostando denaro su un secondo venue — **si ottiene versandone di meno.** Con
€6.043 in XEON, deporne €5.000 lascia fuori ~16% del capitale investito: già dentro la banda
10-25%, a costo operativo zero.
**REGOLA: quando una metrica binaria satura, la decisione va spostata sulla metrica continua** —
qui P(perso tutto) non distingue il 10% dal 40%, il salvataggio sì.
+142
View File
@@ -0,0 +1,142 @@
# 2026-07-29 — L'allerta funzionava, la sua CAUSA era una riga cablata
**Fatto operativo del giorno.** Il 29/07 il feed 5m che alimenta il segnale SKH01 e' ricaduto sul
feed certificato in **6 giri orari su 8** fra le 05:00 e le 12:00 UTC. L'allerta cablata il 26/07 ha
segnalato **ogni volta** — ha fatto esattamente il suo lavoro. Poi ha stampato una causa che non
aveva misurato.
**Codice:** `src/live/livefeed.py` (`last_fetch_error`), `src/live/book.py` (`skh_feed_errors` nel
report), `scripts/live/book_execute.py` (allerta con la causa), `scripts/cron_book.sh` (nota sul
minuto). **Test:** `tests/test_skh_feed_freshness.py` (11 → **16**). **Book, pesi, config, strategia:
INVARIATI.** Nessuna posizione aperta durante l'incidente (book flat: TP01 risk-off, SKH01 flat).
---
## 1. Cosa e' successo, misurato
Dal log `logs/cron_book.log` (la VPS si e' riavviata alle **04:11 UTC**, kernel 6.8.0-134 →
6.8.0-136; il giro delle 04:00 non e' partito perche' la macchina era gia' giu' dalle 03:55):
```
giro (UTC) eta' ultima barra 5m durata del giro
05:00 265 min 46 s
06:00 325 24
07:00 385 29
08:00 445 26
09:00 505 34
10:00 565 25
11:00 0 (fresco) 16 <- ma qui e' fallita la lettura del CONTO
12:00 685 25
12:07 0 (fresco) 10
```
L'eta' cresce di **60 minuti a ogni giro**: e' la firma esatta del fallback, cioe' l'ultima barra
resta quella del feed certificato (rebuild giornaliero delle 00:30) mentre l'orologio avanza. Al
picco la latenza d'uscita di SKH01 e' passata da **~1 ora a ~11 ore**.
## 2. Cosa ha funzionato e cosa no
**Ha funzionato:** l'instrumentazione del 26/07. `feed_age_minutes` → `skh_feed_age_min` → allerta
Telegram, 6 volte su 6, con la scelta dichiarata allora (**allerta, non blocca** — bloccare
fermerebbe anche il ribilancio di TP01, nettato sullo stesso strumento, per un guasto di rete).
**Non ha funzionato:** la riga che diceva *perche'*. Era questa, **cablata**:
```python
"nota": "fresh_5m e' ricaduto sul feed certificato (fetch pubblico KO)"
```
Non veniva da nessuna misura: veniva stampata identica in ogni caso, compreso quello in cui la coda
fresca **era** attaccata e il vecchio era il certificato stesso. E' una presunzione con l'aspetto di
un dato — la forma di difetto che questo progetto ha gia' pagato tre volte in docstring di
produzione (26/07, tre correzioni in due giorni).
Peggio: la causa vera **non era recuperabile a posteriori**, per costruzione. In
`_fetch_recent_5m` l'eccezione di pagina viene ingoiata con un `break` e la funzione ritorna quel
che ha raccolto; se a fallire e' la **prima** pagina il risultato e' un DataFrame vuoto, che a valle
e' indistinguibile da "il venue non ha barre". Quando il guasto e' rientrato, non resta niente da
interrogare — e infatti alle 12:14, provando a mano, `fresh_5m` rispondeva in 1.7 s senza errori.
## 3. La correzione: registrare la causa, non indovinarla
`livefeed._LAST_ERROR` + `last_fetch_error()`. Il fallback resta **silenzioso come comportamento**
(mai operare a cieco > mai operare, scelta del 26/07 confermata): quello che smette di essere
silenzioso e' il **perche'**. La causa risale fino al report (`skh_feed_errors`, per asset) e fino
all'allerta, che ora dice cosa e' successo invece di ipotizzarlo.
Tre guasti che prima erano la stessa riga, e ora sono tre righe diverse:
| caso | cosa si vede oggi |
|---|---|
| eccezione al fetch (rete, rate limit, venue) | `RuntimeError: 429 ... (pagina 1, BTC/USD:BTC)` |
| risposta senza barre, nessuna eccezione | `nessuna barra restituita da BTC/USD:BTC (risposta vuota...)` |
| **coda attaccata, ma il certificato e' vecchio** | `coda fresca attaccata: il feed certificato stesso e' vecchio` |
La terza riga e' quella che la nota cablata **negava**: e' il caso in cui il colpevole non e' la rete
ma il rebuild giornaliero, cioe' il feed-freeze del 14/07 in un'altra veste.
⚠️ Il caso intermedio, che un test pigro salta: l'errore a **meta' paginazione**. La coda parziale
viene attaccata comunque — quindi il feed non e' "caduto", e' solo piu' vecchio del dovuto — e
siccome la paginazione va **in avanti**, cio' che manca sono le barre **piu' recenti**. E' proprio
il caso in cui l'eta' da sola direbbe poco. Blindato in
`test_causa_registrata_anche_con_coda_TRONCATA`.
Blindato anche che la causa **non sopravviva a una chiamata riuscita**: un errore appiccicato
farebbe allertare su un guasto gia' rientrato, e un'allerta che grida senza motivo e' un'allerta che
si smette di leggere.
## 4. Sull'onestà della diagnosi: la causa del 29/07 resta IGNOTA
Ed e' importante scriverlo, perche' la tentazione era chiudere il cerchio con una spiegazione
plausibile. Cio' che si sa e' solo **circostanziale**:
- i giri falliti durano quanto quelli riusciti (**16-46 s in entrambi gli stati**) → errore
**immediato**, non timeout;
- la finestra si apre subito dopo il **riavvio delle 04:11**, ma non si chiude con esso (alle 11:00
funziona, alle 12:00 no);
- lo stesso giorno il percorso del **conto** — rete diversa, via `cerbero-mcp`, stesso venue a valle
— rispondeva `ReadTimeout(15s)` / `404` / `502`;
- i due percorsi falliscono **in alternanza**, non insieme (11:00 feed ok + conto ko; 12:00 conto ok
+ feed ko).
Ipotesi compatibili e **non distinguibili a posteriori**: rate limit per-IP del venue, contesa di
rete/CPU sulla VPS al minuto tondo, degrado post-riavvio. Una prima stesura di questa modifica
scriveva nei commenti "*la causa vera era il rate limit Deribit per-IP saturato da un altro progetto
sulla stessa VPS*" come se fosse un fatto: **rimossa**. Sarebbe stato lo stesso difetto della riga
che stavo correggendo, scritto meglio.
## 5. Il ripiego sul cron, dichiarato come tale
Il job e' stato spostato da `0 * * * *` a **`7 * * * *`** durante l'incidente (ultimo giro al minuto
tondo: 12:00; primo al :07: 12:07, riuscito). Motivo: l'ipotesi della contesa al minuto tondo, che e'
quando parte tutto il resto della macchina.
⚠️ **Non e' un fix verificato: e' un ripiego da UNA osservazione**, preso perche' costa zero. Un
giro riuscito al :07 contro sei falliti al :00 non e' un esperimento — e' un punto. Se il feed torna
stantio anche al :07, l'ipotesi e' morta; e in entrambi i casi la risposta la dara' `skh_feed_errors`
alla prossima occorrenza, non un altro ragionamento. La nota sta in testa a `scripts/cron_book.sh`,
perche' la riga di crontab vive fuori dal repo e una mitigazione invisibile e' una mitigazione che
verra' rimossa per sbaglio.
## 6. Sottoprodotto: anche "conto offline" diceva solo che era offline
Stesso buco, altro ramo. Quando `online` e' falso la ragione c'e' gia' — sta in `mark_src`
(`"fallback close (<Eccezione>)"`) — ma non veniva **mai** stampata: l'allerta diceva *"conto
offline, salto l'esecuzione"*, che e' vero e inutile. Ora l'allerta porta `mark_src` per asset. Il
comportamento (fermarsi, non operare a cieco) e' invariato.
---
## Regole
1. **Una nota di diagnosi cablata e' peggio di nessuna nota.** Nessuna nota manda a guardare i dati;
una nota sbagliata manda a guardare la pista sbagliata, e sembra una misura.
2. **Se un errore viene ingoiato per non bloccare, va registrato nello stesso punto in cui lo si
ingoia.** Fra il `break` e la fine dell'incidente non c'e' un secondo momento buono: quando la
diagnosi diventa urgente, il guasto e' gia' rientrato.
3. **Un'allerta risponde a due domande diverse — *cosa* e *perche'*.** La prima decide (si opera o
no), la seconda ripara. Misurare solo la prima costa un'intera occorrenza del guasto.
4. **Una mitigazione basata su un'osservazione sola si applica pure, ma si scrive che lo e'** —
altrimenti fra tre mesi e' una scelta di progetto di cui nessuno ricorda la fragilita'.
5. **Distinguere i guasti anche quando l'azione e' la stessa.** "Rete ko", "venue senza barre" e
"certificato vecchio" portano tutti a "non mi fido del segnale", ma a tre riparazioni diverse.
@@ -0,0 +1,179 @@
# 2026-07-30 (2º filone) — cerbero-bite viene eliminato: assorbita la raccolta, non il motore
**Decisione dell'operatore:** `/opt/docker/cerbero-bite` viene smantellato e il suo lavoro passa a
PythagorasGoal. **Esito:** book, pesi, config e strategia INVARIATI. Cambia solo *chi* raccoglie
la catena opzioni — e cambia in meglio su tre assi misurati.
## Cosa di bite valeva la pena, e cosa no
L'unica parte **irreversibile** è il dato: una catena opzioni non si ricostruisce a posteriori
(Deribit non serve book storici, non esiste un secondo venue). Tutto il resto è codice, e il codice
si riscrive.
| parte | assorbita? | perché |
|---|---|---|
| `option_chain_snapshots` (1.23M righe) | **sì** | ha appena falsificato il *f* di VRP01; irrecuperabile |
| `market_snapshots` (17.402 righe, 26/03+) | **sì** | dealer net gamma, gamma flip, rischio liquidazioni, funding cross: dati che il progetto non ha altrove |
| raccolta continua | **sì, riscritta** | senza, l'archivio si congela e "aspettare il crash" muore |
| `dvol_history` | no | `fetch_dvol.py` ha storia **più lunga** (2020+ vs 2026-05): copiarla sarebbe una seconda copia peggiore |
| motore credit-spread ETH | no | il progetto ha già la regola *niente short-vol da modello in deploy*; e il conto era a $52 contro un minimo di $720 |
| GUI, kill switch, dead-man, audit chain | no | PythagorasGoal ha già `venue_watch`, `edge_watch`, `monitor_health`, `fee_watch` |
| `decisions` / `positions` | no | 59 valutazioni d'ingresso, 0 posizioni |
Prima di toccare qualsiasi cosa: snapshot `VACUUM INTO` del DB (461 MB) + `audit.log` + config in
`/opt/docker/backups/manual/cerbero-bite-20260730/`, con SHA256.
## Il collettore nuovo — tre difetti di bite non replicati
`scripts/live/collect_chain.py`, cron **`25 * * * *`**.
**1. Una chiamata per strumento invece di due.** `public/get_order_book?depth=3` restituisce già
quote, greche, IV, open interest, volume, book **e** `underlying_price`. Bite chiamava ticker e
orderbook separatamente: doppio costo, e i due potevano riferirsi a istanti diversi.
Un `get_book_summary_by_currency` iniziale dà l'OI di tutta la catena in **una** chiamata e
prefiltra sotto soglia: 551 → **~290 chiamate per asset**.
**2. Pacing invece di raffica.** ⚠️ **Il carico non è mai stato il problema.** ~570 chiamate/ora
sono **0.16/s** se distribuite; bite le sparava in ~26 secondi (**~44/s**) e si auto-saturava il
rate limit per-IP — 12.186 risposte 429 in 26 ore, il 96% nel minuto `:00`. Token bucket a 4/s +
backoff: primo giro reale **574 chiamate, 0 risposte 429**.
Il minuto `:25` è una scelta, non un default: `:00` era la raffica di bite, `:07` è `cron_book`
(da lì passa il feed 5m di SKH01, la cosa che non deve trovare l'IP occupato).
**3. Stato esplicito della quota.** `quote_status` ∈ {`ok`, `no_quote`, `error`}:
- `no_quote` = il venue ha risposto, il book è vuoto → **fatto di mercato**
- `error` = la chiamata è fallita → **fatto di infrastruttura**
Bite li faceva collassare entrambi su "riga con bid/ask NULL", ed è per questo che il guasto del
29/07 (50% di quote perse per 38 ore) non ha prodotto **nessun** segnale: il conteggio righe non
cambiava. Per lo stesso motivo `book_depth_top3` ora è **NULL su errore, mai 0** — bite scriveva 0,
e "chiamata fallita" diventava indistinguibile da "book vuoto".
⚠️ Le righe ereditate portano `quote_status='unknown'`. Bite non registrava il perché e **a
posteriori non è ricostruibile**: si dichiara l'ignoranza invece di inventare uno stato.
## Il silenzio, di nuovo
Un collettore fermo non produce niente, e il niente si legge come "nessun dato quel giorno" invece
che come "raccolta rotta" — su una serie irrecuperabile è il modo più caro di sbagliare. Ogni giro
scrive una riga in `data/chain_collect/runs.jsonl`, **anche quando fallisce**, e
`monitor_health` la sorveglia con cadenza 1h e `max_age_h=3` (due giri persi). È la stessa lezione
di `paper_dvolspread` e di `fresh_5m`, applicata prima che serva invece che dopo.
## Un difetto trovato per strada: due formati ISO nella stessa colonna
L'import del contesto restituiva **17.310 righe dal 2026-05-01** contro le 17.402 dal **2026-03-26**
del database. 92 righe di backfill sono scritte senza microsecondi
(`2026-03-26T12:00:00+00:00`), le altre con (`2026-05-01T15:45:00.062918+00:00`).
`pd.to_datetime` senza `format` **inferisce un formato solo** dal primo elemento e manda gli altri
a `NaT`, che il `dropna` a valle rimuoveva **in silenzio**: la serie perdeva i suoi 5 settimane più
vecchi e la data d'inizio slittava di un mese senza un messaggio.
Corretto con `format="ISO8601"` **e** con uno scarto rumoroso (`_drop_unparsed` stampa quante righe
cadono e perché). **REGOLA: `dropna` dopo un parsing è un rilevatore di difetti travestito da
pulizia — se toglie righe deve dirlo.** Un import silenzioso non è un import pulito, è un import
che non sai se ha funzionato.
## Eliminazione (stessa sera, 21:20 UTC)
Container rimossi, volume `cerbero-bite_bite-data` rimosso, immagine `cerbero-bite:dev` rimossa,
`/opt/docker/cerbero-bite` cancellata. **12 GB liberati** (73G → 61G di disco usato).
Prima di cancellare, quattro verifiche — nessuna delle quali era "il backup esiste":
1. **Lo snapshot è *completo*, non solo integro.** SHA256 `OK` su entrambi i file, ma soprattutto
conteggi confrontati tabella per tabella fra il volume vivo e lo snapshot: `option_chain_snapshots`
1.232.212, `market_snapshots` 17.406, `decisions` 59, `positions` 0 — **4 su 4 identici**, e
identici anche ai parquet importati. *Un hash prova che il file non è corrotto, non che contenga
tutto.*
2. **I 10,6 GB di backup interni al volume non contenevano dati unici.** 32 snapshot sqlite storici:
la domanda giusta non era la loro dimensione ma *se bite potasse lo storico*. Tutti e tre i
campioni controllati (09/06, 01/07, finale) hanno **la stessa riga più vecchia**
(`2026-05-01T20:53:49.294928`) e conteggi monotoni crescenti (218.500 → 665.949 → 946.990 →
1.232.212) → nessuna potatura, sottoinsiemi stretti del DB finale.
3. **Nessuna dipendenza a runtime.** Né cron, né systemd, né route traefik, né altri progetti: i
soli riferimenti rimasti sono documentazione (questo diario, CLAUDE.md, un commento in
`backup.sh` e uno in `health-watch.py`) — cioè memoria storica, che è corretto lasciare.
4. ⚠️ **`cerbero-mcp` è un progetto DIVERSO e serve a PythagorasGoal** (universo Hyperliquid, e il
percorso del conto): progetto compose separato, e la rete `traefik` che condividono è dichiarata
`external:` nel compose di bite → `down -v` non la tocca. Verificato dopo: `Up 41 hours
(healthy)`. *Due servizi con lo stesso prefisso nel nome sono un incidente che aspetta.*
Il codice non è stato cancellato: era già su Gitea (`Adriano/Cerbero-Bite`), e l'unica modifica
locale pendente — il ripiego del collector da `:00` a `:20`, superato dal successore — è stata
committata e pushata come commit di dismissione. **Il dato era l'unica parte irreversibile.**
**REGOLA: prima di cancellare una sorgente si verifica che la copia sia completa, non che
esista** — e "quanto è grande" non è la domanda da fare a un backup, "cosa contiene che l'originale
non ha più" sì.
### Il primo giro dopo l'eliminazione, e un modo di leggere male il nostro stesso indicatore
Verificato invece che dedotto (21:25 UTC, il primo giro con bite già cancellato):
**576 chiamate, 0 risposte 429, 0 errori.** È il controllo che conta, perché il guasto del 29/07
era esattamente la raffica di bite che saturava il rate limit per-IP.
| giro | righe | ok | no_quote | error | **due lati** |
|---|---|---|---|---|---|
| 20:00 | 570 | 552 | 17 | 1 | 71.6% |
| 20:06 | 570 | 570 | 0 | 0 | 75.8% |
| 20:22 | 570 | 570 | 0 | 0 | 75.6% |
| 20:25 | 570 | 570 | 0 | 0 | 75.6% |
| **21:25** | **572** | **572** | **0** | **0** | **75.5%** |
(Il `1 error / 17 no_quote` delle 20:00 è il primo giro in assoluto, con bite ancora acceso a
sparare al minuto `:00`: la firma del problema, catturata nel suo ultimo momento di vita.)
⚠️ **`ok = 572` non significa "572 quote complete".** Nel collettore `ok` vuol dire *almeno un lato
del book* (`bid is not None or ask is not None`); le righe con **entrambi** i lati sono **432 su
572 (75.5%)**. Il resto sono book a un lato solo, normali sulle opzioni molto OTM. Che sia
strutturale e non un degrado si vede dal fatto che la percentuale è **identica a tutti i giri**,
prima e dopo l'eliminazione — non dal fatto che sembri alta.
È la lezione «*una riga presente non è un dato presente*» un livello più in giù, applicata allo
strumento costruito **per** quella lezione: la battuta di cuore distingue `ok`/`no_quote`/`error`,
quindi vedrebbe il guasto del 29/07 (quote vuote), ma **non** vedrebbe una deriva più sottile —
book che diventano progressivamente a un lato solo. Non è cablata una soglia: con cinque giri di
storia sarebbe inventata, e una soglia inventata è peggio di nessuna soglia. **La colonna da
guardare quando ci saranno settimane di serie è "due lati %".**
## File
- `scripts/live/collect_chain.py` + `scripts/cron_chain.sh` — la raccolta (cron `25 * * * *`)
- `scripts/analysis/import_cb_archive.py` — import una-tantum dell'archivio
- `scripts/analysis/certify_cb_chain.py` — certificazione dello store (era `fetch_cb_chain.py`)
- `scripts/research/cblib.py` — `load_chain()` ora unisce archivio + raccolta
- `src/live/monitor_health.py` — nuovo spec `collect_chain`
- `tests/test_collect_chain.py` (11 casi)
## Addendum (stessa sera) — spegnimento, backup, ripresa dopo un riavvio
**Spegnimento.** Prima di fermare i container ho preso uno snapshot **finale** (bite aveva raccolto
fino alle 20:15, oltre il backup delle 19:55) e ho reimportato: archivio a **1.232.212 righe**.
Consegna verificata: ultima riga di bite 20:15:00, prima nostra 20:00:18 → **sovrapposizione, nessun
buco**. `docker compose stop` (non `down -v`: i volumi restano). Effetto misurato: **0 risposte 429**
su cerbero-mcp nei minuti successivi, contro ~650 per ogni giro orario.
**Backup.** `data/raw/` è gitignored e il backup rotativo della VPS non copriva PythagorasGoal: dopo
lo spegnimento di bite l'archivio esisteva in due copie **sullo stesso disco**. Aggiunta
`do_pythagoras` a `/opt/docker/scripts/backup.sh` con un criterio dichiarato: **si salva ciò che non
si può riscaricare**. Dentro: catena + contesto, `data/paper_*` e `data/chain_collect` (serie
forward-only che alimentano i gate pre-registrati — non ricalcolabili per costruzione),
`options_daily`, `live`, `venue_watch`, `fee_watch`, `config/live.json` → **28 MB**. Fuori: i ~110 MB
che si riscaricano dai venue.
Due guardie, entrambe provate **nei due versi**: la funzione fallisce se la catena è assente o
vuota (invece di produrre un archivio che sembra a posto), e verifica che il tar prodotto contenga
davvero la catena. Il caso negativo produce **0 file**. Per poterlo provare la radice è
sovrascrivibile via `PYG_ROOT` — *una guardia che non si riesce a far scattare non è distinguibile
da una rotta.*
⚠️ `/opt/docker/scripts` **non è un repo git**: quella modifica vive solo su disco, e questo diario
è l'unico posto in cui è scritta.
**Riavvio.** La raccolta riprende da sola: `cron` è `enabled` e `active`, e il collettore non
dipende da docker né da cerbero-mcp (API pubblica Deribit diretta) — il contrario di bite, che era un
container. Verificato girando `cron_chain.sh` con `env -i PATH=/usr/bin:/bin`: 574 chiamate, 0
errori, dato e battuta di cuore scritti. ⚠️ **Finestra scoperta: fino al `:25` successivo, senza
recupero.** Il collettore non fa catch-up e non potrebbe: le quote passate non sono richiedibili.
+99
View File
@@ -0,0 +1,99 @@
# 2026-07-30 (5º filone) — f misurato sul 10g: il mio sospetto era sbagliato, e il campione non basta ancora
**Richiesta dell'operatore:** *«misura f sul 10g quando ci sono abbastanza scadenze».*
**Esito: misurato oggi (il campione c'era), campione INSUFFICIENTE per la differenza, un mio
argomento pubblicato oggi REFUTATO. Book, pesi, config INVARIATI.**
Script `scripts/live/vrp_f_watch.py` (in `cron_daily.sh`), test `tests/test_vrp_f_watch.py` (11).
## Il campione c'era già
Prima cosa misurata, non assunta: nella catena (1.235.064 righe, 2026-05-01 → 2026-07-30) ci sono
**8 scadenze utilizzabili per asset su 8**, per **entrambe** le strutture — quindi 16 osservazioni
ciascuna. Non serviva aspettare per fare *la misura*; serve aspettare per rispondere alla
*differenza*, che è un'altra domanda.
## ❌ La correzione: il mio sospetto aveva il meccanismo giusto e la conclusione sbagliata
Nel diario del gate sul tenore, poche ore fa, avevo scritto che la cella vincente
*«sta plausibilmente massimizzando l'errore di modello, non l'edge»*, perché compra l'ala più
lontana e il 30/07 aveva misurato quell'ala sottoprezzata ~2.3× dal modello piatto.
Misurato:
| struttura | f_short | f_long | quota ala/corta | **f_net** |
|---|---|---|---|---|
| canonico 7g δ−0.10 | 1.013 | 2.233 | **18.4%** | **0.718** |
| candidato 10g δ−0.05 | 0.972 | **5.846** | **3.2%** | **0.852** |
**Il meccanismo è confermato e più forte del previsto** — l'ala a δ −0.05 costa **5.85×** il
modello contro 2.23× — **ma la conclusione era rovesciata**: quell'ala pesa il **3.2%** del premio
corto invece del 18.4%, quindi il suo errore muove molto meno il credito **netto**. Il candidato ha
un f **migliore**, non peggiore.
L'aritmetica lo rende ovvio a posteriori: con `k = premio_lungo/premio_corto`,
`f_net = (f_short − k·f_long)/(1 − k)`. Un `f_long` grande fa danno solo se moltiplicato per un `k`
grande. Avevo guardato il fattore e non il peso.
⚠️ **Artefatto escluso prima di crederci.** Un `f_long` di 5.85 su un'opzione quasi senza valore
poteva essere solo il tick minimo (0.0001). Misurato: l'ask dell'ala sta a **22 tick di mediana**
(minimo 15, **0%** delle osservazioni a ≤2 tick). È un prezzo vero, non discretizzazione.
## La differenza NON è stabilita
Confronto **appaiato per (asset, scadenza)** — non due intervalli guardati a occhio:
| | mediana | IC95 bootstrap |
|---|---|---|
| f canonico | 0.718 | [0.662, 0.797] |
| f candidato | 0.852 | [0.809, 0.892] |
| **differenza appaiata** | **+0.109** | **[−0.047, +0.193]** |
11 coppie su 16 positive, **l'IC contiene lo zero**. Il punto stimato favorisce il candidato; la
misura non lo stabilisce. ✅ Replica indipendente: il f del canonico esce **0.718** per un percorso
diverso (finestra DTE e pairing diversi) da quello che stamattina dava 0.73 — le due misure si
confermano.
Al proprio f misurato: canonico **0.43**, candidato **1.18** (a f=1.00 erano 1.32 e 1.55).
## Criterio pre-registrato, e un sorvegliante invece di un promemoria
Dichiarato **prima** di avere il campione pieno, congelato in un test:
> **≥ 40 coppie appaiate** (oggi 16) **E ampiezza IC95 della differenza ≤ 0.12** (oggi 0.241).
Con ~2 coppie/settimana la prima gamba cade verso **fine ottobre 2026**. `vrp_f_watch.py` gira in
`cron_daily.sh`, rifà la misura a ogni giro e **manda una notifica una volta sola** quando il
criterio è soddisfatto. È la disciplina imparata con DVOLSPREAD (35 giorni di limbo): *un lead
senza sorvegliante e senza data è un lead perso*.
⚠️ **Verificata la calibrazione della soglia prima di fidarsene.** Una soglia sull'*ampiezza* di un
IC vale solo se l'IC è calibrato. Misurato su differenza vera nulla: lo zero viene escluso nel
**5.0% / 4.0% / 3.0%** dei casi a n=16/40/60 — esattamente il 5% atteso. (Il test iniziale su un
seed fisso falliva proprio perché quel seed era uno dei 5% legittimi: sostituito con un test sulla
**proprietà**, 100 estrazioni.)
## Cosa questa misura NON fa
**Non promuove niente.** Il candidato è bocciato sul **deflated-Sharpe (0.948 < 0.95)**, che non
dipende da f, e la regola *niente short-vol da modello in deploy* resta. Un f favorevole toglie
**un argomento di cautela su quattro** — restano il gate pre-registrato, il fatto che la regione
mai esplorata (>10g) perde comunque, e l'ineseguibilità sotto ~$2.6k.
Ma la decisione ora poggia su **meno gambe di quante ne avevo dichiarate**, e questo va scritto:
uno dei quattro argomenti era mio, era misurabile, e l'ho misurato sbagliato.
Il valore operativo vero sta sull'altra riga della tabella: **f = 0.718 sul canonico** è il numero
che rende onesti i conti di uno sleeve che **sta nel book**, non di un candidato.
## Regole
- **Un fattore di errore si giudica moltiplicato per il suo peso.** `f_long` 5.85 sembra
devastante e conta il 3%; `f_long` 2.23 sembra mite e conta il 18%. Guardare il fattore senza il
peso porta alla conclusione opposta a quella vera.
- **Prima di credere a un rapporto estremo su un prezzo piccolo, contare i tick.** Un ratio di 5×
su qualcosa che vale un tick è aritmetica di griglia, non mercato.
- **Una soglia su un intervallo di confidenza richiede di verificare la copertura di
quell'intervallo** — altrimenti si pre-registra un criterio che non misura ciò che dice.
- **«Non abbastanza campione» non è «nessuna differenza»**: si aspetta con una data, non si
conclude.
+157
View File
@@ -0,0 +1,157 @@
# 2026-07-30 (3º filone) — profit-take al 50% su VRP01: REFUTED, e una correzione a un numero di stamattina
**Domanda dell'operatore:** *«fai la misura del profit-take al 50%, simula con 3K».*
**Esito: book, pesi, cron, config INVARIATI.** Il profit-take **non entra**. Ma il filone ha
prodotto una correzione favorevole a un numero pubblicato **oggi stesso**, e una mia ipotesi
refutata nella stessa sessione.
Script `scripts/research/r0730_vrp_profit_take.py`, test `tests/test_vrp_profit_take.py` (16 casi).
## Perché questa misura e non un'altra
VRP01 come codificato **tiene fino a scadenza**: in `_vrp_weekly_asset` il payoff è su
`S1 = px[i + tn]`, non esiste gestione infra-settimana. L'onda 03/07 aveva testato 4 overlay di
protezione DD (exit-spike, **stop-loss MTM 1.5/2/3×**, ala di coda, cooldown) e li aveva refutati
4/4 col null del de-levering — ma il profit-take **non era fra quelli**: è un'uscita sul lato del
*profitto*, non del rischio. Era l'ultimo grado di libertà non misurato su questo sleeve, e la
misura del 30/07 sulle quote reali diceva che sarebbe scattato in **13 settimane su 15**.
L'idea è la regola 1 del motore di cerbero-bite (`debit <= 50% del credito`), progetto dismesso lo
stesso giorno. **Non se ne eredita il giudizio: bite non ne ha uno** (59 decisioni, tutte
`no_entry`, 0 posizioni, in testnet). Si misura.
## Fondazione: replica bit-exact
Prima di ogni delta, la re-implementazione riproduce `_vrp_weekly_asset` a **max|diff| = 0.00e+00
su entrambi gli asset, zero date non condivise**. Senza questa, ogni numero sotto sarebbe rumore di
implementazione. Congelata in un test: se qualcuno tocca il sleeve, si rompe.
## Il verdetto
Fee **reali per gamba** (`min(0.03% del sottostante, 12.5% del premio)` = listino Deribit letto da
`public/get_instruments`), identiche a canonico e variante.
| variante | ShFULL | ShHOLD | maxDD | CAGR | peggior sett. | usciti prima | giorni |
|---|---|---|---|---|---|---|---|
| **canonico (a scadenza)** | **1.32** | **0.82** | 10.5% | 10.5% | −7.27% | — | 7.0 |
| PT 25% | 0.22 | −0.44 | 8.6% | 0.9% | −7.27% | 87% | 2.7 |
| **PT 50%** | **−0.18** | **−0.65** | 17.3% | −1.3% | −7.27% | 79% | 3.6 |
| PT 75% | −0.45 | −1.24 | 19.5% | −3.0% | −7.27% | 71% | 4.6 |
**Null del de-levering: REFUTED 6/6** (3 livelli × vol-matched e DD-matched). ⚠️ Nota onesta: sotto
scalatura moltiplicativa lo Sharpe è **invariante**, quindi il null si riduce a «la variante ha
Sharpe più alto?». Il `k` dice solo *quanto* de-levering ottiene lo stesso DD: per PT25 basta
**k=0.818** per avere lo stesso 8.6% di DD **con Sharpe 1.32 invece di 0.22**.
## Il meccanismo — e perché serviva il confronto appaiato
⚠️ **Errore di metodo commesso e corretto in sessione.** Le due varianti sono indicizzate sulla
**data di uscita**, che il profit-take cambia: un `join="inner"` fra le serie tiene solo le
settimane *senza* uscita anticipata, dove i valori coincidono per costruzione. La prima
diagnostica stampava «troncamento 0%, variazione +0%» su tutto — potenza zero, e una conclusione
esattamente opposta al vero. È la trappola dell'inner-join già codificata due volte nel progetto
(venue watch, GTAA), qui in veste nuova. Congelata in `test_confrontare_per_data_di_uscita_da_una_risposta_falsa`.
Rifatto **appaiato per ingresso** (stesso trade, due esiti):
| | BTC (71 trade) | ETH (92 trade) |
|---|---|---|
| scatta sui **vincenti** | **86%** | **91%** |
| scatta sui **perdenti** | 25% | 19% |
| vincenti | +1.419% → +1.023% (**−28%**) | +1.638% → +1.218% (**−26%**) |
| perdenti | −3.649% → −2.941% (−19%) | −4.248% → −3.505% (−17%) |
| somma PnL | +60.2% → **+40.9%** | +56.6% → **+36.5%** |
**Il profit-take tronca del 27% i trade che avrebbero vinto comunque e salva un perdente su
cinque.** La peggior settimana è **identica** (−7.27%) in tutte le varianti: nelle settimane brutte
lo spread non raggiunge mai +50%, quindi si arriva a scadenza e si prende la perdita piena. È pura
troncatura dell'upside.
## ❌ Ipotesi mia, nata e refutata nella stessa sessione
Il meccanismo suggeriva una spiegazione: *su 7 giorni chi tocca +50% è proprio chi sarebbe scaduto
senza valore; a scadenze lunghe — 18g, quella di bite, e i 30-45 DTE dello standard di mestiere —
la regola dovrebbe pagare.* Testata su 6 tenori:
| tenore | Sh hold | Sh PT50 | ΔSh |
|---|---|---|---|
| 7g | 1.32 | −0.18 | −1.50 |
| 10g | 1.51 | 0.12 | −1.40 |
| 14g | 1.14 | −0.56 | −1.71 |
| **18g** (bite) | **1.51** | **0.37** | **−1.14** |
| 21g | 1.09 | −0.27 | −1.36 |
| 28g | 1.31 | 0.06 | −1.25 |
**Negativo a tutti e sei.** A 18g è il meno peggio e il DD migliora davvero (7.1% → 3.8%), ma lo
Sharpe crolla: **firma del de-levering**, non di una protezione. Ipotesi refutata.
⚠️ **La colonna `Sh hold` NON è un risultato.** Sei celle scelte sul campione pieno: il tenore 18
sembra migliore del 7 (1.51 vs 1.32) ma è esattamente la selezione che `study_family_honest` +
deflated-Sharpe esistono per uccidere. La griglia 03/07 si fermava a 10 giorni, quindi il buco è
reale — ma va chiuso con lo strumento giusto, non con questo sweep.
## ✅ Correzione a un numero pubblicato stamattina
Il sleeve modella le fee come **12.5% del credito netto** round-trip. Il listino vero è **0.03% del
sottostante per gamba** (cap 12.5% *del premio della singola opzione*, che quasi mai morde): su ETH
sono $1.14 d'ingresso contro i $2.26 del forfait, cioè il modello **sovrastima le fee di ~2×**.
| lente | ShFULL | ShHOLD | maxDD | CAGR |
|---|---|---|---|---|
| sleeve ufficiale (forfait) | 1.08 | 0.58 | 11.8% | 8.2% |
| **fee reali per gamba** | **1.32** | **0.82** | 10.5% | 10.5% |
Combinato col **f = 0.73** misurato stamattina sulle quote reali, il numero onesto di VRP01 è
**ShFULL 0.47 / DD 14.5%**, non lo **0.31** che ho scritto oggi in CLAUDE.md — che era calcolato
con le fee forfettarie. Il f resta il difetto dominante; la fee lo attenua di ~+0.16.
**Nessuna azione:** `fee_frac` **non è stato cambiato**. Il forfait è conservativo, e questo
progetto preferisce i numeri di ammissione conservativi (stessa logica per cui l'audit d'ancora
del 03/07 su VRP01 è stato accolto come «numeri conservativi, non gonfiati»). Cambiarlo alzerebbe
i numeri di uno sleeve senza aggiungere edge.
## Rientro immediato dopo l'uscita
Testato come strategia a sé (non è un overlay: cambia la cadenza). PT50 + rientro fa **Sh 1.19**
contro 1.32 del canonico, CAGR 4.9% contro 10.5%, 200 trade contro 163. Il suo **ShHOLD 2.42** è
vistoso — ed è precisamente la firma che questo progetto ha imparato a non credere: non è
selezionabile in-sample (Sharpe FULL più basso), quindi crederci sarebbe selezione sull'hold-out.
**Non è un lead.**
## $3.000 — la domanda che viene prima
Parametri veri da `public/get_instruments` (30/07): **ETH `min_trade_amount` = 1 contratto = 1 ETH;
BTC = 0.1 BTC**. Collaterale = strike corto (convenzione cash-secured del sleeve).
| | spot | lotto min | collaterale/lotto | a $3.000 | fee round-trip |
|---|---|---|---|---|---|
| BTC | $63.917 | 0.1 | **$6.210** | **0 lotti — FUORI** | $7.67 = 17.8% del credito |
| ETH | $1.906 | 1.0 | $1.832 | 1 lotto | $2.29 = 12.6% del credito |
Tre conseguenze:
1. **A $3.000 il sleeve 50/50 diventa ETH-only** — cioè non è più il sleeve misurato.
2. **Al peso di book (12%) l'allocazione è $360 = 0 lotti.** Per un solo lotto ETH servirebbe il
**61% del conto** su un singolo sleeve.
3. Quindi a $3.000 la domanda «il profit-take migliora VRP01?» **non è la domanda che decide**:
VRP01 non è collocabile a quel capitale in nessuna forma sensata.
## Cosa resta
- **Profit-take: REFUTED**, a ogni livello, a ogni f, a ogni tenore, contro il null del de-levering.
Con questo il conto degli overlay refutati su VRP01 sale a **5 su 5**, e il filone «gestire VRP01
dentro il modello» è chiuso su tutti i lati misurabili.
- **Buco reale rimasto:** il tenore oltre i 10 giorni non è mai passato per `study_family_honest`.
Non è urgente (le opzioni non sono eseguibili prima di ~$2.6k, e a $3k solo ETH e a peso assurdo).
- **Il vincolo binding non è la ricerca.** Vale la nota del 26/07: qui si è misurato un ΔSharpe che
non cambia niente, mentre le leve che decidono restano il capitale che entra e il conto che non
sparisce.
## Regole
- **Un'uscita si giudica su un confronto APPAIATO PER INGRESSO**, mai allineando due serie sulla
data di uscita: la variante che stai testando è esattamente quella che cambia quella data, e il
join tiene solo i casi in cui non è successo niente.
- **Una regola d'uscita che scatta più spesso sui vincenti che sui perdenti non è protezione, è
troncatura** — e si vede in una riga: la peggior settimana non cambia.
- **Prima di misurare il rendimento a un capitale dato, misurare il lotto minimo del venue.** Qui
la risposta operativa («non è collocabile») non dipendeva da nessuno Sharpe.
+157
View File
@@ -0,0 +1,157 @@
# 2026-07-30 — VRP01 contro le quote REALI: il f del credito netto è 0.73, non 1.0
**Esito:** nessun cambio a book, pesi, cron o config. Un'ipotesi di VRP01 è **falsificata con
misura**, e il dataset che l'ha falsificata entra nel progetto (estrattore + certificazione +
harness + test). Il muro dichiarato per il deploy — il *f* di stress — resta in piedi, intatto.
## Da dove viene il dato
`/opt/docker/cerbero-bite` accumula dal 2026-06-09 la catena opzioni Deribit **mainnet**: entrambe
le ali, scadenze 1g→3 mesi, ora per ora, con la profondità top-3 del book. È la fonte che il
progetto cita dal 20/06 (`options_vrp_calibrate.py`) e che finora era stata usata una volta sola,
via export manuale in `/tmp`.
Il motivo per cui quel dato si **memorizza** invece di richiederlo quando serve: una catena opzioni
non è ricostruibile a posteriori — Deribit non serve book storici. Un'ora non raccolta è persa per
sempre. Stessa asimmetria dello storico spot certificato, con l'aggravante che qui non esiste un
secondo venue da cui recuperarla.
## La domanda
`src/portfolio/sleeves.py:136` — `VRP_CFG` gira a **`f=1.0`**, applicato al credito **NETTO**:
```python
net_prem = (_bs_put(S0, Ks, T, sig) - _bs_put(S0, Kl, T, sig)) * cfg["f"]
```
cioè assume che il mercato paghi esattamente ciò che Black-Scholes su DVOL-ATM dice, **per entrambe
le gambe**. Il caveat di ammissione ("premio MODELLATO su DVOL ATM, skew non esplicito") era
dichiarato dal 19/06 e mai quantificato, per mancanza di quote vere.
## D1 — copertura: la struttura c'è
Finestra settimanale 4-10 DTE: **8 scadenze su 8** hanno **entrambe** le gambe quotate, per
entrambi gli asset. Delta realizzati **−0.270** (target −0.280) e **−0.099** (target −0.100): la
struttura misurata è quella del sleeve, non una sua approssimazione.
## D2 — il numero: f = 0.73
Confronto agli **stessi strike** (così il rapporto isola l'errore di *prezzo*, non la scelta dello
strike), fill conservativo (vendi al bid, compri all'ask):
| grandezza | mediana | p25 | p75 |
|---|---|---|---|
| f gamba **corta** (venduta) | **1.02** | 0.88 | 1.12 |
| f gamba **lunga** (comprata) | **2.30** | 1.68 | 2.87 |
| **f credito NETTO** ← quello che entra nel book | **0.73** | 0.71 | 0.82 |
| f credito netto, a mid | 0.80 | 0.79 | 0.89 |
IC95% bootstrap sulla mediana **[0.698, 0.780]**; **0 osservazioni su 15** arrivano a 1.0.
⚠️ **La calibrazione del 20/06 non è contraddetta, è replicata**: misurava la **sola gamba corta** e
trovava f ≈ 1.0; qui la stessa quantità, con implementazione indipendente, dà **1.02**. La
differenza è che VRP01 è uno *spread*, e il problema sta nell'altra gamba.
## Il meccanismo (senza il quale il numero sarebbe un artefatto)
**IV(corta) − DVOL = +0.8 pp**, **IV(lunga) − DVOL = +7.5 pp**. Il modello prezza entrambe le gambe
a vol ATM; l'ala più OTM — quella che si **compra** — sta 8 punti sopra per skew, quindi costa
**~2.3× il modello**, e il credito netto si comprime del 27%.
Colpisce esattamente il punto su cui VRP01-v2 era stato promosso: *"(a) defined-risk taglia la coda
(worst-week −16.6%→−7.4%)"*. Nel modello quell'assicurazione è comprata a vol ATM, cioè quasi
gratis. Nel mercato costa più del doppio. **Il difetto non è nel premio incassato, è nella
protezione comprata.**
## Conseguenza, misurata
VRP01 standalone sostituendo **solo** `f` (replica sana a f=1.0: 1.08 / 0.58 / −11.8% contro i
1.10 / 0.60 / 12% pubblicati):
| f | Sh FULL | DD FULL | CAGR | Sh HOLD-OUT |
|---|---|---|---|---|
| **1.00** (assunto) | 1.08 | −11.8% | 8.2% | **+0.58** |
| **0.80** (misurato a mid) | 0.51 | −14.4% | 3.6% | **−0.02** |
| **0.73** (misurato, fill conservativo) | 0.31 | −15.3% | 2.0% | **−0.23** |
Book a 5 sleeve (VRP01 al 12%), ancore canoniche: FULL 2.215 → **2.146** (Δ −0.069),
HOLD 2.347 → **2.244** (Δ −0.103), DD invariato.
**Lettura onesta: il book non crolla** — l'effetto è dentro la banda d'ancora (canonico 2.22 contro
mediana de-luckata 1.95). Ma il LOO del 26/07 attribuiva a VRP01 **+0.122 di FULL**: **circa metà di
quel contributo era il prezzo che il modello si faceva da solo.** L'audit d'ancora aveva corretto la
fortuna di calendario; l'ottimismo di *prezzo* non l'aveva corretto nessuno.
## D3 — ciò che solo questo dato permette
Le stesse due gambe sono riquotate **~164 volte per trade** (orarie) fino a scadenza. Da qui:
- il **50%-profit-take scatterebbe in 13/15 settimane** → la regola di gestione diventa testabile;
- **peggior mark infra-settimana** (N=13 trade con path): mediana **−6.9%** del capitale, minimo
**−81.7%**, su un trade che è finito **in utile**.
⚠️ Il sleeve marca solo a scadenza: quel minimo **non esiste nei suoi numeri**. È la stessa classe
di errore della lente wick accoppiata del 25/07 — *un rischio valutato sul minimo non si misura
sulle chiusure*. Il DD 12% di VRP01 è un DD di chiusure settimanali.
## D4 — ciò che il dato NON dice, ed è la ragione per cui si raccoglie
**Nella finestra raccolta VRP01 non avrebbe aperto una sola posizione.** IV-rank mediano 0.12 (ETH)
e 0.08 (BTC) contro il gate >0.30: **0 settimane su 8** per entrambi. Il massimo di DVOL raccolto
sta al **24° percentile** (ETH) e **28°** (BTC) della storia.
Quindi il f = 0.73 è misurato nel regime in cui il sleeve **sta flat**. Lo skew è strutturale e in
stress si irripidisce, quindi la direzione è robusta — ma **la taglia in stress resta non
misurata**, e il criterio dichiarato il 19/06 ("rivalutare quando cerbero-bite cattura un crash")
non è stato toccato da questo lavoro.
## Il difetto trovato nel dato, e la certificazione che ora c'è
Il feed ha un guasto **in corso** dal 29/07 05:00 UTC: il collettore persiste la riga anche quando
il ticker fallisce (rate-limit per-IP), con `bid`/`ask`/`iv`/`delta` NULL. Il **conteggio righe non
cambia** — 13.000/giorno prima e dopo — quindi ogni controllo di copertura basato sulle righe dice
"tutto bene". Tasso di quote vuote per settimana: 0.4 · 0.7 · 2.2 · 1.5 · 0.5 · 0.4 · 0.3 → **22%**.
`scripts/analysis/fetch_cb_chain.py` certifica quattro difetti (quote vuote, book incrociato,
premio non monotono nello strike, `depth==0` ambiguo by design) ed è il posto dove è stata
imparata la lezione seguente.
⚠️ **La prima stesura della certificazione confrontava "tutto il campione" con "ultimi 7 giorni" —
e diluiva un guasto di 2 giorni al 13.5%**, cioè commetteva a 7 giorni lo stesso errore che
dichiarava di voler evitare a 3 mesi. Con la statistica giusta (**giorno peggiore** della finestra)
lo stesso dato dice **51.7%** e lo status passa da `DEGRADATO` a `QUOTE-VUOTE`.
**REGOLA: un guasto IN CORSO non si misura con una media su una finestra — si misura al suo giorno
peggiore. Qualunque finestra è abbastanza lunga da nascondere un guasto abbastanza giovane.**
Congelata in `test_giorno_peggiore_non_si_lascia_diluire_dalla_media`.
## Cosa NON è stato fatto, e perché
**`VRP_CFG["f"]` non è stato cambiato.** La misura sta su 15 osservazioni, 7 settimane, un solo
regime — per giunta il regime in cui il sleeve è flat. Sostituire 1.0 con 0.73 significherebbe
propagare in tutto il book un numero misurato dove il book non opera. La mossa corretta è il
**caveat quantificato**: i numeri 1.10 / 0.60 / 12% si citano d'ora in poi con "a f=1.0; f misurato
sulle quote reali 0.73 [0.70, 0.78], a cui l'hold-out standalone è −0.23".
Che VRP01 stia al 12% e non sia deployato è, retroattivamente, la decisione giusta **per il motivo
giusto**: non "short-vol da modello per prudenza", ma "il modello sovrastima il credito del 27% e
lo fa sulla gamba che doveva proteggere".
## Regole nuove
1. **Il *f* di una struttura multi-gamba non è il *f* di una sua gamba.** Misurare la sola gamba
venduta dà la risposta sbagliata **con segno rassicurante** (1.02 invece di 0.73). Ogni futura
calibrazione su quote reali di una struttura a N gambe si fa sul **netto**.
Congelata in `test_il_f_della_gamba_corta_non_e_il_f_dello_spread` (3 ali, identità algebrica
`f_net = (1 − f_long·k)/(1 − k)` — una soglia sola sarebbe stata una fixture fortunata).
2. **Un guasto in corso si misura al giorno peggiore, non in media** (sopra).
3. **Una riga presente non è un dato presente.** Il difetto delle quote vuote è invisibile a
qualunque controllo che conti righe: va contato ciò che è **quotato**, non ciò che è **scritto**.
È la terza occorrenza della stessa famiglia dopo la contabilità a 3 stati di `paper_dvolspread`
(26/07) e il silenzio letto come zero di `fresh_5m` (26/07).
## File
- `scripts/analysis/fetch_cb_chain.py` — estrazione + certificazione → `data/raw/cb_chain.parquet`
- `scripts/research/cblib.py` — harness (loader, `pick_legs`, `f_factors`, `close_cost_path`)
- `scripts/research/r0730_vrp_real_quotes.py` — lo studio (D1-D4, meccanismo, sweep f, `--book`)
- `tests/test_cb_chain_vrp.py` — 14 casi (rilevatori + controlli positivi + guardia di convenzione)
+124
View File
@@ -0,0 +1,124 @@
# 2026-07-30 (4º filone) — il buco del tenore chiuso col gate onesto: nessun cambio a VRP01
**Richiesta dell'operatore:** *«chiudi il buco del tenore con study_family_honest».*
**Esito: `earns_slot_honest = False`. Book, pesi, cron, config INVARIATI.**
Script `scripts/research/r0730_vrp_tenor_gate.py`, test `tests/test_vrp_tenor_gate.py` (12 casi).
## Il buco, e perché era reale
La griglia strutture del 03/07 (`r0703_vrpimp_structgrid`) cercava su `TENOR_GRID = (3, 5, 7, 10)`:
**oltre i 10 giorni non è mai stato guardato.** Lo sweep del 30/07 sul profit-take aveva toccato
14/18/21/28g di passaggio e mostrato che il 18g *sembrava* battere il 7g in hold-to-expiry
(1.51 vs 1.32) — sei celle scelte sul campione pieno, cioè esattamente la selezione che questo
gate esiste per uccidere.
## Perché il gate è composto a mano, e non è una scorciatoia
`altlib.study_family_honest` è cablato sui candidati **direzionali**: vuole
`factory(tf=..., **params) -> target_fn` e passa da `candidate_daily`, che costruisce i rendimenti
da una serie di *posizioni* su BTC/ETH. VRP01 non è direzionale. Si usano quindi i suoi **tre
componenti reali**, nello stesso ordine e con le stesse soglie: selezione in-sample-only →
`altlib.deflated_sharpe` (importato, non riscritto — c'è un test che lo verifica) →
`altlib.marginal_vs_tp01` (importato).
**Famiglia dichiarata nel docstring PRIMA di guardare i numeri:** 8 tenori × 3 delta corti ×
3 delta lunghi = **72 celle**. Riaprire il tenore riapre la struttura, e il conteggio dei trial si
fa **al rialzo** — contarne meno gonfia il deflated-Sharpe.
## Il risultato
| | tenore | δ corto | δ lungo | Sh IS | Sh FULL | Sh HOLD | maxDD | CAGR |
|---|---|---|---|---|---|---|---|---|
| **scelta al buio** | 10g | −0.28 | −0.05 | **1.75** | 1.55 | 1.01 | 9.6% | 13.5% |
| VRP01 canonico | 7g | −0.28 | −0.10 | 1.50 | 1.32 | 0.82 | 10.5% | 10.5% |
Rango del canonico: **17/72 in-sample, 26/72 sul campione pieno**. La selezione al buio sceglie
un'altra cella, e quella cella batte il canonico sia in-sample sia full.
**Ma il gate si chiude sul deflated-Sharpe:**
| | DSR su 72 trial | esito |
|---|---|---|
| cella scelta | **0.948** | **FAIL** (soglia 0.95) |
| VRP01 canonico | 0.885 | FAIL |
`marginal_vs_tp01` dà **ADDS** a entrambe (corr +0.016, `robust_oos` True, `has_insample_edge`
True, `is_hedge` False). Quindi il verdetto **non** è «VRP01 è rotto» né «il tenore non conta»:
è che il vantaggio apparente non sopravvive al conto dei trial.
## Come il buco si chiude davvero: la regione nuova perde
Questo è il punto che rende la chiusura pulita, più del DSR:
| | cella | Sh IS | rango |
|---|---|---|---|
| miglior cella **≤10g** (già coperta dal 03/07) | 10g −0.28/−0.05 | 1.75 | 1/72 |
| miglior cella **>10g** (territorio mai guardato) | 18g −0.28/−0.05 | 1.56 | **8/72** |
Solo **3 celle su 10** nella top-10 in-sample stanno oltre i 10 giorni. **Si è aperta la regione
mai esplorata e la regione mai esplorata ha perso** contro celle che il 03/07 aveva già visto e
non promosso. Il buco non è "chiuso perché il gate boccia": è chiuso perché **guardandoci dentro
non c'è niente**.
## ⚠️ Il vincitore sta dove il modello sbaglia di più
La cella scelta compra l'ala **più lontana** (δ lungo −0.05), e 5 delle 10 celle migliori fanno lo
stesso. Il 30/07 ha **misurato** che il modello piatto sottoprezza proprio l'ala che si *compra*
(IV(lunga)−DVOL **+7.5pp** contro +0.8pp della corta, ~**2.3×** il modello), e che l'errore cresce
con la distanza dallo strike. Una selezione che premia il δ lungo più piccolo sta plausibilmente
massimizzando **l'errore di modello**, non l'edge.
Onestà su questo punto: è un **sospetto motivato, non una dimostrazione**. Il *mediano* in-sample
non separa −0.10 da −0.05 (1.37 contro 1.37); a separarsi è la **coda alta** della griglia. Ma
basta a spostare l'onere della prova, perché `f` **non è misurato** fuori dalla struttura canonica.
⚠️ E la sensibilità a `f` non risolve: applicandolo uniformemente la cella scelta degrada *meno*
(f=0.73 → 0.84 contro 0.47 del canonico), ma **f uniforme è la lente sbagliata proprio per questa
struttura**, il cui errore è concentrato in una gamba sola. Un numero rassicurante ottenuto con lo
strumento sbagliato non è rassicurazione.
## ⚠️ Quanto è robusto il mio stesso verdetto
Il DSR dipende da quanti trial si dichiarano, e qui il verdetto **si ribalta**:
| conteggio | N | DSR | esito |
|---|---|---|---|
| solo gli 8 tenori | 8 | 0.983 | **PASS** |
| **la griglia dichiarata** | **72** | **0.948** | **FAIL** |
| 72 + 288 simulate del 03/07 | 360 | 0.909 | FAIL |
La griglia è stata dichiarata **prima** di guardare i numeri e il conteggio fatto al rialzo — ma il
verdetto va citato per quello che è: **fallisce per 0.002**, non è una refutazione netta. (L'ultima
riga usa trial *simulati* dalla distribuzione osservata, non le Sharpe vere del 03/07, che vengono
da un motore diverso: indicazione, non misura.) Congelato in
`test_il_verdetto_dipende_dal_numero_di_trial_dichiarati`, così che nessuno possa farlo passare
un domani restringendo il conteggio.
## Decisione
**Nessun cambio a VRP01**, per quattro ragioni in ordine di peso:
1. **Il gate pre-registrato fallisce.** Una soglia dichiarata in anticipo che poi si aggira non è
una soglia.
2. **La regione davvero nuova non vince** — quindi questo studio non ribalta il 03/07, lo conferma.
3. **Il vincitore sta nell'angolo dove abbiamo misurato che il modello è meno affidabile**, e lì
`f` non è misurato.
4. Niente di tutto questo è eseguibile prima di ~$2.6k, e a $3.000 VRP01 è **0 lotti** al peso di
book.
**Il seguito giusto non è un altro backtest, è una misura.** Se il 10g/−0.28/−0.05 interessa, la
domanda che decide è *quanto vale f su quella struttura sulle quote vere* — e da oggi la catena la
raccogliamo noi ogni ora. Serve però che il collettore accumuli abbastanza scadenze a 10 giorni:
oggi ci sono 15 osservazioni sul solo canonico.
## Regole
- **Quando si riapre un parametro si riapre la sua famiglia**, e i trial si contano al rialzo: il
deflated-Sharpe è l'unico posto dove barare è indolore e invisibile.
- **Dichiarare la griglia prima di guardare i numeri**, e pubblicare la sensibilità del verdetto al
conteggio — un gate che passa solo con la propria griglia preferita non è un gate.
- **Un buco si chiude meglio mostrando che dentro non c'è niente che bocciando il candidato**: qui
la frase che conta non è «DSR 0.948» ma «la regione mai esplorata è ottava».
- **Se la selezione converge dove un difetto di modello è già misurato, il sospetto vale più del
numero** — e si dice che è un sospetto.
@@ -0,0 +1,224 @@
# 2026-08-07 — La crescita del capitale, il fisco che nessuno aveva contato, e se invece fosse un ETF
**Richieste dell'operatore, in sequenza:** *«stato progetto»* → *«riepiloga piano»* → *«grafico della
crescita per anno con versamento e con guadagno»* → *«con 800 al mese»* → *«sistema dinamico dove
imposti valore iniziale, mensile e durata, e calcola la best curva fissando il tempo»* → *«il
guadagno come viene calcolato? e se mettessi in MSCI World o ETF SP500?»* → *«quale è la miglior
strategia?»*.
**Esito: book, pesi, cron, config INVARIATI.** Nessuna decisione operativa cambia. Cambiano tre
numeri pubblicati e cade un'affermazione su GTAA01.
---
## 0. Il buco trovato per primo: quattro risultati mai registrati
Ricostruendo il piano per l'operatore ho scoperto che **quattro commit del 27/07 sera non sono né
in CLAUDE.md né in un diario**: vivono solo nei messaggi di commit e negli script
(`r0727_3k_vs_5k.py`, `r0727_orizzonte10.py`, `r0727_tasse.py`). Uno di questi cambia il numero di
testa del piano — vedi §2. È il motivo per cui questo diario esiste prima ancora del lavoro nuovo.
---
## 1. Come si calcola il «guadagno» — la domanda che andava fatta
Nessuna traiettoria del progetto ipotizza un rendimento. Il meccanismo, ora scritto:
1. si parte dai ritorni giornalieri **veri** del book live (TP01 75% + SKH01 25%), 2.692 giorni dal
2019-03-14, già netti di commissioni;
2. si toglie la fortuna d'ancora: `r − (1−0.89)·media(r)`;
3. si **rimescolano a blocchi di 20 giorni** (block bootstrap): blocchi, non giorni singoli, per
non distruggere il raggruppamento della volatilità;
4. si compone: `cap *= (1+r)` ogni giorno, deposito ogni 30, imposta a fine anno, su 4.000 percorsi;
5. **`guadagno = mediana(capitale) − versato`**.
Drift implicito: **17,1% annuo, vol 10,9%**. Non è un'assunzione sul rendimento — è l'assunzione
che *il futuro somigli a quei 7 anni*. Che è esattamente ciò che §3 mette alla prova.
Script: `scripts/research/r0807_growth_yearly.py` (`--lump`, `--dep`, `--anni`, `--json`).
---
## 2. ⚠️ Il fisco durante l'ACCUMULO — la voce mai contata
`TAX_RATE` compariva in **un solo punto** di tutto il progetto: la lordizzazione del bersaglio in
fase di *prelievo*. L'accumulo componeva al lordo per dieci o vent'anni. Misurato il 27/07
(`r0727_tasse.py`) e riprodotto oggi su lump €5.000 + €500/mese:
| | 5 anni | 10 anni | 15 anni |
|---|---|---|---|
| costo del fisco d'accumulo | **−15,7%** | **−29,8%** | **−42,6%** |
(27/07, lump €10k: −16,8% / −31% / −44% → replica coerente su lump diverso.)
**L'errore è composto, non una tantum.** Conseguenza da tenere presente: *tutte* le tabelle a 15-20
anni pubblicate in CLAUDE.md sono al lordo del fisco d'accumulo e vanno lette con questo sconto
sopra. Assunzioni dichiarate (33% plusvalenze, minusvalenze in carry 4 anni, 0,2% annuo sul valore),
**non un parere fiscale**.
Piano a €800/mese, 15 anni: capitale mediano **$450.107** netto contro $776.366 lordo.
📌 **Risultato contro-intuitivo:** versare di più **ritarda il sorpasso** (l'anno in cui il guadagno
cumulato supera tutto il versato): 7º anno a €500/mese, 8º a €800, perché si alza l'asticella che
il guadagno deve superare. I €300 in più non comprano il sorpasso, comprano il **traguardo**: la
mediana tocca il bersaglio al 12º anno invece che al 15º, e P(bersaglio) a 15 anni passa da 73,2% a
99,0%.
⚠️ **€800/mese non bastano per il vincolo dei 10 anni**: P(entro 10 anni) col fisco = **25,5%**.
Servono ~€880-1.050/mese (27/07), e a quel punto si versano oltre $119.000 per arrivare a $272.061.
---
## 3. E se invece fosse un ETF S&P 500 o MSCI World
Script `scripts/research/r0807_asset_compare.py`. Tre cose andavano rese comparabili:
- **la griglia** — le azioni hanno ~252 barre/anno, il book 365: portate su calendario con **0,0 a
borsa chiusa** (convenzione GTAA01). Senza, il Sharpe esce ×1,20 (lezione 25/07);
- **il fisco** — il book realizza ogni anno al 33%; un UCITS ad accumulazione paga il 26% **alla
vendita**. Il differimento è un vantaggio strutturale dell'ETF, ora nel modello (le curve ETF
sono valori di *liquidazione*, già al netto dell'imposta latente);
- **il bersaglio** — $272.061 vale per la rendita perpetua *del book* e per il 33%. Ricalcolato per
ciascuno.
| a 15 anni, €5.000 + €500/mese | book | S&P 500 | MSCI World (proxy) |
|---|---|---|---|
| rendita perpetua | 11,67% | 4,16% | 3,09% |
| capitale-rendita necessario | $254.524 | $646.172 | $869.729 |
| **lente A** — storia piena di ciascuno | $293.823 → **115%** | $204.663 → **32%** | $188.417 → 22% |
| **lente B** — stessa finestra 2019-26 | $295.540 → **118%** | $343.805 → **110%** | $296.707 → 82% |
**Il risultato che conta non è quale vince, è che le due lenti danno risposte opposte.** Sulla
storia piena il book stravince; sulla stessa finestra **l'S&P 500 accumula più del book**. Il
divario della lente A viene interamente dal fatto che i 30 anni dell'indice contengono il 2000 e il
2008, crolli che la strategia non ha mai vissuto.
📌 **E in una riga della tabella delle serie c'è il fatto più importante:** sulla stessa finestra il
rendimento è quasi identico — **17,4% contro 16,8%**. Tutta la differenza è nel rischio: vol 11,0%
contro 19,6%, maxDD 10,5% contro 33,7%. **Il book non guadagna di più, perde di meno** — che è
precisamente ciò che il progetto scrive di TP01 dal 19/06, qui misurato contro un'alternativa vera.
E la rendita perpetua vive sul drawdown: per questo il book ha bisogno di **2,5× meno capitale**.
⚠️ MSCI World è un **proxy** (70% SPY + 30% EFA): URTH/ACWI/VT non sono nell'abbonamento dati del
conto IB. Fra 50% e 80% di quota USA il drift si muove di 0,7 punti e il Sharpe di 0,05.
---
## 4. Quale strategia: book, ETF o un mix
Script `scripts/research/r0807_best_strategy.py`.
⚠️ **Difetto della prima stesura, corretto: un mix esiste solo dove esistono ENTRAMBE le serie.**
Confrontavo «storia piena» contro «stessa finestra» come due lenti, ma calcolavo i bersagli del mix
sull'intersezione in entrambe — quindi la lente «storia piena» dichiarava trent'anni e ne usava
sette (per l'ETF puro dava rendita 8,63% invece del 4,16% vero). **Il confronto fra finestre non è
disponibile per un portafoglio misto.** Rifatto su una finestra sola, con gli scenari espressi come
spostamento del **drift**, applicabile simmetricamente ai due lati.
| quota sul book | base | equity a 30 anni | book dimezzato | entrambi cauti | peggiore | **rimpianto max** |
|---|---|---|---|---|---|---|
| solo ETF | 68% | 23% | 68% | 23% | 23% | 53% |
| 25% book | 80% | 41% | 60% | 27% | 27% | 34% |
| **50% book** | **86%** | 58% | 48% | 27% | 27% | **20%** |
| 75% book | 84% | 69% | 32% | 23% | 23% | 35% |
| solo book | 75% | **75%** | 16% | 16% | 16% | 52% |
**Risposta: 50/50**, non perché vinca (vince solo nello scenario base) ma perché ha il **rimpianto
massimo più basso**. ⚠️ Il criterio del solo caso peggiore **non** distingue 25% da 50% (27,09%
contro 26,99% = pareggio dentro il rumore): a separarli è il rimpianto.
📌 **L'asimmetria fra i due stress È il risultato.** Quello sull'equity è **misurato** — trent'anni
esistono e dicono 11,3% invece di 16,5%. Quello sul book è **giudiziale** — metà del drift, scelto a
mano, perché 7,4 anni sono tutta la storia che ha e *non c'è nulla con cui stressarlo*. Si può
discutere la taglia del taglio, non lo si può togliere. La sua conseguenza è brutale: col drift
dimezzato il capitale-rendita del book puro passa da $254k a **$771.646** (rendita 11,67% → 3,85%).
**Perché il mix non è un compromesso:** correlazione book↔S&P **+0,082** nei giorni di borsa aperta,
**+0,046** nei ribassi; nel 5% di giornate peggiori dell'indice (media −2,94%) il book fa **−0,11%**.
Il capitale-rendita del 50/50 è **$235.769**, più basso sia del solo ETF ($311.567) sia del solo
book ($254.524): due motori scorrelati *abbassano l'asticella*.
⚠️ Non c'è il rischio di venue (spingerebbe ancora verso il mix), e la decisione del 26/07 tiene
tutto su Deribit fino a $20k: questa analisi è **materiale per quella soglia**, non un'indicazione
di agire adesso.
---
## 5. Il simulatore nel browser, e la sua verifica
`scripts/web/` — motore di accumulo in JavaScript (`engine.js`), serie esportata da
`export_series.py`, pagine assemblate da `build.py`.
**Il motore JS deve dare la stessa risposta del Python, e lo si prova:** `test_engine.js` confronta
mediane e probabilità su due configurazioni già calcolate, verifica che il *versato* (deterministico)
coincida al centesimo, e include un **controllo positivo** (un motore col fisco spento dev'essere
rilevato fuori tolleranza — un test che non sa fallire non è un test). Il risolutore («quanto serve
al mese per centrare il bersaglio in N anni») è validato contro `dep_necessario` di `r0727_tasse.py`:
scarti −0,4% / −0,6% / −1,1% su tre configurazioni.
Misura che ha cambiato una scelta: la banda del versamento suggerito resta **±1% da 1.200 a 3.000
percorsi** → non domina il Monte Carlo ma la granularità della bisezione (~€5). Percorsi tenuti
bassi e **incertezza dichiarata**, invece di pagare tempo per una precisione che non arriva.
---
## 6. Quattro errori miei, tutti trovati da un controllo e non a occhio
Sono la parte riutilizzabile del diario.
**(a) Dati inventati in un grafico.** Le righe degli anni 1-2 di una serie erano scritte *a memoria*
perché l'output del terminale era troncato da `tail`. Le ha trovate il confronto riga-per-riga fra
il JSON e i dati incollati nella pagina. **Regola: i dati di una pagina si INIETTANO da un file, mai
si trascrivono** — ora è `build.py` a farlo, e il passaggio manuale non esiste più.
**(b) «Distorsione sistematica» che non esisteva.** Il motore JS sembrava +0,75% sopra il Python su
8 semi, tutti positivi. Ma erano **8 estrazioni contro UN solo punto Python** (seme 807), che stava
in basso nella propria distribuzione: 8 segni concordi rispetto a un punto rumoroso non sono 8
osservazioni indipendenti. Misurato bene (8 semi per parte): **−0,01%, t = −0,04**; e i due
campionatori cadono entrambi entro 1,7 SE dall'**atteso analitico** della media di blocco.
**Regola: un confronto punto-contro-distribuzione non produce evidenza di distorsione.**
**(c) Un confronto impossibile per costruzione** — §4, il mix sull'intersezione.
**(d) Una pagina pubblicata rotta.** Python scrive le chiavi dei pesi come `"0.0"`/`"1.0"`, la pagina
le ricostruiva con `String(0)` → `"0"`: ogni lookup `undefined`, script morto alla prima riga utile.
I pesi intermedi funzionavano *per caso*. **Il controllo che usavo (`node --check`) valida solo la
SINTASSI**: ora c'è `smoke.js`, che esegue le pagine con un DOM finto e segnala sia le eccezioni sia
gli elementi riempiti con `"undefined"`. **Regola: le chiavi di un dizionario Python si LEGGONO dal
JSON, non si ricostruiscono.**
---
## 7. ⚠️ Effetto collaterale del check: un gate di GTAA01 ora FALLISCE
`tests/test_gtaa_band_gate.py::test_la_proposta_non_e_selezionata_sull_hold_out` — la proposta
(banda 25%, cadenza 5g) risulta **9ª/30 in-sample e 8ª/30 sull'hold-out**: migliora passando
all'hold-out, cioè la firma che il test intercetta. CLAUDE.md registra **4/30 e 5/30** (27/07).
Caratterizzato prima di riportarlo:
- i due ranghi sono separati da **0,00116 di Sharpe** su un'ampiezza di griglia di 0,3124 = lo
**0,4%**: il criterio non ha mai avuto margine, era una differenza di un rango;
- il calcolo è **deterministico** (due corse, `max|diff| = 0.0`) e il codice del gate è **invariato**
dal 27/07 (nessun commit su `r0727_gtaa_band_gate.py`, `gtaa.py`, `eqlib.py`, `eq_splits.py`);
- quindi è cambiato **il dato**: `data/raw/` è gitignored e i parquet equity vengono riscritti ogni
giorno dal cron con `ADJUSTED_LAST` di IB, che è retroattivo.
📌 **La lezione vale più del test: un gate validato su dati sovrascritti ogni giorno non è
ri-verificabile.** Il lato cripto non ha questo problema (`rebuild_history.py` ricostruisce da una
sorgente deterministica); il lato equity sì.
**Il test NON è stato toccato** — allentare una soglia perché ha smesso di passare è ciò che questo
progetto vieta, e un `xfail` silenzierebbe esattamente il segnale. Nulla di operativo dipende da
questo (GTAA01 non è deployabile per il blocco PRIIPs e non è nel book live), ma l'affermazione
*«il rango NON migliora sull'hold-out»* oggi è falsa: **decisione dell'operatore** se correggere
l'affermazione, ripensare il gate, o congelare uno snapshot dei parquet equity per renderlo
riproducibile.
---
## Cosa NON cambia
Book, pesi, cron, `config/live.json`, i gate pre-registrati (STATARB 27/09, XSR01 23/10,
DVOLSPREAD 24/10), la decisione di venue (100% Deribit fino a $20k), il muro pubblicato di
$272.061. Gli script di questo diario non toccano la produzione.
@@ -0,0 +1,180 @@
# 2026-08-07 — Un gate che falliva, un criterio che non misurava, e una gamba con 13 anni in meno
**Book, pesi, cron, config: INVARIATI.** `REBAL_BAND_USD` resta $50; GTAA01 resta non deployabile
(PRIIPs) e sotto `GTAA_MIN_CAPITAL`. Cambia un test, cambia un'affermazione in CLAUDE.md, e si
aggiunge una guardia di certificazione che mancava.
Script: `scripts/research/r0807_gtaa_gate_resolution.py`.
Test: `tests/test_eq_history_guard.py` (11) + `tests/test_gtaa_band_gate.py` (16, criterio (A)
sostituito).
---
## Il punto di partenza
Il 07/08, facendo il giro dei test, `test_la_proposta_non_e_selezionata_sull_hold_out` falliva:
```
la proposta e' 8a sull'hold-out ma 9a in-sample: sta meglio dove non doveva essere guardata
```
Il gate (A) del 27/07 (`r0727_gtaa_band_gate.py`) era stato registrato cosi': «proposta 4/30
in-sample, 5/30 hold-out → il rango NON migliora sull'hold-out, quindi non e' selection-on-holdout».
Il codice non era stato toccato (`git log src/portfolio/gtaa.py` fermo al 26/07). Erano cambiati i
**dati**: `data/raw/` e' gitignored e il cron ri-scarica ogni notte i sei ETF con `ADJUSTED_LAST`,
che IB rivede all'indietro a ogni dividendo.
La tentazione ovvia era allentare la soglia o mettere un `xfail`. Sarebbe stato mettere a tacere
esattamente il segnale. La domanda giusta e' un'altra: **il criterio misura cio' che dichiara?**
---
## (0) Il difetto trovato per strada: TLT ha 13.5 anni in meno
Prima ancora di guardare il criterio, la copertura delle sei gambe:
| gamba | prima barra | quotato dal | mancano | barre | pre-2015 | 2015+ |
|---|---|---|---|---|---|---|
| SPY | 1996-08-14 | 1993-01-22 | 3.6a | 7540 | 4625 | 2915 |
| QQQ | 1999-03-10 | 1999-03-10 | 0.0a | 6896 | 3981 | 2915 |
| IWM | 2000-05-26 | 2000-05-22 | 0.0a | 6586 | 3671 | 2915 |
| **TLT** | **2016-02-03** | **2002-07-22** | **13.5a** | 2642 | **0** | 2642 |
| GLD | 2004-11-18 | 2004-11-18 | 0.0a | 5460 | 2545 | 2915 |
| HYG | 2007-04-11 | 2007-04-04 | 0.0a | 4861 | 1946 | 2915 |
(SPY parte dal 1996 perche' la richiesta chiede `durationStr="30 Y"`: e' il **tetto**, non un
difetto. La distinzione conta, senza di essa una guardia segnalerebbe ogni serie lunga.)
**GTAA01 gira su CINQUE gambe prima del 2016**, e la gamba assente e' proprio quella che
diversifica — le obbligazioni. Conseguenza diretta sul gate (A): l'in-sample (pre-2015) e
l'hold-out (2015+) **non sono la stessa strategia**.
Non e' successo il 07/08: nel `logs/cron_daily.log` TLT parte dal 2016-02-03 fin dal primo giro
registrato (24/06), quindi da **prima** della validazione del 27/07. E non e' un fetch da rifare:
una richiesta retro esplicita (`endDateTime=2016-01-01`, `durationStr="5 Y"`) su questo conto IB
ritorna **0 barre**. La storia non c'e'.
**Perche' nessuna certificazione l'ha vista.** Il feed equity ha guardie su integrita', gap lunghi,
spike, split non aggiustati (25/07) e cross-check col gemello UCITS (26/07). **Tutte guardano
DENTRO la serie.** Una serie troncata e' perfettamente integra: non ha buchi, non ha salti, non ha
duplicati. E' la terza volta in due settimane che una guardia tarata su una classe di difetto non
sorveglia le altre (soglia 50% cieca allo split 2:1; soglia sulla deviazione cieca alla
contaminazione EUR/USD; ora: ogni controllo cieco a cio' che la serie ha perso).
### Cablato
`fetch_ib_equities.certify(sym, df, prev)` ora ha **due** guardie, perche' i due difetti non si
vedono nello stesso modo:
- **`TRONCATO`** — la serie ha perso storia *rispetto al disco* (parte >10 giorni dopo, o ha >5
barre in meno). Prende una troncatura il giorno in cui compare; e' cieca a una gia' presente.
**Il file NON viene sovrascritto** — e neppure fuso: `ADJUSTED_LAST` e' ri-aggiustato
all'indietro a ogni dividendo, quindi incollare una vintage vecchia a una nuova creerebbe un
salto sul giunto, un difetto peggiore di quello che si voleva evitare.
- **`STORIA-CORTA`** — la serie parte >1 anno dopo la quotazione dello strumento, e non al tetto
della richiesta. Prende anche una troncatura presente da sempre, che e' il caso di TLT.
Riferimento: `PRIMA_QUOTAZIONE`, sei simboli, **fonte secondaria dichiarata**.
Controlli positivi obbligatori nei test: il giro normale di ogni notte non deve scattare, una
serie al tetto 30Y non deve scattare, un ETF giovane (HYG) non deve scattare, un simbolo fuori
tabella non viene giudicato. *Una guardia che non segnala mai e' indistinguibile da una rotta.*
---
## (1) Il criterio non aveva risoluzione — misurato, non argomentato
| | valore |
|---|---|
| rango della proposta | 9/30 in-sample · 8/30 hold-out |
| distanza dal rango precedente | **0.00116** di Sharpe in-sample |
| spread dell'intera griglia | 0.3124 |
| il verdetto si decideva su | **0.37% dello spread** |
E la misura che chiude la questione — **il criterio applicato a ogni cella della griglia passa
14/30 (47%)**. Non e' un caso: la somma dei ranghi e' la stessa nelle due finestre, quindi
`rank_in <= rank_oos` e' vero per circa **meta' delle celle per costruzione**, qualunque cosa la
griglia contenga.
> Un gate che una cella a caso passa il 47% delle volte non distingue una proposta onesta da una
> selezionata sull'hold-out. E' una moneta.
Contorno: lo spostamento tipico fra le due finestre e' di **8 ranghi** (massimo 25), e lo Spearman
IS/OOS e' **+0.05**. Su questa griglia il rango in-sample non porta informazione sul rango
hold-out — il che rende il confronto fra i due ranghi doppiamente privo di senso.
---
## (2) Il criterio decidibile
**La proposta del 27/07 e' una BANDA, non una cadenza.** `REBAL_EVERY=5` e' gia' la produzione e
non era in discussione. Quindi la domanda sulla provenienza della scelta e': *a cadenza di
produzione, quale banda si sceglie guardando solo il pre-2015?*
| banda | Sh in-sample | Sh hold-out |
|---|---|---|
| 0% | 0.5396 | 0.8261 |
| 5% | 0.5714 | 0.8640 |
| 10% | 0.5956 | 0.8629 |
| **25%** | **0.6398** ← argmax | 0.8529 |
| 40% | 0.6247 | **0.9081** ← argmax |
| 60% | 0.5874 | 0.7573 |
- banda scelta **sui soli dati pre-2015**: **25%** = la proposta, con margine **+0.0151** sulla 2ª;
- banda scelta **sull'hold-out**: **40%** — diversa. *(Controllo positivo: se coincidessero, il
gate non avrebbe potenza e non andrebbe citato come validazione.)*
- cella scelta al buio su **tutta** la griglia: cadenza 1, banda **25%** — stessa banda.
**La proposta e' l'esatto contrario di una selezione-sull'hold-out**: e' la cella che si sceglie
senza guardare l'hold-out, e chi avesse guardato l'hold-out ne avrebbe scelta un'altra. E il
margine e' **0.0151** contro i **0.00116** su cui si decideva il criterio a ranghi: **13×**.
⚠️ **Cio' che questo criterio NON dice:** che la banda scelta in-sample sia la migliore
sull'hold-out. Non lo e'. Con lo Spearman IS/OOS a ~0, nessuna cella di questa griglia lo sarebbe
in modo affidabile. Il gate (A) risponde alla domanda sulla **provenienza** della scelta, non a
quella sulla **previsione**. Confonderle e' esattamente il modo in cui si finisce a selezionare
sull'hold-out credendo di validare.
---
## (3) Robustezza al difetto (0)
Rifatto tutto sull'universo a **5 gambe** (senza TLT), coerente fra le due finestre:
blind **25%**, hold-out **40%**, margine **+0.0164**. Verdetto identico. Il criterio a ranghi
resta una moneta anche li' (passa 14/30).
Quindi: il difetto dei dati **non e' cio' che decide questo verdetto** — ma resta un difetto, e va
riparato per suo conto. Che e' cio' che si e' fatto al punto (0).
---
## Cosa cambia
- `tests/test_gtaa_band_gate.py`: il criterio a ranghi e' **ritirato** e sostituito da
`test_la_banda_proposta_e_quella_scelta_al_buio` + il suo controllo positivo
(`test_chi_guardasse_l_hold_out_sceglierebbe_una_banda_DIVERSA`) + un test sul margine.
Il **motivo** del ritiro e' congelato in
`test_il_confronto_fra_ranghi_e_una_moneta_ed_e_per_questo_che_e_stato_RITIRATO` — si congela il
motivo, non l'esito, che dipende dai dati e si muove da solo.
- `r0727_gtaa_band_gate.py`: il gate (A) stampa il criterio decidibile; il confronto fra ranghi
resta come descrizione, con la data del ritiro.
- CLAUDE.md: l'affermazione «proposta 4/30 in-sample, 5/30 hold-out → il rango NON migliora» e'
corretta.
- `fetch_ib_equities.py`: le due guardie sulla storia + il riepilogo finale che le elenca.
---
## Regole
1. **Un test che fallisce senza che il codice sia cambiato sta segnalando che i dati non sono
versionati.** Prima di toccarlo, si guarda cosa e' cambiato sotto.
2. **Un criterio va misurato sulla sua risoluzione prima che sul suo esito.** Se decide su una
frazione di percento dello spread, il verdetto e' rumore in entrambi i versi — anche quando
passa. Il 27/07 quel criterio *passava*, e passava per caso.
3. **Un gate si valida contando quante volte lo passa un candidato a caso.** Qui: 47%. Il numero
si poteva calcolare il 27/07 senza dati nuovi.
4. **Una certificazione che guarda solo dentro la serie non vede cio' che la serie ha perso.**
Una serie troncata e' integra, senza gap, senza spike, senza duplicati: passa tutto.
5. **Distinguere «giovane», «al tetto della richiesta» e «troncato».** Sono tre cose diverse e
solo la terza e' un difetto; senza la distinzione la guardia segnala sempre e viene ignorata.
6. **Provenienza e previsione sono due domande diverse.** Un gate anti-selezione dice da dove
viene la scelta, non se funzionera'.
+164
View File
@@ -0,0 +1,164 @@
# 2026-08-07 — Il piano rifatto al netto: muro, traiettorie, versamenti
**Book, pesi, cron, config: INVARIATI.** Non tocca la produzione: rifa' i numeri del *piano di
accumulo*, che erano al lordo del fisco.
Script: `scripts/research/r0807_piano_netto.py`. Test: `tests/test_piano_netto.py` (16).
---
## Il debito
Il 07/08 (`r0727_tasse.py`, `r0807_growth_yearly.py`) era stato misurato che l'accumulo composto al
lordo sovrastima il capitale del **15.7% a 5 anni, 29.8% a 10, 42.6% a 15**. Il fatto era stato
scritto in memoria — *"TUTTE le tabelle a 15-20 anni pubblicate sopra sono al LORDO"* — ma i numeri
non erano stati rifatti. Sono numeri che sono serviti a decidere: la traiettoria da $600, la
tabella «quanto versare per un orizzonte dato», la rendita €/g.
**E il muro stesso non era neutro.** `$272.061` viene da una convenzione **asimmetrica**: il
prelievo viene lordizzato (€50/g netti → $29.690/anno lordi al 33%) ma il capitale che resta
investito compone **senza mai pagare imposte**, in accumulo come in prelievo. Le due meta' del
conto non usano lo stesso fisco.
---
## (0) Il controllo di replica, che ha trovato subito qualcosa
Prima regola: a fisco spento tutto deve riprodurre i numeri pubblicati, altrimenti un numero
diverso non si distingue da un bug.
| | perpetua | muro |
|---|---|---|
| costante pubblicata (`VR.TARGET`, citata ovunque) | — | **$272.061** |
| questa implementazione, fisco OFF, 4000 path | 10.9131% | **$272.061** |
| `r0726_capwall_refresh.perp_and_wall` ai suoi **2000** path | 11.0107% | $269.648 |
| lo stesso, portato a 4000 path | 10.9131% | **$272.061** |
Replica esatta al dollaro fra due implementazioni separate. ⚠️ **Ma trovato per strada:** la
funzione che ha prodotto il muro gira di default a **2000 path**, e a quella taglia da' $269.648 —
**0.9% di rumore Monte Carlo**. Il muro pubblicato e' corretto (fu calcolato a 4000), ma **la sua
terza cifra significativa non e' un'informazione**: si cita **$272k**, non $272.061.
---
## (1) Il muro, nella convenzione coerente
Imposte pagate ogni anno **dentro** il portafoglio (stessa meccanica dell'accumulo: plusvalenza
annua al netto dei movimenti di cassa, carry 4 anni, patrimoniale 0.2%), prelievo gia' netto:
| convenzione | prelievo/anno | perpetua | muro |
|---|---|---|---|
| (a) pubblicata — fisco solo sul prelievo | $29.690 | 10.91% | **$272.061** |
| (b) coerente, aliquota 33% | $19.892 | **7.70%** | **$258.338** |
| (b) coerente, aliquota 26% | $19.892 | 8.42% | $236.310 |
**−5.0%.** I due errori della convenzione (a) vanno in versi opposti e **si compensano quasi**:
lordizzare il prelievo alza il muro, non tassare il capitale investito lo abbassa. Ma si
compensano *per caso*, non per costruzione — e' il tipo di errore che si vede solo rifacendo il
conto in modo coerente. Cio' che resta scoperto e' la patrimoniale e la non-linearita' della
rendita perpetua nel drift.
---
## (2) Le traiettorie — ed e' qui che il fisco morde
Orizzonte 25 anni, 3000 path, seed 725: **esattamente la macchina che ha prodotto la tabella
pubblicata**, quindi la colonna LORDA e' una replica di controllo.
| €/mese | versato in 20a | LORDO: anni | P(20a) | NETTO: anni | P(20a) |
|---|---|---|---|---|---|
| 0 | $600 | mai | 0% | mai | 0% |
| **250** | $66.818 | **16.3a** *(pubbl. 16.2)* | **92%** *(pubbl. 92%)* | **19.8a** | **52%** |
| 500 | $133.035 | 12.4a *(pubbl. 12.4)* | 100% | 14.7a | 99% |
| 800 | $212.496 | 10.0a | 100% | 11.4a | 100% |
| 1000 | $265.470 | 9.0a *(pubbl. 9.0)* | 100% | 10.0a | 100% |
| 2000 | $530.340 | 6.0a *(pubbl. 6.0)* | 100% | 6.4a | 100% |
**Il livello €250/mese — quello con cui il 26/07 il piano risultava «P(entro 20a) 92%» — al netto
diventa una moneta: 52%.**
⚠️ **La colonna «anni» e' la mediana CONDIZIONATA all'arrivo** (convenzione di
`r0726_capwall_refresh.trajectory`, quindi confrontabile con la tabella pubblicata) e va letta
insieme alla probabilita' accanto.
> **Errore mio, catturato prima di pubblicare.** La prima stesura calcolava la mediana
> sull'**intero** vettore, con i non-arrivi codificati `-1`. Risultato: €250/mese risultava passare
> da 15.7 a **15.3** anni col fisco — *piu' veloce* — mentre la probabilita' crollava da 91% a 53%.
> Con meta' dei path a `-1` la mediana del vettore cade sui **primi** arrivi. **Un non-arrivo va
> messo a +∞, non a −1: messo a −1 il numero migliora tanto piu' quanto peggio va la colonna**, ed
> era abbastanza plausibile da finire in un verdetto.
---
## (3) Quanto versare per un orizzonte dato — al netto
Bersaglio $258.338. Fra parentesi il numero pubblicato (lordo, bersaglio $272.061).
| orizzonte | P=50% | P=75% | P=90% | P=95% | tot. versato @P=90% |
|---|---|---|---|---|---|
| **10 anni** | €998/m | €1.162/m | **€1.323/m** *(€1.178)* | €1.424/m | **$175.058** *($155.923)* |
| 15 anni | €470/m | €570/m | **€672/m** *(€509)* | €725/m | $133.983 *($101.643)* |
| 20 anni | €245/m | €306/m | **€371/m** *(€237)* | €417/m | $98.762 *($63.406)* |
**Il fisco costa +12% al mese a 10 anni, +32% a 15, +57% a 20.** Cresce con l'orizzonte perche'
l'errore era composto: piu' tempo, piu' interessi mai maturati sulle imposte non pagate.
E la lettura del 26/07 si **rafforza**: a 10 anni versi **$175k** per arrivare a $258k (il
rendimento fa il 32%), a 20 anni ne versi **$99k** (il rendimento fa il 62%). *A orizzonti corti
non fai lavorare la strategia, compri il capitale coi bonifici* — al netto ancora di piu'.
---
## (4) Rendita €/g mediana — al netto
Le imposte sono gia' dentro la perpetua (7.70%): il numero e' netto e **non va lordizzato una
seconda volta**.
| €/mese | 5a | 10a | 15a | 20a | P(€50/g a 20a) |
|---|---|---|---|---|---|
| 0 | 0.20 | 0.34 | 0.59 | 1.01 | 0.0% |
| **250** | 4.38 | 11.82 | 24.61 | **46.61** *(pubbl. 91.30)* | **42.0%** *(pubbl. 90.0%)* |
| 500 | 8.56 | 23.31 | 48.65 | 92.11 | 97.6% |
| 800 | 13.58 | 37.08 | 77.47 | 146.78 | 100.0% |
| 1000 | 16.93 | 46.26 | 96.67 | 183.18 | 100.0% |
| 2000 | 33.66 | 92.18 | 192.79 | 365.24 | 100.0% |
A 20 anni la rendita di €250/mese si **dimezza** (91.30 → 46.61 €/g) e P(€50/g) passa da **90% a
42%**. La non-linearita' resta: da 15 a 20 anni la rendita raddoppia a ogni livello.
---
## Cosa cambia e cosa no
**Cambia:** il livello di versamento che il piano dichiarava sufficiente. €250/mese al lordo
sembrava «P 92%, il piano funziona»; al netto e' 52%, e per tornare a ~90% servono **€371/mese**
a 20 anni. Il muro si sposta poco (−5%), i **versamenti** si spostano molto (+57% a 20 anni).
**Non cambia:**
- senza versamenti il capitale-rendita non si raggiunge **mai**, a qualunque lente fiscale;
- l'ordine di importanza delle leve (versare > quando > quanto presto si smette > piatto vs
crescente > frequenza) e' invariato: il fisco colpisce tutte le colonne allo stesso modo;
- il rischio di venue resta fuori scala rispetto a tutto questo (a p=5% il risultato mediano e'
zero comunque).
⚠️ **Assunzioni fiscali dichiarate, NON un parere fiscale** (33%, sensibilita' a 26%, minusvalenze
in carry 4 anni, patrimoniale 0.2%/anno). Il modello tassa la variazione **annua** di valore =
**limite superiore** rispetto alla pura realizzazione, stretto perche' TP01 ribilancia ogni giorno
e SKH01 chiude round-trip discreti.
---
## Regole
1. **Un modello che tassa una meta' del conto e non l'altra non e' conservativo, e' incoerente** —
e i due errori possono compensarsi quasi esattamente, il che li rende invisibili finche' non si
rifa' il conto in modo simmetrico.
2. **Un non-arrivo va codificato +∞, mai −1.** Con −1 la mediana *migliora* quanto piu' la colonna
peggiora.
3. **Una mediana condizionata va sempre stampata accanto alla sua probabilita'**, o dice il
contrario di quello che sembra.
4. **Prima di pubblicare un numero nuovo, far riprodurre alla macchina quello vecchio** — qui la
colonna LORDA riproduce 4 righe su 4 della tabella pubblicata, ed e' l'unica ragione per cui la
colonna NETTA e' leggibile.
5. **Un Monte Carlo ha una risoluzione, e va detta.** $272.061 e' esatto quanto $269.648: la
differenza fra i due e' la taglia del campione, non un'informazione sul piano.
@@ -0,0 +1,154 @@
# 2026-08-19 — Quattro 🚨 per una manutenzione annunciata, e cosa c'era dietro
**Richiesta:** *"su Adp_VPS mi sono arrivati questi messaggi"* — quattro allarmi VENUE WATCH del
18/08, incollati senza domanda. La domanda vera era: e' successo qualcosa di grave?
**No.** Ma il modo in cui l'ho scoperto ha rivelato tre difetti, e uno riguarda gli ordini.
**Toccati:** `src/live/venue_watch.py`, `src/live/deribit.py` (tabella `_CONTRACT` + `check_specs`),
`scripts/live/venue_watch.py`. **Test:** `tests/test_venue_watch.py` 23 → **35**; suite intera
**618 verdi**. **Book, pesi, `config/live.json`, THRESHOLD_BPS, PERSIST_HOURS: INVARIATI.**
---
## 0. Cosa era successo davvero
Manutenzione Deribit **annunciata il 14/08 per il 18/08 alle 09:00 UTC**, downtime dichiarato
**15–30 minuti**. Il book si e' astenuto ai giri delle 09:07 e 10:07 UTC — `conto non leggibile
(offline) -> stop, non eseguo a cieco` — e alle 11:07 eseguiva di nuovo. **Il sistema ha fatto la
cosa giusta.**
I 572 minuti di "feed SKH stantio" non erano una deriva nascosta: con la coda 5m non attaccabile
il book e' ripiegato sul feed certificato, che e' di suo vecchio di ~9,5 ore. Prima (08:07) e dopo
(11:07) diceva `fresco (0 min)`.
Ma `venue_watch` ha visto la piattaforma bloccata fino alle **14:07 UTC**: la manutenzione ha
sforato l'annuncio **di ore, non di minuti**. E ha mandato quattro 🚨 identici, **tutti dopo che
il book aveva gia' ripreso**.
## 1. Perche' quattro messaggi uguali: l'allarme non aveva memoria
Il rilevatore di dislocazione e' tarato con cura — 100 bps, 4 ore a segno costante, «zero falsi
allarmi in 8 anni», controllo positivo su Bitfinex 2018-19 — e la macchina a stati `step()`
allerta **una volta per streak** e poi tace.
Accanto, il blocco piattaforma era un `if` secco senza stato:
```python
if obs["platform_locked"]:
report["alerts"].append("Deribit public/status: PIATTAFORMA BLOCCATA (locked=true)")
```
Nessuna persistenza, nessuna deduplica, nessuna nozione di manutenzione. Un rilevatore disciplinato
con accanto uno che grida al lupo ogni ora, **e con lo stesso titolo**: *«PRIMO PASSO: prelievo di
prova»*. Il costo non e' il fastidio: e' che un allarme massimo speso per un evento atteso e'
un allarme che non verra' letto il giorno che e' vero — l'unico giorno che conta.
Ora il lock passa da `lock_step()`, pura e testata, con gli stessi livelli degli altri stati:
| condizione | esito |
|---|---|
| bloccata + manutenzione dichiarata, entro `MAINT_GRACE_HOURS` (2) | ⚠️ **una volta**, «attesa, non allarme» |
| manutenzione che **sfora** la tolleranza | 🚨 **una volta**, «ha SFORATO 2h» |
| bloccata **senza** manutenzione dichiarata | 🚨 subito, una volta |
| rientrata | avviso di rientro, una volta |
| `public/status` **illeggibile** | **niente**: le ore restano dove sono |
Rigiocando il 18/08: quattro messaggi identici diventano **⚠️ → 🚨 (ha sforato) → rientrato**. Tre
messaggi che dicono tre cose diverse.
⚠️ L'ultima riga della tabella e' quella che mi premeva: dichiarare «e' rientrato» perche' non si
e' riusciti a *guardare* sarebbe la bugia peggiore possibile in questo file. `locked is None` non
azzera niente e non annuncia niente.
⚠️ E la tolleranza non e' un'assoluzione: la manutenzione declassa l'allarme **solo dentro la
finestra**, e oltre lo **rialza**. Il 18/08 e' la ragione per cui la regola non poteva essere
«se e' manutenzione, stai zitto»: Deribit aveva annunciato mezz'ora ed e' rimasta bloccata per ore.
Una manutenzione che dura sei volte l'annuncio **e' di nuovo una notizia.**
## 2. Il messaggio dichiarava un valore che non aveva letto
Il parser accetta qualunque valore diverso da `false`/`none` — Deribit risponde anche `partial` —
e il testo era cablato: `(locked=true)`. Il runbook al passo 2 manda a controllare *proprio quel
campo*: mandarci qualcuno con in testa la stringa sbagliata e' peggio che non dirgliela.
Adesso `platform_status()` restituisce il valore grezzo, il messaggio lo stampa e lo **stato lo
salva**. Del 18/08 non e' piu' ricostruibile quale fosse: nessuno lo registrava.
## 3. Il difetto che poteva costare: le specifiche contratto
Cercando altro, il confronto con gli annunci Deribit ha trovato una cosa che nessun allarme
sorvegliava. Il 18/08 dopo le 09:00 UTC Deribit ha aggiornato **tick, contract size e minimum
order size dei perpetual lineari USDC** (annuncio del 14/08). La tabella `_CONTRACT` di
`deribit.py`, che e' quella con cui si costruiscono gli ordini, era **cablata a mano** e non se
n'e' accorta:
| | dichiarato | venue dal 18/08 |
|---|---|---|
| BTC tick | 0.5 | **0.1** |
| ETH tick | 0.05 | **0.01** |
| ETH min/step | 0.001 | **0.0001** |
Nessun ordine e' stato rifiutato, e la ragione **non e' merito nostro**: i cambi erano *riduzioni*,
e un valore piu' grosso resta conforme. Il costo effettivo era di granularita' — su ETH
l'incremento minimo restava **$1.92** invece di **$0.19** su un conto da $597 (0,32% contro 0,03%).
⚠️ Il giorno che Deribit **alza** un minimo, la stessa cecita' fa **rifiutare gli ordini**, e non
c'e' niente che lo dica prima.
**Scelta di disegno: la tabella dichiarata resta l'autorita' per costruire un ordine; il venue
diventa il controllore, non la fonte.** Prendere i valori dall'API dentro il percorso di
esecuzione avrebbe reso l'ordine dipendente da come ha risposto una GET — cioe' non ricostruibile
dopo. Invece `check_specs()` gira **nel venue_watch orario** (sola lettura, fuori dal percorso
ordini) e confronta; la tabella si aggiorna a mano, di proposito, in git.
Il confronto dichiara la **direzione**, che e' l'unica cosa che serve per decidere se correre:
- `granularita'` — dichiarato piu' grosso: conforme, si perde precisione → ⚠️, si aggiorna con calma;
- `rifiuto` — dichiarato piu' fine: **il venue rifiuta** → 🚨, si corregge subito.
⚠️ Uno strumento **non letto** non e' una divergenza e non viene contato come «combacia»: finisce
in `non_letti`. Silenzio e uguaglianza non sono la stessa cosa, e solo una delle due e' rassicurante.
Tabella aggiornata ai valori veri e verificata: `check_specs()` risponde `divergenze: []`,
`non_letti: []`. Il floor `min_order_usd = $5` del book e' indipendente, quindi lo step piu' fine
**non** apre la porta a ordini da 19 centesimi.
## 4. Il difetto piu' lento: la referenza non e' piu' indipendente
`venue_watch` misura Deribit contro un consenso di referenze USD. Erano **due**: Coinbase e
Bitstamp. Ma le comunicazioni del 12–18/08 dicono «Deribit **by Coinbase**», mettono il **Coinbase
Index** come riferimento per una parte dei perpetual lineari, e instradano lo spot Deribit su
**Coinbase Exchange**.
Il rilevatore esiste per rispondere a «Deribit sta scollando dal mondo?». Se una delle due
referenze e' **la casa madre**, uno shock di Coinbase muove Deribit e la referenza *insieme*, e lo
scarto in bps resta piccolo **proprio nell'ora in cui dovrebbe aprirsi**. Con due referenze, il
consenso indipendente si riduceva di fatto a Bitstamp.
Aggiunta **Kraken** come terza. BTC ed ETH restano sul Deribit Index (hanno opzioni quotate), quindi
oggi la contaminazione e' di *proprieta'*, non ancora di *calcolo*: si interviene finche' e' teorica.
⚠️ **Onesta' sulla taratura.** «Zero falsi allarmi in 8 anni» e' stato misurato con l'insieme di
referenze di allora. `THRESHOLD_BPS` e `PERSIST_HOURS` non sono stati toccati, ma il consenso ora
si calcola su tre serie invece di due, e **quel numero non e' stato ri-misurato**. Quello che si
puo' affermare leggendo il codice e' la *direzione*: con tre referenze il consenso e' la **mediana**
(robusta a un outlier) invece della media di due, e lo spread max-min si allarga → si va piu'
spesso in **BLIND**, che e' lo stato morbido. Cioe' il modo in cui questa modifica puo' sbagliare
e' **«allerta di meno»**, non «grida al lupo». Per il numero vero si rilancia
`scripts/research/r0726_venue_tripwire.py` con la terza serie.
Misurato subito dopo: BTC +3.0 bps, ETH +2.5 bps, **3 referenze**, spread fra referenze 1.5 e 0.7
bps. Le tre concordano strettamente: nessuna deriva verso BLIND nella pratica.
## 5. Cosa NON e' stato fatto, e resta aperto
- **Il Rulebook del 12/08 non lo sorveglia nessuno.** Introduce ADL e perdita socializzata,
*emergency powers in qualifying circumstances*, la disciplina dei conti dormienti, e la
precisazione che Deribit ha *«limited administrative authority, rather than direct control»*
sugli asset custoditi da terzi. Per un sistema il cui runbook dice «l'azione giusta e'
prelevare», questa e' materia di rischio-venue pura — e il watcher guarda solo i prezzi.
- **La taratura a tre referenze non e' ri-misurata** (vedi §4).
- **Il verso della finestra di manutenzione e' euristico**: `MAINT_GRACE_HOURS = 2` non legge gli
annunci, li **presume**. Un feed degli annunci Deribit renderebbe la tolleranza esatta invece
che ragionevole.
@@ -0,0 +1,156 @@
# 2026-08-21 — «Zero falsi allarmi in 8 anni» non descriveva il sistema che gira
**Richiesta:** *"analizza e fai B1 e B2"* — B1: portare in memoria operativa la sessione del 19/08,
che stava solo nel diario e nel commit. B2: ri-misurare la taratura del tripwire di venue dopo
l'aggiunta della terza referenza, debito dichiarato quel giorno e mai chiuso.
**Toccati:** `scripts/research/r0821_venue_refs.py` (nuovo), `tests/test_venue_watch.py` (35 → 37),
`CLAUDE.md`. **Book, pesi, `config/live.json`, `THRESHOLD_BPS`, `PERSIST_HOURS`: INVARIATI.**
---
## 0. Il debito, come era stato dichiarato
Il 19/08 e' stata aggiunta **Kraken** come terza referenza, perche' Coinbase ha comprato Deribit e
una referenza che e' la casa madre non misura piu' se Deribit scolla dal mondo. Il diario fu onesto
sul limite: *«"Zero falsi allarmi in 8 anni" e' stato misurato con l'insieme di referenze di allora
… quel numero non e' stato ri-misurato»*, e dichiarava la sola **direzione** dell'errore — con la
mediana di tre il consenso e' piu' robusto e lo spread max-min si allarga, quindi si va piu' spesso
in BLIND, che e' lo stato morbido: il modo di sbagliare e' «allerta di meno».
La direzione era giusta. Ma ri-misurando salta fuori un fatto piu' grosso, che non era nel verso
previsto perche' non riguardava la modifica del 19/08 **ma la taratura originale**.
## 1. Il fatto che struttura tutto: la profondita' delle referenze
| asset | venue | barre | da | a |
|---|---|---|---|---|
| BTC | coinbase | 69.643 | 2018-08-14 | 2026-07-26 |
| BTC | bitstamp | 69.663 | 2018-08-14 | 2026-07-26 |
| BTC | **bitfinex** | 33.000 | 2018-08-14 | **2022-05-21** |
| BTC | **kraken** | **702** | 2026-06-26 | 2026-07-26 |
| ETH | coinbase | 64.554 | 2019-03-14 | 2026-07-26 |
| ETH | bitstamp | 64.572 | 2019-03-14 | 2026-07-26 |
| ETH | **bitfinex** | **0** | — | — |
| ETH | kraken | 702 | 2026-06-26 | 2026-07-26 |
Il tetto di Kraken e' stato **ri-verificato oggi sulla rete**, non creduto da un commento del 26/07:
chieste 70.286 ore, ricevute **704** (l'1,00% del richiesto). L'endpoint OHLC pubblico ritorna le
ultime ~700 candele qualunque `since`.
**Conseguenza: la taratura a 8 anni con Kraken dentro non e' ottenibile.** Non per pigrizia — per
struttura della fonte. E non e' un problema per il sorvegliante live, a cui servono le ultime ore.
## 2. Il falso allarme che c'era, e che nessuno aveva visto
Frontiera a zero falsi allarmi, per insieme di referenze, punto in produzione (100 bps, 4h):
| insieme | asset | ore utili | non-BLIND | soglia minima a 4h | falsi allarmi a (100, 4h) |
|---|---|---|---|---|---|
| **LIVE-pre (CB+BS)** | BTC | 69.633 | 100,0% | **150 bps** | **1** |
| | ETH | 64.541 | 100,0% | 100 bps | 0 |
| CALIB (CB+BS+BF) | BTC | **65.043** | 93,4% | 75 bps | **0** |
| | ETH | 64.541 | 100,0% | 100 bps | 0 |
| **LIVE-post (CB+BS+KR)** | BTC | 69.633 | 100,0% | **150 bps** | **1** |
| | ETH | 64.541 | 100,0% | 100 bps | 0 |
Due cose in questa tabella.
**(a) «Zero falsi allarmi in 8 anni» non ha mai descritto la configurazione in produzione.** Quel
numero viene dalla riga CALIB, che ha `bitfinex` nel consenso — e il sorvegliante live non l'ha mai
avuta. Il 65.043 e' la firma: e' esattamente il numero di ore che CLAUDE.md cita al punto (1) del
bullet VENUE WATCH. Sul consenso reale le ore sono 69.633 e i falsi allarmi sono **1**.
**(b) Aggiungere Kraken non lo ripara**, perche' su 8 anni Kraken porta un mese: LIVE-post e
LIVE-pre danno numeri **identici** sulla storia lunga.
Il falso allarme e':
```
2020-03-13 07:00 -> 10:00 UTC 4 ore picco -418,7 bps segno -1
```
Il **crash COVID**. Cioe' proprio l'evento che la memoria elencava come esempio di cio' su cui il
tripwire *non* scattava: *«zero falsi allarmi inclusi crash COVID 2020-03, maggio 2021, LUNA e
novembre 2022»*.
## 3. Perche' spariva a tre referenze — e perche' non e' una buona notizia
Nella stessa finestra, con `bitfinex` nel consenso, **1 delle 4 ore diventa BLIND** (utilizzabili
75%) → il run si spezza, non arriva mai a 4 ore consecutive, l'episodio non esiste. Ma la
dislocazione **e' ancora li'**: mediana **−343 bps** su quelle ore.
⚠️ **Lo zero non veniva da un consenso piu' accurato, veniva da un'ora buttata.** «Zero falsi
allarmi» puo' voler dire *piu' preciso* oppure *piu' cieco*, e le due si distinguono solo guardando
la quota di ore utilizzabili — che nella riga CALIB e' 93,4% contro il 100,0% delle altre.
Congelato in due test puri (`tests/test_venue_watch.py`), perche' e' il meccanismo e non il numero
a essere trasferibile:
- `test_una_terza_referenza_non_puo_aumentare_le_ore_utilizzabili` — lo spread max-min e' monotono
nel numero di referenze, quindi «piu' referenze» non e' gratis: sposta verso BLIND;
- `test_una_sola_ora_BLIND_spezza_lo_streak_e_impedisce_l_allarme` — con un caso di controllo che
DEVE scattare, altrimenti il test non proverebbe nulla.
## 4. La direzione dichiarata il 19/08 e' confermata, e la sua TAGLIA dipende dal venue
Confronto **appaiato** (stesse ore, mai due campioni diversi):
| | ore | non-BLIND 2 ref | 3 ref | Δ | \|scarto\| mediano, differenza appaiata |
|---|---|---|---|---|---|
| BTC + bitfinex | 33.000 | 99,95% | 86,04% | **−13,91 pp** | −0,04 bps |
| BTC + kraken | 702 | 100,00% | 100,00% | **+0,00 pp** | −0,04 bps |
| ETH + kraken | 702 | 100,00% | 100,00% | +0,00 pp | +0,03 bps |
«Piu' referenze → piu' BLIND» e' vero, ma con Bitfinex costa **14 punti** di ore utilizzabili e con
Kraken **zero**. Non e' una proprieta' del numero tre: e' una proprieta' di **quanto la terza
referenza e' d'accordo con le altre**. Bitfinex nel 2018-2022 era il venue con i problemi bancari —
metterlo nel consenso e' metterci dentro il rumore che il controllo positivo usa come *segnale*.
## 5. Controllo positivo: intatto
Bitfinex 2018-19 come bersaglio, consenso Coinbase+Bitstamp: **22 episodi**, il piu' lungo **2.324
ore**, picco **1.136 bps = 11,4x** la soglia. Il rilevatore vede i casi veri.
## 6. Decisione: la soglia NON si tocca, ma la giustificazione cambia
Il criterio dichiarato in anticipo il 26/07 aveva tre gambe: **(a) zero falsi allarmi in 8 anni**,
(b) margine ≥3x sul caso storico piu' debole (FTX ~300 bps) → soglia ≤100 bps, (c) minima latenza.
**La gamba (a) non e' soddisfatta** dalla configurazione reale. Le altre due reggono, e l'economia
del 26/07 risolve da sola:
- 1 falso allarme in 8 anni = 0,125/anno × 0,248% di costo = **0,031%/anno** di equity attesa,
contro il **100%** che un vero positivo evita → break-even a `p > 0,031%`, e ogni `p` plausibile
(0,5-5%) e' 16-160 volte sopra;
- alzare a 150 bps per ripristinare lo zero porterebbe il margine su FTX da **3,0x a 2,0x**, sotto
il vincolo (b) dichiarato prima di guardare i dati.
**Quindi (100 bps, 4h) resta**, ma perche' **un falso allarme ogni 8 anni e' economico**, non
perche' non ce ne siano. E il numero da citare e' **1 in 8 anni** — che e', ironicamente, proprio
l'esempio che il punto (4) del bullet usava per il break-even: la memoria si contraddiceva da sola
e la meta' giusta era quella dell'economia.
## 7. Cio' che resta aperto
- **La terza referenza non e' validabile sulla storia.** Kraken e' verificata su un mese e su quel
mese non cambia nulla. Se serve una validazione lunga, va cercata una fonte che pagini davvero
(il tetto ~700 e' dell'endpoint pubblico, non di ccxt).
- **Il Rulebook Deribit del 12/08 non lo sorveglia nessuno** (ADL, perdita socializzata, *emergency
powers*, conti dormienti) — invariato dal 19/08.
- **`MAINT_GRACE_HOURS = 2` presume gli annunci invece di leggerli.** Non e' teorico: due
`locked=true` in quattro giorni (18/08 ~4h, 21/08 ~1h).
## REGOLE
- **Un numero di taratura va etichettato con la CONFIGURAZIONE su cui e' stato misurato**, non solo
con la finestra. «Zero falsi allarmi in 8 anni» era vero e inutile: descriveva un consenso che la
produzione non ha mai avuto, e nessun test poteva accorgersene perche' i due percorsi (ricerca e
live) tenevano la lista delle referenze in due posti diversi.
- **Uno "zero" si legge sempre accanto alla quota di campione utilizzabile.** Meno falsi allarmi
perche' si vede meglio e meno perche' si vede di meno hanno lo stesso valore stampato e valore
opposto.
- **Quando due affermazioni della stessa memoria si contraddicono** (qui «zero falsi allarmi» e «a
1 ogni 8 anni serve p > 0,031%»), la contraddizione e' un'informazione: una delle due e' stata
scritta guardando i dati.
- **Il debito dichiarato il 19/08 era corretto ma sottodimensionato:** diceva «il numero non e'
ri-misurato» e il numero era sbagliato **prima** della modifica che lo aveva fatto dichiarare.
+141
View File
@@ -0,0 +1,141 @@
# 2026-08-22 — SOL come terza gamba: tutto il guadagno è un anno solo, e quell'anno il dato non è buono
**Richiesta:** dopo *"hai già provato ad analizzare utilizzo di XRP o SOL o UNI?"* — sì, ma sempre
dentro panieri cross-sectional su Hyperliquid. SOL è l'**unico dei tre eseguibile su Deribit** e
TP01/SKH01 non erano mai stati misurati su di lui. *"si fai una analisi"*.
**Esito: SCARTATO.** L'ipotesi a priori (*diluisce*) era registrata prima di guardare, ed è confermata.
**Toccati:** `scripts/research/r0822_sol_leg.py` (nuovo), `tests/test_sol_leg.py` (5), `CLAUDE.md`,
`data/raw/alt_sol_*.parquet` (namespace nuovo). **Book, pesi, `config/live.json`, cron: INVARIATI.**
---
## 0. Il dato, prima della strategia
Storico ricostruito da Deribit mainnet: `SOL/USDC:USDC`, **466.776 barre 5m dal 2022-03-15**,
0 gap, coerenza resample maxΔ 0.00 bps. Poi certificato — ed è la certificazione a decidere il
disegno dell'esperimento, non il contrario.
| | med bps vs Coinbase | p95 | max | >1% |
|---|---|---|---|---|
| 2022 | 8.1 | 40.1 | **2478.6** | 1.3% |
| 2023 | 7.6 | 30.0 | 1010.3 | 0.6% |
| 2024 | 5.9 | 22.7 | 109.4 | 0.0% |
| 2025 | 4.0 | 14.4 | 269.1 | 0.0% |
| 2026 | 3.9 | 12.4 | 51.7 | 0.0% |
Conferma esatta del verdetto del 19/06 (*«SOL 🟡 pulito da ~2024; 2022-23 rumoroso»*). Flat a 1h
**0,2%** (usabile), a 5m **20,8%** con run fino a 177 barre (~15h) — lontano da LTC (82%) ma non
è BTC/ETH (~0%).
Da qui **due lenti dichiarate prima di misurare**: `L-FULL` (2022-03+, usa gli anni segnalati) e
`L-PULITA` (2024+, dato buono ma quasi tutto hold-out).
## 1. Le gambe da sole (meccanismi CONGELATI, nessuna ri-ottimizzazione)
| gamba | Sharpe | maxDD | CAGR | Sh hold-out |
|---|---|---|---|---|
| TP01 BTC | 1.13 | −16.2% | 15.2% | +0.28 |
| TP01 ETH | 1.10 | −15.2% | 15.2% | +0.62 |
| **TP01 SOL** | **0.91** | −12.7% | 9.8% | **−0.24** |
| SKH01 BTC | 1.28 | −21.4% | 33.6% | +1.49 |
| SKH01 ETH | 1.05 | −27.4% | 30.9% | +1.49 |
| **SKH01 SOL** | **0.51** | **−40.5%** | 11.3% | +1.05 |
⚠️ **SKH01-V2-DD su SOL fa 40,5% di drawdown.** La variante «-DD» esiste *perché* fu selezionata,
nella 2ª ondata del 23/06, sul criterio **maxDD < 30%** (BTC 21%, ETH 27%). Su un asset nuovo il
criterio stesso per cui la variante è stata scelta **fallisce**. Non è un dettaglio: è la firma di
un parametro tarato su due asset e presentato come proprietà del meccanismo.
## 2. Il livello che conta: il book
24 ancore, **mediana delle differenze appaiate** (regola 26/07: un Δ eredita la fortuna d'ancora).
| | L-FULL (2022-03+) | L-PULITA (2024+) |
|---|---|---|
| dSharpe FULL | **+0.094** (>0 in **24/24**) | **−0.099** (>0 in **0/24**) |
| dSharpe hold-out | **−0.166** (>0 in **0/24**) | **−0.166** (>0 in **0/24**) |
| DD più basso di | +1.435 pp (24/24) | +1.470 pp (24/24) |
| d CAGR | +0.105 pp (58%) | **−1.339 pp** (0/24) |
All'ancora canonica: 2 gambe Sh 1.44 / DD −9.4% / CAGR 14.7% → 3 gambe Sh 1.48 / DD −7.5% /
CAGR 13.6% su L-FULL; su L-PULITA 1.54 → **1.30**.
## 3. Il drawdown scende — ma è de-levering (5ª occorrenza)
Aggiungere SOL abbassa DD **e** CAGR insieme. Il null codificato chiede: *lo stesso DD si compra
più a buon mercato riducendo la size?* Si cerca `k` con `maxDD(k·book_2gambe) = maxDD(book_3gambe)`:
| lente | k | Sh 3 gambe | Sh 2 gambe × k | CAGR 3g | CAGR 2g × k | verdetto |
|---|---|---|---|---|---|---|
| L-FULL | 0.793 | 1.48 | 1.44 | 13.6% | 11.5% | SOL aggiunge |
| **L-PULITA** | 0.886 | **1.30** | **1.54** | 12.6% | 14.5% | **de-levering** |
**L'unica lente in cui SOL aggiunge è quella costruita sui dati che la certificazione segnala.**
## 4. E dentro quella lente, il guadagno è un anno
| anno | 2g Sh | 3g Sh | dSh | dCAGR |
|---|---|---|---|---|
| 2022 | 1.37 | 0.46 | **−0.91** | −6.0 pp |
| **2023** | 1.34 | 2.40 | **+1.06** | **+11.1 pp** |
| 2024 | 1.65 | 1.36 | −0.29 | −5.6 pp |
| 2025 | 1.00 | 0.80 | −0.20 | −2.7 pp |
| 2026 | 2.70 | 2.48 | −0.22 | −2.9 pp |
Gamba SOL da sola: 2022 **−1.99** · 2023 **+2.65** · 2024 +0.45 · 2025 +0.17 · 2026 +1.46.
**4 anni su 5 negativi.** Il 2023 è l'anno in cui SOL risalì da ~$8 a ~$100 dopo il crollo FTX: un
trend-follower su quel movimento guadagna una fortuna **una volta sola**. Non è un meccanismo che
trasferisce, è un evento.
E la correlazione col book attuale è **+0.404** (L-FULL) e **+0.561** (L-PULITA) — vicina allo
0.74 per cui il trend multi-asset fu scartato il 19/06, **e in salita** man mano che il dato
migliora.
## 5. Ciò che non è il vincolo
**L'eseguibilità non c'entra:** `SOL_USDC-PERPETUAL` ha min 0.001 SOL = **$0.09**, contro il
pavimento `min_order` di $5 del book. SOL sarebbe tradabile oggi a $644. È la prima volta in questo
progetto che un candidato viene bocciato **senza** che il muro sia la taglia del conto.
## 6. ⚠️ Effetto collaterale del mio stesso lavoro: un guardrail disattivato in silenzio
CLAUDE.md dichiara: *«`load_data("SOL", ...)` → FileNotFoundError (guardrail: solo dati certi)»*.
**Non è codice.** `load_data` non ha alcuna whitelist: solleva l'eccezione solo perché il file non
esiste. Ricostruendo lo storico in `data/raw/sol_1h.parquet` **ho disattivato il guardrail senza
che nulla lo segnalasse** — e quel file non sarebbe stato rinfrescato dal cron (`--asset BTC ETH`),
quindi sarebbe diventato dato stantio con l'aspetto di dato attivo.
È la stessa forma dei tre difetti dei giorni scorsi: un controllo che funziona per configurazione,
non per costruzione.
**Riparato con la convenzione che il progetto già usa** (`hl_`, `eq_`, `eqx_`, `fut_`): SOL vive in
`data/raw/alt_sol_*.parquet`, fuori dal namespace nudo. Guardrail verificato ripristinato.
⚠️ **Errore mio nel test che doveva sorvegliarlo:** la prima stesura elencava a mano i prefissi
leciti e bocciava `eqx_`, `fut_`, `vol_term_`, `fundnews_` — namespace veri che non conoscevo.
Riscritto per **derivare** gli asset a rischio da `rebuild_history.DERIBIT_INSTR`: l'invariante non
è «quali prefissi esistono» (lista che invecchia) ma «quali asset possono finire nel namespace
nudo», che sta nel codice. Stessa lezione di `fee_watch` il giorno prima.
## VERDETTO
**SOL come terza gamba direzionale: SCARTATO.** Hold-out negativo a 24/24 ancore in entrambe le
lenti; sulla finestra pulita peggiora tutto; il DD migliore è de-levering; il guadagno della
finestra sporca è un anno solo; la correlazione col book sale col migliorare del dato. **Book,
pesi, universo direzionale invariati.**
## REGOLE
- **Un meccanismo si trasferisce a un asset nuovo con i parametri CONGELATI, o non è un
trasferimento ma una nuova famiglia** — e allora servono `study_family_honest` e deflated-Sharpe.
- **Un criterio di selezione va riprovato sull'asset nuovo:** SKH01-V2-DD fu scelta per maxDD<30%
e su SOL fa 40,5%. Il criterio era una proprietà dei due asset su cui fu tarato, non del sistema.
- **Quando un risultato dipende dalla finestra, guardare quale finestra la CERTIFICAZIONE
approva** — qui le due si contraddicono e la lente che promuove è quella non certificabile.
- **Un contributo positivo si scompone per anno prima di crederci:** +0.094 di Sharpe mediano
sembra un plateau (24/24 ancore) ed è un anno solo con quattro anni negativi intorno.
- **Ricostruire dati per un'analisi può disattivare un guardrail** che vive nell'assenza di un
file. Prima di scaricare un asset fuori universo, chiedersi in quale namespace atterra.
+152
View File
@@ -0,0 +1,152 @@
# Ondata multi-agente 2026-08-22 — 20 filoni, branch `research/wave-0822`
**Mandato dell'operatore:** *"metti decine di agenti a fare analisi di nuove strategie possibili.
Lavora su branch separato. Lo scopo e' sempre lo stesso arrivare ai 50 giornalieri velocemente."*
**Esito in una riga: 0 candidati promossi, 1 difetto di produzione che avrebbe falsato un gate fra
36 giorni, 3 soglie pubblicate falsificate, 1 leva strutturale che nessun gate del progetto sa
vedere. Book, pesi, cron, config INVARIATI.**
Ledger completo per filone: `docs/research/RESULTS-0822.md`. Briefing dato agli agenti:
`docs/research/BRIEF-0822.md`. 21 script in `scripts/research/r0822_*.py` (15.295 righe, compilano
tutti, ognuno gira da solo).
## 0. Come e' stata condotta (e perche' conta)
Vincolo di macchina: **2 core**, 7 GB, e sulla stessa VPS gira il libro con **soldi veri**
(`cron_book` al minuto :07). Il briefing imponeva `nice -n 19`, budget 15 min/run, sola lettura su
`config/`, `data/live/`, `src/live/`, `scripts/live/`, cron. **Ha tenuto**: al picco di carico
(load 14 su 2 core) il giro delle 17:07 del libro e' girato in **18 secondi**, feed fresco, nessuna
azione, nessun OOM.
⚠️ **Fatto operativo da ricordare: il cron gira dal working tree.** Con questo branch attivo,
stanotte alle 00:30 il cron esegue il codice di QUESTO branch. Verificato che il diff vs `main`
tocca **solo** `scripts/research/` e `docs/research/` -> produzione identica. **E' anche il motivo
per cui nessuna riparazione e' stata applicata qui: sarebbe andata live senza una decisione.**
Il briefing dava agli agenti, **in anticipo**, i dieci modi in cui questo progetto si e' gia'
ingannato (null del de-levering, TP01 travestito, selezione sull'hold-out, fortuna d'ancora, Sharpe
implausibile, win-rate come knob, ...) e la lista dei filoni morti. **Sette agenti hanno catturato
un errore proprio prima di pubblicare**, e tre hanno refutato una propria ipotesi in corsa.
## 1. Il risultato che va agito — 4 monitor forward su 6 sono rotti
`fetch_hyperliquid` (e `resample_tf`) scrivono la barra del **giorno in corso**; `advance()` dei
monitor la consuma e **porta `last_ts` su di essa** -> le ore restanti di ogni giorno non entrano in
nessun rendimento registrato.
| monitor | barre coincidenti col replay | **min/giorno registrati** | gate |
|---|---|---|---|
| `paper_statarb` | **0/46** | **4** | **STATARB 27/09** |
| `paper_dvolspread` | 0/28 | **2** | DVOLSPREAD 24/10 |
| `paper_xsr` | 1/28 | **41** | XSR01 23/10 |
| `paper_portfolio` | 7/56 | 19 | — |
| `paper_prevday` | 1259/1319 | 1.438 | — |
| `paper_combo` | 7/37 | 1.402 | — (sano **per caso**: aspetta una borsa) |
**Il gate STATARB del 27/09 si ribalta su 2 criteri su 3**: Sharpe registrato **+1,96** contro
**−2,02** ricostruito, maxDD **2,2% contro 15,3%** (guardia <10%).
✅ **Ma la finestra non va persa**, ed e' misurato due volte in modo indipendente: il feed **non
riscrive le barre chiuse** (`paper_prevday` 1427/1488 barre identiche al bit dopo 62 notti; e le 6
barre di `paper_statarb` recuperate dopo il guasto EPERM del 09-15/07 coincidono al bit).
**-> La riparazione e' "riparare `advance()` + RIGENERARE", non "riparare e azzerare": nessuna data
di gate si sposta.**
**Guardia raccomandata** (non implementata): `ts_ultima_barra + cadenza <= mtime del file`, grazia
5 min. O(1), segnala 5/6, **tace sul sano**, controllo positivo sintetico 6/6 nei due versi.
⚠️ `monitor_health` non poteva vederlo: **una serie fresca, completa e sbagliata passa ogni controllo
di freschezza**. E `implausible_sharpe` esiste dal 26/07 ma **non e' mai stato puntato sulle serie
forward** (avrebbe segnalato Sharpe −15,8 su 28 barre).
## 2. Tre soglie pubblicate, falsificate con misure
1. **"XS01 serve ~$20k"** -> **non esiste soglia da min-order**. L'origine del numero era *"rumore di
arrotondamento"*, una stima a occhio del 19/06. Haircut ~0 gia' a **$200-600 allocati**.
**Meccanismo**: gli ordini sono **due popolazioni** — il ribilanciamento del segnale e' il 13%
degli ordini ma il **75% del nozionale** (ticket $13,65, passa sempre); la deriva del vol-target
e' l'87% degli ordini ma il **25% del nozionale** (ticket $0,64, il pavimento la taglia **ed e'
gratis**). *Contare gli ordini da' 16% e sembra un disastro; contare il nozionale da' 75%.*
Due agenti indipendenti ci sono arrivati per strade diverse.
⚠️ **Il "$20k di XS01" e il "$20k della decisione di venue" erano due cose diverse conflate in
CLAUDE.md.** Il primo cade; **il secondo regge intatto** — e' una decisione dell'operatore
sull'asse della rovina, non sull'eseguibilita'.
2. **"Slippage = rischio #1 di XSR01"** -> **refutato con margine 21x** al livello di liquidita'
odierno (mezzo-spread 0,7-1,0 bps contro i ~16 che servirebbero a uccidere l'edge).
3. **"BTC opzioni fuori a $3.000 (min 0.1 = $6.210/lotto)"** -> misurato sulla famiglia **inverse**,
che il conto (in USDC) **non puo' marginare**. La famiglia USDC-lineare ha lotti **10x piu'
piccoli**. Il muro resta, ma per il **prezzo del lotto**, non per quello che si credeva.
## 3. La leva: l'unica variabile che nessun gate del progetto sa vedere
**Lo Sharpe e' invariante alla scala** (misurato: 1,31 a ogni cella del knob) -> `deflated_sharpe` e
`marginal_vs_tp01` non falliscono sulla leva, **non la vedono**. E' per questo che in due mesi la
scala non e' mai stata esaminata.
Il libro gira al **7% di Kelly** e raccoglie il **15%** della crescita massima in log. Il gradino
eseguibile 1,00x -> 1,25-1,50x vale **14,7 anni -> 12,9-11,6** al capitale-rendita (€500/mese, netto
fisco). **Lo scettico ha confermato il risultato di testa** e ha tolto la sua condizione bloccante:
sotto la lente wick accoppiata il maxDD prende un **ricarico moltiplicativo costante del ~3,5%**, non
un'amplificazione (il maxDD e' multi-giorno, il wick e' di un giorno).
**Il gradino resta NON autorizzato**: cadono una riserva su tre. Restano il drift stimato su 7,4 anni
(k* e' lineare nel suo errore) e la **coda assente dal dataset** — un solo giorno a −10% all'anno
porta k* da ~10x a **2x**.
📌 **Ma la lezione del 25/07 e' vera e non si trasferisce:** su una regola a **UN giorno**
(daily-loss, stop di conto) close-only e' **esattamente cieca** — 0,00 breach/anno contro 0,40-1,21
veri, rapporto **INF**. **Sul canale prop/funded la lente accoppiata resta obbligatoria.**
## 4. Cosa e' morto, e come
**Filoni chiusi con autopsia** (l'elenco per esteso e' nel ledger): adaptive-horizon (il "vincitore
adattivo" e' un lookback **costante** travestito), dealer-gamma (la gamba tradeable e' **incoerente**:
BTC non separa, ETH separa **al rovescio**), ortho-screen **7/7**, oi-pin (il max-pain **non batte
mai** la media a 7 giorni dello spot), term-structure (la pendenza e' un **termometro contemporaneo**),
skew direzionale (**il prezzo muove lo skew**, t 3,1-9,4 su 8/8 — non il contrario), flow-squeeze,
basis-calendar (il basis dei datati **E'** il funding del perp), alt-options (alt), xs-lite,
vrp-quote-vere.
Tre chiusure di famiglia che valgono per le prossime ondate:
- **Il filone funding si chiude sul QUARTO lato** (affollamento): misurato su **53.430 ore / 3 anni**,
non predice ne' direzione ne' volatilita'. E i futures datati non sono un quinto lato: sono lo
stesso lato quotato diversamente (+7,33% implicito contro +6,48% realizzato, premio incassabile
+0,85%/anno con **IC95 che contiene lo zero**).
- **La mean-reversion non risorge** sotto due conditioner mai provati (volume, shock 3σ): la selezione
in-sample sceglie il ramo di **continuazione** in entrambi i casi.
- 📌 **Uno screen largo su BTC/ETH direzionale NON PUO' passare il proprio gate.** Su 168 trial il
massimo Sharpe atteso dal **puro rumore** e' **1,572**, sopra il soffitto direzionale misurato
(~1,3). Non e' sfortuna, e' aritmetica. **Le prossime ondate o dichiarano famiglie molto piu'
piccole in anticipo, o cambiano meccanismo.**
⚠️ **Tre volte in questa ondata l'eseguibilita' a $600 NON e' stata il vincolo** (haircut 0,00-0,01;
lotti $7-242; margine ~$148). Dopo due mesi in cui il muro era sempre il capitale, adesso muoiono
tutti sull'edge. **E' un'informazione sul dove cercare.**
## 5. Regole nuove, e una ritirata
**Nuove:**
- **L'open interest non misura la negoziabilita'** — su Deribit USDC sono quasi **anti-correlati
(rho di rango −0,77)**: SOL_USDC e' 1ª per OI e ultima per quote a due lati (**9%**); BTC_USDC ha
**5** strumenti con OI>=100 e il **93%** dei put quotati.
- **Il deflated-Sharpe va calcolato DI SCREEN, non solo di famiglia** (168 trial, non 24).
- **Un placebo si controlla per BILANCIAMENTO DEL SEGNO prima di usarlo**: un null che concorda col
segnale solo nel 14% dei casi non e' un null, e' la strategia invertita — e fabbrica celle
"significative".
- **Il null del de-levering e' DEGENERE quando la variante e' una ri-scalatura** (`sh(k*base) ===
sh(base)`): il test che serve e' **iso-peso sullo Sharpe**.
- **Un gate che stampa `None` va verificato prima di dichiararlo "non girato".**
- **Su una finestra interamente post-hold-out, `marginal_vs_tp01` non puo' dare ADDS per
costruzione** — un NEUTRAL li' non e' un giudizio.
**Ritirata (era stata pubblicata poche ore prima, in questa stessa ondata):**
❌ *"Su equity a gradino un overlay giornaliero e' non-causale"* — **falso su questo motore**:
`backtest_signals` contabilizza al giorno d'**ingresso** in **291/293** trade, e la "riparazione" e'
un **no-op bit-exact**. Il "+0,04 fantasma" era la differenza fra due varianti **entrambe causali**,
e quella scartata era la **migliore sull'hold-out**. *Il costo di una regola derivata da un difetto
inesistente e' gia' stato pagato.*
## 6. Cio' che resta aperto (decisioni dell'operatore, non mie)
1. **Riparare `advance()` + rigenerare** le serie forward, prima del 27/09.
2. **Cablare la guardia D2** (`ts_ultima_barra + cadenza <= mtime`) in `monitor_health`.
3. **Il collettore della catena** raccoglie la famiglia inverse; ETH_USDC costa **+587 chiamate/giro
(+90%)** ed e' una decisione sul rate limit per-IP, che il 29/07 e' gia' costata un guasto.
4. **Rimisurare `f` di VRP01 term-structure-consistent** (il 42% del difetto e' li', e la regola per
prenderlo era gia' scritta il 03/07).
5. **XS01 e' eseguibile a ~$1.300 di conto**, non a $20k. Resta fuori **per la decisione di venue**,
che e' un'altra cosa. Se il piano cambia, si riapre prima.
+188
View File
@@ -0,0 +1,188 @@
# 2026-08-22 (sera) — Seconda ondata: XS01 fuori dalla sua finestra, e il canale funded ridimensionato di 5x
**Branch:** `research/wave-0822` · **9 filoni** · **0 candidati promossi** · **libro, pesi, cron,
config INVARIATI.**
Registro per filone: `docs/research/RESULTS-0822.md` (sezioni 21-29). Briefing: `BRIEF-0822.md`.
---
## Perche' una seconda ondata
La prima (20 filoni) si era chiusa con un risultato di testa — **PROP-ALLOC**: su un conto *funded*
riallocare per la **barriera di drawdown** invece che per lo Sharpe porta J da 0,335 a 0,738, con
**P(≥50 €/g) da €600 in 36 mesi = 42%**. Il percorso piu' veloce mai misurato in questo progetto.
E si era chiusa con l'agente che dichiarava contro se stesso il proprio limite: *"tutto il vantaggio
poggia sul drift di XS01 misurato sulla sua finestra di scoperta"*, con un gate che era **un'attesa di
anni** (*"non aprire un funded prima che XS01 abbia una finestra fuori dal 2024-2026"*).
La seconda ondata e' stata mirata su quello, piu' sui falsificatori che gli agenti stessi avevano
**nominato senza poterli eseguire**.
---
## 1. XS01 regge fuori dalla sua finestra — ed e' piu' forte li' (§21)
La finestra esisteva gia': gli stessi 19 ticker su **Binance spot 2021-01 → 2023-12**, che contiene
**LUNA e FTX**. Meccanismo **congelato**, nessuna griglia cercata.
**Mediana di fase +1,12 fuori campione contro +0,37 nella finestra di scoperta; differenza appaiata
+0,668, positiva in 10/10 fasi**, p=0,013 contro permutazione a fee zero, sopravvive a 30 bps/lato.
L'obiezione ovvia — *"Binance non e' la verita'"* — e' stata **misurata invece che aggirata**: quella
regola riguarda l'**ancoraggio di prezzo**, non un ranking cross-sezionale, e lo scarto USDT e' un
**fattore comune** che sparisce nello z-score. Lo stesso sleeve sui due venue da' **corr 0,9991**.
**Null "universo dove non dovrebbe funzionare"** (11 settoriali SPDR, 1998+, meccanismo congelato):
**−0,45, 0/10 fasi positive** → **terza conferma indipendente che il cross-sectional e'
crypto-specifico**.
## 2. Il falsificatore che l'autore ha nominato contro se stesso — eseguito, e non falsifica (§28)
La validazione di venue di §21 girava **solo sul 2024+**, cioe' senza il depeg USDT che il fuori
campione contiene. Soglia dichiarata da lui: `corr ≥ 0,99`.
**Corr mediana 0,9992, minima 0,9921. dSharpe appaiato −0,000. Il titolo passa da +1,12 a +1,11.**
Guardando il canale del danno — i ribilanciamenti — su 734 solo **10 cambiano una gamba su cinque**, e
**zero dentro la finestra del depeg**.
**Il punto di metodo:** la divergenza va **scomposta**, perche' le due componenti sono domande diverse.
La **comune** arriva a −39 bps nel depeg ed e' quella che lo z-score annulla; la **idiosincratica** —
l'unica che cambia il ranking — sale solo da 2,0 a 3,6 bps mediani. *Riportare solo la prima avrebbe
dato la risposta rassicurante e sbagliata.*
E ha trovato che **il caso peggiore del campione non e' il depeg: e' il 2025-10-10** (cascata di
liquidazioni sulle /USDT, INJ a 1.981 bps mentre BTC/ETH stanno a 21). **Il meccanismo temuto e'
REALE**; e' semplicemente caduto nella finestra di *scoperta*, non nel fuori campione.
## 3. Ma il numero funded si ridimensiona di 5x — e il colpevole non e' la finestra (§29)
Decomposizione a **un grado di liberta' per volta**:
| passo | J | Δ |
|---|---|---|
| il pubblicato (HL, 19 gambe, finestra di scoperta) | 0,739 | — |
| → venue Binance, **date allineate** | 0,732 | **−0,006** |
| → **13 gambe** | 0,426 | **−0,307** |
| → pannello lungo | 0,459 | +0,034 |
| → **fuori campione 2021-2023** | 0,520 | **+0,061** |
**Il 42% del numero pubblicato sta nelle 6 gambe che fuori campione non esistono** (ARB OP SUI APT SEI
TIA) — **e quelle 6 entrarono nell'universo nel 2026-06 guardando la liquidita' HL del 2024+, cioe'
dentro la finestra di scoperta.** La finestra, da sola, **migliora**. Allargare l'universo man mano
che le gambe nascono non recupera nulla.
**Il numero operativo: P(≥50 €/g) da €600 in 36 mesi = 7,8% [7,2–9,1%], P(zero) 25,5%** — contro il
42% pubblicato stamattina. Il peso 0,50 non sopravvive; la **regione [25%, 38%] e' entro il 3%
dell'ottimo su tutte e tre le finestre**.
**`GATE PROP-01`** sostituisce l'attesa di anni: **(a)** leggere il **listino della firm** — ≥10 delle
13 gambe shortabili, verifica a **€0** e **bloccante prima di ogni spesa**, *stessa classe
dell'errore GTAA01/PRIIPs*; **(b)** banda d'ancora di SKH01 sotto la lente prop, **2026-10-31**, PASS
se > +0,05; **(c)** un'eval HYRO $100k costa **$579 su un conto di $635**.
## 4. L'allarme sul peso di TP01 e' falsificato NEL VERSO (§26)
L'agente aveva registrato nel docstring, **prima di misurare**, che si aspettava di confermarlo.
Invece: **TP01 ~0,375 e' l'argmax sia sulla finestra che contiene il 2022 sia su quella che non lo
contiene**, e nel sinistro il libro con **meno** TP01 fa **meglio** — TP01 va flat mentre **SKH01 si
gira short e guadagna**. Test dei segni 12/12 (p=0,0005), 8/8 sul solo pre-2024.
**Null del de-levering, 7a occorrenza, in veste nuova** ("protezione dal crash"): a leva comune TP01
protegge davvero, ma **a iso-sopravvivenza meno TP01 paga di piu'** (payout $4.490 → $2.119,
monotono).
Tre cose che valgono piu' dell'allarme rimosso:
- **"2024-2026 non contiene un crash" e' falsa nella forma**: ha buy&hold a −60% di DD. Manca la
**taglia** (~2,3x sulla coda). La domanda giusta e' *"e se ne arriva uno due volte piu' grande"*.
- **Alle leve funded il 2022 non era una minaccia** (min equity −1,4/−2,4% contro barriera −6%): cio'
che uccide un conto a barriera e' la **regola a un giorno su una giornata qualunque**.
- **Il rischio vero dell'ottimo e' XS01, non TP01** — e l'agente ha demolito la propria ipotesi
contraria dentro la sessione.
## 5. Tre filoni chiusi con margine
**BOCPD (§23) — l'orizzonte adattivo e' CHIUSO DEFINITIVAMENTE.** Il falsificatore e' stato eseguito
con i rilevatori che nominava (Adams & MacKay + optimal partitioning causale) e **questa volta ha
avuto potenza**: 68/96 celle davvero adattive, contro 0 del primo tentativo. Con potenza, **0/68** su
entrambe le condizioni. **La decomposizione e' il risultato: l'adattivita' spiega il −7% del vantaggio
su TP01** (+0,326 del miglior lookback costante contro +0,305 dell'adattivo). *Il 100% e' "un
orizzonte piu' corto", non "adattarlo".*
**MAKER (§22) — il segno dipende da `<` contro `<=`.** Il passivo **vince sul 92-98% degli ordini e
perde sulla media** (5 ordini su 1535 fanno il 42% del danno). Forma speculare del profit-take di
VRP01. Tetto **$2,96/anno a $635** nel caso impossibile.
**SURFACE-RV (§27) — chiuso, e il meccanismo vale piu' del verdetto.** Censimento su 1,24 M quote:
**0 violazioni di monotonia su 1,1 M**, 1 di convessita' su 1,03 M che vale **$0,00**. E `|residuo|`
cresce **monotonamente col largo del mercato** → **l'incoerenza al mid *e'* la larghezza del mercato
guardata attraverso il mid.** Questo uccide il controfattuale USDC che l'agente stesso aveva
costruito.
## 6. BIN-FREQ: la direzione e' reale, la taglia e' selezione (§25)
Argmax **+0,112 in 23/23 ancore**, ma **mediana di famiglia +0,007** con 39/72 celle positive =
monetina. **L'argmax vale 16x la mediana: punta, non plateau.** Direzione solidissima (0/72 sul segno
inverso, trasferisce a SKH01_V1).
**Due premesse del mio briefing, misurate e refutate:** *"dimezza gli ordini"* → i nettati calano del
**17%** e i sotto-min-order **sono di TP01**; *"converti il risparmio di fee"* → **a fee zero
l'effetto resta l'87-110%**, quindi non e' risparmio di costo ma informazione sul rendimento lordo.
E la domanda che avevo posto era **il confronto sbagliato** (la banda del livello si cancella in un
disegno appaiato) — **ma la risposta corretta e' peggiore, non migliore, per il candidato**.
Riapertura pre-registrata: **non una data, una soglia di CAPITALE** ($5.600 / $53.000), perche' cio'
che fallisce e' il rapporto fra un costo **fisso** e un beneficio **proporzionale**.
## 7. Il critico: i difetti stanno nella CUCITURA, non nei filoni (§24)
**Una regola mia, pubblicata la sera stessa e ritirata poche ore dopo:** avevo scritto che
`dealer_net_gamma` e' *"il GEX col segno invertito"*. **Falso**, e la fonte gira su questa stessa VPS
(`cerbero-mcp/.../common/options.py:11-14` **dichiara la convenzione**). Verificato in due comandi.
La correlazione a −0,95 era esattamente cio' che una convenzione diversa **deve** produrre.
**E il difetto piu' grande dell'ondata: il deflated-Sharpe misurato ai suoi due estremi degeneri lo
stesso giorno da agenti che non si citano** — e **tre gate pre-registrati** ci poggiano sopra.
---
## Il filo che tiene insieme la giornata: `deflated_sharpe` non ha una regione utile in mezzo
**Tre agenti indipendenti, tre strade diverse, stessa conclusione.**
`altlib.deflated_sharpe` calcola `sr0 = sd(Sharpe dei trial) × mult(N)`: dipende dalla **varianza**
della griglia, non solo da N.
- **VOL-SIZE** (ondata 1) lo dichiara **VACUO**: 1,000 anche per il baseline.
- **BOCPD** lo misura dall'altro capo: **0,998 PASS** dentro la famiglia omogenea → **0,555 FAIL** con
l'sr0 di screen. *"Gonfiare N col padding alza N e non la varianza."*
- **CRITICO** trova che l'1,572 di ORTHO-SCREEN implica sd≈0,58, e che **le stesse 168 celle
dichiarate come 7 famiglie da 24 danno 1,15** — sotto il soffitto ~1,3: il verdetto *"impossibile
per aritmetica"* **si ribalta senza toccare un dato**, e la cura che suggerisce e' la manovra che il
progetto ha proibito il 30/07.
- **BIN-FREQ** chiude il cerchio dall'alto: su una famiglia **binaria** il DSR **riacquista potenza**
(0,977 contro baseline 0,834) perche' le celle scartano insiemi di trade molto diversi. *Non e' il
candidato a essere piu' solido: e' la famiglia a essere piu' larga.*
**Non basta contare i trial di screen: serve la VARIANZA di screen.** E il numero di trial dichiarati
resta una scelta dell'autore, cioe' l'unico posto dove barare e' indolore e invisibile — con in piu'
il fatto che ora sappiamo che **la stessa griglia da' verdetti opposti a seconda di come la si
partiziona**.
---
## Cosa NON e' stato fatto, e perche'
**Nessuna riparazione applicata.** Il cron esegue dalla **working tree**, che e' su questo branch: una
riparazione andrebbe live alle 00:30 senza una decisione dell'operatore. Il diff tocca **solo**
`scripts/research/`, `docs/` e `CLAUDE.md` (verificato).
Restano dell'operatore: **(1)** riparare `advance()` + rigenerare i monitor forward prima del gate
STATARB del **27/09**; **(2)** decidere del branch; **(3)** la verifica a costo zero che decide il
canale funded — **leggere il listino di una prop firm**.
📌 **E la risposta onesta al mandato, che al critico era stato chiesto di dare se vera: nessuna misura
di ricerca di questa giornata batte "versare".** L'effetto piu' grande misurato oggi vale
**€0,0113/giorno**; versare €500/mese vale **~1456x** quello. La ricerca ha smesso di essere il
vincolo binding il 26/07, e due ondate da 29 filoni lo hanno **confermato invece che ribaltarlo**.
+96
View File
@@ -0,0 +1,96 @@
# 2026-08-23 — Libro di bordo: i trade allineati col tempo, il giornale, l'analista
**Libro, pesi, cron di strategia, config: INVARIATI. Nessun ordine.** Tutto ciò che segue è
sorveglianza e registrazione.
## La domanda che l'ha fatto nascere
*«I trade vengono salvati?»* — sì, in `data/live/book_executions.jsonl`. Ma non allineati col
tempo: `book_execute.py:213` scriveva
```python
ts_utc = str(pd.Timestamp(r['last_data'])) # la data della BARRA DI SEGNALE
```
19 righe su 19 a `00:00:00`. E non era cosmetico: **un trade risultava registrato sei giorni prima
di essere eseguito** — ETH 0.04 @ 1.869,74, fill vero il **2026-07-14 alle 14:00**, scritto
**08/07**. La riconciliazione lo isola da sola: 18 fill concordano fra log e jsonl, 1 no, ed è
quello.
L'ora vera esisteva **solo** in `logs/cron_book.log` — gitignored, fuori dal backup, ruotabile.
La cronologia reale del libro live viveva in un file che una rotazione avrebbe cancellato senza
che nessuno se ne accorgesse.
## Cosa c'è adesso
**`data/live/trades.db`** (sqlite, dentro il perimetro del backup rotativo). `fills` con il
contesto del segnale a quel giro, `roundtrips` **derivati** e ricalcolati da zero, `equity`
oraria (1.437 letture), `journal`. Sync orario in `cron_book`, subito dopo l'esecuzione.
Tre fonti che **si incrociano e non si sovrascrivono**: il cron log (ora vera + contesto), il
jsonl (i fill), il venue (autorevole su `order_id` ma **tronca**: 1 trade su BTC, 0 su ETH).
`reconcile()` riporta le divergenze e non ripara niente da solo.
**`docs/journal/YYYY-MM-DD.md`**, 62 voci ricostruite dall'arming. Quattro livelli separati per
provenienza, e la separazione è il prodotto:
| livello | chi scrive | può sbagliare? |
|---|---|---|
| numeri | feed certificato + DB | è una misura |
| Lettura | 12 regole dichiarate, ognuna con id | deterministica |
| Analisi | un modello (`claude-opus-5`) | **sì**, ed è firmata |
| Nota | l'operatore | — |
L'analisi parte ogni giorno su Telegram con una testata di numeri; se manca, il messaggio parte
lo stesso **dicendo perché**.
## Cosa ha trovato il lavoro, oltre al difetto iniziale
**P&L del libro dall'arming: +$37,50 su $598,06 (+6,27%) in 64 giorni**, 12 round-trip di cui 11
in utile, fee totali $0,41. Riconciliazione indipendente: la ricostruzione FIFO dà +$38,15 contro
i +$37,50 dell'equity del venue — scarto $0,65 (1,7%), coerente col funding pagato sui long.
Ma il numero che conta è un altro: **tutto il P&L è di sei giorni**. Fino al 17/08 il conto era a
$597,12, cioè **−$0,94 in otto settimane**; l'equity è rimasta invariata nell'**80% delle
giornate**. Non è un difetto — è cosa sono TP01 e SKH01 — ma significa che +6,27% in due mesi non
è un tasso di rendimento.
E l'analista ha aggiunto la lettura che le regole non producono: quei sette giorni sono anche gli
**unici in cui il libro è stato a mercato**, e coincidono con +22,94% su BTC e +29,49% su ETH →
la finestra **non separa l'edge dal beta** a un rialzo forte, né il trend dal breakout.
## Cinque difetti trovati dai test o leggendo l'uscita, nessuno a occhio
1. **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.
2. **L'IV-rank era la statistica sbagliata col nome giusto**: percentile a un anno etichettato
come il gate di VRP01, che usa quello **espandente**. Verdetto **opposto** (0,52 «sopra»
contro 0,18 «sotto»); il valore giusto combacia con «0/8 settimane passano il gate» (30/07).
3. Il renderer cadeva in `KeyError` se mancava il blocco mercato.
4. «24 giri attesi» su un giorno **in corso** → allarme a ogni esecuzione.
5. Libro e P&L leggevano **due istanti diversi**: la stessa pagina mostrava due equity.
## Il ciclo di retroazione, e il limite che resta
Al primo giro reale il modello ha letto la **propria analisi precedente** — con l'avviso del
tripwire — e l'ha commentata. `senza_analisi()` toglie la sua sezione prima di dargli la pagina.
**Nessun controllo automatico può distinguere il meta-commento da prosa valida: si vede solo
leggendo l'uscita.**
E il limite dichiarato quando la guardia è stata scritta si è materializzato subito: **due errori
su due giri con sonnet-5, nessuno dei due con una cifra nuova** — una frase su un merge mai
raccontato, e un round-trip corretto dichiarato inesistente. `numeri_non_supportati()` prende
l'invenzione, non il ragionamento. Modello portato a **opus-5** (primo giro pulito, affermazioni
verificate a mano contro il DB), ma **due osservazioni contro una non provano niente**: è un
tentativo di abbassare un tasso.
## Regole
- Un **dato operativo non ricostruibile** non può vivere in un file gitignored: si materializza
dove il backup arriva.
- Una **guardia più stretta del contratto** produce allarmi che si impara a ignorare (il tripwire
validava sulla sola pagina mentre il prompt include anche lo storico, e bocciava un'equity vera).
- Una regola che si accende su **$2 di cumulato** insegna a saltare la sezione: serve una soglia
di rilevanza.
- **Chi scrive in un registro va firmato**, o il registro perde il suo valore probatorio.
- Una **guardia sui numeri non copre il ragionamento**.
@@ -0,0 +1,184 @@
# 2026-08-23 — Ondate 7-8 e il critico di chiusura: 17 filoni, 0 candidati, 3 numeri di testa riscritti
**Branch:** `research/wave-0822` · **Registro per filone:** `docs/research/RESULTS-0822.md` §41-57
**Libro, pesi, cron, config: INVARIATI.** `git diff main -- src/ config/ scripts/live/ scripts/cron_*.sh tests/` vuoto a ogni checkpoint.
## Perche' esiste questa voce
Il mandato era *"metti decine di agenti a fare analisi di nuove strategie possibili... arrivare ai 50
giornalieri velocemente"*. Le ondate 1-3 (§1-40) avevano gia' dato 0 candidati. Queste due ne
aggiungono 17 e chiudono con un agente incaricato di **attaccare l'ondata invece di estenderla**.
La risposta al mandato e' negativa, ed e' quantificata: **la somma di tutti i lead positivi vale
+0,036 €/giorno**, contro i **+71 punti di probabilita'** che valgono €250 → €500 al mese.
Questa voce non ripete il registro. Tiene le tre cose che il registro, per costruzione, non puo'
dire: cosa e' cambiato **nella memoria operativa**, cosa ho sbagliato **io**, e cosa resta all'operatore.
## 1. Il risultato che nessun filone cercava
§50 chiedeva *"qual e' il miglior terzo sleeve eseguibile a $635"* e ha trovato che **il candidato
piu' forte mai misurato dal progetto era gia' in produzione — in monitor da giugno, senza gate
pre-registrato e senza deflated-Sharpe.** Sette candidati, **sette muri diversi, e nessuno dei sette
e' una soglia di capitale**: non e' il conto piccolo a fermarli.
§54 gli ha scritto il gate mancante. Passa **8 condizioni su 10**, e le due che mancano sono la
stessa: **la cella che gira non e' quella che la selezione onesta sceglie** (quella viva fallisce il
DSR a 0,905), e la selezione onesta compra il libro **long-flat**, cioe' butta via la gamba per cui
PREVDAY fu promosso. *Non e' un parametro da ritoccare: sono due strategie diverse.*
Verifica mia sopra il filone: la serie e' **intatta, 1512 barre su 1512** — e' l'unico monitor che
il difetto `advance()` non tocca. Ma la finestra e' **0,172 anni** e li' l'**MDE e' 4,72 di Sharpe**:
il +2,11 forward **non e' distinguibile da zero** su 26 ingressi. **Qualunque cosa il gate decida,
non puo' appoggiarsi al numero forward.**
## 2. Il critico, e le tre cose che vanno riscritte
Prima di ogni accusa ha **riprodotto** con macchineria propria: i quattro muri **al dollaro**, il
funding (−2,1597%/anno), il dShFULL di §42, e che il muro **e'** esattamente `prelievo/perpetua` su
4 lenti su 4. **Il nucleo quantitativo dell'ondata regge.** Poi ha falsificato **due sue attese
scritte prima di misurare** e tre miei numeri.
**(a) Il muro non e' $313k: e' la mediana di una banda esplosiva.** SE del drift **5,151%/anno**;
+1 SE → $204.517, −1 SE → $709.753, **−2 SE → il traguardo non esiste a nessun capitale**.
«€500/mese → P(20a) 85%» diventa **~0% a −1 SE**. Meccanismo: il muro e' un `1/x` su una quantita'
(la rendita perpetua) che **si annulla prima del drift** → errore asimmetrico verso l'alto.
Il pezzo che brucia: **per otto ondate ho stampato accanto a quel numero la risoluzione MONTE CARLO
(0,7%)** — la precisione del simulatore — **e mai quella del suo ingresso, cento volte piu' grande.**
**(b) «Positivo in 24 ancore su 24» vale ~2 osservazioni.** Corr media fra le 24 ancore di TP01
**0,631 → N_eff 1,55**; fra le 10 fasi di XS01 **0,790 → N_eff 1,23**. E **non si salva sulla
differenza appaiata**: la componente comune non si cancella (N_eff 1,64-2,24) — era l'attesa a
priori del critico, **refutata**. Sulla stessa grandezza la **banda d'ancora e' 4,3x piu' stretta
dell'IC95, che contiene lo zero** (su XS01: 3,8x; due misure indipendenti, stesso fattore ~4).
⚠️ **Non cadono i verdetti** — poggiano anche su iso-vol, maxDD, selection-on-holdout, edge lordo.
**Cade la precisione dei numeri, non la direzione delle decisioni.**
**(c) Il gradino di leva a 1,50x era gia' morto.** §53 lo boccia (peggior giorno strutturale
**21,48% > 20%**) e fissa **k max difendibile 1,40**. Sopravvive solo il **1,25x**, che vale
**+€144/mese misurati direttamente** (non €164, che veniva da un'interpolazione lineare) e
**+1,8 anni a muro congelato / +3,0 a muro mobile** — *e la convenzione va sempre detta, perche' le
due letture distano piu' di quasi tutti gli effetti che questo progetto misura.*
**In piu': tre baseline sotto lo stesso nome «libro 75/25».** `hourly` 1,683/11,22% (la lente di
**ogni muro e traiettoria**) · `canonical` 1,800/9,56% · mediana d'ancora 1,626/10,4%. **Spread 0,12
di Sharpe, piu' grande di quasi tutti i Δ dell'ondata**: un Δ accostato al baseline sbagliato cambia
piu' del Δ. **Ogni numero va scritto con la sua lente attaccata.**
## 3. Cosa ho sbagliato io
Cinque errori, tutti su numeri **gia' pubblicati**, due dei quali stavano in `CLAUDE.md`:
| # | cosa avevo scritto | cos'e' |
|---|---|---|
| a | «la convinzione di TP01 sta spesso a 1/3 o 2/3» | **il bucket 2/3 non esiste** — `tsmom_blend` media tre `np.sign()`, la famiglia ha **un** grado di liberta', non tre. Trovato da **due agenti indipendenti** |
| b | «la catena USDC costa +90% di chiamate» | **+18%** — i 587 erano il conteggio grezzo, senza il filtro OI≥100 che il collettore applica |
| c | «le opzioni BTC sono fuori a $3.000 per il lotto» | quello e' il **collaterale per VENDERE**; comprare costa il **premio**. Il muro vero e' il **tick da 5,00 USDC** |
| d | «il gradino vale +1,8a / +€164» | lettura a **muro fermo**, convenzione **mai dichiarata** |
| e | «la coda muove k\* di 1-2 unita'» | **4,6** |
E uno catturato **prima** di pubblicarlo, che vale la pena tenere perche' e' della famiglia che
stavo criticando: avevo formulato l'MDE di PREVDAY come *«la precisione apparente viene dal numero
di mark, non di scommesse»*. **Falso**: la SE dello Sharpe annualizzato va con `1/sqrt(anni)`
**indipendentemente dalla frequenza**, e infatti barra e trade danno lo stesso 4,72. Il fatto vero
e' piu' banale: **63 giorni sono 63 giorni.**
Il critico ha fatto lo stesso su di se': la sua prima stesura **de-luckava una serie gia'
de-luckata** (0,89²) e stampava un finto +31,5% sul muro. *Il controllo che l'ha preso e' stato
guardare il DRIFT stampato accanto al muro, non il muro.*
## 4. Due difetti di contabilita' nel piano, entrambi a favore
- **«€X/mese» versa ogni 30 GIORNI** → 121/182/243 versamenti invece di 120/180/240
(+0,83/+1,11/+1,25%), in **ogni tabella dal 25/07**.
- **Il contatore `versato` e' uno scalare che non si ferma al traguardo** → il *«a 10 anni i bonifici
fanno il 73%»* e' l'intero orizzonte; **fino all'arrivo e' il 61%** ($190.265). *Stessa famiglia
del bug `paid` catturato il 25/07 — la lezione era codificata e il difetto era in un altro punto.*
## 5. Cosa e' stato refutato, e perche' e' interessante
Tre meccanismi di protezione, **due caduti sulla premessa prima che sul prezzo**:
- **TAIL-HEDGE (§46):** comprare put deep-OTM fa **SALIRE** il maxDD in **162/162 celle**, a ogni
lente di f — perche' il beta del libro al sottostante e' **+0,076**. *Non si assicura un libro che
nei crash e' gia' quasi piatto.*
- **TP01-TWIN (§49):** un ensemble di definizioni di trend protegge **peggio** (0/24 ancore, 3,2x
peggio nel 2022) — e i meccanismi **non erano ridondanti** (corr di posizione 0,61): la ridondanza
non era il problema.
- **ANCHOR-ENSEMBLE (§47):** su TP01 il drift **non puo'** cambiare, per **algebra**
(`lordo_ens == media(lordi)`, residuo 1,4e-17).
E il lead dello spot (§52) **muore dove servirebbe**: regge a $600, **si annulla a $272k** — sparisce
esattamente al muro che pretende di spostare.
## 6. MDE: quanti «SCARTATI» sono in realta' «non misurabile»
Il critico ha misurato la finestra della catena opzioni: **77 giorni di superficie** → **MDE 4,3 di
Sharpe**. Ogni SCARTATO di §4/§5/§7/§11 che poggia su un confronto di Sharpe e' un **non-risultato
su quell'asse** (le loro parti valide sono lead-lag, placebo e censimenti). L'ondata dichiara il
proprio MDE in §6, §10, §43, §48, §56 — **disciplina reale** — ma tre etichette restano piu' forti
della misura, e una conta: 🚨 **§21 XS01 fuori campione, il PILASTRO del canale funded, ha effetto
+1,12 contro un MDE di 1,13.** Sta *esattamente* al proprio limite di rilevabilita', e viene
propagato fino a P(≥50 €/g) come se fosse noto a due cifre. *(Equita': gira anche un null di
permutazione a fee zero, p=0,013, che ha piu' potenza del t-stat. Il problema non e' «nessuna
evidenza», e' la precisione attribuita al livello.)*
## 7. La risposta al mandato
| lead | €/giorno a $635 | eseguibile oggi |
|---|---|---|
| gradino di leva 1,25x | **+0,046** | no — la manopola non esiste |
| spot al posto del perpetual | +0,017 | no — domanda fiscale aperta |
| PREVDAY al 15% (de-luckato) | +0,014 | no — gira la cella sbagliata |
| binario di frequenza | +0,011 | no — 3 gate su 4 falliti |
| esecuzione passiva | +0,005 | no — l'IC contiene lo zero |
| **funding (costo scoperto)** | **−0,023** | **lo paghi gia'** |
**Somma di tutti i lead positivi, se fossero autorizzati e additivi — non lo sono, e nessuno e'
eseguibile oggi: +0,036 €/giorno.** Sullo stesso motore e sugli stessi percorsi, **€250 → €500 al
mese porta P(20a) dal 14% all'85%** e la mediana da 23,4 a 17,3 anni. **Rapporto ~1.400 a 1.**
🚨 **`L'ONDATA NON HA PRODOTTO NIENTE CHE AVVICINI I 50 €/GIORNO.`** Ha prodotto (i) un **costo gia'
in essere** che porta P(20a) a €250/mese dal 49% al 14% (il funding), (ii) **quattro monitor rotti**
che avrebbero fatto decidere un gate al contrario, (iii) un **punto singolo di guasto** nel trasporto
degli allarmi, (iv) **tre lead reali tutti bloccati da qualcosa che non e' la ricerca**.
**Il suo valore e' difensivo ed e' reale: ha impedito decisioni sbagliate.** E nulla di sepolto sotto
uno «SCARTATO» merita di essere riesumato.
## 8. A credito dell'ondata
**Quattro auto-correzioni in 24 ore**, ed e' il suo dato piu' sano: §45 «lo spot non si liquida»
falsificato da §52; §39 «non esiste una linea USDC datata» falsificato lo stesso giorno; la regola
«overlay non causale» **ritirata** dallo scettico; «`dealer_net_gamma` e' il GEX invertito» ritirata
**leggendo il sorgente** che gira su questa stessa VPS.
## 9. Cosa resta all'operatore
Sette decisioni, nessuna delle quali richiede altra ricerca. Brief:
`https://claude.ai/code/artifact/9ca378f7-464a-4ee1-a520-38a026a34fc3`
1. **Riparare `advance()` e rigenerare** prima del gate STATARB del **27/09** (35 giorni) — oggi il
gate si deciderebbe **al contrario** (Sharpe +1,96 registrato contro −2,02 vero).
2. **Che fare del branch** `research/wave-0822` (106 commit, tutti in `scripts/research/` e `docs/`).
3. **Chiedere alla firm** se ha una lista ristretta propria (costo €0, blocca una spesa di $579).
4. **Chiedere al commercialista** se i derivati Deribit sono al 26% o al 33% (vale ~$22k di muro).
5. **Costruire la chiave di scala** in config, se si vuole il gradino **1,25x** (e **solo** quello).
6. **Riparare il trasporto degli allarmi** — la parte (c) cambia il comportamento, quindi e' una scelta.
7. **Decidere di `paper_prevday`**: allinearlo alla cella onesta, ritirarlo, o lasciarlo scrivendo
che la sua finestra non e' evidenza.
## Regole nuove
1. **Un muro calcolato come `X/y` con `y` stimato va pubblicato con la banda di `y`**, non con la
risoluzione del simulatore — e se `y` si annulla prima del suo ingresso, l'errore e' **asimmetrico**
e la banda non e' simmetrica attorno al punto.
2. **«N/N ancore» e' robustezza alla SCELTA dell'ancora, ~2 osservazioni indipendenti — non N prove.**
La banda d'ancora **non e' un intervallo di confidenza** e non va usata al posto di uno; e **non si
attacca un p-value** a un conteggio di ancore o di finestre sovrapposte.
3. **Un Δ si scrive con la sua BASELINE attaccata.** Tre lenti dello stesso libro distano 0,12 di
Sharpe, piu' della maggior parte dei Δ misurati: la lente sbagliata cambia piu' del risultato.
4. **Un argomento refutato due volte per due strade indipendenti non va ereditato come regola**
(il «soffitto ~1,3» e l'aritmetica del DSR di screen che ne discendeva).
5. **Prima di chiudere una famiglia, confrontare l'etichetta con il proprio MDE dichiarato** — §48
chiude un filone su una branca che dichiara essa stessa un fattore 44 sotto l'MDE.
6. **Un contatore cumulativo dentro un simulatore va fermato all'evento che sta misurando**, o
risponde a una domanda diversa da quella posta (2ª occorrenza in un mese, in due punti diversi).
@@ -0,0 +1,271 @@
# 2026-08-25 — La manutenzione del martedì, e i due difetti che ha scoperchiato
*Scritto da Claude (agente), su richiesta dell'operatore. Firmato come vuole P13: l'analisi in
prosa è opinione di un lettore fallibile, i numeri qui sotto vengono dai log e sono riproducibili.*
## Come è cominciata
Domanda dell'operatore: «stato trades». Report normale del libro di bordo — 24 fill, equity
$598,06 → $667,88 (+11,67%), 16 round-trip di cui 15 in utile, netto +39,78. Poi il `--reconcile`
ha stampato la riga che ha aperto la giornata:
```
venue: NON LETTO (HTTPError) — non e' 'zero trade', e' 'non misurato'
```
Non era il gateway. Era **Deribit in manutenzione**: `system_maintenance`, codice 11051, HTTP 503
sia sul pubblico che sul privato. Iniziata fra le **08:57:40Z** (ultimo 200 OK nei log di
`cerbero-mcp`) e le **09:01:46Z** (primo 503). Rientrata verso le 09:20 — ~20 minuti, coerenti con
i 15-30 annunciati da Deribit per le sue release.
## Cosa dicono i log, contati invece che ricordati
1.499 giri di `cron_book` fra il 2026-06-23 e il 2026-08-25:
| esito | n | % |
|---|---|---|
| manutenzione Deribit | 3 | 0,20% |
| traceback duro | 5 | 0,33% |
| giri senza esito utile | 26 | 1,7% |
E gli episodi di venue non sono sparsi:
```
2026-07-21T09:00 Tue 502 su get_positions (Deribit giù, vista dal gateway)
2026-08-11T09:07 Tue system_maintenance 11051
2026-08-18T09:07 Tue system_maintenance 11051 (giù anche alle 10:07)
2026-08-25T09:07 Tue system_maintenance 11051
```
**Quattro martedì su dieci, tutti fra le 09:00 e le 09:07 UTC.** Il supporto Deribit conferma la
meccanica: le release escono il martedì alle 09:00 UTC. Il minuto `:07` del cron cadeva dentro
quella finestra — e ci cadeva per costruzione, non per sfortuna.
**Il punto singolo di guasto non è Deribit: siamo noi.** Dei 5 traceback, **4 sono il nostro
gateway** `cerbero-mcp.tielogic.xyz` (un 404 su `get_positions`, un 502, due `ReadTimeout`).
## I due difetti veri
### 1. Una riga sola per due guasti che vogliono azioni opposte
Fino a oggi qualunque guasto sul percorso Deribit stampava `conto non leggibile (offline)`, con la
nota di diagnosi **cablata**. Ma "Deribit in manutenzione" (aspetta, rientra da sola) e "il nostro
gateway è rotto" (ripara) non sono la stessa notizia. È **P4** violata, con l'aggravante di **P4
seconda metà**: *una nota di diagnosi cablata è peggio di nessuna nota*, perché si legge come una
misura.
Peggio ancora: il 18/08 **il codice 11051 era già dentro il processo**, nello stesso minuto,
raccolto da `livefeed`. Semplicemente non arrivava a chi decideva la gravità dell'allarme.
### 2. La finestra scoperta del disaster-SL — e l'asset che sparisce
`ensure_disaster_sl` ricostruisce un bracket incoerente **cancellando prima e ripiazzando dopo**.
Fra le due chiamate la posizione è senza alcuno stop on-book. Finché il ripiazzamento sollevava,
quell'eccezione risaliva fino a `main()`: il guasto peggiore (**posizione scoperta**) aveva la
stessa faccia di un errore qualunque.
E c'è il corollario che è successo davvero. Il **2026-07-21 alle 09:00 UTC** il 502 è arrivato
dentro `ensure_disaster_sl` su BTC. Nel log di quel giro **ETH non compare**: non è stato
ribilanciato e — quel che conta — **la sua protezione non è stata verificata**. Un guasto su un
asset toglieva la rete di sicurezza all'altro.
## Cosa è stato fatto
**`src/live/venue_probe.py` (nuovo).** Interroga l'API **pubblica** Deribit in diretta — niente
gateway, niente credenziali — e classifica: `VENUE_MANUTENZIONE` / `VENUE_GIU` / `GATEWAY` /
`IGNOTO`. La sonda parte **solo dopo un guasto**: sul percorso sano costa zero. Rispetta **P1**:
non ridichiara la firma 11051, la importa da `venue_watch.is_maintenance`.
Su **P9** (*un allarme massimo speso per un evento atteso è un allarme che non verrà letto il
giorno che è vero*): la manutenzione dentro lo slot declassa il titolo a ℹ️. Ma con due paletti,
perché il rischio qui è costruire il silenzio proprio nell'ora in cui serve:
- declassa **solo su evidenza** della sonda, mai sull'orologio da solo → un gateway rotto di
martedì mattina resta 🛑;
- declassa **solo dentro la durata annunciata** (30 min) → il 18/08 alle 10:07 la manutenzione
aveva sforato, e torna una notizia. Stessa logica di `MAINT_GRACE_HOURS`, altra domanda.
**Isolamento per asset** in `book_execute`: un asset che esplode non ferma il ciclo, e il giro
esce con codice 2 per essere contabile.
**Stato `naked`** in `ensure_disaster_sl`: due tentativi di ripiazzamento, e se falliscono
entrambi lo stato è distinto da `place-failed` (**P5**: guasti diversi si distinguono anche quando
l'azione è la stessa). Non è "non sono riuscito a proteggere": è "**ho tolto la protezione e non
sono riuscito a rimetterla**" → 🚨 sempre, **mai** declassato da P9.
Non è stata invertita la sequenza in *piazza-poi-cancella*: due STOP `reduce_only` contemporanei
sono *probabilmente* innocui, ma "probabilmente" non basta per cambiare il ciclo di vita dei
bracket su un percorso con soldi veri senza misurarlo. **Riparato il silenzio, non toccata la
sequenza.**
**Cron `:07` → `:47`.** I due vincoli sono entrambi misurati e compatibili: fuori dai ~26s del
minuto tondo (il collettore catena si auto-satura il rate-limit per-IP: 12.186 risposte 429 in 26
ore, 96% nel minuto `:00`, misura del 30/07) **e** fuori dallo slot di release. Il commento in
`cron_book.sh` è stato riscritto: lasciarlo dire `:07` sarebbe stato il difetto §5.7 in versione
nuova.
**Previsione dichiarata (M12).** Sulle 4 finestre osservate, 3 sono rientrate entro l'ora. Il `:47`
ne avrebbe scavalcate **3 su 4**. Se martedì prossimo il `:47` becca comunque la manutenzione, la
previsione è sbagliata e lo slot non è quello che credo.
## Cosa NON è stato fatto, e perché
**Il fallback diretto ai privati Deribit è bloccato, non rinviato.** Le credenziali Deribit
esistono **solo dentro il gateway**: in locale c'è `CERBERO_TOKEN` e basta. Leggere conto e
posizioni scavalcando `cerbero-mcp` richiede **chiavi API create dall'operatore** sul conto
Deribit. È una decisione con una superficie di rischio propria (una chiave in più che può
trapelare), non un refactor.
È stato fatto il pezzo che non le richiede — la sonda pubblica — e resta a debito in §5.11 il
resto. Nota onesta: la sonda pubblica **dice di chi è il guasto, non lo aggira**. Con il gateway
giù il libro continua ad astenersi; sa solo dire perché.
## Test
**19 nuovi** (12 in `test_venue_probe.py`, 7 in `test_book_resilienza_venue.py`), nessuno tocca la
rete. Suite: **730 passati, 1 fallito** — il fallito è quello già noto di §5.9 (SKH01 `canonical`
1,9223 contro banda cablata `<1,9`, deriva dei dati, non del codice).
Controllo positivo fatto, perché un test mai visto fallire non dimostra niente: contro il codice
vecchio **5 dei 7** test di resilienza falliscono. Con una riserva da dichiarare — il test di
isolamento, sul codice vecchio, fallisce perché il modulo di diagnosi non esiste, non perché
dimostri l'isolamento rotto. La prova di *quel* difetto è il log del 21/07, dove ETH non compare.
---
## Coda: la suite di test ha mandato un allarme falso sul telefono dell'operatore
Il primo giro al nuovo minuto `:47` è andato bene — entrambi gli asset elaborati, entrambi i
disaster-SL verificati `ok`, exit 0 — ma nel log c'era una riga che non poteva essere vera:
```
💰 USCITA DI FONDI: $5,000.00 -> $667.68 (-86.6%) · cap/asset ora $333.84
```
Il conto non ha mai visto $5.000. Ha visto $598-668 da sempre.
**L'ho causato io**, lanciando `uv run pytest` per verificare le riparazioni di oggi.
`test_book_live.py::test_la_formula_del_report_ha_potenza_anche_a_libro_flat` prende solo
`monkeypatch` (niente `tmp_path`), sostituisce `shadow_report` con uno che dichiara
`real_equity=5000.0`, e chiama `book.book_report()` — che come **effetto collaterale** scrive
`data/live/equity_seen.json`. Riprodotto isolando il singolo test: watermark $667,68 → **$5.000**.
L'helper `_write_cfg` esisteva già proprio per questo — il difetto gemello è del **2026-07-26** —
ma quel test, aggiunto il **21/08**, non lo usa. È la terza volta che la stessa scommessa perde.
### Non era cosmetico
Il watermark alimenta il cap di fallback:
```
cap_fallback = min(cap_fisso_di_config, watermark × frac)
```
Con $5.000 dentro: `min($3.000, $2.500) = $2.500` per asset invece di `$334`. Su un conto da $668
sono fino a **$5.000 di nozionale lordo, ~7,5x di leva**. E il ramo che ci arriva è raggiungibile:
`eq_fallback` in `book_execute` **allerta e NON blocca**, per scelta dichiarata.
Cioè: **lanciare la suite di test poteva armare esattamente il pericolo che il watermark esiste
per impedire** (nota del 26/07 in `book.py` sul cap fisso e la leva 3,35x).
Danno reale oggi: **nessuno**. Alle 09:47 l'equity era leggibile, quindi il cap è stato calcolato
sull'equity vera e il watermark è stato riscritto col valore giusto. La finestra scoperta è stata
~09:25 → 09:47, e in quella finestra non c'è stato nessun giro con equity illeggibile. È andata
bene per la direzione del caso, non perché ci fosse una protezione.
### Riparazione, e perché è strutturale
`tests/conftest.py` con una fixture **autouse** che devia `EQUITY_WATERMARK` in `tmp_path` per
**ogni** test. Chiedere a ogni autore di ricordarsi il monkeypatch è la scommessa che ha già perso
due volte: la protezione deve valere anche per il test che qualcuno scriverà domani senza aver
letto niente. Un test che vuole davvero pilotare il watermark continua a funzionare — il suo
monkeypatch esplicito gira dopo e vince.
Più una guardia in `test_cap_watermark.py` che si accende se qualcuno rimuove la fixture:
controllo positivo, perché una protezione mai vista fallire non è una protezione.
**Resta aperto il principio più largo** (§5.12): un test non dovrebbe poter scrivere in
`data/live/` *affatto*. Oggi è deviato solo il watermark — `trades.db` e `book_executions.jsonl`
sono ancora esposti allo stesso errore.
### La lezione
Un **effetto collaterale su file** trasforma un test puro in un attore sul sistema vivo. Qui il
test non menzionava il watermark, non lo importava, non lo asseriva: lo scriveva passando per una
funzione di produzione tre livelli più in basso. **Il perimetro di un test non è quello che il test
dice di toccare: è quello che tocca il codice che chiama.**
---
## Seconda parte della giornata: il versamento, e le tre misure che ne sono uscite
Alle **11:03:35Z** sono atterrati **1.400 USDC**: equity **$667,88 → $2.066,88**. Il giro delle
11:47 ha ribilanciato correttamente (cap/asset $1.033, BTC +$238, ETH +$319, disaster-SL `placed`
su entrambi alla taglia nuova) — la prima volta che il ramo riparato al mattino gira sul serio.
Poi l'operatore ha chiesto tre cose in fila, e ognuna ha rotto qualcosa.
### (1) «€500/mese per 10 anni»
Rifatto sul conto vero invece che citare la tabella da $635. **Non centra**: capitale mediano
$114.934, rendita 18,35 €/g, **P(≥50 €/g) = 0,0%** su 3.000 traiettorie. Il bersaglio con €500/m
arriva al 17° anno; per averlo a 10 servono €1.718/mese.
Il numero che ordina tutto: **€100/mese in più valgono +4,07%/anno di drift**, cioè +27% su tutto
il drift del libro. Dettaglio in `30-piano-capitale-fisco.md`.
### (2) «A cosa serve XSR01, allora?» → e poi: «l'abbiamo fatto per la leva»
Due osservazioni dell'operatore, entrambe centrate, che hanno spostato la conversazione dal
candidato al **disegno**.
XSR01 ha già fallito `weights_tilt_null` (peso ottimo ~0). Ma la risposta vera è che **anche un
uplift di strategia riuscito vale meno di un bonifico modesto**, e questo si applica a qualunque
sleeve, non solo a XSR01.
Poi la misura che ha ribaltato la discussione sulla leva: **il libro non è poco levato, è FERMO**.
Esposizione lorda realizzata in 64 giorni live: mediana **0,00x**, media 0,05x, **max 0,52x** su un
tetto strutturale di 1,0x, esposto in **14 giorni su 64**. Il cap non ha mai morso: il vincolo è il
segnale. *Il basso drawdown di TP01 non viene dall'essere piccolo nel mercato — viene dallo stare
fuori dal mercato.*
⚠️ Correzione che mi sono fatto da solo: quel 78% è il **regime attuale**, non la media. Sull'intera
storia i giorni flat sono il **28,0%** — 2,7% nel 2021, 77,0% nel 2022, 75,6% nel 2026.
### (3) «Allora usiamo l'ETF quando il libro è flat» → SCARTATO
Test in `r0825_capitale_fermo.py`. **Perde** a iso-rischio (Sharpe 1,01 contro 1,40 del 50/50 e
1,35 del libro), e il null a maschera casuale lo mette al **30° percentile**: fa peggio di
commutare a caso.
E qui la parte che vale più del risultato. Stavo per scrivere un meccanismo pulito — *«il libro va
flat quando anche l'azionario soffre»* — sostenuto da un aggregato netto (SPY 4,91% nei giorni
flat contro 21,48% negli altri, −16,57%). **La scomposizione per anno lo ha demolito**: il segno
alterna, 3 anni su e 4 giù, e il **2022** — l'anno che doveva reggerlo — ha il segno **opposto**.
Artefatto di composizione: i giorni flat stanno negli **anni** brutti per l'azionario, non nei
**giorni** brutti. M9 ha fatto esattamente il suo lavoro, su di me.
### I due difetti di misurazione trovati addosso
1. **Maschera vuota vestita da risultato.** La prima versione prendeva i giorni flat dalla serie
**de-luckata**; ma `deluck` sottrae una costante, quindi lo zero esatto sparisce. Maschera
vuota → dinamico identico al book → e lo script ha stampato tabelle piene e un p-value. Lo ha
rivelato solo la riga che stampava `0 = 0.0%`.
**Regola: stampare la CARDINALITÀ di una maschera prima di usarla.**
2. **`r0822_slip_audit.py` aveva l'equity CABLATA a `636.0`** con un commento che diceva di leggerla
dal watermark — P1 in piena regola. Il giorno del versamento avrebbe continuato a stampare $636,
sbagliando di 3,3x proprio la sezione che esiste per dire *quando la misura scade*. Riparato
leggendo il watermark — e poi riparato **di nuovo**, perché la prima riparazione divideva tutti i
fill per l'equity di oggi mentre i fill del campione sono stati eseguiti a conti diversi
($597–$2.067). Ora la normalizzazione è **per fill**, e a $600 riproduce il 22,0% originale.
### La misura di slippage, rifatta alla taglia vera
26 fill (erano 18), taglia $6–$319. I due più grandi mai eseguiti sono di oggi e hanno preso
**1,01%** e **0,54%** della loro barra 5m, con il print **a metà del range** (q=0,50). Il caso
peggiore resta un fill da **$74 del 18/07 al 21,9%** — un sabato, nastro inesistente.
📌 **L'attrito non è funzione della taglia: è funzione di `taglia / volume della barra`.** Un fill
4,3× più grande in un'ora liquida ha fatto 20× meno partecipazione di uno piccolo in un'ora morta.
⚠️ Ma non è «assente», è **«non ancora testato»**: nel campione non c'è ancora un fill grande in una
barra sottile, e il weekend è dove TP01 fa il 38% del proprio gross.
+38
View File
@@ -0,0 +1,38 @@
# 2026-08-25 — Il versamento da $3.000: cosa compra, e cosa NON compra
**Domanda dell'operatore:** *"rianalizza e vediamo come procedere. potrei versare a breve altri 3k"*.
**Script:** `scripts/research/r0825_versamento_3k.py` (lente L3, stessi semi e path del piano:
tutto appaiato, M22). Assunzioni dichiarate: 3k = $3.000 USDC, lump oggi, start $2.065 (watermark
18:47:13Z). Controllo M23: da $2.065 il 10a riproduce $114.929 contro i $114.934 pubblicati da
$2.067 — la macchina riproduce il numero vecchio.
## Cosa compra (€500/mese, appaiato sugli stessi path)
| orizzonte | senza lump | con lump | Δ | €/g con lump | P(≥50€/g) |
|---|---|---|---|---|---|
| 5a | $44.921 | $49.730 | +10,7% | 7,94 | 0% |
| 10a | $114.929 | $122.491 | +6,6% | 19,56 | 0% |
| 15a | $228.770 | $241.490 | +5,6% | 38,56 | 12,3% → 17,3% |
| 20a | $408.105 | $427.738 | +4,8% | 68,30 | 79,4% → 83,9% |
Il lump = **5,5 mesi di versamenti anticipati in un colpo** (N3: e' la prima leva, esercitata).
Pietre miliari con €500/mese: $15k (C\* Hyperliquid) 1,7a → **1,3a**; $20k (si riapre la scelta
del venue) 2,4a → **1,9a**.
## L'effetto collaterale che conta: il gate XSR01 del 23/10 si RIBALTA
P(capitale ≥$5k al 23/10): **0,0% → 100,0%** (mediana $5.664, p10 $5.417). Senza lump il gate
moriva da solo sul criterio di capitale e i suoi tre difetti erano accademici. Col lump il
criterio formale **passa**, e la decisione poggerebbe per intero su:
(a) il monitor rotto che registra ~41 min/giorno (§5.1); (b) l'haircut col pavimento sbagliato
di 5-7× (§5.3); (c) un C\* vero $15-20k contro i $1.266 che il 25% di $5.065 mette sul venue.
**Il lump rende il gate LEGGIBILE senza rendere XSR01 comprabile** — il caso peggiore per un
criterio scritto male. La scelta fra riscrivere adesso (dichiarandolo) e lasciare-e-citare va
presa **prima** che il lump atterri, non il 23/10.
## Meccanica live a $5.065 — niente da toccare
cap per-asset $1.032 → $2.532 (equity×0,5, si adegua da solo); min_order $5 dal 0,48% al 0,20%
del cap (C2); fallback min($3.000, wm×0,5) = $2.532; disaster-SL invariato (e il nome continua a
ingannare). ⚠️ **Slip-audit da rifare** dopo i primi fill: misurato su $597-2.067, a $5k la taglia
relativa raddoppia — lo script con normalizzazione per-fill c'e' gia'.
@@ -0,0 +1,114 @@
# 2026-08-25 — XSR01 sotto la lente della RENDITA: e' un conto deposito con un secondo venue
**Domanda dell'operatore:** *"rendita perpetua ma non ho ancora capito se serve XSR01"*.
**Script:** `scripts/research/r0825_xsr_rendita.py` (N11: ogni numero qui sotto lo riproduce).
## Perche' era una misura nuova
XSR01 era stato giudicato tre volte — ammissione (25/07), gate di deploy pre-registrato (23/10),
accumulo (oggi) — e **mai sotto la lente della rendita**. Sono criteri diversi: l'accumulo premia
il **drift**, la rendita premia la **perpetua** (il prelievo piu' alto che sopravvive a 20 anni con
P≥90%). Dichiarato l'obiettivo (N6), il criterio cambia, e nessuno aveva rifatto il conto.
## Cosa mi aspettavo prima di misurare (M12)
(a) a iso-nozionale il mix perde drift e **alza** il muro; (b) a iso-rischio (M6) il verdetto puo'
**ribaltarsi**; (c) il vincolo che decide non sara' ne' (a) ne' (b) ma il **capitale**.
**Tutte e tre vere** — ma (c) e' arrivata con una gamba che non avevo previsto: il null.
## Le serie, e la finestra in cui esistono entrambe
| serie | finestra | drift/a | vol/a | Sharpe | maxDD | SE drift |
|---|---|---|---|---|---|---|
| libro L3 — **tutta** la storia | 2019-03-14 → 2026-08-22 | 15,19% | 11,29% | 1,35 | −12,4% | 5,19% |
| libro L3 — finestra comune | 2024-01-01 → 2026-08-22 | 10,96% | 10,14% | 1,08 | −8,6% | 7,97% |
| XSR01 — finestra comune | idem (965 g, 2,64 anni) | **3,72%** | 2,34% | 1,59 | −2,5% | 1,46% |
corr libro↔XSR01 **+0,049**. Finestra comune = **35%** della storia del libro → **il muro calcolato
qui NON e' il $313k pubblicato**: si confronta solo con se stesso (base $602.660).
📌 Sharpe di XSR01 a oggi, **lente dei gate, sole barre chiuse: 1,56** — il "1,82" pubblicato e' una
**terza** lente (XSR-REPRO, 22/08). Si cita sempre la coppia (lente, ultima barra chiusa).
## (2) iso-nozionale — XSR01 ALZA il muro
w 5→50%: muro da $604k a $668k (**+0,3% → +10,8%**). Il mix e' piu' liscio ma piu' povero, e per
una rendita il drift comanda. **A iso-nozionale XSR01 peggiora l'obiettivo dichiarato.**
## (3) iso-rischio (M6) — si ribalta, e sale il sospetto
Ri-scalando ogni mix a `vol(libro)`: w 25% → k **1,32x**, muro **$478.729 (−20,6%)**.
⚠️ **L'argmax e' al BORDO** (w=50%, k=1,93x): il muro scende **monotonamente** in w, quindi la
griglia non indica un ottimo, dice *"il piu' possibile"* — e cio' che si compra in quella direzione
e' il **k**, non XSR01 (M8). Sopra 1,40x il libro **non puo' eseguire** (decisione 23/08, e in
`config/live.json` non esiste una chiave di scala). Peso portato avanti: **25%, k 1,32x**.
## (3b) IL NULL — ed e' il risultato della sessione
A iso-vol vale `drift = Sharpe × vol_libro`: la colonna "drift" della sezione (3) **e' la colonna
"Sharpe" ri-etichettata**. Tutto il guadagno di muro e' guadagno di **Sharpe da diversificazione**.
Quattro sostituti, stesso peso 25%, stessa ri-scalatura:
| sostituto | muro | Δ vs base |
|---|---|---|
| **XSR01 (vero)** | **$478.729** | **−20,6%** |
| N1 mescolato — stessi rendimenti, ordine casuale (3 semi) | $475.933 / $483.846 / $484.421 | −21,0 / −19,7 / −19,6% |
| N2 rumore gaussiano, media e vol di XSR01 (3 semi) | $457.751 / $499.263 / $531.158 | −24,0 / −17,2 / −11,9% |
| N3 rumore, **drift ZERO** (3 semi) | $558.080 / $617.270 / $662.436 | −7,4 / **+2,4** / **+9,9%** |
| **N4 conto remunerato 3,72%, vol 0** | **$477.607** | **−20,8%** |
| N4 conto remunerato 4,0%, vol 0 | $469.353 | −22,1% |
📌 **Il MECCANISMO di XSR01 vale 0,8% di muro** — dentro la risoluzione Monte Carlo (spread fra semi
0,151% di perpetua ≈ $17k di muro, M23). **Mescolare i suoi rendimenti non cambia niente.**
📌 **N3 (drift zero) non paga**: mediana $617k **sopra** la base. La sola riduzione di varianza non
compra rendita. Quindi **cio' che si compra e' il DRIFT scorrelato**, non la scorrelazione.
🚨 **N4 e' la riga che risponde alla domanda.** Un **conto remunerato** allo stesso tasso (3,72%),
**vol zero, corr zero, nessun secondo venue**, da' $477.607 contro i $478.729 di XSR01: **identici
dentro la risoluzione**. Al 4,0% e' **meglio**. Ed e' un confronto **in svantaggio per il conto**:
la lente L3 gli applica il **33%** di `c-sexies`, mentre un BOT paga 12,5% e un deposito 26%.
## (4)-(5) gate e risoluzione
`weights_tilt_null` (XSR01 25% vs 0%): Δ_is +0,061 · Δ_hold +0,162 · pctl 25,8 < 90,0 → **PASS**.
⚠️ hold-out del gate = 2025-01-01 → la gamba in-sample e' **un solo anno**: gira, ma e' un indizio.
Differenza appaiata di drift **+1,16%/anno, SE 0,48% → t +2,40**. Drift XSR01 **+3,72%, SE 1,46%,
t +2,55**. Risolto, ma di poco, e su 2,64 anni.
## (6) il vincolo che non e' nelle tabelle
XSR01 gira su **Hyperliquid**: il suo peso e' capitale che **esce** da Deribit, non che si aggiunge.
A $2.067 il 25% sono **$517**, contro un **C\* misurato di $15.000-20.000** (il gate 23/10 e' tarato
su ~$3.000, §5.3). Per un 25% sopra C\* servono **$60.000 sul conto totale**.
E l'haircut mangia **proprio la cosa che il null dice di star comprando**:
| haircut | netto/anno | vs conto 4,0% | vs conto 2,0% |
|---|---|---|---|
| 0% | 3,72% | SOTTO | sopra |
| 20% | 2,97% | SOTTO | sopra |
| 40% (soglia del gate) | 2,23% | SOTTO | sopra |
| 60% | 1,49% | SOTTO | **SOTTO** |
**Pareggio con un conto al 2%: haircut 46%. Con un conto al 4%: non pareggia nemmeno a haircut ZERO.**
E l'haircut pubblicato ($14,41 di ticket) e' **~2,4x ottimista e senza script che lo riproduca**.
## VERDETTO
**4/6 condizioni** — ma il conteggio non e' la lettura. La lettura e':
> Sotto la lente **rendita perpetua**, XSR01 fa una cosa reale — porta un **drift scorrelato a bassa
> vol** — e la fa in modo **non proprietario**: mescolarlo non cambia il risultato, e un conto
> remunerato allo stesso tasso lo **eguaglia a vol zero e senza un secondo venue**.
> Il vincolo binding non e' il rendimento: e' il **capitale** ($60.000 per un 25% sopra C\*), e sotto
> quella soglia la domanda *"serve XSR01?"* **non ha una risposta comprabile**.
**Cosa NON dice.** Non dice che XSR01 e' morto: lo Sharpe standalone 1,56 e il DSR 0,983 reggono, e
sotto la lente **accumulo** il conto va rifatto (li' il drift comanda in modo diverso). Dice che
**per la rendita non e' lo strumento**, e che il gate del 23/10 sta per decidere su una gamba che a
questo capitale non e' comprabile.
## Cosa e' cambiato in me mentre misuravo
Ho copiato in questo script **lo stesso difetto che avevo riparato stamattina** in
`r0825_capitale_fermo.py`: la maschera dei giorni flat presa dalla serie **de-luckata**, dove gli
zeri esatti non esistono piu' perche' `deluck` sottrae una costante. Stampava `0.0%` e non si sarebbe
notato senza la riga che conta i giorni. Riparata con l'`assert` che manca(va) a monte: la maschera
si prende dalla **serie grezza**. *Riparare un difetto in un file non lo ripara nella testa.*
@@ -0,0 +1,95 @@
# 2026-08-26 — `advance()` riparato e rigenerato, quattro debiti chiusi in un giorno
Quattro debiti di CLAUDE.md §5 chiusi: **§5.1** (advance + rigenerazione + guardia),
**§5.12** (isolamento test esteso), **§5.5** (test di leva cancellato con nota),
**§5.9** (test rosso indagato e ancorato). Suite: **751 passati, 0 falliti** — tutta verde
per la prima volta dal ~24/08.
## §5.1 — advance() consuma solo barre CHIUSE, e le serie sono RIGENERATE
**Il fix** (`src/live/paper_guard.py` + 6 monitor): la riga
`new = [i for i in range(len(ts)) if ts[i] > last_ts]` diventa `PG.nuove_chiuse(ts, last_ts,
cadenza)` — una barra open-labeled e' chiusa quando `ts + cadenza <= adesso`. Filtro condiviso,
importato da tutti e sei i monitor (anche `paper_combo`, che era sano *per caso*: ora e' sano
*per costruzione*).
⚠️ **D6 pagata DI NUOVO scrivendo il fix:** la prima stesura di `indice_chiuso` usava `asi8`
assumendo nanosecondi — pandas 3 usa `us` di default, e l'intero nella scala sbagliata dava
"chiusa" la barra del giorno in corso **senza eccezioni**. Beccata dal test di fumo, riparata
con la sottrazione dall'epoca (la forma di `resample_tf`), e blindata da un test che prova
`ns/us/s`. *La regola che stavo cablando e' quella che stavo violando.*
**La guardia** (era "raccomandata e non cablata"): `monitor_health` ha ora lo stato
**PREMATURO** — ultima barra che chiude DOPO l'mtime del file, grazia 5 min. Derivata dalle
spec esistenti (P1), con `open_labeled=False` per `collect_chain` che timbra i giri, non barre
(P14: senza il flag avrebbe allertato sempre). Controllo positivo sul dato vivo: **ha segnalato
esattamente i 5 rotti e taciuto sui 2 sani** prima della rigenerazione; dopo, 7/7 OK.
**La rigenerazione** (`scripts/live/paper_regen.py`): stesso `start_ts` pre-registrato, config
congelata, replay del codice di produzione riparato — il metodo validato due volte dall'audit
del 22/08 (0 barre chiuse cambiate su 1.427/1.488 + 6/6 al bit). Vecchi file archiviati come
`*.pre_regen_20260826.*` (evidenza del difetto, nel perimetro di backup). **Nessuna data di
gate si sposta.**
| monitor | barre | Sharpe rotto → vero |
|---|---|---|
| `paper_statarb` (gate **27/09**) | 58 → 57 | **+1,95 → −1,61** — il ribaltamento previsto dall'audit |
| `paper_dvolspread` (kill 24/10) | 32 → 31 | −14,73 → −4,41 |
| `paper_xsr` (gate 23/10) | 32 → 31 | −4,98 → −2,72 |
| `paper_prevday` | 1584 → 1584 | +0,39 → +0,40 |
`paper_portfolio` **non** rigenerato (gamba GTAA su ADJUSTED_LAST ri-aggiustato: il replay non
sarebbe la serie registrata — P12); tolta la sola coda non chiusa, cosi' la guardia non resta
accesa per sempre su un difetto gia' riparato (P14). Storia pre-fix dichiarata corrotta.
## §5.12 — un test non puo' piu' scrivere nel libro di bordo vivo
`tests/conftest.py`: oltre al watermark, ora deviati **`trades.db`** (wrapper su `connect` —
il default e' catturato alla definizione, patchare la costante non serviva a niente) e
**`docs/journal/`** (pagine tracciate da git). Per `book_executions.jsonl`, che i test caricano
ad-hoc con importlib e conftest non puo' raggiungere prima: **impronta a inizio suite, verifica
a fine suite**, col falso positivo possibile (fill reale del cron :47 durante la suite)
dichiarato nel messaggio.
## §5.5 — il test di leva e' CANCELLATO, non aggiustato
`test_leva_massima_da_config_resta_sotto_o_uguale_a_1x` misurava `frac x n_asset`: con una
chiave di scala la grandezza vera diventerebbe `frac x n_asset x scala` e il test avrebbe
continuato a passare smettendo di controllare. Al suo posto una nota che rimanda al tetto sul
PRODOTTO di GATE SCALA-01, da cablare nel codice che leggera' la chiave, quando esistera'.
## §5.9 — il test rosso non segnalava un guasto: segnalava una banda scritta male
`r0826_skh_band_drift.py` — feed tagliato a date crescenti, stesso codice di produzione:
| taglio | Sharpe hold-out |
|---|---|
| 02/07 (audit) | **1,6376** — riproduce l'audit |
| 25/07 (banda cablata) | 1,5751 |
| 01→15/08 | 1,566 → 1,547 (scivola piano) |
| **22/08** | **1,8966** |
| oggi | 1,9306 — riproduce il rosso |
**Il dato regge** (in-sample 1,424 **identico su ogni taglio**; il taglio all'epoca riproduce
l'epoca). Il codice non c'entra. 📌 **La scoperta vera: la SOLA settimana 15-22/08 (rally ETH
con SKH01 long) vale +0,35 di Sharpe hold-out** — il numero e' cosi' fragile, e chi cita
"hold-out 1,9" oggi citerebbe 1,55 di una settimana fa. Coerente con §2: l'hold-out canonico
di SKH01 era gia' il numero da non citare.
**La riparazione:** il test ora **taglia il feed al 02/07** e verifica la riproduzione stretta
(±0,02) di full/in-sample/hold-out/maxDD. Si rompe se cambiano codice o dato sulla finestra
congelata — e per nessun altro motivo. La deriva del vivo non e' affare suo: per quella ci
sono i monitor (e da oggi la guardia PREMATURO).
Nel farlo, un altro inciampo istruttivo: la prima esecuzione del drift stampava **sette righe
identiche** — `run_asset` memoizza in un dict di modulo (`_CACHE`), non in `lru_cache`, e lo
svuotamento non lo toccava. Anche il test riparato ora pulisce quel dict, prima E dopo, per
non avvelenare gli altri test.
## Conseguenze sui gate (nessuna data si muove)
- **STATARB 27/09**: il monitor ora misura la serie vera (**−1,61** a oggi). Coi criteri
pre-registrati invariati, a oggi punta al RITIRO — si legge quel giorno, non prima.
- **XSR01 23/10 / DVOLSPREAD 24/10**: metrica primaria finalmente su serie reali.
Restano i difetti dichiarati (§5.3 pavimento del gate XSR01; veto DVOLSPREAD ora sorvegliato
dalla guardia).
+58
View File
@@ -0,0 +1,58 @@
# 2026-08-26 — USDC Rewards su Deribit: il prodotto esiste, il conto NON li riceve
**Domanda dell'operatore:** *"con 5k non si possono far partire altre strategie/investimenti?"*
→ unica pista compatibile con "100% Deribit fino a $20k": rendimento sull'USDC fermo (il libro
e' flat il 75% dei giorni del 2026, e la misura del 25/08 dice che un 3,7-4% su quel capitale
vale quanto tutto XSR01).
## Il prodotto (verificato SUL VENUE prima che sulle fonti, N10)
- API pubblica `public/get_currencies`, 2026-08-26: **USDC `apr: 3.4`** · USDE `apr: 4.0` ·
USYC nel pool cross-collateral · haircut cross-collateral USDC **0%** → il saldo matura
MENTRE fa da margine, nessun lock.
- Fonti (Deribit Insights): programma "USDC Rewards" dal 15/07/2025 — Deribit custodisce
presso Coinbase, Coinbase paga, Deribit gira agli **utenti di giurisdizioni autorizzate**
(lista non pubblicata). Maturazione sul **minimo di equity USDC delle 24h** (00:00 UTC),
pagamento mensile in unica soluzione nei primi ~14 giorni del mese successivo. Tasso
variabile (4% a lug 2025, 3,4% oggi).
## La verifica empirica: il conto NON li riceve
L'operatore era da cellulare → verifica indiretta sulla NOSTRA serie equity oraria
(`data/live/trades.db`), che su libro flat e' piatta salvo accrediti:
| finestra | letture | equity | salti orari ≥$0,40 | reward atteso |
|---|---|---|---|---|
| 01-14 lug (paga giugno) | 326 | $598,06 → $598,49 | 1 (= il fill ETH del 14/07) | ~$0,65 — **assente** |
| 01-14 ago (paga luglio) | 334 | $596,92 → $597,12 | **0** | **~$1,70-2,00 — assente** |
Un accredito da $2 su una serie che si muove di $0,20 in due settimane sarebbe stato
inequivocabile. **Due mesi indipendenti, stesso esito: nessun reward.**
## VERDETTO (stesso giorno, poche ore dopo): l'Italia e' ESCLUSA PER LEGGE — pista chiusa
La causa non era il conto ma **MiCA**: il regolamento UE vieta la remunerazione dei token di
moneta elettronica, e **Coinbase — che e' chi paga i reward del programma Deribit — ha cessato
i reward USDC in tutta l'EEA dal 2024-12-01** proprio per questo. Conferme indipendenti:
(a) l'espansione Deribit del 2026-08-01 aggiunge **80 paesi, nessuno EEA**; (b) il transaction
log del conto non ha MAI avuto una voce reward (misurato stamattina su due mesi). **Nessun
ticket necessario: la risposta e' normativa, non di supporto.** Cade anche la domanda fiscale.
⚠️ **Episodio di sicurezza, registrato perche' non si ripeta.** L'operatore ha chiesto dei
reward in una chat dove due sedicenti agenti ("Matt Andreas [MOD]", "Tom Mavencourt") hanno
risposto a copione — stessa domanda fuori tema due volte, scuse per un "guasto" mai segnalato,
l'avviso "beware of impersonators" usato per comprarsi fiducia — e l'affermazione
**"Yes, Italy is supported for USDC rewards": FALSA** (un agente Deribit vero sa che l'EEA e'
esclusa). Pattern coerente con lo script dei wallet-drainer: trattenere in chat, poi chiedere
"verifica" (link/2FA/chiavi API/schermo). Regola permanente: il supporto passa SOLO
dall'app ufficiale o da support.deribit.com; nessun codice, chiave o link, mai; una
risoluzione vera non richiede azioni dell'utente.
## Cosa resta della pista "rendimento sul capitale fermo"
- **USDC rewards: morta** per residenti EEA finche' MiCA resta cosi'.
- **USDE (Ethena, apr 4.0 dall'API)** come collaterale: non e' un EMT, MiCA non lo vieta allo
stesso modo — ma ha rischio proprio (depeg, basis-trade, Ethena GmbH chiusa dopo BaFin).
Se si apre, va da candidato: misura + gate + verifica C6 sul NOSTRO conto.
- **USYC**: probabile riservato a istituzionali — da verificare prima di parlarne.
- Altrimenti vale N3: a questo capitale la leva vera restano i versamenti.
+105
View File
@@ -0,0 +1,105 @@
# 2026-08-26 — USDE come collaterale a rendimento: analisi da candidato
**Domanda dell'operatore:** *"analizziamo usde"* — dopo la chiusura della pista USDC rewards
(Italia esclusa da MiCA). **Script:** `scripts/research/r0826_usde_scenari.py` (N11).
## Verificato SUL VENUE (API pubblica, oggi — N10)
- `apr: 4.0` per USDE (era "fino a 9%" al lancio 03/2025: tasso = APR settimanale Ethena − 5%
di fee Deribit; comprime coi funding) · reward **giornalieri** ~12:00 UTC sul minimo di
equity USDE, voce nel Transaction Log → **falsificazione in 24-72h**
- spot `USDE_USDC` attivo: spread osservato **~3 bps**, fee spot **zero**
- **haircut cross-collateral 10%** (USDC 0%): il 90% fa margine — al nostro profilo di leva
(max realizzata 0,52x su tetto 1,0x) **non morde**
- **indice `usde_usd` multi-exchange con mediana e clamp ±0,5%** — NON il book interno:
è la differenza strutturale dal caso Binance del 10/10/2025 ($0,65 dall'oracle sul proprio
book da $8M mentre USDe quotava ~$0,99 altrove, riscatti regolari, peg tornato in 8h)
- eligibilità **per residenza, lista non pubblica** → si verifica sul CONTO, non sui documenti
(la lezione USDC di stamattina)
## Rischi dichiarati (p non stimabile → si controlla con la QUOTA, N4)
R1 **emittente**: basis trade (staking + short perp); fallimento = fino a −100% della quota —
si SOMMA al rischio venue accettato il 26/07, non lo sostituisce. R2 **marcatura in crash**
(P10: l'accoppiamento — il mark scende proprio quando il libro è lungo). R3 **tasso**: 9→4%
in 17 mesi; funding negativi prolungati → ~0. R4 **regolatorio EU** (Ethena GmbH liquidata
dopo BaFin; USDe non è EMT MiCA — per questo PUÒ pagare dove USDC non può).
📌 Nota a favore da misurare se si procede: il rendimento USDe sale coi **funding positivi**,
cioè quando il nostro libro long li PAGA (−2,16%/anno): sconto parziale correlato sulla tassa
di funding.
## L'aritmetica (dallo script)
| equity | quota 50% rende | −100% costa | note |
|---|---|---|---|
| $2.065 | $41/anno | $1.032 | conversione ripagata in ~3 giorni |
| $5.065 | $101/anno | $2.532 | scenario post-versamento |
| $20.000 | $400/anno | $10.000 | dove la posta diventa seria |
Mark −1% = 3 mesi di resa · −3,5% = 11 mesi · **−100% = 25 anni: non si recupera mai**
→ la leva di controllo è la **quota**, non il tasso.
## PROPOSTA (pre-registrata qui, esito da scrivere sotto)
**Test di eligibilità sul conto**: convertire **~$500 USDC→USDE** (costo <$0,20 totale),
tenere **3 giorni**, guardare il Transaction Log alle ~12:00 UTC (reward atteso ~$0,05/g).
Regola dichiarata PRIMA di vedere l'esito: **≥1 voce reward in 3 giorni → idoneo**, e si apre
la decisione di quota (con un gate: quota massima, chi la decide, cosa la riapre);
**0 voci → non idoneo**, si riconverte e la pista si chiude come l'USDC.
L'esecuzione è dell'operatore (app: Spot → USDE/USDC) o autorizzata esplicitamente via gateway.
Il libro non c'entra: nessun codice del percorso soldi viene toccato dal test.
## ESECUZIONE DEL TEST (stesso giorno, 13:04 UTC — autorizzata dall'operatore: "fai test")
Ordine via gateway, limit marcabile con banda di sicurezza sul prezzo (0,995-1,005):
**500 USDE @ 1,0003, filled, fee 0** (`USDE_USDC-8977542793`). Costo totale ~$0,15.
Prima finestra utile di reward: ~**28/08 12:00 UTC** (il calcolo usa il minimo di equity
USDE della finestra); verifica finale il **29/08**: ≥1 voce reward nel Transaction Log →
idoneo; 0 voci → si riconverte e la pista si chiude.
🚨 **DIFETTO TROVATO E RIPARATO DURANTE IL TEST — il test valeva gia' per questo.**
`shadow._equity` leggeva SOLO il conto USDC: dopo la conversione il book avrebbe visto
$1.556 (−24,3%) al giro delle 13:47 → falso 💰 "USCITA DI FONDI" **e vendita indesiderata
di ~$140 di posizioni** (i target scalano con l'equity). Riparato in 35 minuti, prima del
giro: `_collaterale_usde()` valuta l'USDE all'**indice pubblico** `usde_usdc` (mediana
multi-exchange — la lezione Binance 10/10), con tre proprieta' blindate da 6 test nuovi
(`tests/test_shadow_usde.py`): un **depeg PASSA nel sizing** (mai nascosto), sopra la pari
si **clampa a 1,0**, indice illeggibile → **1,0 dichiarato, mai 0** (contare 0 ricreerebbe
il falso −24%: il fallback si sceglie sul danno, P5). Verificato live: equity vista dal
book $2.055,88 ("mainnet USDC + USDE 500 @ 0.9999").
*Un test da $500 progettato per misurare l'eligibilita' ha scoperto che il book era cieco
al cross-collateral: se la prima conversione fosse stata fatta a quota vera, l'errore
sarebbe costato caro. I test piccoli esistono per questo.*
*Esito eligibilita': (da scrivere entro il 29/08)*
## STRUTTURA (stesso giorno, ~14:20 UTC — "struttura il progetto per gestire subito usde")
La patch d'emergenza delle 13:07 e' diventata struttura di prima classe:
- **`config/live.json` sezione `usde`** — l'unica autorita' sui parametri (P1): `index_name`,
`haircut` 0.10, `quota_max_frac` 0.50 (tetto di ALLERTA — la quota effettiva la decide
l'operatore), `depeg_warn` 0.99 / `depeg_crit` 0.95 coi **criteri dichiarati** in `_nota_usde`
(P6: warn = fuori dalla banda spot ~3 bps e oltre il clamp ±0,5% per fonte dell'indice;
crit = meta' del buffer di haircut consumata).
- **`src/live/usde.py`** — modulo unico per config, catena di prezzo (indice pubblico → ticker
spot → 1,0 dichiarato) e valutazione `valuta()` PURA. `shadow._collaterale_usde` ora DERIVA
da qui (niente ridichiarazioni); i 6 test di shadow passano invariati.
- **`scripts/live/usde_watch.py`** + `cron_usde.sh` alle **12:35 UTC** (dopo la finestra reward
~12:00, fuori da :00/:25/:47) — sola lettura: (1) **reward per DELTA di equity al netto dei
trade spot** (il gateway non espone il Transaction Log; un delta con trade nel mezzo si
dichiara, trade illeggibili → delta NON attribuito, P12); (2) **depeg**: 🚨 solo sotto crit
e ripetuto, ⚠️ warn/quota/BLIND solo alla transizione (P9); (3) **quota sul totale**, che
allerta anche per deriva PASSIVA (il libro perde → la quota sale da sola, N4). Applica il
**verdetto pre-registrato** (≥1 reward entro il 29/08 → IDONEO; zero → riconvertire) invece
di lasciarlo a un promemoria. Limite dichiarato: cadenza giornaliera, un depeg intraday puo'
sfuggire all'ALLERTA — ma non al SIZING, che legge l'indice a ogni giro orario del book.
- **Serie `data/live/usde_watch.jsonl`** — dentro il perimetro di backup, `ts` in ms epoch →
sorvegliata da **`monitor_health`** (max_age 30h, `open_labeled=False`): un watch fermo
spegnerebbe gli allarmi depeg e il silenzio si leggerebbe come "va tutto bene" (P5).
- **Baseline registrata alle 14:17:52Z**: 500 USDE @ 1,0000 (indice) = $500,00 · quota 24,3%
(tetto 50%) · margine utilizzabile ~$2.008 · verdetto IN_ATTESA. E' la lettura che rende
misurabile il delta del 28/08.
- **Test: 775 passati** (+17 nuovi in `tests/test_usde_watch.py`: valutazione condivisa,
rilevatore reward, verdetto — incluso che NON anticipa la scadenza del 29/08 —, condizioni
di allerta, `px=None` che non finge un depeg).

Some files were not shown because too many files have changed in this diff Show More