95424f0755a795dedba686a87d90d26ad84fbea6
148 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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
|
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |