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>
This commit is contained in:
@@ -1611,6 +1611,108 @@ 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.
|
||||
- 💰 **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
|
||||
commit**, ne' in CLAUDE.md ne' in un diario — e uno cambia il numero di testa del piano.
|
||||
`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 €5.000 + €500/mese): −15.7% a 5 anni · −29.8% a 10 · −42.6% a 15**
|
||||
(27/07 su lump €10k: −16.8 / −31 / −44% → replica coerente). **L'errore e' COMPOSTO.**
|
||||
⚠️ **Conseguenza: TUTTE le tabelle a 15-20 anni pubblicate sopra sono al LORDO** del fisco
|
||||
d'accumulo e vanno lette con questo sconto. Assunzioni dichiarate (33% plusvalenze, minusvalenze
|
||||
in carry 4 anni, 0.2% annuo sul valore), **non un parere fiscale**; il modello tassa la variazione
|
||||
ANNUA di valore = limite superiore, stretto perche' il book realizza quasi tutto entro l'anno.
|
||||
**Vincolo dei 10 anni (operatore, 49 anni): il piano NON lo regge.** €5k+€500/m → P(entro 10a)
|
||||
**19.7%** al lordo; €10k+€500/m → 33.9% lordo ma **3.8% col fisco**. Servono **€880/mese a P=50%**,
|
||||
**€1.051 a P=75%** (lump €10k) → si versano oltre $119.000 per arrivare a $272.061: *a orizzonte
|
||||
corto non fai lavorare la strategia, compri il capitale coi bonifici*.
|
||||
📌 **Contro-intuitivo: versare di piu' RITARDA il sorpasso** (l'anno in cui il guadagno cumulato
|
||||
supera tutto il versato): 7º anno a €500/m, **8º a €800/m** — alza l'asticella. I €300 in piu'
|
||||
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`.
|
||||
- ⚖️ **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.**
|
||||
Tre cose rese comparabili: **griglia** (azioni su calendario con 0.0 a borsa chiusa = convenzione
|
||||
GTAA01; senza, Sharpe ×1.20 — lezione 25/07), **fisco** (book realizza ogni anno al 33%; UCITS ad
|
||||
accumulazione paga 26% **alla vendita** → le curve ETF sono valori di *liquidazione*: il
|
||||
differimento e' un vantaggio strutturale dell'ETF ed e' nel modello), **bersaglio** ($272.061 vale
|
||||
per la rendita perpetua *del book* e per il 33% → ricalcolato per ciascuno).
|
||||
| a 15a, €5k+€500/m | book | S&P 500 | MSCI World (proxy) |
|
||||
|---|---|---|---|
|
||||
| rendita perpetua | 11.67% | 4.16% | 3.09% |
|
||||
| capitale-rendita | $254.524 | $646.172 | $869.729 |
|
||||
| lente A (storia piena) | $293.823 → **115%** | $204.663 → 32% | $188.417 → 22% |
|
||||
| lente B (stessa finestra) | $295.540 → 118% | $343.805 → **110%** | $296.707 → 82% |
|
||||
📌 **Il risultato non e' chi vince, e' che le due lenti si contraddicono:** sulla storia piena il
|
||||
book stravince, **sulla stessa finestra l'S&P 500 accumula PIU' del book** — il divario della
|
||||
lente A e' tutto nei crolli 2000/2008 che la strategia non ha mai vissuto.
|
||||
📌 **E sulla stessa finestra il rendimento e' quasi identico — 17.4% contro 16.8%.** Tutta la
|
||||
differenza e' 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,
|
||||
misurata contro un'alternativa vera. La rendita perpetua vive sul drawdown → **2.5× meno capitale**.
|
||||
⚠️ **Un MIX esiste solo dove esistono ENTRAMBE le serie** (errore commesso e corretto: la lente
|
||||
"storia piena" calcolava i bersagli del mix sull'intersezione → dichiarava 30 anni e ne usava 7).
|
||||
Percio' la scelta si giudica su UNA finestra con gli scenari espressi come spostamento del
|
||||
**drift**, simmetrico sui due lati. **A 12 anni, quota del proprio bersaglio:**
|
||||
| w book | base | equity 30a | book/2 | entrambi cauti | peggiore | **rimpianto max** |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 0% | 68% | 23% | 68% | 23% | 23% | 53% |
|
||||
| 25% | 80% | 41% | 60% | 27% | 27% | 34% |
|
||||
| **50%** | **86%** | 58% | 48% | 27% | 27% | **20%** |
|
||||
| 75% | 84% | 69% | 32% | 23% | 23% | 35% |
|
||||
| 100% | 75% | **75%** | 16% | 16% | 16% | 52% |
|
||||
**Risposta: 50/50** — non perche' vinca (vince solo nel base) ma per il **rimpianto minimo**.
|
||||
⚠️ Il criterio del solo caso peggiore **non** distingue 25% da 50% (27.09 vs 26.99% = pareggio
|
||||
dentro il rumore): a separarli e' il rimpianto.
|
||||
📌 **L'asimmetria fra i due stress E' il risultato:** quello sull'equity e' **MISURATO** (30 anni
|
||||
esistono: 11.3% invece di 16.5%), quello sul book e' **GIUDIZIALE** (meta' del drift, a mano,
|
||||
perche' 7.4 anni sono tutta la storia che ha e non c'e' nulla con cui stressarlo). Conseguenza
|
||||
brutale: col drift dimezzato il capitale-rendita del book puro passa da $254k a **$771.646**
|
||||
(rendita 11.67% → 3.85%).
|
||||
**Perche' il mix non e' un compromesso:** corr book↔S&P **+0.082** (borsa aperta), **+0.046** nei
|
||||
ribassi; nel 5% di giornate peggiori dell'indice (media −2.94%) il book fa **−0.11%** → il
|
||||
capitale-rendita del 50/50 e' **$235.769**, piu' basso sia del solo ETF ($311.567) sia del solo
|
||||
book ($254.524): **due motori scorrelati abbassano l'asticella**.
|
||||
⚠️ MSCI World e' un **PROXY** 70% SPY + 30% EFA (URTH/ACWI/VT non sono nell'abbonamento dati IB);
|
||||
fra 50 e 80% di quota USA il drift si muove di 0.7pt e il Sharpe di 0.05. Il rischio di venue NON
|
||||
e' nel conto (spingerebbe ancora verso il mix) e la decisione del 26/07 tiene tutto su Deribit
|
||||
fino a $20k → **questa analisi e' materiale per quella soglia, non un'indicazione di agire ora**.
|
||||
- 🖥️ **SIMULATORE NEL BROWSER — `scripts/web/` (2026-08-07).** Motore di accumulo in JavaScript
|
||||
(`engine.js`) sui ritorni veri del book esportati da `export_series.py`; pagine assemblate da
|
||||
`build.py` (dati **iniettati** da JSON, mai trascritti); `test_engine.js` prova che il motore
|
||||
riproduce `r0807_growth_yearly.py` e `dep_necessario`; `smoke.js` ESEGUE le pagine con un DOM
|
||||
finto. **REGOLE (quattro errori miei, tutti trovati da un controllo e non a occhio):**
|
||||
(a) i dati di una pagina si **iniettano da un file**, mai si trascrivono — due anni di una serie
|
||||
erano stati scritti *a memoria* perche' `tail` aveva troncato l'output;
|
||||
(b) **un confronto punto-contro-distribuzione non prova una distorsione**: "8 semi JS tutti sopra
|
||||
il Python, +0.75%" erano 8 estrazioni contro UN punto rumoroso → misurato bene (8 semi per parte)
|
||||
**−0.01%, t = −0.04**, ed entrambi i campionatori entro 1.7 SE dall'atteso ANALITICO;
|
||||
(c) le chiavi di un dizionario Python si **leggono dal JSON**, non si ricostruiscono
|
||||
(`"0.0"` vs `String(0)`=`"0"` → pagina pubblicata rotta, e i pesi intermedi funzionavano *per caso*);
|
||||
(d) **`node --check` valida solo la SINTASSI**: una pagina puo' passarlo e morire alla prima riga.
|
||||
Misura che ha guidato una scelta: 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) → percorsi
|
||||
tenuti bassi e incertezza **dichiarata**.
|
||||
- **Soffitto strutturale BTC/ETH-direzionale ~1.3** superato SOLO espandendo a un meccanismo diverso:
|
||||
cross-sectional su universo Hyperliquid certificato (XS01) → portafoglio Sharpe ~1.55.
|
||||
- **Sweep "strategie alternative" (2026-06-20) — 104 ipotesi / 153 agenti / NIENTE di nuovo regge.**
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
# 2026-08-07 — La crescita del capitale, il fisco che nessuno aveva contato, e se invece fosse un ETF
|
||||
|
||||
**Richieste dell'operatore, in sequenza:** *«stato progetto»* → *«riepiloga piano»* → *«grafico della
|
||||
crescita per anno con versamento e con guadagno»* → *«con 800 al mese»* → *«sistema dinamico dove
|
||||
imposti valore iniziale, mensile e durata, e calcola la best curva fissando il tempo»* → *«il
|
||||
guadagno come viene calcolato? e se mettessi in MSCI World o ETF SP500?»* → *«quale è la miglior
|
||||
strategia?»*.
|
||||
|
||||
**Esito: book, pesi, cron, config INVARIATI.** Nessuna decisione operativa cambia. Cambiano tre
|
||||
numeri pubblicati e cade un'affermazione su GTAA01.
|
||||
|
||||
---
|
||||
|
||||
## 0. Il buco trovato per primo: quattro risultati mai registrati
|
||||
|
||||
Ricostruendo il piano per l'operatore ho scoperto che **quattro commit del 27/07 sera non sono né
|
||||
in CLAUDE.md né in un diario**: vivono solo nei messaggi di commit e negli script
|
||||
(`r0727_3k_vs_5k.py`, `r0727_orizzonte10.py`, `r0727_tasse.py`). Uno di questi cambia il numero di
|
||||
testa del piano — vedi §2. È il motivo per cui questo diario esiste prima ancora del lavoro nuovo.
|
||||
|
||||
---
|
||||
|
||||
## 1. Come si calcola il «guadagno» — la domanda che andava fatta
|
||||
|
||||
Nessuna traiettoria del progetto ipotizza un rendimento. Il meccanismo, ora scritto:
|
||||
|
||||
1. si parte dai ritorni giornalieri **veri** del book live (TP01 75% + SKH01 25%), 2.692 giorni dal
|
||||
2019-03-14, già netti di commissioni;
|
||||
2. si toglie la fortuna d'ancora: `r − (1−0.89)·media(r)`;
|
||||
3. si **rimescolano a blocchi di 20 giorni** (block bootstrap): blocchi, non giorni singoli, per
|
||||
non distruggere il raggruppamento della volatilità;
|
||||
4. si compone: `cap *= (1+r)` ogni giorno, deposito ogni 30, imposta a fine anno, su 4.000 percorsi;
|
||||
5. **`guadagno = mediana(capitale) − versato`**.
|
||||
|
||||
Drift implicito: **17,1% annuo, vol 10,9%**. Non è un'assunzione sul rendimento — è l'assunzione
|
||||
che *il futuro somigli a quei 7 anni*. Che è esattamente ciò che §3 mette alla prova.
|
||||
|
||||
Script: `scripts/research/r0807_growth_yearly.py` (`--lump`, `--dep`, `--anni`, `--json`).
|
||||
|
||||
---
|
||||
|
||||
## 2. ⚠️ Il fisco durante l'ACCUMULO — la voce mai contata
|
||||
|
||||
`TAX_RATE` compariva in **un solo punto** di tutto il progetto: la lordizzazione del bersaglio in
|
||||
fase di *prelievo*. L'accumulo componeva al lordo per dieci o vent'anni. Misurato il 27/07
|
||||
(`r0727_tasse.py`) e riprodotto oggi su lump €5.000 + €500/mese:
|
||||
|
||||
| | 5 anni | 10 anni | 15 anni |
|
||||
|---|---|---|---|
|
||||
| costo del fisco d'accumulo | **−15,7%** | **−29,8%** | **−42,6%** |
|
||||
|
||||
(27/07, lump €10k: −16,8% / −31% / −44% → replica coerente su lump diverso.)
|
||||
|
||||
**L'errore è composto, non una tantum.** Conseguenza da tenere presente: *tutte* le tabelle a 15-20
|
||||
anni pubblicate in CLAUDE.md sono al lordo del fisco d'accumulo e vanno lette con questo sconto
|
||||
sopra. Assunzioni dichiarate (33% plusvalenze, minusvalenze in carry 4 anni, 0,2% annuo sul valore),
|
||||
**non un parere fiscale**.
|
||||
|
||||
Piano a €800/mese, 15 anni: capitale mediano **$450.107** netto contro $776.366 lordo.
|
||||
|
||||
📌 **Risultato contro-intuitivo:** versare di più **ritarda il sorpasso** (l'anno in cui il guadagno
|
||||
cumulato supera tutto il versato): 7º anno a €500/mese, 8º a €800, perché si alza l'asticella che
|
||||
il guadagno deve superare. I €300 in più non comprano il sorpasso, comprano il **traguardo**: la
|
||||
mediana tocca il bersaglio al 12º anno invece che al 15º, e P(bersaglio) a 15 anni passa da 73,2% a
|
||||
99,0%.
|
||||
|
||||
⚠️ **€800/mese non bastano per il vincolo dei 10 anni**: P(entro 10 anni) col fisco = **25,5%**.
|
||||
Servono ~€880-1.050/mese (27/07), e a quel punto si versano oltre $119.000 per arrivare a $272.061.
|
||||
|
||||
---
|
||||
|
||||
## 3. E se invece fosse un ETF S&P 500 o MSCI World
|
||||
|
||||
Script `scripts/research/r0807_asset_compare.py`. Tre cose andavano rese comparabili:
|
||||
|
||||
- **la griglia** — le azioni hanno ~252 barre/anno, il book 365: portate su calendario con **0,0 a
|
||||
borsa chiusa** (convenzione GTAA01). Senza, il Sharpe esce ×1,20 (lezione 25/07);
|
||||
- **il fisco** — il book realizza ogni anno al 33%; un UCITS ad accumulazione paga il 26% **alla
|
||||
vendita**. Il differimento è un vantaggio strutturale dell'ETF, ora nel modello (le curve ETF
|
||||
sono valori di *liquidazione*, già al netto dell'imposta latente);
|
||||
- **il bersaglio** — $272.061 vale per la rendita perpetua *del book* e per il 33%. Ricalcolato per
|
||||
ciascuno.
|
||||
|
||||
| a 15 anni, €5.000 + €500/mese | book | S&P 500 | MSCI World (proxy) |
|
||||
|---|---|---|---|
|
||||
| rendita perpetua | 11,67% | 4,16% | 3,09% |
|
||||
| capitale-rendita necessario | $254.524 | $646.172 | $869.729 |
|
||||
| **lente A** — storia piena di ciascuno | $293.823 → **115%** | $204.663 → **32%** | $188.417 → 22% |
|
||||
| **lente B** — stessa finestra 2019-26 | $295.540 → **118%** | $343.805 → **110%** | $296.707 → 82% |
|
||||
|
||||
**Il risultato che conta non è quale vince, è che le due lenti danno risposte opposte.** Sulla
|
||||
storia piena il book stravince; sulla stessa finestra **l'S&P 500 accumula più del book**. Il
|
||||
divario della lente A viene interamente dal fatto che i 30 anni dell'indice contengono il 2000 e il
|
||||
2008, crolli che la strategia non ha mai vissuto.
|
||||
|
||||
📌 **E in una riga della tabella delle serie c'è il fatto più importante:** sulla stessa finestra il
|
||||
rendimento è quasi identico — **17,4% contro 16,8%**. Tutta la differenza è nel rischio: vol 11,0%
|
||||
contro 19,6%, maxDD 10,5% contro 33,7%. **Il book non guadagna di più, perde di meno** — che è
|
||||
precisamente ciò che il progetto scrive di TP01 dal 19/06, qui misurato contro un'alternativa vera.
|
||||
E la rendita perpetua vive sul drawdown: per questo il book ha bisogno di **2,5× meno capitale**.
|
||||
|
||||
⚠️ MSCI World è un **proxy** (70% SPY + 30% EFA): URTH/ACWI/VT non sono nell'abbonamento dati del
|
||||
conto IB. Fra 50% e 80% di quota USA il drift si muove di 0,7 punti e il Sharpe di 0,05.
|
||||
|
||||
---
|
||||
|
||||
## 4. Quale strategia: book, ETF o un mix
|
||||
|
||||
Script `scripts/research/r0807_best_strategy.py`.
|
||||
|
||||
⚠️ **Difetto della prima stesura, corretto: un mix esiste solo dove esistono ENTRAMBE le serie.**
|
||||
Confrontavo «storia piena» contro «stessa finestra» come due lenti, ma calcolavo i bersagli del mix
|
||||
sull'intersezione in entrambe — quindi la lente «storia piena» dichiarava trent'anni e ne usava
|
||||
sette (per l'ETF puro dava rendita 8,63% invece del 4,16% vero). **Il confronto fra finestre non è
|
||||
disponibile per un portafoglio misto.** Rifatto su una finestra sola, con gli scenari espressi come
|
||||
spostamento del **drift**, applicabile simmetricamente ai due lati.
|
||||
|
||||
| quota sul book | base | equity a 30 anni | book dimezzato | entrambi cauti | peggiore | **rimpianto max** |
|
||||
|---|---|---|---|---|---|---|
|
||||
| solo ETF | 68% | 23% | 68% | 23% | 23% | 53% |
|
||||
| 25% book | 80% | 41% | 60% | 27% | 27% | 34% |
|
||||
| **50% book** | **86%** | 58% | 48% | 27% | 27% | **20%** |
|
||||
| 75% book | 84% | 69% | 32% | 23% | 23% | 35% |
|
||||
| solo book | 75% | **75%** | 16% | 16% | 16% | 52% |
|
||||
|
||||
**Risposta: 50/50**, non perché vinca (vince solo nello scenario base) ma perché ha il **rimpianto
|
||||
massimo più basso**. ⚠️ Il criterio del solo caso peggiore **non** distingue 25% da 50% (27,09%
|
||||
contro 26,99% = pareggio dentro il rumore): a separarli è il rimpianto.
|
||||
|
||||
📌 **L'asimmetria fra i due stress È il risultato.** Quello sull'equity è **misurato** — trent'anni
|
||||
esistono e dicono 11,3% invece di 16,5%. Quello sul book è **giudiziale** — metà del drift, scelto a
|
||||
mano, perché 7,4 anni sono tutta la storia che ha e *non c'è nulla con cui stressarlo*. Si può
|
||||
discutere la taglia del taglio, non lo si può togliere. La sua conseguenza è brutale: col drift
|
||||
dimezzato il capitale-rendita del book puro passa da $254k a **$771.646** (rendita 11,67% → 3,85%).
|
||||
|
||||
**Perché il mix non è un compromesso:** correlazione book↔S&P **+0,082** nei giorni di borsa aperta,
|
||||
**+0,046** nei ribassi; nel 5% di giornate peggiori dell'indice (media −2,94%) il book fa **−0,11%**.
|
||||
Il capitale-rendita del 50/50 è **$235.769**, più basso sia del solo ETF ($311.567) sia del solo
|
||||
book ($254.524): due motori scorrelati *abbassano l'asticella*.
|
||||
|
||||
⚠️ Non c'è il rischio di venue (spingerebbe ancora verso il mix), e la decisione del 26/07 tiene
|
||||
tutto su Deribit fino a $20k: questa analisi è **materiale per quella soglia**, non un'indicazione
|
||||
di agire adesso.
|
||||
|
||||
---
|
||||
|
||||
## 5. Il simulatore nel browser, e la sua verifica
|
||||
|
||||
`scripts/web/` — motore di accumulo in JavaScript (`engine.js`), serie esportata da
|
||||
`export_series.py`, pagine assemblate da `build.py`.
|
||||
|
||||
**Il motore JS deve dare la stessa risposta del Python, e lo si prova:** `test_engine.js` confronta
|
||||
mediane e probabilità su due configurazioni già calcolate, verifica che il *versato* (deterministico)
|
||||
coincida al centesimo, e include un **controllo positivo** (un motore col fisco spento dev'essere
|
||||
rilevato fuori tolleranza — un test che non sa fallire non è un test). Il risolutore («quanto serve
|
||||
al mese per centrare il bersaglio in N anni») è validato contro `dep_necessario` di `r0727_tasse.py`:
|
||||
scarti −0,4% / −0,6% / −1,1% su tre configurazioni.
|
||||
|
||||
Misura che ha cambiato una scelta: la banda del versamento suggerito resta **±1% da 1.200 a 3.000
|
||||
percorsi** → non domina il Monte Carlo ma la granularità della bisezione (~€5). Percorsi tenuti
|
||||
bassi e **incertezza dichiarata**, invece di pagare tempo per una precisione che non arriva.
|
||||
|
||||
---
|
||||
|
||||
## 6. Quattro errori miei, tutti trovati da un controllo e non a occhio
|
||||
|
||||
Sono la parte riutilizzabile del diario.
|
||||
|
||||
**(a) Dati inventati in un grafico.** Le righe degli anni 1-2 di una serie erano scritte *a memoria*
|
||||
perché l'output del terminale era troncato da `tail`. Le ha trovate il confronto riga-per-riga fra
|
||||
il JSON e i dati incollati nella pagina. **Regola: i dati di una pagina si INIETTANO da un file, mai
|
||||
si trascrivono** — ora è `build.py` a farlo, e il passaggio manuale non esiste più.
|
||||
|
||||
**(b) «Distorsione sistematica» che non esisteva.** Il motore JS sembrava +0,75% sopra il Python su
|
||||
8 semi, tutti positivi. Ma erano **8 estrazioni contro UN solo punto Python** (seme 807), che stava
|
||||
in basso nella propria distribuzione: 8 segni concordi rispetto a un punto rumoroso non sono 8
|
||||
osservazioni indipendenti. Misurato bene (8 semi per parte): **−0,01%, t = −0,04**; e i due
|
||||
campionatori cadono entrambi entro 1,7 SE dall'**atteso analitico** della media di blocco.
|
||||
**Regola: un confronto punto-contro-distribuzione non produce evidenza di distorsione.**
|
||||
|
||||
**(c) Un confronto impossibile per costruzione** — §4, il mix sull'intersezione.
|
||||
|
||||
**(d) Una pagina pubblicata rotta.** Python scrive le chiavi dei pesi come `"0.0"`/`"1.0"`, la pagina
|
||||
le ricostruiva con `String(0)` → `"0"`: ogni lookup `undefined`, script morto alla prima riga utile.
|
||||
I pesi intermedi funzionavano *per caso*. **Il controllo che usavo (`node --check`) valida solo la
|
||||
SINTASSI**: ora c'è `smoke.js`, che esegue le pagine con un DOM finto e segnala sia le eccezioni sia
|
||||
gli elementi riempiti con `"undefined"`. **Regola: le chiavi di un dizionario Python si LEGGONO dal
|
||||
JSON, non si ricostruiscono.**
|
||||
|
||||
---
|
||||
|
||||
## 7. ⚠️ Effetto collaterale del check: un gate di GTAA01 ora FALLISCE
|
||||
|
||||
`tests/test_gtaa_band_gate.py::test_la_proposta_non_e_selezionata_sull_hold_out` — la proposta
|
||||
(banda 25%, cadenza 5g) risulta **9ª/30 in-sample e 8ª/30 sull'hold-out**: migliora passando
|
||||
all'hold-out, cioè la firma che il test intercetta. CLAUDE.md registra **4/30 e 5/30** (27/07).
|
||||
|
||||
Caratterizzato prima di riportarlo:
|
||||
|
||||
- i due ranghi sono separati da **0,00116 di Sharpe** su un'ampiezza di griglia di 0,3124 = lo
|
||||
**0,4%**: il criterio non ha mai avuto margine, era una differenza di un rango;
|
||||
- il calcolo è **deterministico** (due corse, `max|diff| = 0.0`) e il codice del gate è **invariato**
|
||||
dal 27/07 (nessun commit su `r0727_gtaa_band_gate.py`, `gtaa.py`, `eqlib.py`, `eq_splits.py`);
|
||||
- quindi è cambiato **il dato**: `data/raw/` è gitignored e i parquet equity vengono riscritti ogni
|
||||
giorno dal cron con `ADJUSTED_LAST` di IB, che è retroattivo.
|
||||
|
||||
📌 **La lezione vale più del test: un gate validato su dati sovrascritti ogni giorno non è
|
||||
ri-verificabile.** Il lato cripto non ha questo problema (`rebuild_history.py` ricostruisce da una
|
||||
sorgente deterministica); il lato equity sì.
|
||||
|
||||
**Il test NON è stato toccato** — allentare una soglia perché ha smesso di passare è ciò che questo
|
||||
progetto vieta, e un `xfail` silenzierebbe esattamente il segnale. Nulla di operativo dipende da
|
||||
questo (GTAA01 non è deployabile per il blocco PRIIPs e non è nel book live), ma l'affermazione
|
||||
*«il rango NON migliora sull'hold-out»* oggi è falsa: **decisione dell'operatore** se correggere
|
||||
l'affermazione, ripensare il gate, o congelare uno snapshot dei parquet equity per renderlo
|
||||
riproducibile.
|
||||
|
||||
---
|
||||
|
||||
## Cosa NON cambia
|
||||
|
||||
Book, pesi, cron, `config/live.json`, i gate pre-registrati (STATARB 27/09, XSR01 23/10,
|
||||
DVOLSPREAD 24/10), la decisione di venue (100% Deribit fino a $20k), il muro pubblicato di
|
||||
$272.061. Gli script di questo diario non toccano la produzione.
|
||||
Reference in New Issue
Block a user