diff --git a/CLAUDE.md b/CLAUDE.md index c39f52a..48637ea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -610,6 +610,10 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis | €500 | 19.6a (48%) | 15.7a (94%) | **12.4a (100%)** | | €1000 | 14.8a (95%) | 12.0a (100%) | **9.0a (100%)** | | €2000 | 10.0a (100%) | 8.5a (100%) | **6.0a (100%)** | + ⛔ **QUESTA TABELLA E' AL LORDO del fisco d'accumulo — la versione NETTA e' nel bullet "IL FISCO + DURANTE L'ACCUMULO" (r0807_piano_netto, 07/08) e cambia la riga di testa: €250/mese passa da + P(20a) 92% a 52%.** Le colonne qui restano perche' sono la replica di controllo del fattore + d'ancora, non perche' siano il piano. ✅ La colonna ×0.60 **riproduce esattamente** i numeri del 25/07 (19.6a / 14.8a) = validazione indipendente della replica. ⚠️ **Cio' che NON cambia col fattore: senza depositi il capitale-rendita non si raggiunge mai** (0% dei path a 20 anni a OGNI fattore) — l'accumulo @@ -622,6 +626,9 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis | **10 anni** | €806/m | €995/m | **€1.178/m** | €1.299/m | **$155.923** | | 15 anni | €313/m | €408/m | €509/m | €583/m | $101.643 | | 20 anni | €129/m | €180/m | €237/m | €280/m | $63.406 | + ⛔ **AL LORDO: i numeri da usare sono quelli NETTI** (€1.323 / €672 / €371 a P=90%, bersaglio + $258k) nel bullet "IL FISCO DURANTE L'ACCUMULO" — il fisco costa **+12% al mese a 10 anni, +32% + a 15, +57% a 20**. ⚠️ **Comprimere l'orizzonte da 20 a 10 anni costa 2.5× al mese E 2.5× in totale**: a 10 anni versi $155k per arrivare a $272k (il rendimento fa il 43%), a 20 anni ne versi $63k (il rendimento fa il **77%**). **A orizzonti corti non fai lavorare la strategia, COMPRI il @@ -1611,23 +1618,50 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis deploy**, con questo gate come giustificazione. **REGOLA: un parametro d'ESECUZIONE scelto guardando il risultato e' selezione come ogni altra** e passa per gli stessi gate, anche quando "non tocca l'allocazione". - ⚠️ **QUESTO GATE OGGI FALLISCE (2026-08-07) e la sua misura NON e' riproducibile.** - `test_la_proposta_non_e_selezionata_sull_hold_out`: la proposta e' **9ª/30 in-sample e 8ª/30 - sull'hold-out** (migliora dove non doveva essere guardata) contro il **4/30 e 5/30** registrato - sopra. Caratterizzato: i due ranghi distano **0.00116 di Sharpe** su un'ampiezza di griglia di - 0.3124 (**0.4%**) → *il criterio non ha mai avuto margine, era un rango*; il calcolo e' - **deterministico** (2 corse, `max|diff| = 0.0`) e il codice e' **invariato** dal 27/07 (nessun - commit su `r0727_gtaa_band_gate.py`, `gtaa.py`, `eqlib.py`, `eq_splits.py`) → **e' cambiato il - DATO**: `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'. **Test NON toccato** (allentare una soglia perche' ha smesso di passare e' - proprio cio' che questo progetto vieta; un `xfail` silenzierebbe il segnale). Niente di operativo - dipende da questo — GTAA01 non e' deployabile (PRIIPs) e non e' nel book live — ma - **l'affermazione "il rango NON migliora sull'hold-out" oggi e' falsa**: decisione dell'operatore - se correggerla, ripensare il gate, o congelare uno snapshot dei parquet equity. - Diario `2026-08-07-crescita-fisco-etf-scelta.md` §7. + ⚠️ **CORREZIONE 2026-08-07 — il criterio (A) qui sopra e' RITIRATO: non misurava cio' che + dichiarava, e il "4/30 in-sample, 5/30 hold-out" non e' un'evidenza.** Il test lo aveva + segnalato smettendo di passare (9ª/30 in-sample, 8ª/30 hold-out) **senza che il codice fosse + cambiato** — `data/raw/` e' gitignored e il cron riscrive i parquet equity ogni notte con + `ADJUSTED_LAST` di IB, che e' retroattivo. Misurato in `r0807_gtaa_gate_resolution.py`: + **(a)** i due ranghi distavano **0.00116 di Sharpe** su uno spread di griglia di **0.3124** + (0.4%); **(b)** e soprattutto **il criterio `rank_in <= rank_oos` lo passano 14/30 celle + (47%) PER COSTRUZIONE** — la somma dei ranghi e' la stessa nelle due finestre → *e' una moneta, + e il 27/07 la moneta era uscita bene*. Contorno: spostamento tipico fra le due finestre **8 + ranghi** (max 25), **Spearman IS/OOS +0.05**. + ✅ **CRITERIO SOSTITUITO, e la proposta ne esce piu' forte di prima.** La proposta e' una + **BANDA** (la cadenza settimanale e' gia' `REBAL_EVERY=5` in produzione), quindi la domanda + decidibile e' *quale banda si sceglie a cadenza di produzione guardando solo il pre-2015*: + esce **25% = la proposta**, con margine **+0.0151** di Sharpe sulla seconda (**13×** il margine + del vecchio criterio); chi avesse scelto **sull'hold-out** avrebbe preso **40%** (controllo + positivo: se coincidessero il gate non avrebbe potenza). Su **tutta** la griglia la cella al + buio e' cadenza 1 / banda **25%** — stessa banda. **La proposta e' il CONTRARIO di una + selezione-sull'hold-out.** Regge identico sull'universo a **5 gambe** (blind 25%, hold-out 40%, + margine +0.0164). ⚠️ Il criterio dice da dove VIENE la scelta, **non** che sia la migliore + sull'hold-out (con Spearman ~0 nessuna cella lo sarebbe): provenienza ≠ previsione. + ⚠️ **TROVATO PER STRADA, ed e' il difetto vero: TLT ha 13.5 ANNI DI STORIA IN MENO.** 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, cioe' quella che diversifica. Non e' + di oggi (cosi' fin dal primo giro nel `cron_daily.log`, 24/06 = **prima** della validazione del + 27/07) e **non e' un fetch da rifare**: una richiesta retro esplicita a IB su questo conto + ritorna **0 barre**. Conseguenza metodologica: **l'in-sample e l'hold-out di GTAA01 non sono la + stessa strategia**, e ogni confronto fra le due finestre su questo sleeve va letto cosi'. + ✅ **Guardia cablata** (`fetch_ib_equities.certify`, test `tests/test_eq_history_guard.py`, 11): + **`TRONCATO`** = storia persa rispetto al disco → **il file NON viene sovrascritto** (e neppure + fuso: `ADJUSTED_LAST` e' ri-aggiustato all'indietro, incollare due vintage crea un salto sul + giunto); **`STORIA-CORTA`** = parte >1 anno dopo la quotazione e non al tetto della richiesta + (`PRIMA_QUOTAZIONE`, 6 simboli, **fonte secondaria dichiarata**). Controlli positivi + obbligatori: giro normale, serie al tetto 30Y, ETF giovane, simbolo fuori tabella. + **REGOLE:** (a) **un criterio si misura sulla sua RISOLUZIONE prima che sul suo esito** — se + decide su una frazione di percento dello spread e' rumore anche quando passa; (b) **un gate si + valida contando quante volte lo passa un candidato a caso** (qui 47%: il conto si poteva fare + il 27/07 senza dati nuovi); (c) **una certificazione che guarda solo DENTRO la serie non vede + cio' che la serie ha PERSO** — una serie troncata e' integra, senza gap, senza spike, senza + duplicati, e passa tutto (3ª occorrenza dopo split 2:1 e contaminazione EUR/USD); (d) + distinguere «giovane» / «al tetto della richiesta» / «troncato», o la guardia segnala sempre e + viene ignorata; (e) **un test che fallisce senza che il codice sia cambiato sta segnalando che + i dati non sono versionati** — si guarda sotto prima di toccarlo. + Diari `2026-08-07-crescita-fisco-etf-scelta.md` §7 (scoperta) e + `2026-08-07-gate-gtaa-e-storia-troncata.md` (risoluzione). - 💰 **IL FISCO DURANTE L'ACCUMULO — mai contato in nessuna traiettoria, vale −30% a 10 anni (misurato 2026-07-27, registrato qui il 2026-08-07).** ⚠️ I quattro risultati del 27/07 sera (`r0727_3k_vs_5k.py`, `r0727_orizzonte10.py`, `r0727_tasse.py`) erano **solo nei messaggi di @@ -1649,6 +1683,56 @@ Prima ondata di ricerca onesta su BTC/ETH certificati (5 track, harness condivis comprano il **traguardo**, non il sorpasso: mediana al bersaglio al 12º anno invece del 15º, P(bersaglio) a 15a da 73.2% a **99.0%**. Lump €3k vs €5k = ~1.8 mesi ogni €1.000 → non e' una decisione. Script `scripts/research/r0807_growth_yearly.py`. + ✅ **TABELLE RIFATTE AL NETTO (2026-08-07) — il muro si sposta poco, i VERSAMENTI molto.** + `scripts/research/r0807_piano_netto.py`, test `tests/test_piano_netto.py` (16), diario + `2026-08-07-piano-al-netto.md`. **Book/pesi/cron/config INVARIATI.** + **(0) Controllo di replica superato:** a fisco spento la nuova macchina riproduce **$272.061 al + dollaro** (implementazione separata) e la colonna LORDA delle traiettorie riproduce **4 righe su + 4** della tabella pubblicata (16.3/12.4/9.0/6.0 contro 16.2/12.4/9.0/6.0). ⚠️ 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 (0.9%)**: si cita **$272k**, non $272.061. + **(1) IL MURO era calcolato con una convenzione ASIMMETRICA** — prelievo lordizzato 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%)**; a 26% $236.310. + I due errori vanno in versi OPPOSTI e **si compensano quasi — per caso, non per costruzione**. + **(2) TRAIETTORIE da $600** (25a, 3000 path, seed 725; mediana CONDIZIONATA all'arrivo + P(20a)): + | €/mese | LORDO anni / P(20a) | **NETTO anni / P(20a)** | + |---|---|---| + | 0 | mai / 0% | **mai / 0%** | + | **250** | 16.3a / **92%** | **19.8a / 52%** | + | 500 | 12.4a / 100% | **14.7a / 99%** | + | 800 | 10.0a / 100% | **11.4a / 100%** | + | 1000 | 9.0a / 100% | **10.0a / 100%** | + | 2000 | 6.0a / 100% | **6.4a / 100%** | + 📌 **€250/mese — il livello con cui il piano risultava «P 92%, funziona» — al netto e' una + moneta (52%).** + **(3) QUANTO VERSARE, al netto** (bersaglio $258.338; fra parentesi il vecchio numero lordo): + | orizzonte | P=50% | P=75% | **P=90%** | P=95% | tot. versato @P=90% | + |---|---|---|---|---|---| + | **10 anni** | €998/m | €1.162/m | **€1.323/m** *(€1.178)* | €1.424/m | **$175.058** *($155.923)* | + | 15 anni | €470/m | €570/m | **€672/m** *(€509)* | €725/m | $133.983 *($101.643)* | + | 20 anni | €245/m | €306/m | **€371/m** *(€237)* | €417/m | $98.762 *($63.406)* | + **Il fisco costa +12% al mese a 10 anni, +32% a 15, +57% a 20** (cresce con l'orizzonte perche' + l'errore era composto). La lettura del 26/07 si RAFFORZA: a 10 anni versi $175k per arrivare a + $258k (il rendimento fa il **32%**), a 20 anni ne versi $99k (il rendimento fa il **62%**). + **(4) RENDITA €/g mediana, netta** (perpetua 7.70%, imposte gia' dentro — non lordizzare due + volte): €250/m → 4.38 (5a) / 11.82 (10a) / 24.61 (15a) / **46.61 (20a)**, P(€50/g a 20a) + **42.0%** contro i **91.30 €/g e 90.0%** pubblicati; €500/m → 92.11 e 97.6%; €800/m → 146.78. + **COSA NON CAMBIA:** senza versamenti il capitale-rendita non si raggiunge **mai** a nessuna + lente fiscale; l'ordine delle leve (versare > quando > quanto presto si smette > piatto vs + crescente > frequenza) e' invariato; il rischio di venue resta fuori scala (a p=5% il mediano + e' zero comunque). + ⚠️ **ERRORE MIO catturato prima di pubblicare:** la prima stesura calcolava la mediana degli + anni sull'INTERO vettore coi non-arrivi a `-1` → €250/mese risultava passare da 15.7 a **15.3** + anni col fisco (*piu' veloce*) mentre P crollava da 91% a 53%, perche' con meta' dei path a −1 + la mediana cade sui PRIMI arrivi. **REGOLA: un non-arrivo va codificato +∞, mai −1** — con −1 il + numero migliora tanto piu' quanto peggio va la colonna. E **una mediana condizionata si stampa + sempre accanto alla sua probabilita'**. + **REGOLE:** (a) un modello che tassa una meta' del conto e non l'altra non e' conservativo, e' + **incoerente** — e i due errori possono compensarsi quasi esattamente, il che li rende + invisibili finche' non si rifa' il conto in modo simmetrico; (b) prima di pubblicare un numero + nuovo, **far riprodurre alla macchina quello vecchio**; (c) **un Monte Carlo ha una risoluzione + e va detta** ($272.061 e' esatto quanto $269.648: la differenza e' la taglia del campione). - ⚖️ **BOOK vs ETF (S&P 500 / MSCI World) — le due lenti danno risposte OPPOSTE, e la scelta robusta e' un MIX 50/50 (2026-08-07).** Script `r0807_asset_compare.py` + `r0807_best_strategy.py`; diario `2026-08-07-crescita-fisco-etf-scelta.md`. **Book/pesi/cron/config INVARIATI.**