ab497cc028b679ef78c9c6071074e7a6546ed25d
586 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
ba5ea2f5c3 |
docs: diario 07/08 e memoria — e un gate di GTAA01 che ORA FALLISCE
Diario 2026-08-07-crescita-fisco-etf-scelta.md + i bullet corrispondenti in CLAUDE.md (fisco d'accumulo, confronto book/ETF, scelta 50/50, simulatore web). Registra anche un buco trovato ricostruendo il piano: i QUATTRO risultati del 27/07 sera (r0727_3k_vs_5k, r0727_orizzonte10, r0727_tasse) non erano ne' in CLAUDE.md ne' in un diario — vivevano solo nei messaggi di commit, e uno di essi cambia il numero di testa del piano. GATE GTAA01 CHE FALLISCE (test_gtaa_band_gate::test_la_proposta_non_e_selezionata _sull_hold_out): la proposta e' 9a/30 in-sample e 8a/30 sull'hold-out contro il 4/30 e 5/30 registrato il 27/07 — cioe' migliora dove non doveva essere guardata. Caratterizzato prima di riportarlo: i due ranghi distano 0.00116 di Sharpe su un'ampiezza di griglia di 0.3124 (0.4%), quindi il criterio non ha mai avuto margine; il calcolo e' deterministico (2 corse, max|diff| = 0.0) e il codice e' invariato dal 27/07 -> e' cambiato il DATO, perche' data/raw/ e' gitignored e i parquet equity sono riscritti ogni giorno dal cron con ADJUSTED_LAST di IB, che e' retroattivo. REGOLA NUOVA: un gate validato su dati sovrascritti ogni giorno non e' ri-verificabile. Il lato cripto non ha il problema (rebuild_history.py ricostruisce da sorgente deterministica), il lato equity si'. Il test NON e' stato toccato: allentare una soglia perche' ha smesso di passare e' proprio cio' che questo progetto vieta, e un xfail silenzierebbe il segnale. Niente di operativo dipende da questo (GTAA01 non e' deployabile per il blocco PRIIPs e non e' nel book live), ma l'affermazione "il rango NON migliora sull'hold-out" oggi e' falsa e la decisione su cosa farne e' dell'operatore. Book, pesi, cron, config/live.json e i gate pre-registrati: INVARIATI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ed2532b991 |
feat(web): simulatore di accumulo nel browser, verificato contro il Python
scripts/web/ — motore in JavaScript (engine.js) sui ritorni VERI del book esportati da export_series.py, pagine assemblate da build.py. Da "sistema dinamico dove imposti valore iniziale, mensile e durata, e calcola la best curva fissando il tempo": la simulazione gira nel browser, quindi il motore va riscritto e VA PROVATO che dia la stessa risposta. test_engine.js confronta mediane e probabilita' con r0807_growth_yearly.py su due configurazioni, esige che il versato (deterministico) coincida al centesimo, e include un controllo positivo — un motore col fisco spento DEVE risultare fuori tolleranza, perche' un test che non sa fallire non e' un test. Il risolutore e' validato contro dep_necessario di r0727_tasse.py: -0.4 / -0.6 / -1.1%. smoke.js ESEGUE le pagine con un DOM finto. Serve perche' node --check valida solo la sintassi: ho pubblicato una pagina che lo passava e moriva alla prima riga utile (chiavi Python "0.0" ricostruite in JS come String(0) = "0"; i pesi intermedi funzionavano per caso). Altri due errori che questi strumenti hanno intercettato: - due anni di dati di un grafico scritti A MEMORIA perche' tail aveva troncato l'output -> ora i dati si INIETTANO da JSON (build.py), il passaggio manuale non esiste piu'; - una "distorsione sistematica" del motore JS (+0.75%, 8 semi tutti positivi) che erano 8 estrazioni contro UN punto Python rumoroso. Misurato bene, 8 semi per parte: -0.01%, t = -0.04; ed entrambi i campionatori cadono entro 1.7 SE dall'atteso ANALITICO della media di blocco. Scelta guidata da una misura: la banda del versamento suggerito resta +-1% da 1.200 a 3.000 percorsi -> non domina il Monte Carlo ma la granularita' della bisezione (~5 EUR). Percorsi tenuti bassi e incertezza dichiarata, invece di pagare tempo per una precisione che non arriva. Nessun impatto sulla produzione: non tocca book, pesi, cron o config. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
56141b0ffe |
research(portafoglio): book vs ETF — le due lenti si contraddicono, la scelta robusta e' 50/50
r0807_asset_compare.py (book / S&P 500 / MSCI World sullo stesso piano) e r0807_best_strategy.py (quale peso scegliere a 12 anni). Da "e se mettessi in MSCI World o ETF SP500?" e "quale e' la miglior strategia?". Tre cose rese comparabili: la GRIGLIA (azioni su calendario con 0.0 a borsa chiusa = convenzione GTAA01; senza, Sharpe x1.20), il FISCO (book realizza ogni anno al 33%, UCITS ad accumulazione paga il 26% alla vendita -> le curve ETF sono valori di liquidazione: il differimento e' un vantaggio strutturale dell'ETF e va nel modello), il BERSAGLIO (272.061$ vale per la rendita perpetua DEL BOOK e per il 33% -> ricalcolato per ciascuno). Il risultato non e' chi vince, e' che le due lenti si contraddicono: sulla storia piena il book arriva al 115% del proprio bersaglio e l'S&P al 32%; sulla stessa finestra 118% e 110%, e l'S&P ACCUMULA PIU' del book. Il divario e' tutto nei crolli 2000/2008 che la strategia non ha mai vissuto. E sulla stessa finestra il rendimento e' quasi identico (17.4% vs 16.8%): la differenza e' tutta nel rischio (vol 11.0 vs 19.6%, maxDD 10.5 vs 33.7%). Il book non guadagna di piu', perde di meno — conferma indipendente di cio' che il progetto scrive di TP01 dal 19/06, contro un'alternativa vera. Difetto corretto in sessione: un MIX esiste solo dove esistono ENTRAMBE le serie. La prima stesura confrontava "storia piena" contro "stessa finestra" ma calcolava i bersagli del mix sull'intersezione in tutti e due i casi -> dichiarava 30 anni e ne usava 7 (per l'ETF puro: rendita 8.63% invece del 4.16% vero). Rifatto su una finestra sola con gli scenari come spostamento del drift, simmetrico sui due lati. A 12 anni vince 50/50 sul RIMPIANTO massimo (20% contro 52% del book puro e 53% dell'ETF puro); il criterio del solo caso peggiore non distingue 25% da 50% (27.09 vs 26.99% = pareggio nel rumore). L'asimmetria fra i due stress e' il risultato: quello sull'equity e' misurato (30 anni esistono), quello sul book e' giudiziale (7.4 anni sono tutta la sua storia). MSCI World e' un PROXY 70% SPY + 30% EFA: URTH/ACWI/VT non sono nell'abbonamento dati del conto IB, e la nota lo dichiara invece di nasconderlo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
68c6894d85 |
research(capitale): il fisco durante l'ACCUMULO non era mai stato contato
r0807_growth_yearly.py: crescita anno per anno separando versamenti e guadagno, con e senza l'imposta d'accumulo. Nasce da "grafico della crescita per anno con versamento e con guadagno". TAX_RATE compariva in UN SOLO punto del progetto: la lordizzazione del bersaglio in fase di PRELIEVO. L'accumulo componeva al lordo per dieci o vent'anni. Costo (lump 5k + 500/mese): -15.7% a 5 anni, -29.8% a 10, -42.6% a 15 — replica coerente col 27/07 su lump 10k (-16.8/-31/-44%). L'errore e' COMPOSTO. Conseguenza: tutte le tabelle a 15-20 anni pubblicate in CLAUDE.md sono al lordo. Contro-intuitivo e misurato: versare di piu' RITARDA il sorpasso (l'anno in cui il guadagno cumulato supera il versato) — 7o anno a 500/mese, 8o a 800 — perche' alza l'asticella. I 300 in piu' comprano il traguardo (12o anno invece del 15o, P(bersaglio) a 15a da 73.2% a 99.0%), non il sorpasso. Riusa senza riscriverle la contabilita' fiscale di r0727_tasse.accumula e il block bootstrap di r0725_capcurve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f81c783ea7 |
fix(sicurezza): dashboard 8787 solo su 127.0.0.1, era raggiungibile da internet
La riga era "8787:8787", cioe' pubblicata su tutte le interfacce. ufw non la fermava: il DNAT che Docker installa in nat/PREROUTING devia il pacchetto prima della catena INPUT su cui ufw lavora, e in FORWARD la catena DOCKER lo accetta prima delle catene ufw-*-forward (DOCKER-USER era vuota). Verificato: da IP pubblico la dashboard rispondeva HTTP 200. Dietro c'erano conto e posizioni reali (monta .env.mainnet per lo Shadow live), senza autenticazione, su http.server della stdlib, processo root. Svista e non scelta: la riga sotto lega gia' il gateway IB a 127.0.0.1 con il commento "raggiungibile solo da localhost dell'host". Dopo il fix: DNAT con -d 127.0.0.1/32, listener solo su 127.0.0.1:8787, da IP pubblico connessione rifiutata. pythagoras-ibgw non toccato. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
a2f28153d8 |
docs(bite): verificato il primo giro post-eliminazione, e come NON leggere quote_status
Il giro delle 21:25 (primo con bite gia' cancellato): 576 chiamate, 0 risposte 429, 0 errori. E' il controllo che conta, perche' il guasto del 29/07 era la raffica di bite che saturava il rate limit per-IP. Aggiunta la tabella dei 5 giri della giornata, che mostra invarianza prima/dopo. ⚠️ E una precisazione sul nostro stesso strumento: 'ok' significa ALMENO UN LATO del book, non quota completa. Con ok=572 le righe a due lati sono 432 (75.5%). Che sia strutturale (opzioni molto OTM) e non un degrado si vede dall'invarianza fra i giri, non dal fatto che il numero sembri alto. E' 'una riga presente non e' un dato presente' un livello piu' in giu', applicata allo strumento costruito per quella lezione: la battuta di cuore vedrebbe il guasto del 29/07 (quote vuote) ma non una deriva verso book a un lato solo. Nessuna soglia cablata: con 5 giri di storia sarebbe inventata, e una soglia inventata e' peggio di nessuna soglia. La colonna da guardare e' 'due lati %'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
933ccff057 |
docs(bite): cerbero-bite ELIMINATO — cosa e' stato verificato prima di cancellare
Container, volume, immagine e cartella rimossi il 2026-07-30 (12 GB liberati). Book, pesi, cron, config INVARIATI: la raccolta era gia' passata al successore e la sovrapposizione fra le due ha coperto la consegna senza buchi. Le quattro verifiche, nessuna delle quali era 'il backup esiste': 1. Snapshot COMPLETO, non solo integro: SHA256 OK su entrambi i file, ma soprattutto conteggi confrontati tabella per tabella fra volume vivo e snapshot (1.232.212 / 17.406 / 59 / 0), identici anche ai parquet importati. Un hash prova che il file non e' corrotto, non che contenga tutto. 2. I 10,6 GB di backup interni al volume non contenevano dati unici. La domanda giusta non era la loro dimensione ma se bite potasse lo storico: tutti e tre i campioni controllati hanno la STESSA riga piu' vecchia (2026-05-01T20:53:49) e conteggi monotoni crescenti -> nessuna potatura, sottoinsiemi stretti. 3. Zero dipendenze a runtime: ne' cron, ne' systemd, ne' route traefik, ne' altri progetti. I riferimenti rimasti sono documentazione, che resta. 4. cerbero-mcp e' un progetto DIVERSO e serve a PythagorasGoal (Hyperliquid, percorso del conto). Progetto compose separato; la rete traefik condivisa e' external: nel compose di bite, quindi down -v non la tocca. Verificato dopo: Up 41 hours (healthy). Due servizi con lo stesso prefisso sono un incidente che aspetta. Il codice non e' stato perso: era su Gitea (Adriano/Cerbero-Bite) e l'unica modifica pendente e' stata committata la' come commit di dismissione. REGOLA: prima di cancellare una sorgente si verifica che la copia sia COMPLETA, non che esista. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e9a4538054 |
chore(gitignore): la battuta di cuore del collettore e' stato runtime, non sorgente
data/chain_collect/runs.jsonl era finito tracciato nel commit
|
||
|
|
444b804415 |
ops(backup): PythagorasGoal nel backup rotativo, solo il dato non ricostruibile
data/raw/ e' gitignored e /opt/docker/scripts/backup.sh non copriva questo
progetto: dopo lo spegnimento di cerbero-bite la catena opzioni esisteva in
due copie SULLO STESSO DISCO.
Aggiunta do_pythagoras con criterio dichiarato — si salva cio' che non si
puo' riscaricare:
dentro (28 MB): catena + contesto, data/paper_* e data/chain_collect
(serie forward-only che alimentano i gate pre-registrati: non sono
ricalcolabili, sono un registro di cosa si sapeva e quando),
options_daily, live, venue_watch, fee_watch, config/live.json
fuori (~110 MB): quanto si riscarica dai venue (rebuild_history, fetch_dvol,
fetch_hyperliquid, fetch_ib_equities) + cache
Due guardie provate nei DUE versi: fallisce se la catena e' assente o vuota
invece di produrre un archivio che sembra a posto, e verifica che il tar
contenga davvero la catena (caso negativo: 0 file prodotti). La radice e'
sovrascrivibile via PYG_ROOT solo per poter far scattare la guardia.
Verificato che dopo un riavvio la raccolta riprenda da sola: cron enabled +
active, nessuna dipendenza da docker o cerbero-mcp; giro provato con env -i
(574 chiamate, 0 errori). Finestra scoperta fino al :25 successivo, senza
catch-up.
/opt/docker/scripts NON e' un repo git: la modifica vive solo su disco, il
diario e' l'unico posto in cui e' scritta.
Book, pesi, config, strategia INVARIATI.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
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> |
||
|
|
0a77290636 |
research(capitale): il fisco durante l'ACCUMULO non era mai stato contato — vale il 31% a 10 anni
r0727_tasse.py. TAX_RATE=0.33 compare in tutto il progetto in UN SOLO punto: la lordizzazione del bersaglio (fase di RENDITA). L'accumulo compone al lordo per dieci o vent'anni. 10.000 EUR + 500/mese, 10 anni, capitale mediano: nessuna imposta (modello pubblicato) 229.638$ P(entro 10a) 34.5% plus 26% 173.284$ 8.5% plus 33% + patrimoniale 0.2% 158.401$ 3.8% = -31% Versamento necessario a 10 anni (lump 10k): P=50% da 602 a 880 EUR/m; P=75% da 790 a 1.051. Cioe' +33%: il numero dato stamattina (790-870 EUR/m) era al lordo del fisco. L'errore e' COMPOSTO, non una tantum: -16.8% a 5 anni, -31% a 10, -44% a 15, -55% a 20. Assunzioni dichiarate (NON un parere fiscale): 33% cripto da L.199/2025 (misurato anche a 26%, perche' e' aperto se i derivati di sede estera seguano quel regime), minusvalenze riportabili 4 anni, 0.2% annuo sul valore. Il modello tassa la variazione ANNUA di valore, quindi anche la parte non realizzata a cavallo del 31/12: e' un LIMITE SUPERIORE rispetto alla pura realizzazione, ma il turnover del book lo rende stretto. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
067c89fc16 |
research(capitale): aggiunta la riga 10k al filone orizzonte-10
10.000 EUR + 500/mese: P(entro 10 anni) 33.9% (contro 19.7% con 5k), mediana 10.7 anni, rendita a 10 anni 42.25 EUR/g. Raddoppia quasi la probabilita' ma resta fuori dal vincolo. Versamento richiesto con lump 10k: P=50% -> 604 EUR/m, P=75% -> 793, P=90% -> 975. Cioe' 5.000 EUR in piu' oggi valgono 77 EUR/mese per 10 anni (~9.240): meno del 2.45x misurato su 20 anni, perche' a orizzonte corto il lump compone meno. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fa18621eb3 |
research(capitale): 50 EUR/g in 10 anni costa ~870 EUR/mese, non 500
Vincolo nuovo dell'operatore (49 anni, non oltre 10 anni). r0727_orizzonte10.py. Il piano attuale NON regge il vincolo: 5.000 EUR + 500/mese danno P(entro 10a) = 19.7% (mediana incondizionata ~11.4 anni). Quanto serve al mese per 10 anni, con lump 5.000: P=50% -> 689 EUR P=75% -> 870 EUR P=90% -> 1.047 EUR A P=75% si versano $119.273 per arrivare a $272.061: e' la frase del 26/07 col prezzo attaccato (a orizzonte corto non fai lavorare la strategia, compri il capitale coi bonifici). Tabella inversa (lump 5k), cio' che si compra in 10 anni: 500/m -> 36.90 EUR/g 800/m -> 55.57 1.000/m -> 72.66 1.500/m -> 105.94 Due difetti miei corretti prima di pubblicare: - la colonna "anni mediani" era CONDIZIONATA ai percorsi che arrivano: mostrava 9.4 anni accanto a P=15%, che e' contraddittorio. Ora e' etichettata "mediana SE ce la fa". - il muro stampato (254.524$, ricalcolato dalle serie di questo script) non era quello usato nelle simulazioni (272.061$ pubblicato). Le due costruzioni del book live danno rendite perpetue 10.91% e 11.67%; si tiene la conservativa e si dichiara la differenza. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1aa5a0616a |
research(capitale): 3k o 5k -> ~3.7 mesi su 11.5 anni, non e' una decisione importante
r0727_3k_vs_5k.py. Domanda dell'operatore, poi ristretta a "fregatene del fuori": quanto versare su Deribit dei 6.043 EUR fermi in XEON. Tutto su Deribit, 500 EUR/mese, bersaglio 272.061$: 3.000 EUR -> 11.73 anni 4.000 -> 11.58 5.000 -> 11.42 6.043 -> 11.28 Ogni 1.000 EUR in piu' all'inizio vale ~1.8 MESI. P(entro 20a) 100% in tutti i casi. Il motivo strutturale: fino al traguardo entrano ~69.000 EUR di versamenti, quindi il versamento iniziale e' il 4-9% del flusso totale. La decisione che conta e' la SOSTENIBILITA' dei 500/mese (26/07: smettere al 5o anno porta P(muro) dal 90% al 53% = venti volte l'effetto misurato qui). Aggiunto anche il taglio con il venue dentro (quota fuori 46% vs 16%) e il fatto che con i versamenti su Deribit quella quota si DILUISCE: 4.0 anni di copertura versando 3k, 0.7 anni versando 5k -> la differenza fra i due e' temporanea, non una postura permanente. simulate() accetta dep_to (dove vanno i versamenti); replica del 26/07 preservata. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
d0c804ebfc |
research(gtaa): l'assenza di API DEGIRO vale -0.02 di Sharpe, non e' squalificante
Domanda dell'operatore: "degiro ha api?". Fatto: no, non ufficiale; Revolut nemmeno (la sua e' per pagamenti); IB si'. I wrapper non ufficiali girano su credenziali + seed 2FA e si rompono IN SILENZIO a ogni cambio di front-end — e il progetto ha gia' pagato quel prezzo con fresh_5m il 26/07. Un esecutore che puo' rompersi senza dirlo e' peggio dell'esecuzione manuale. Misurato il costo di NON automatizzare invece di discuterlo: carico operativo: 15 settimane/anno con >=1 ordine (29% dei controlli, 1.4 per volta) ritardo 1g -0.02 Sharpe (peggiora in 6/11 anni = moneta) ritardo 3g -0.13 ritardo 10g -0.27 Il costo non e' il ritardo tipico ma la coda: il rischio dell'operativita' manuale e' la dimenticanza, e si copre con un allarme, non con una API (gtaa_rebalance_plan esiste gia' in produzione ed e' nato per un esecutore). Nota di metodo: sulla finestra UCITS di 3.2 anni la curva del ritardo NON e' monotona (5g -0.26, 10g -0.13) -> il campione corto non risolve differenze di questa taglia, quindi il numero si legge sulla finestra lunga a 10 anni, dove lo e'. Book, pesi, cron, config INVARIATI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XBbYmiXqbUNuGpK9sfbsGp |
||
|
|
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 |
||
|
|
6664575e1c |
❌ GTAA01 NON deployabile: blocco PRIIPs CONFERMATO sul conto reale
Il rischio sollevato poche ore fa e' stato verificato tentando l'ordine. Il broker rifiuta: "Trading limitato — Questo prodotto non dispone di un KID in inglese o in una lingua approvata per il vostro Paese. I clienti retail possono negoziare prodotti retail preconfezionati solo se e' disponibile un KID appropriato." Non e' piu' un'ipotesi regolatoria: e' un rifiuto d'ordine documentato. SPY/QQQ/IWM/TLT/GLD/HYG sono ETF domiciliati USA, gli emittenti non pubblicano il KID e i broker UE ne vietano l'ACQUISTO al retail. ⚠️ Le QUOTAZIONI restano visibili — l'operatore vedeva tutti e sei i prezzi in piattaforma, ed e' esattamente cio' che rendeva invisibile l'assunzione. COSA CADE: lo sleeve cosi' com'e' non e' deployabile, e con esso il piano di attivarlo a ~$13k. Restano valide come RICERCA e nulle come DEPLOY: validazione a 30 anni (22/06), fix costi IB (25/07), GTAA_MIN_CAPITAL, e il LOO del 26/07 che lo indicava come l'unico sleeve positivo nel 100% delle estrazioni su tutte e tre le metriche. COSA NON CADE: tutte le traiettorie, i muri e le tabelle di rendita usano book_series(with_gtaa=0) = solo TP01+SKH01 su Deribit -> nessun numero del piano va rifatto. E il book live non lo include. VIA D'USCITA (non percorsa): equivalenti UCITS. NON e' una sostituzione di ticker — storia piu' corta (si perde la validazione a 30 anni, cioe' cio' che lo rendeva credibile), ritenuta/TER/replica diversi (decine di bps su un CAGR del 3.65%), quotazione LSE/Xetra con orari e valuta diversi da uno sleeve che decide sul close USA. Percorso onesto: validare sull'INDICE e negoziare il VEICOLO, dichiarando tracking error e ritenuta come costi. REGOLA: la negoziabilita' sul conto REALE va verificata quando lo sleeve entra in RICERCA, non quando entra nel book. Cinque settimane di misure poggiavano su un'assunzione mai controllata, e il controllo e' costato un ordine di prova. Book, pesi, cron, config INVARIATI. 411 test verdi. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
b3082de9af |
⚠️ GTAA01: negoziabilita' degli strumenti MAI VERIFICATA (rischio aperto)
Domanda dell'operatore ("GTAA01 puo' essere in revolut?") che scopre un'assunzione mai
controllata in 5 settimane di lavoro sullo sleeve.
GTAA01 usa SPY, QQQ, IWM, TLT, GLD, HYG = ETF DOMICILIATI NEGLI USA. Sotto il regolamento
PRIIPs un investitore retail residente nell'UE tipicamente NON puo' acquistarli, perche'
gli emittenti USA non pubblicano il KID; i broker UE — Interactive Brokers incluso, che e'
esattamente il venue che lo sleeve assume — li bloccano in acquisto per la clientela
retail.
COSA POGGIA SU QUESTA ASSUNZIONE: i 30 anni di storia, il fix dei costi IB reali del
25/07, la soglia GTAA_MIN_CAPITAL $3.000, il contributo al book, e il risultato del LOO del
26/07 che lo indica come l'UNICO sleeve positivo nel 100% delle estrazioni su tutte e tre
le metriche. Nessuno di questi numeri e' sbagliato come backtest; quello che non e' mai
stato verificato e' se lo sleeve sia ACQUISTABILE dal conto reale dell'operatore.
DA VERIFICARE PRIMA DEL DEPLOY, non dopo. Se il blocco c'e' servono gli equivalenti UCITS
(CSPX/SXR8, EQQQ/SXRV, IUSN/CSUSS, DTLA/IDTL, SGLN/IGLN, IHYU), che sono strumenti DIVERSI
per domicilio, valuta, TER e replica -> rifetch dei dati e rivalidazione, non una
sostituzione di ticker.
SU REVOLUT nello specifico la domanda resta piu' stretta: universo ETF limitato, prodotto
retail leggero, e un ribilanciamento settimanale a 6 gambe con banda $50 non e' cio' per
cui e' pensato. Il confronto va fatto su esistenza degli strumenti e costo per ordine.
Nota permanente nel sorgente sopra EQ_UNIVERSE + bullet in CLAUDE.md.
REGOLA: la negoziabilita' di uno strumento sul conto REALE va verificata quando lo sleeve
entra in RICERCA, non quando entra nel book. E' l'analogo azionario di cio' che il progetto
gia' fa sul crypto (min-order, haircut small-cap, eseguibilita' a $600): la stessa
disciplina non era stata applicata all'equity.
Book, pesi, cron, config INVARIATI (GTAA01 non e' nel book live).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
dc4135a781 |
fix: le soglie della tabella anni contraddicevano la decisione venue
L'operatore ha chiesto "GTAA01 e XS01 sono in deribit?". No, e la domanda scopre un'incoerenza in cio' che avevo presentato. MAPPA REALE DEI VENUE: TP01, SKH01 -> Deribit (gli unici LIVE) VRP01 -> Deribit opzioni (paper: regola "niente short-vol da modello") XS01 -> Hyperliquid (stat-mode, serve ~$20k sulla gamba) GTAA01 -> Interactive Brokers, 6 ETF azionari (paper) L'INCOERENZA: la tabella anno-per-anno annotava "anno 1: GTAA01 entra nel book" e "anno 8: XS01 eseguibile", ma attivare GTAA01 E' lo split di venue, e l'operatore ha deciso il 2026-07-26 di restare 100% Deribit fino a $20k. Le due cose non stanno insieme: sotto i $20k quelle attivazioni non avvengono. COSA NON ERA SBAGLIATO: i NUMERI. `book_series(with_gtaa=0)` usa il solo book Deribit a 2 sleeve, quindi tutte le traiettorie, i muri e le rendite pubblicate NON assumono nessuna delle due attivazioni — sono Deribit-only e coerenti con la decisione. Sbagliata era solo la colonna di annotazione, che descriveva cio' che sarebbe POSSIBILE come se fosse pianificato. Etichette corrette: le soglie ora dicono "sarebbe eseguibile ... ma la decisione venue dice $20k", e i $20k sono marcati come il punto in cui GTAA01/XS01 diventano una SCELTA. REGOLA: un'annotazione che descrive una possibilita' accanto a numeri che descrivono un piano viene letta come parte del piano. Se una decisione registrata la esclude, va detto nella riga stessa. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
95f7fb30a3 |
fix: il massimo di una simulazione non e' una statistica della strategia
L'operatore ha contestato un numero che avevo citato io ("anno migliore +184%"). Aveva
ragione, e l'errore era di METODO, non di calcolo.
IL NUMERO E' VERO. Tracciato l'anno estremo: 18 blocchi da 20 giorni, nessuno
significativamente negativo (+20% +15% +12% +10% +8% ... -1%). La popolazione lo consente:
blocchi 20g reali con mediana -0.1%, p95 +8.5%, max +22.4%, skew +2.15 — firma classica di
un trend-follower. E la materia prima esiste: la miglior finestra 365g REALE e' +89.8%.
MA CITARLO ERA SBAGLIATO, perche' il massimo di N estrazioni cresce con N:
su 1.000 anni simulati -> max +96.0%
su 5.000 -> max +135.2%
su 114.000 -> max +184.3%
Il numero che avevo dato parlava del mio N_PATHS, non del book. Con 1.000 percorsi avrei
scritto +96% per la stessa identica strategia.
I NUMERI CORRETTI SONO I PERCENTILI: p1 -11.9% · p5 -5.5% · MEDIANA +16.0% · p95 +51.2% ·
p99 +71.8%. Vale simmetricamente per il "peggiore -27.4%", anch'esso minimo campionario (a
1.000 percorsi era -19.1%): la coda sinistra onesta e' p1 = -11.9%.
CABLATO: r0726_decadimento.py aveva lo stesso difetto ("drawdown PEGGIORE 44.2%") -> ora
stampa p99 = 26.0% e dichiara che il 44.2% e' un massimo campionario da non citare come
"il caso peggiore".
REGOLA: il massimo (o il minimo) di una simulazione e' una statistica del NUMERO DI
SIMULAZIONI, non della strategia. Si citano i percentili. Stessa famiglia dell'errore gia'
codificato oggi ("un percentile stampato a 0 decimali mente esattamente agli estremi"):
gli estremi sono dove i numeri sembrano piu' informativi e lo sono meno.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
66b4b2b9c0 |
research: tabella anni parametrizzabile da riga di comando
"E con 1000 al mese?" non deve richiedere di modificare lo script: importo mensile e versamento iniziale passano come argomenti. Modificarlo ogni volta significherebbe avere due versioni dei numeri in giro senza sapere quale ha prodotto cosa. uv run python scripts/research/r0726_tabella_anni.py # EUR 500/mese uv run python scripts/research/r0726_tabella_anni.py 1000 # altro mensile uv run python scripts/research/r0726_tabella_anni.py 1000 10000 # mensile + iniziale EUR 1.000/mese: traguardo al capitale mediano all'anno 9 (2035) invece del 12; P(traguardo) 80% a 10 anni contro 16%. Il totale versato a 20 anni raddoppia ($270.917 vs $138.482). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
bdd9e60355 |
research: tabella anno per anno del piano (EUR 5.000 + 500/mese)
Mette in forma leggibile le misure di r0726_piano_5k500.py, anno per anno e con gli anni di calendario, piu' tre colonne che mancavano e che servono a leggerla onestamente: quanto hai VERSATO fino a quel punto (senza, il capitale sembra rendimento), la banda p10-p90 (meta' dei percorsi sta fuori dalla mediana) e la soglia attraversata. Traguardo EUR 50/g al capitale mediano: anno 12 (2038). P(traguardo) 16% a 10 anni, 53% a 12, 92% a 15, 99.9% a 20. Il pezzo che conta: la quota di capitale che viene dal RENDIMENTO invece che dai versamenti e' 10% al primo anno, 39% al quinto, 63% al decimo, 88% al ventesimo. I primi anni si giudicano sui versamenti, non sui risultati — e' il motivo per cui il piano e' fragile all'interruzione precoce (misurato: i primi 5 anni sono il 25% dei soldi e il 58% del risultato). Regola del progetto rispettata: un numero pubblicato deve avere uno script committato che lo riproduce. Ipotesi dichiarate in testa allo script: x0.89 misurato, book live TP01+SKH01, fisco 33%, NESSUN rischio di venue e NESSUN decadimento dell'edge (misurati in r0726_venue_risk.py e r0726_decadimento.py, da leggere insieme a questa). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
e320e3c2ba | merge: edge watch — criteri di kill pre-registrati per il book live | ||
|
|
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> |
||
|
|
1296fa2d96 |
research: "dai per scontato che non perdiamo mai?" — meta' infondata, meta' e' il punto piu' debole del piano
Obiezione dell'operatore, presa sul serio. Due parti con risposte opposte. PARTE 1 (infondata): le perdite SONO nel modello. Il block bootstrap ricampiona i ritorni reali a blocchi di 20 giorni e conserva la forma dei drawdown. Serie reale: 35.6% giorni in perdita, 27.5% flat, 36.9% in guadagno; giorno peggiore -3.94%, peggior mese -5.76%. Sui 5.000 percorsi: maxDD mediano 14.4%, p90 19.8%, PEGGIORE 44.2%; anni-calendario in perdita 5.8% su 95.000 anni simulati. ⚠️ ERRORE MIO CATTURATO PRIMA DI PUBBLICARE: la prima stesura diceva 63.9% di giorni in perdita. Artefatto — il de-luck sottrae una costante a OGNI giorno (e' cosi' che riduce il drift lasciando la vol invariata, come prescrive la misura d'ancora), quindi trasforma il 27.5% di giorni FLAT in piccoli negativi. REGOLA: una correzione uniforme sul drift e' giusta per le domande sul drift e sbagliata per quelle sulla distribuzione — la stessa serie dice 36% o 64% a seconda di quale si guarda, senza che sia cambiato niente. PARTE 2 (coglie il punto): l'assunzione ottimista c'e' ed e' che l'EDGE CONTINUI A ESISTERE per vent'anni. Il bootstrap assume che il futuro sia il passato rimescolato; nessuna parte del progetto misura il decadimento dell'alpha. Misurato ora: edge intatto -> 11.6a, P(20a) 99.9% edge dimezzato -> 15.8a, P 76.6% decade a zero in 20a -> 14.3a, P 65.5% decade a zero in 10a -> oltre 20a, P 18.4% morto dall'anno 10 -> oltre 20a, P 42.0% morto dall'anno 5 -> oltre 20a, P 0.0% Il piano NON e' fragile a un dimezzamento dell'edge, lo e' alla sua morte. E i due casi non sono distinguibili in anticipo: e' la ragione per cui esistono i gate pre-registrati. IL LIMITE STRUTTURALE: il peggior BIENNIO dell'intero campione e' +3.0%, cioe' POSITIVO. Sette anni di storia crypto contengono due tori: un decennio davvero brutto non e' mai successo, quindi il bootstrap non lo puo' estrarre. Se i 20 anni fossero tutti come quel biennio, P(traguardo) 2.9% e capitale finale $149.014 contro $136.847 versati — il piano non fallirebbe, semplicemente non renderebbe. Non e' un parametro da alzare: non si puo' simulare un regime peggiore di qualunque cosa ci sia nel campione. Book, pesi, piano INVARIATI. Cambia cosa si sorveglia. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
8b21d29e69 |
fix(dashboard): taglia del book letta dal conto, non cablata
Il cruscotto dichiarava "cap $300/asset · capitale reale ≈ $600" come testo fisso: sarebbe diventato falso al primo deposito, sulla pagina che si guarda per capire cosa sta girando. Ora legge equity reale + max_notional_per_asset_frac + disaster_sl_pct dalla config. Reso dinamico solo il testo di stato del book LIVE. I $600/$2000 restanti in dashboard.py sono i capitali d'inizio CONGELATI dei libri paper (forward-monitor): quelli devono restare fissi o le serie perdono continuita'. Verificato il percorso di ESECUZIONE: nessuna assunzione cablata sulla taglia da $600 (book.py / shadow.py / book_execute.py). Reso: "capitale reale $596.92 · cap $298/asset · disaster-SL on-book −30%". 391 test verdi. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
eb7c3af636 | merge: piano 5k+500/mese + strozzatura cap post-deposito | ||
|
|
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> |
||
|
|
d1cf44f874 | merge: piano versamenti — interruzione, crescita, calendario, domanda inversa | ||
|
|
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> |
||
|
|
e8ce60d41c | merge: rivalutazione strategia — 75/25 confermato, nessun cambio | ||
|
|
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> |
||
|
|
4450321a81 | merge: venue watch — tripwire di fallimento exchange (100bps/4h, zero falsi allarmi in 8 anni) | ||
|
|
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> |
||
|
|
0ec6f8b761 |
decision: concentrazione 100% Deribit fino a $20k (decisione dell'operatore)
L'analisi venue-risk di stamattina raccomandava lo split a ~$3k (GTAA01 su IB, 20-25% fuori dal rischio-exchange). L'operatore ha deciso, DOPO aver visto la tabella della rovina, di restare concentrato fino a $20k. Registrato con i termini espliciti perche' non venga ri-litigato alla soglia dei $3k. ACCETTATO: P(perso TUTTO) resta 10/18/34/64% a p=0.5/1/2/5% invece di 0/0/4/27%. IN CAMBIO DI: ~EUR 0.08/g di rendita + commissione fissa IB + un secondo venue da gestire, per proteggere $750 alla soglia dei $3k. L'argomento dell'operatore REGGE sull'asse su cui ottimizza: sulla probabilita' di ARRIVARE al capitale-rendita lo split vale +1-3pp (81% -> 83% a p=1%), fatto misurato nella tabella del §2, non una concessione. L'argomento contro resta scritto: zero e' ASSORBENTE (andare a zero all'anno 10 di un piano da 16 anni = non arrivarci piu', si riparte da EUR 0 + versamenti), quindi il valore del non-andare-a-zero non e' proporzionale alla frazione salvata. SI RIAPRE a $20k, o PRIMA se cambia il piano (orizzonte/versamenti) o se `p` diventa stimabile invece che assunto. CORREZIONE A UN MIO SUGGERIMENTO, verificata nel codice: avevo detto "non lasciare su Deribit piu' di quanto serve a girare il book". E' inerte — `src/live/book.py:81` fa `raw = weight * equity * (...)` con equity = saldo reale del conto, quindi prelevare $100 riduce il nozionale di $100 (1:1), non mette al sicuro $100. Tenere meno saldo a pari nozionale richiederebbe di scollegare il sizing dal conto e usare il margine = scambiare rischio-venue con rischio di liquidazione, oggi escluso dal cap a 1.0x. Agli atti anche: "exchange FDIC" non esiste (FDIC = depositi bancari USD; la pass-through di alcuni exchange copre solo il contante). Le protezioni reali sono SIPC (IB: ETF/azioni = GTAA01, non le crypto via Paxos) e segregazione CFTC (CME, taglia contratti inaccessibile a questa scala). Book, pesi, cron, config INVARIATI. Nessun cambio di codice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
dc60624772 | merge: muro come punto fisso — previsione refutata, book deployable a 73.900 |