ricerca: XSR01 sotto la lente RENDITA (filone 70) + cosa compra un versamento da $3k

XSR-RENDITA (r0825_xsr_rendita.py): prima valutazione di XSR01 sul criterio della
perpetua. A iso-nozionale alza il muro; a iso-rischio lo abbassa del 20,6% MA il null
mostra che il meccanismo vale 0,8% (mescolare i rendimenti non cambia nulla) e un
conto remunerato allo stesso tasso lo eguaglia a vol zero senza secondo venue.
A drift zero il muro SALE: si compra un drift scorrelato, non la scorrelazione.
L'haircut non pareggia un conto al 4% nemmeno a zero. Vincolo binding: capitale
($60k per un 25% sopra C*). Corretta in CLAUDE.md la riga Sharpe 1,82 (terza lente;
la lente dei gate da' 1,79 alla scoperta / 1,56-1,63 a oggi).

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
This commit is contained in:
Adriano Dal Pastro
2026-08-26 06:56:40 +00:00
parent 4f91b25b72
commit f10d847816
7 changed files with 789 additions and 2 deletions
+10 -2
View File
@@ -17,7 +17,7 @@ chi la riapre deve battere il motivo, non ripetere la misura.
| `docs/memory/40-produzione-e-deploy.md` | esecutore, tripwire, monitor, libro di bordo, PRIIPs/UCITS | tocchi cio' che gira con soldi veri |
| `docs/memory/50-dati-e-feed.md` | difetti del dato trovati e riparati, catena opzioni | tocchi i feed |
| `docs/memory/60-metodo-e-gate.md` | i gate codificati in `altlib.py` | valuti un candidato |
| `docs/research/RESULTS-0822.md` | registro per filone §1-69 | vuoi il dettaglio di un filone |
| `docs/research/RESULTS-0822.md` | registro per filone §1-70 | vuoi il dettaglio di un filone |
| `docs/diary/` (123 voci) | la sessione originale, per data | vuoi il contesto completo |
---
@@ -91,6 +91,7 @@ sono all'ancora fortunata; le stime oneste sono la **mediana della banda d'ancor
| VRP01 | f = 1,00 | **f = 0,73** misurato sulle quote reali (IC95 [0,698; 0,780]) |
| muro capitale-rendita | $272k (lordo) | **$313k** al netto di fisco **e** funding — banda **[$187k $1,14M]** |
| P(≥50 €/g), canale funded, 36 mesi | 42% | **2,6%** [1,5 4,7], P(zero) 40,3% |
| XSR01 | Sharpe 1,82 (e' una **terza** lente, divisore fisso 50) | **1,79** alla scoperta / **1,56-1,63** a oggi — lente dei gate, sole barre chiuse. Citare sempre la coppia (lente, ultima barra chiusa) |
| soffitto direzionale BTC/ETH | ~1,3 | **~1,15** col funding dentro |
📌 **Il libro a k=1 rende MENO dell'S&P 500** (15,19% contro 17,40%, stessa finestra): il vantaggio
@@ -161,12 +162,19 @@ sull'hold-out; cambiarne le soglie guardando l'esito, pure.
| gate | data | criterio | stato |
|---|---|---|---|
| **STATARB** | 2026-09-27 | soglie 24/07 (non toccate) + diagnostica statica sempre-short | 🚨 **si ribalta col difetto `advance()`**: riparata → RITIRO, attuale → candidato |
| **XSR01** | 2026-10-23 | Sharpe ≥1,0 **E** haircut a $5.000 ≤40% (se sfonda → ritiro a prescindere), poi `weights_tilt_null` e capitale ≥$5k | 🚨 legge un monitor **mal tarato** (vedi §5.3) |
| **XSR01** | 2026-10-23 | Sharpe ≥1,0 **E** haircut a $5.000 ≤40% (se sfonda → ritiro a prescindere), poi `weights_tilt_null` e capitale ≥$5k | 🚨 legge un monitor **mal tarato** (§5.3), e P(capitale ≥$5k quel giorno) = **0,0%** (mediana $2.635) → **il criterio di capitale non e' raggiungibile**. Sotto la lente RENDITA il sleeve e' **eguagliato da un conto remunerato** (📌 sotto) |
| **DVOLSPREAD** | kill 2026-10-24 se Sh<0,50; decisione 2027-01-24 | (a) Sharpe>0 (b) marginale ADDS+robust_oos+insample_edge (c) **DSR ≥0,95** (d) `weights_tilt_null`; **veto** se barre attive <80% → si estende, non si decide | il veto **non scatta** su una serie che registra 2 min/giorno (§5.1) |
| **GATE PROP-01** | chiuso 22-23/08 | (a) listino 13/13 ✅ (b) ancora SKH01 23/23 ✅ (c) economica+sopravvivenza 2/2 ✅ | **chiuso 3/3** — ma il numero operativo e' sceso 42% → 7,8% → 4,4% → 2,6% |
| **GATE PREVDAY-01** | scritto 23/08 | 10 condizioni | **8/10**: la cella che GIRA non e' quella che la selezione onesta sceglie, e quella viva **fallisce il DSR** (0,905) |
| **`edge_watch`** (kill del book live) | continuo | **(A)** Sharpe rolling 36m < 0,5 → si riapre `weights_tilt_null`+DSR, il book **non si spegne da solo**; **(B)** in un anno con DD buy&hold >10%, il DD di TP01 deve restare <75% di quello | stato 27/07: Sharpe 36m +1,51, protezione **8/8** |
📌 **XSR01 sotto la lente RENDITA (25/08): il meccanismo vale ~0.** Mescolarne i rendimenti da' lo
stesso muro ($476-484k contro $478,7k), e un **conto remunerato** allo stesso tasso (3,72%, vol 0, corr 0,
nessun secondo venue) da' **$477,6k** — identico dentro la risoluzione MC, e **meglio** al 4,0%. Cio' che
si compra e' un **drift scorrelato**, non la scorrelazione (a drift zero il muro SALE). E l'haircut lo
mangia: **non pareggia un conto al 4% nemmeno a haircut ZERO**; pareggia il 2% solo sotto il 46%.
Per un 25% sopra il C\* vero servono **$60.000** di conto. `r0825_xsr_rendita.py`.
📌 **Un gate superato non e' un numero confermato:** differenze e livelli ereditano la fortuna
d'ancora in modo diverso (nella differenza si cancella in parte, nel livello per niente).
+38
View File
@@ -0,0 +1,38 @@
# 2026-08-25 — Il versamento da $3.000: cosa compra, e cosa NON compra
**Domanda dell'operatore:** *"rianalizza e vediamo come procedere. potrei versare a breve altri 3k"*.
**Script:** `scripts/research/r0825_versamento_3k.py` (lente L3, stessi semi e path del piano:
tutto appaiato, M22). Assunzioni dichiarate: 3k = $3.000 USDC, lump oggi, start $2.065 (watermark
18:47:13Z). Controllo M23: da $2.065 il 10a riproduce $114.929 contro i $114.934 pubblicati da
$2.067 — la macchina riproduce il numero vecchio.
## Cosa compra (€500/mese, appaiato sugli stessi path)
| orizzonte | senza lump | con lump | Δ | €/g con lump | P(≥50€/g) |
|---|---|---|---|---|---|
| 5a | $44.921 | $49.730 | +10,7% | 7,94 | 0% |
| 10a | $114.929 | $122.491 | +6,6% | 19,56 | 0% |
| 15a | $228.770 | $241.490 | +5,6% | 38,56 | 12,3% → 17,3% |
| 20a | $408.105 | $427.738 | +4,8% | 68,30 | 79,4% → 83,9% |
Il lump = **5,5 mesi di versamenti anticipati in un colpo** (N3: e' la prima leva, esercitata).
Pietre miliari con €500/mese: $15k (C\* Hyperliquid) 1,7a → **1,3a**; $20k (si riapre la scelta
del venue) 2,4a → **1,9a**.
## L'effetto collaterale che conta: il gate XSR01 del 23/10 si RIBALTA
P(capitale ≥$5k al 23/10): **0,0% → 100,0%** (mediana $5.664, p10 $5.417). Senza lump il gate
moriva da solo sul criterio di capitale e i suoi tre difetti erano accademici. Col lump il
criterio formale **passa**, e la decisione poggerebbe per intero su:
(a) il monitor rotto che registra ~41 min/giorno (§5.1); (b) l'haircut col pavimento sbagliato
di 5-7× (§5.3); (c) un C\* vero $15-20k contro i $1.266 che il 25% di $5.065 mette sul venue.
**Il lump rende il gate LEGGIBILE senza rendere XSR01 comprabile** — il caso peggiore per un
criterio scritto male. La scelta fra riscrivere adesso (dichiarandolo) e lasciare-e-citare va
presa **prima** che il lump atterri, non il 23/10.
## Meccanica live a $5.065 — niente da toccare
cap per-asset $1.032 → $2.532 (equity×0,5, si adegua da solo); min_order $5 dal 0,48% al 0,20%
del cap (C2); fallback min($3.000, wm×0,5) = $2.532; disaster-SL invariato (e il nome continua a
ingannare). ⚠️ **Slip-audit da rifare** dopo i primi fill: misurato su $597-2.067, a $5k la taglia
relativa raddoppia — lo script con normalizzazione per-fill c'e' gia'.
@@ -0,0 +1,114 @@
# 2026-08-25 — XSR01 sotto la lente della RENDITA: e' un conto deposito con un secondo venue
**Domanda dell'operatore:** *"rendita perpetua ma non ho ancora capito se serve XSR01"*.
**Script:** `scripts/research/r0825_xsr_rendita.py` (N11: ogni numero qui sotto lo riproduce).
## Perche' era una misura nuova
XSR01 era stato giudicato tre volte — ammissione (25/07), gate di deploy pre-registrato (23/10),
accumulo (oggi) — e **mai sotto la lente della rendita**. Sono criteri diversi: l'accumulo premia
il **drift**, la rendita premia la **perpetua** (il prelievo piu' alto che sopravvive a 20 anni con
P≥90%). Dichiarato l'obiettivo (N6), il criterio cambia, e nessuno aveva rifatto il conto.
## Cosa mi aspettavo prima di misurare (M12)
(a) a iso-nozionale il mix perde drift e **alza** il muro; (b) a iso-rischio (M6) il verdetto puo'
**ribaltarsi**; (c) il vincolo che decide non sara' ne' (a) ne' (b) ma il **capitale**.
**Tutte e tre vere** — ma (c) e' arrivata con una gamba che non avevo previsto: il null.
## Le serie, e la finestra in cui esistono entrambe
| serie | finestra | drift/a | vol/a | Sharpe | maxDD | SE drift |
|---|---|---|---|---|---|---|
| libro L3 — **tutta** la storia | 2019-03-14 → 2026-08-22 | 15,19% | 11,29% | 1,35 | 12,4% | 5,19% |
| libro L3 — finestra comune | 2024-01-01 → 2026-08-22 | 10,96% | 10,14% | 1,08 | 8,6% | 7,97% |
| XSR01 — finestra comune | idem (965 g, 2,64 anni) | **3,72%** | 2,34% | 1,59 | 2,5% | 1,46% |
corr libro↔XSR01 **+0,049**. Finestra comune = **35%** della storia del libro → **il muro calcolato
qui NON e' il $313k pubblicato**: si confronta solo con se stesso (base $602.660).
📌 Sharpe di XSR01 a oggi, **lente dei gate, sole barre chiuse: 1,56** — il "1,82" pubblicato e' una
**terza** lente (XSR-REPRO, 22/08). Si cita sempre la coppia (lente, ultima barra chiusa).
## (2) iso-nozionale — XSR01 ALZA il muro
w 5→50%: muro da $604k a $668k (**+0,3% → +10,8%**). Il mix e' piu' liscio ma piu' povero, e per
una rendita il drift comanda. **A iso-nozionale XSR01 peggiora l'obiettivo dichiarato.**
## (3) iso-rischio (M6) — si ribalta, e sale il sospetto
Ri-scalando ogni mix a `vol(libro)`: w 25% → k **1,32x**, muro **$478.729 (20,6%)**.
⚠️ **L'argmax e' al BORDO** (w=50%, k=1,93x): il muro scende **monotonamente** in w, quindi la
griglia non indica un ottimo, dice *"il piu' possibile"* — e cio' che si compra in quella direzione
e' il **k**, non XSR01 (M8). Sopra 1,40x il libro **non puo' eseguire** (decisione 23/08, e in
`config/live.json` non esiste una chiave di scala). Peso portato avanti: **25%, k 1,32x**.
## (3b) IL NULL — ed e' il risultato della sessione
A iso-vol vale `drift = Sharpe × vol_libro`: la colonna "drift" della sezione (3) **e' la colonna
"Sharpe" ri-etichettata**. Tutto il guadagno di muro e' guadagno di **Sharpe da diversificazione**.
Quattro sostituti, stesso peso 25%, stessa ri-scalatura:
| sostituto | muro | Δ vs base |
|---|---|---|
| **XSR01 (vero)** | **$478.729** | **20,6%** |
| N1 mescolato — stessi rendimenti, ordine casuale (3 semi) | $475.933 / $483.846 / $484.421 | 21,0 / 19,7 / 19,6% |
| N2 rumore gaussiano, media e vol di XSR01 (3 semi) | $457.751 / $499.263 / $531.158 | 24,0 / 17,2 / 11,9% |
| N3 rumore, **drift ZERO** (3 semi) | $558.080 / $617.270 / $662.436 | 7,4 / **+2,4** / **+9,9%** |
| **N4 conto remunerato 3,72%, vol 0** | **$477.607** | **20,8%** |
| N4 conto remunerato 4,0%, vol 0 | $469.353 | 22,1% |
📌 **Il MECCANISMO di XSR01 vale 0,8% di muro** — dentro la risoluzione Monte Carlo (spread fra semi
0,151% di perpetua ≈ $17k di muro, M23). **Mescolare i suoi rendimenti non cambia niente.**
📌 **N3 (drift zero) non paga**: mediana $617k **sopra** la base. La sola riduzione di varianza non
compra rendita. Quindi **cio' che si compra e' il DRIFT scorrelato**, non la scorrelazione.
🚨 **N4 e' la riga che risponde alla domanda.** Un **conto remunerato** allo stesso tasso (3,72%),
**vol zero, corr zero, nessun secondo venue**, da' $477.607 contro i $478.729 di XSR01: **identici
dentro la risoluzione**. Al 4,0% e' **meglio**. Ed e' un confronto **in svantaggio per il conto**:
la lente L3 gli applica il **33%** di `c-sexies`, mentre un BOT paga 12,5% e un deposito 26%.
## (4)-(5) gate e risoluzione
`weights_tilt_null` (XSR01 25% vs 0%): Δ_is +0,061 · Δ_hold +0,162 · pctl 25,8 < 90,0 → **PASS**.
⚠️ hold-out del gate = 2025-01-01 → la gamba in-sample e' **un solo anno**: gira, ma e' un indizio.
Differenza appaiata di drift **+1,16%/anno, SE 0,48% → t +2,40**. Drift XSR01 **+3,72%, SE 1,46%,
t +2,55**. Risolto, ma di poco, e su 2,64 anni.
## (6) il vincolo che non e' nelle tabelle
XSR01 gira su **Hyperliquid**: il suo peso e' capitale che **esce** da Deribit, non che si aggiunge.
A $2.067 il 25% sono **$517**, contro un **C\* misurato di $15.000-20.000** (il gate 23/10 e' tarato
su ~$3.000, §5.3). Per un 25% sopra C\* servono **$60.000 sul conto totale**.
E l'haircut mangia **proprio la cosa che il null dice di star comprando**:
| haircut | netto/anno | vs conto 4,0% | vs conto 2,0% |
|---|---|---|---|
| 0% | 3,72% | SOTTO | sopra |
| 20% | 2,97% | SOTTO | sopra |
| 40% (soglia del gate) | 2,23% | SOTTO | sopra |
| 60% | 1,49% | SOTTO | **SOTTO** |
**Pareggio con un conto al 2%: haircut 46%. Con un conto al 4%: non pareggia nemmeno a haircut ZERO.**
E l'haircut pubblicato ($14,41 di ticket) e' **~2,4x ottimista e senza script che lo riproduca**.
## VERDETTO
**4/6 condizioni** — ma il conteggio non e' la lettura. La lettura e':
> Sotto la lente **rendita perpetua**, XSR01 fa una cosa reale — porta un **drift scorrelato a bassa
> vol** — e la fa in modo **non proprietario**: mescolarlo non cambia il risultato, e un conto
> remunerato allo stesso tasso lo **eguaglia a vol zero e senza un secondo venue**.
> Il vincolo binding non e' il rendimento: e' il **capitale** ($60.000 per un 25% sopra C\*), e sotto
> quella soglia la domanda *"serve XSR01?"* **non ha una risposta comprabile**.
**Cosa NON dice.** Non dice che XSR01 e' morto: lo Sharpe standalone 1,56 e il DSR 0,983 reggono, e
sotto la lente **accumulo** il conto va rifatto (li' il drift comanda in modo diverso). Dice che
**per la rendita non e' lo strumento**, e che il gate del 23/10 sta per decidere su una gamba che a
questo capitale non e' comprabile.
## Cosa e' cambiato in me mentre misuravo
Ho copiato in questo script **lo stesso difetto che avevo riparato stamattina** in
`r0825_capitale_fermo.py`: la maschera dei giorni flat presa dalla serie **de-luckata**, dove gli
zeri esatti non esistono piu' perche' `deluck` sottrae una costante. Stampava `0.0%` e non si sarebbe
notato senza la riga che conta i giorni. Riparata con l'`assert` che manca(va) a monte: la maschera
si prende dalla **serie grezza**. *Riparare un difetto in un file non lo ripara nella testa.*
+32
View File
@@ -328,6 +328,38 @@ Ogni numero va letto con la sua banda d'ancora e la sua lente.
(ampiezza effettiva 4.5 → c'e' un fattore comune da togliere); e i suoi null vanno confrontati
**a fee zero**, perche' permutare un segnale ne fa esplodere il turnover e il null perderebbe per
costo invece che per assenza di informazione (p-value trionfale e falso).
🚨 **SOTTO LA LENTE *RENDITA PERPETUA* IL MECCANISMO VALE ~0 (2026-08-25, `r0825_xsr_rendita.py`).**
Prima valutazione di XSR01 sul criterio della **perpetua** invece che su Sharpe o accumulo — N6:
dichiarato l'obiettivo, cambia il criterio, e nessuno aveva rifatto il conto.
Finestra comune libro↔XSR01 **2024-01-01 → 2026-08-22 (965 g, 2,64 anni = 35% della storia del
libro)** → i muri qui sotto **non sono** il $313k pubblicato, si confrontano solo fra loro
(base libro-solo: perpetua 3,30%, muro **$602.660**). XSR01 su questa finestra: drift **3,72%/a**
(SE 1,46%, t +2,55), vol 2,34%, Sharpe **1,56**, maxDD 2,5%, corr col libro **+0,049**.
· **iso-nozionale il muro SALE** (+0,3% a w=5% → +10,8% a w=50%): per una rendita il drift comanda.
· **iso-rischio (M6)** si ribalta: w=25%, k **1,32x** → muro **$478.729 (20,6%)**. Ma **l'argmax e'
al BORDO** (w=50%, k=1,93x, muro scende monotonamente in w) → la griglia dice *"il piu' possibile"*,
e cio' che si compra in quella direzione e' il **k**, non XSR01 (M8). Sopra 1,40x il libro non
puo' eseguire (decisione 23/08 + nessuna chiave di scala in config).
· **IL NULL, che e' il risultato.** A iso-vol `drift = Sharpe × vol_libro`, quindi tutto il
guadagno di muro e' guadagno di **Sharpe da diversificazione**. Quattro sostituti a w=25%:
**XSR01 mescolato** (stessi rendimenti, ordine casuale, 3 semi) → $475.933 / $483.846 / $484.421
contro i **$478.729** del vero → **il meccanismo vale 0,8% di muro, dentro la risoluzione MC**
(spread fra semi 0,151% di perpetua ≈ $17k). **Rumore a media e vol di XSR01** → mediana $499.263.
**Rumore a drift ZERO** → mediana **$617.270, SOPRA la base**: la sola riduzione di varianza
**non compra rendita**. Si compra il **drift scorrelato**, non la scorrelazione.
· 🚨 **Un CONTO REMUNERATO allo stesso tasso lo eguaglia**: 3,72% a vol 0, corr 0, nessun secondo
venue → **$477.607**; al 4,0% → **$469.353, meglio**. Ed e' un confronto **in svantaggio per il
conto**: la lente L3 gli applica il 33% di `c-sexies` (un BOT paga 12,5%, un deposito 26%).
· **L'haircut mangia esattamente cio' che il null dice di star comprando**: 3,72% lordi → 2,97% a
haircut 20%, **2,23% alla soglia 40% del gate**, 1,49% al 60%. **Non pareggia un conto al 4,0%
nemmeno a haircut ZERO**; pareggia il 2,0% solo sotto il **46%**. E l'haircut pubblicato ($14,41
di ticket) e' ~2,4x ottimista e senza script che lo riproduca (XSR-REPRO).
· `weights_tilt_null` (25% vs 0%) **PASS** (Δ_is +0,061 · Δ_hold +0,162 · pctl 25,8 < 90,0) — ma
l'hold-out del gate e' 2025-01-01, quindi la gamba in-sample e' **un solo anno**: indizio, non prova.
· **Il vincolo binding non e' il rendimento, e' il CAPITALE**: a $2.067 un 25% sono $517 contro un
**C\* misurato $15.000-20.000**; per un 25% sopra C\* servono **$60.000 sul conto totale**.
📌 **Cosa NON dice:** non che XSR01 sia morto — Sharpe standalone 1,56 e DSR 0,983 reggono, e sotto
la lente **accumulo** il conto va rifatto. Dice che **per la RENDITA non e' lo strumento**.
- **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.
+64
View File
@@ -16,6 +16,7 @@ null de-levering superato + eseguibilita' al capitale dichiarato.
| 6 | OI-PIN | **SCARTATO** | il max-pain batte uno strike casuale ma **non batte mai (0/24) la media a 7 giorni dello spot**, un livello che non usa NESSUN dato di opzioni: non e' pinning, e' reversione verso il centro recente con l'OI come stimatore rumoroso di quel centro |
| 8 | VOL-SIZE | **LEAD RIDIMENSIONATO** — gate 22/12 **gia' fallito oggi** | dare a SKH01 una size per-trade regge a **23/23 ancore**, 8/8 anni, null di permutazione e trasferimento su V1 — ma vale **+0,07 di Sharpe di libro, un terzo della fortuna d'ancora del libro stesso (+0,196)**. Il vol-target di **libro** e' invece falsificato: compra peso SKH gia' respinto e peggiora l'eseguibilita' |
| — | **XSR-REPRO** (integrita') | 🚨 **DIFETTO DI PRODUZIONE** | il numero 1.82 e' SPIEGATO e non era sbagliato (era su una **terza** lente, e su una barra non ancora chiusa) — ma cercandone la causa e' emerso che **`paper_xsr` registra ~41 minuti di mercato al giorno**, non un giorno. Tre gate pre-registrati leggono serie costruite cosi' |
| 70 | **XSR-RENDITA** | **SCARTATO sotto la lente RENDITA** (non come sleeve) | il muro scende del 20,6% a iso-rischio, ma **mescolare i rendimenti di XSR01 da' lo stesso muro** (il meccanismo vale 0,8%, dentro la risoluzione MC) e un **conto remunerato allo stesso tasso lo eguaglia a vol 0 e senza secondo venue**. A drift zero il muro **sale**: si compra un drift scorrelato, non la scorrelazione. E l'haircut non pareggia un conto al 4% **nemmeno a haircut ZERO** |
| 5 | SKEW | **SCARTATO** (Q1, Q2) + **LEAD** (Q3, gate 2027-02-22) | il prezzo muove lo skew (t 3,1-9,4 su 8/8 test), **non il contrario** (max |t| in avanti 2,35 contro 2,08 atteso dal rumore). Ma Q3 e' grosso: **il f=0,73 di VRP01 e' per il 42% STRUTTURA A TERMINE e solo per il 25% skew** |
| — | **HL-EXEC** (audit di fatto) | **3 falsificazioni misurate** | il pavimento vero e' **$10 (non $5)** e il taker **4,50 bps (non 5,0)** — ma il *"XS01 serve ~$20k"* e' **refutato del tutto** (nessuna soglia da min-order), il *"XSR01 ~$5.000"* e' **conservativo di 1,7x** (vero ~$3.000), e lo **slippage "rischio #1" di XSR01 e' refutato** con margine **21x** |
| — | **SLIP-AUDIT** (audit di fatto) | **SCARTATO** = nessun costo nascosto a questa taglia | i backtest a 10 bps RT restano **conservativi di ~1,5 bps/lato**; nessuna evidenza di impatto sopravvive al null (p=0,274; estremi avversi **1/18 contro 4,7 attesi**). **Ma la misura ha una data di scadenza** |
@@ -3730,3 +3731,66 @@ pubblicato, e nessuno dei tre produce reddito.
**Con questa sono 69 filoni e 0 candidati promossi.** I vincoli binding restano due: **il capitale che
entra** e **il conto che non sparisce**.
---
## 70 — XSR-RENDITA (r0825_xsr_rendita.py) — XSR01 sul criterio della PERPETUA
**Domanda dell'operatore:** *"rendita perpetua ma non ho ancora capito se serve XSR01"*. XSR01 era
stato giudicato su **ammissione**, **gate di deploy** e **accumulo**, mai sulla **rendita** — e sono
criteri diversi (l'accumulo premia il drift, la rendita la **perpetua**). N6: dichiarato l'obiettivo,
si rifa' il conto.
**Finestra.** Un MIX esiste solo dove esistono ENTRAMBE le serie → **2024-01-01 → 2026-08-22**
(965 g, 2,64 anni, **35%** della storia del libro). ⚠️ **I muri di questo filone NON sono il $313k
pubblicato**: base libro-solo su questa finestra = perpetua 3,30%, muro **$602.660**.
XSR01, lente dei gate su sole barre chiuse: drift **3,72%/a** (SE 1,46% → t +2,55), vol 2,34%,
Sharpe **1,56**, maxDD 2,5%, corr col libro **+0,049**.
**(a) iso-nozionale: il muro SALE** (+0,3% a w=5% → **+10,8%** a w=50%). Il mix e' piu' liscio e piu'
povero, e per una rendita il drift comanda.
**(b) iso-rischio (M6): si ribalta** — w=25%, k **1,32x** → muro **$478.729 (20,6%)**.
⚠️ **argmax al BORDO** (w=50%, k=1,93x; il muro scende **monotonamente** in w): la griglia non indica
un ottimo, dice *"il piu' possibile"*, e in quella direzione si compra il **k**, non XSR01 (M8).
Sopra 1,40x il libro **non puo' eseguire** (decisione 23/08; nessuna chiave di scala in config).
🚨 **(c) IL NULL — ed e' il risultato.** A iso-vol `drift = Sharpe × vol_libro`: la colonna "drift"
della tabella iso-rischio **e' la colonna "Sharpe" ri-etichettata**, quindi tutto il guadagno di muro
e' guadagno di **Sharpe da diversificazione**. Quattro sostituti a w=25%, stessa ri-scalatura:
| sostituto | muro | Δ vs base |
|---|---|---|
| **XSR01 (vero)** | **$478.729** | **20,6%** |
| XSR01 **mescolato** (3 semi) | $475.933 · $483.846 · $484.421 | 21,0 · 19,7 · 19,6% |
| rumore a media e vol di XSR01 (3 semi) | $457.751 · $499.263 · $531.158 | 24,0 · 17,2 · 11,9% |
| rumore a **drift ZERO** (3 semi) | $558.080 · $617.270 · $662.436 | 7,4 · **+2,4** · **+9,9%** |
| **conto remunerato 3,72%, vol 0** | **$477.607** | **20,8%** |
| conto remunerato 4,0%, vol 0 | $469.353 | 22,1% |
📌 **Il meccanismo di XSR01 vale 0,8% di muro** — dentro la risoluzione Monte Carlo (spread fra semi
**0,151%** di perpetua ≈ $17k, M23). **Mescolarne i rendimenti non cambia niente.**
📌 **A drift zero il muro SALE**: la sola riduzione di varianza **non compra rendita**. Cio' che si
compra e' un **drift scorrelato**, non la scorrelazione.
🚨 **Un conto remunerato allo stesso tasso lo eguaglia**, a vol 0, corr 0 e **senza un secondo venue**
— e il confronto e' **in svantaggio per il conto**: la lente L3 gli applica il 33% di `c-sexies`,
mentre un BOT paga 12,5% e un deposito 26%.
**(d) L'haircut mangia esattamente cio' che si sta comprando.** 3,72% lordi → 2,97% a haircut 20%,
**2,23% alla soglia 40% del gate**, 1,49% al 60%. **Non pareggia un conto al 4,0% nemmeno a haircut
ZERO**; pareggia il 2,0% solo sotto il **46%**. L'haircut pubblicato ($14,41/ticket) e' ~2,4x
ottimista e **senza script che lo riproduca** (XSR-REPRO).
**(e) `weights_tilt_null` (25% vs 0%): PASS** (Δ_is +0,061 · Δ_hold +0,162 · pctl 25,8 < soglia 90,0)
— ma l'hold-out del gate e' 2025-01-01 e la gamba in-sample e' **un solo anno**: indizio, non prova.
**(f) Il vincolo binding non e' il rendimento, e' il CAPITALE.** XSR01 gira su Hyperliquid: il suo
peso e' capitale che **esce** da Deribit. A $2.067 un 25% sono **$517** contro un **C\* misurato
$15.000-20.000**; per un 25% sopra C\* servono **$60.000 sul conto totale**.
**VERDETTO 4/6 — ma la lettura non e' il conteggio:** sotto la lente rendita XSR01 fa una cosa reale
(porta un drift scorrelato a bassa vol) **in modo non proprietario**. **Non dice che e' morto**
(Sharpe 1,56 e DSR 0,983 reggono, e sotto la lente accumulo il conto va rifatto): dice che **per la
rendita non e' lo strumento**, e che il gate del 23/10 sta per decidere su una gamba che a questo
capitale **non e' comprabile**.
**Con questa sono 70 filoni e 0 candidati promossi.**
+159
View File
@@ -0,0 +1,159 @@
"""r0825_versamento_3k.py — cosa compra un versamento di $3.000 ADESSO, dal conto vero.
DOMANDA (operatore, 2026-08-25 sera): *"rianalizza e vediamo come procedere. potrei versare a
breve altri 3k"*. Il conto passerebbe da ~$2.065 a ~$5.065 — esattamente a cavallo della soglia
$5k su cui sta scritto il criterio di capitale del gate XSR01 (23/10), e a un terzo del muro
$15-20k che e' insieme il C* vero di Hyperliquid E la soglia della decisione vincolante
"100% Deribit fino a $20k" (26/07).
ASSUNZIONI DICHIARATE:
- "3k" = 3.000 USDC = $3.000 (i versamenti precedenti dell'operatore sono in USDC);
- il lump atterra OGGI. "A breve" puo' voler dire fra settimane: ritardarlo di un mese sposta
i numeri di poco e sempre nello stesso verso (un po' meno beneficio). Non lo modello.
- equity di partenza: 2.065,00 letta dal watermark alle 18:47:13Z di oggi (l'istante
dell'evento, non l'istante della scrittura).
LENTE: L3 CONGIUNTA (funding esatto + fisco d'accumulo + ancora de-luckata), la stessa di
`r0825_piano_10a_500` stessi semi, stessi path: ogni confronto qui e' APPAIATO (M22).
Stessi difetti ereditati e dichiarati la': 121 versamenti in 10 anni, `versato` scalare.
M23: N_PATHS 3000, blocchi 20g. La banda del muro resta [$187k $1,14M]: i numeri assoluti
qui sotto stanno sulla lente `hourly`+L3 e vanno letti con quella etichetta (P7).
uv run python scripts/research/r0825_versamento_3k.py
"""
from __future__ import annotations
import sys
from pathlib import Path
import numpy as np
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "scripts" / "research"))
import r0725_capcurve as CC # noqa: E402
import r0807_piano_netto as PN # noqa: E402
import r0822d_piano_vero as PV # noqa: E402
import r0823_deposit_timing as DT # noqa: E402
START_OGGI = 2065.00 # watermark 2026-08-25T18:47:13Z
LUMP_USD = 3000.0 # il versamento ipotizzato, in USD
START_LUMP = START_OGGI + LUMP_USD
DEP = 500.0 # EUR/mese, il piano dichiarato
ORIZZONTI = (5, 10, 15, 20)
N_PATHS = 3000
SEED = PV.SEED_TRAJ
BLOCK = PV.BLOCK
GATE_XSR = 59 # giorni da oggi al 2026-10-23 (25/08 -> 23/10)
MILESTONE = (5_000.0, 15_000.0, 20_000.0) # criterio gate · C* Hyperliquid · muro "100% Deribit"
def sez(t: str) -> None:
print(f"\n{'='*100}\n {t}\n{'='*100}")
def eur_g(cap: np.ndarray, perp: float) -> np.ndarray:
return cap * perp / 365.0 / CC.EURUSD
def main() -> None:
print("=" * 100)
print(f" r0825 — IL VERSAMENTO DA $3.000: ${START_OGGI:,.0f} -> ${START_LUMP:,.0f}")
print("=" * 100)
B = PV.costruisci_serie()
r = PV.deluck(B["fund"].values.astype(float))
lente = PV.Lente("L3 congiunta", r, lordizza=False)
lente.perp, lente.muro = PV.muro_di(lente)
print(f"\n lente L3: drift {lente.drift:.2%} · vol {lente.vol:.2%} · perpetua {lente.perp:.2%}"
f" · muro ${lente.muro:,.0f}")
# ---------------------------------------------------- (1) cosa compra il lump, appaiato
sez(f"(1) COSA COMPRA IL LUMP — €{DEP:.0f}/mese, stessi path, da ${START_OGGI:,.0f} vs "
f"${START_LUMP:,.0f}")
print(f" {'oriz.':>6} {'senza lump':>13} {'con lump':>13} {'guadagno':>10} "
f"{'€/g senza':>11} {'€/g con':>9} {'P(50) senza':>12} {'P(50) con':>10}")
print(" " + "-" * 92)
d10 = {}
for anni in ORIZZONTI:
rng = np.random.default_rng(SEED)
ii = DT.boot_idx(len(r), N_PATHS, anni * 365, BLOCK, rng)
paths = r[ii]
a = PN.accumula(paths, DEP, lente.muro, lente.aliq, lente.patr, start=START_OGGI)
b = PN.accumula(paths, DEP, lente.muro, lente.aliq, lente.patr, start=START_LUMP)
ea, eb = eur_g(a["cap"], lente.perp), eur_g(b["cap"], lente.perp)
pa, pb = float((ea >= 50).mean()), float((eb >= 50).mean())
if anni == 10:
d10 = dict(a=a, b=b, ea=ea, eb=eb, pa=pa, pb=pb)
print(f" {anni:>4}a ${np.median(a['cap']):>11,.0f} ${np.median(b['cap']):>11,.0f} "
f"{np.median(b['cap'])/np.median(a['cap'])-1:>9.1%} {np.median(ea):>10.2f} "
f"{np.median(eb):>8.2f} {pa:>11.1%} {pb:>9.1%}")
lump_in_mesi = LUMP_USD / CC.EURUSD / DEP
print(f"\n il lump equivale a {lump_in_mesi:.1f} mesi di versamenti anticipati in un colpo.")
print(f" N3: la leva 'versare' resta la prima — questo lump E' quella leva, esercitata.")
# ---------------------------------------------------- (2) pietre miliari
sez("(2) QUANDO ARRIVANO LE PIETRE MILIARI (€500/mese, primo passaggio, 10 anni di path)")
rng = np.random.default_rng(SEED)
ii = DT.boot_idx(len(r), N_PATHS, 10 * 365, BLOCK, rng)
paths10 = r[ii]
print(f" {'soglia':>9} {'cosa sblocca':<44} {'senza lump':>11} {'con lump':>9}")
print(" " + "-" * 82)
naming = {5_000: "criterio di capitale del gate XSR01",
15_000: "C* vero di Hyperliquid (pavimento misurato)",
20_000: "decisione '100% Deribit fino a $20k' si riapre"}
for ms in MILESTONE:
riga = []
for st in (START_OGGI, START_LUMP):
out = PN.accumula(paths10, DEP, ms, lente.aliq, lente.patr, start=st)
if st >= ms:
riga.append("gia' li'")
continue
d = PV.leggi(out["colpito"], anni_sim=10)
riga.append("oltre 10a" if not np.isfinite(d["med"]) else f"{d['med']:.1f}a")
print(f" ${ms:>7,.0f} {naming[int(ms)]:<44} {riga[0]:>11} {riga[1]:>9}")
# ---------------------------------------------------- (3) il gate del 23/10
sez(f"(3) GATE XSR01 (2026-10-23, fra {GATE_XSR} giorni) — P(capitale >= $5.000 quel giorno)")
rng = np.random.default_rng(SEED)
ii = DT.boot_idx(len(r), N_PATHS, GATE_XSR, BLOCK, rng)
pg = r[ii]
for st, nome in ((START_OGGI, "senza lump"), (START_LUMP, "con lump")):
out = PN.accumula(pg, DEP, 5_000.0, lente.aliq, lente.patr, start=st)
p = float((out["cap"] >= 5_000.0).mean())
print(f" {nome:<11} start ${st:>7,.0f} -> P(>= $5k al 23/10) = {p:>6.1%} "
f"(mediana ${np.median(out['cap']):,.0f}, p10 ${np.percentile(out['cap'],10):,.0f})")
print(f"\n ⚠️ Il criterio FORMALE diventa raggiungibile col lump — ma il C* VERO del venue e'")
print(f" $15.000-20.000 (§5.3), il 25% a ${START_LUMP:,.0f} sono ${START_LUMP*0.25:,.0f} su")
print(f" Hyperliquid, e la decisione vincolante del 26/07 dice 100% Deribit fino a $20k.")
print(f" Il lump rende il gate LEGGIBILE, non rende XSR01 comprabile.")
# ---------------------------------------------------- (4) meccanica live a $5.065
sez(f"(4) COSA CAMBIA NELLA MECCANICA LIVE, DA SOLO, A ${START_LUMP:,.0f}")
print(f" cap per-asset (equity x 0,5, nessun tetto assoluto sul percorso normale):")
print(f" ${START_OGGI*0.5:,.0f} -> ${START_LUMP*0.5:,.0f} per asset — nessuna config da toccare,")
print(f" il profilo di rischio RELATIVO non cambia (leva lorda max resta 1,0x; realizzata")
print(f" max 0,52x: il vincolo e' il segnale, non il cap)")
print(f" min_order $5: passa dal {5/(START_OGGI*0.5):.2%} al {5/(START_LUMP*0.5):.2%} del cap")
print(f" per-asset (C2: un parametro in valuta assoluta pesa meno al crescere del conto)")
print(f" fallback a equity illeggibile: min($3.000, watermark x 0,5) = "
f"min(3000, {START_LUMP*0.5:,.0f}) -> ${min(3000.0, START_LUMP*0.5):,.0f}")
print(f" disaster-SL -30%: invariato — resta rotolante e simmetrico (peggior DD misurato")
print(f" dall'ingresso -60,6%/-61,5%: il nome inganna anche a $5k)")
print(f" ⚠️ slip-audit: misurato su fill a $597-2.067; a ${START_LUMP:,.0f} la taglia relativa")
print(f" raddoppia -> la misura VA RIFATTA dopo i primi fill alla taglia nuova (C2/C5),")
print(f" lo script c'e' gia' (`r0822_slip_audit.py`, normalizzazione per-fill)")
# ---------------------------------------------------- verdetto
sez("VERDETTO (runtime)")
med_a, med_b = np.median(d10["a"]["cap"]), np.median(d10["b"]["cap"])
print(f" a 10 anni con €500/mese: ${med_a:,.0f} -> ${med_b:,.0f} ({med_b/med_a-1:+.1%}), "
f"€/g {np.median(d10['ea']):.2f} -> {np.median(d10['eb']):.2f}")
print(f" P(>=50 €/g a 10a): {d10['pa']:.1%} -> {d10['pb']:.1%}")
print(f" il lump anticipa il piano di ~{lump_in_mesi:.0f} mesi e rende leggibile il gate del")
print(f" 23/10; NON rende comprabile XSR01 (C* $15-20k) e NON riapre la scelta del venue ($20k).")
if __name__ == "__main__":
main()
+372
View File
@@ -0,0 +1,372 @@
"""r0825_xsr_rendita.py — XSR01 serve alla RENDITA PERPETUA? (non all'accumulo, non allo Sharpe)
DOMANDA (operatore, 2026-08-25): *"rendita perpetua ma non ho ancora capito se serve XSR01"*.
PERCHE' E' UNA MISURA NUOVA E NON UNA CITAZIONE. XSR01 e' stato giudicato tre volte — ammissione
(25/07), gate di deploy (23/10, pre-registrato), accumulo (oggi) e **mai sotto la lente della
rendita**. Sono criteri diversi: l'accumulo premia il DRIFT, la rendita premia la **PERPETUA**,
cioe' il prelievo piu' alto che sopravvive a 20 anni con P>=90% (definizione 25/07, invariata).
La perpetua e' una funzione di drift **e** di coda: un diversificatore che non aggiunge drift puo'
comunque alzarla, ed e' esattamente il caso che nessuno ha misurato. N6: l'obiettivo si dichiara
prima di ottimizzarlo qui e' dichiarato, quindi si misura quello.
COSA MI ASPETTO PRIMA DI MISURARE (M12: una previsione dichiarata va misurata, non assunta):
(a) a ISO-NOZIONALE il mix perde drift (XSR01 rende 4,2%/a contro i 15,2% del libro) e quindi
**alza il muro** anche se abbassa la vol -> XSR01 sembrera' inutile;
(b) a ISO-RISCHIO (M6, la lente obbligatoria per un diversificatore a basso CAGR) il mix puo'
essere ri-scalato fino alla vol del libro e allora il verdetto puo' **ribaltarsi**;
(c) il vincolo che decide non sara' ne' (a) ne' (b) ma il **capitale**.
Se (c) e' vero, le prime due sezioni sono aritmetica su una cosa che non si puo' comprare.
TRE DIFETTI EREDITATI, DICHIARATI PRIMA DEI NUMERI (nessuno riparato qui):
1. **La finestra comune e' corta.** Il libro ha ~7,4 anni, XSR01 ~2,6 (Hyperliquid parte 2024).
Regola del 07/08, gia' violata una volta: **un MIX esiste solo dove esistono ENTRAMBE le
serie**. Quindi il muro del mix NON e' confrontabile col $313k pubblicato (7,4 anni): il
confronto valido e' **libro-sulla-finestra-comune vs mix-sulla-finestra-comune**, appaiato.
2. **Il numero di titolo di XSR01 (Sharpe 1.82) non e' la sua serie.** XSR-REPRO (22/08): 1.82
viene da una TERZA lente (divisore fisso 50); la lente che ha girato i gate da' **1.79** alla
scoperta e **1.63** a oggi. Qui si usa la **lente dei gate su sole barre chiuse**, ed e' l'unica
citabile sempre con la coppia (lente, ultima barra chiusa).
3. **Il forward monitor di XSR01 e' rotto** (`advance()` registra ~41 min di mercato al giorno,
vol registrata 0,46% contro 2,74% ricalcolata): i 31 giorni di `data/paper_xsr/returns.jsonl`
**non sono usabili** e non entrano in questo script. Qui si misura il BACKTEST, non il vivo.
uv run python scripts/research/r0825_xsr_rendita.py
"""
from __future__ import annotations
import sys
from pathlib import Path
import numpy as np
import pandas as pd
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "scripts" / "research"))
import r0725_capcurve as CC # noqa: E402
import r0807_piano_netto as PN # noqa: E402
import r0822_xsr_repro as XR # noqa: E402
import r0822d_piano_vero as PV # noqa: E402
from src.portfolio.portfolio import weights_tilt_null # noqa: E402
ANN = np.sqrt(365.0)
N_WALL = 1500 # M23: la risoluzione del Monte Carlo si dichiara — misurata in sezione 6
SEED_WALL = PV.SEED_WALL
BLOCK = PV.BLOCK
PESI = (0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.40, 0.50)
def sez(t: str) -> None:
print(f"\n{'='*100}\n {t}\n{'='*100}")
def _sh(r: np.ndarray) -> float:
r = np.asarray(r, float)
return float(r.mean() / r.std() * ANN) if r.std() > 0 else 0.0
def _dd(r: np.ndarray) -> float:
eq = np.cumprod(1.0 + np.asarray(r, float))
return float((eq / np.maximum.accumulate(eq) - 1.0).min())
def perpetua(r: np.ndarray, aliq: float, patr: float, n_paths: int = N_WALL,
seed: int = SEED_WALL) -> float:
"""Il prelievo annuo (frazione del capitale) piu' alto con P(cap a 20a >= cap iniziale) >= 90%.
Bisezione IDENTICA a `PV.muro_di` non re-implementata a mano: stessa `PN.sopravvivenza`,
stessi 13 passi, stesso criterio `p10_end >= cap0`. Cambia solo che qui la serie e' un
argomento invece che un attributo di `Lente`, perche' vanno confrontati molti mix."""
lo, hi = 0.0, 0.40
for _ in range(13):
mid = (lo + hi) / 2
s = PN.sopravvivenza(r, 1e6, 1e6 * mid, 20, aliq, patr, n_paths=n_paths, seed=seed)
lo, hi = (mid, hi) if s["p10_end"] >= 1e6 else (lo, mid)
return lo
def muro_da(perp: float, prelievo: float) -> float:
return prelievo / perp if perp > 0.002 else float("inf")
def se_drift(r: np.ndarray, n: int = 2000, seed: int = 20260825) -> float:
"""SE annualizzata del drift, block-bootstrap a blocchi di 20 giorni (la stessa dipendenza
seriale che usa il muro). Serve a dire quanto e' RISOLTA la differenza fra due mix."""
rng = np.random.default_rng(seed)
B = CC._boot_paths(np.asarray(r, float), n, len(r), BLOCK, rng)
return float(B.mean(axis=1).std() * 365.0)
def main() -> None:
print("=" * 100)
print(" r0825 — XSR01 SERVE ALLA RENDITA PERPETUA?")
print("=" * 100)
# ---------------------------------------------------------------- (0) le due serie
sez("(0) LE DUE SERIE E LA FINESTRA IN CUI ESISTONO ENTRAMBE")
B = PV.costruisci_serie()
libro_full = pd.Series(PV.deluck(B["fund"].values.astype(float)), index=B.index)
lente_full = PV.Lente("L3 congiunta", libro_full.values, lordizza=False)
prelievo = lente_full.prelievo
aliq, patr = lente_full.aliq, lente_full.patr
# XSR01: lente dei GATE (basket_from_positions, demean) su sole barre CHIUSE.
P, S = XR.panel(partial_last=False)
xsr_full = XR.lens_L1(P, S).dropna()
ultima = xsr_full.index.max()
# l'ultima barra su disco e' quella del giorno IN CORSO (difetto §5.1): si scarta.
xsr_full = xsr_full[xsr_full.index < pd.Timestamp.utcnow().normalize()]
chiusa = xsr_full.index.max()
print(f" libro L3 (75/25, funding dentro, ancora de-luckata): "
f"{libro_full.index.min().date()} -> {libro_full.index.max().date()} "
f"({len(libro_full)} giorni)")
print(f" XSR01 lente-dei-gate, sole barre chiuse: "
f"{xsr_full.index.min().date()} -> {chiusa.date()} ({len(xsr_full)} giorni)")
print(f" (ultima barra su disco {ultima.date()} = giorno IN CORSO, scartata — difetto §5.1)")
print(f" Sharpe XSR01 a oggi, questa lente: {_sh(xsr_full.values):.2f} "
f"[il '1.82' pubblicato e' una TERZA lente — XSR-REPRO 22/08]")
ix = libro_full.index.normalize().intersection(xsr_full.index.normalize())
lb = pd.Series(libro_full.values, index=libro_full.index.normalize()).reindex(ix)
xs = pd.Series(xsr_full.values, index=xsr_full.index.normalize()).reindex(ix)
lb, xs = lb.dropna(), xs.dropna()
ix = lb.index.intersection(xs.index)
lb, xs = lb.reindex(ix).values, xs.reindex(ix).values
print(f"\n FINESTRA COMUNE: {ix.min().date()} -> {ix.max().date()} ({len(ix)} giorni, "
f"{len(ix)/365:.2f} anni)")
print(f" copre il {len(ix)/len(libro_full):.0%} della storia del libro -> il muro calcolato "
f"qui NON e' il $313k pubblicato (7,4 anni): si confronta solo con se stesso.")
# ---------------------------------------------------------------- (1) le due gambe
sez("(1) LE DUE GAMBE SULLA FINESTRA COMUNE — e quanto e' diversa da tutta la storia")
print(f" {'serie':<34} {'drift/a':>9} {'vol/a':>8} {'Sharpe':>8} {'maxDD':>9} {'SE drift':>10}")
print(" " + "-" * 84)
for nome, r in (("libro L3 — TUTTA la storia", libro_full.values),
("libro L3 — finestra comune", lb),
("XSR01 — finestra comune", xs)):
print(f" {nome:<34} {r.mean()*365:>8.2%} {r.std()*ANN:>7.2%} {_sh(r):>8.2f} "
f"{_dd(r):>8.1%} {se_drift(r):>9.2%}")
corr = float(np.corrcoef(lb, xs)[0, 1])
print(f"\n correlazione libro <-> XSR01 sulla finestra comune: {corr:+.3f}")
# ⚠️ la maschera dei FLAT si prende dalla serie GREZZA, non da quella de-luckata: `deluck`
# sottrae una costante e gli zeri esatti spariscono (difetto trovato e riparato il 25/08).
grezza = pd.Series(B["fund"].values.astype(float), index=B.index.normalize()).reindex(ix)
flat = (grezza.abs() < 1e-12).values
assert flat.sum() > 0, "maschera flat vuota: si sta guardando la serie sbagliata"
print(f" giorni in cui il libro e' FLAT: {flat.mean():.1%} ({flat.sum()} giorni) "
f"— li' XSR01 rende {xs[flat].mean()*365:+.2%}/anno annualizzato contro "
f"{xs[~flat].mean()*365:+.2%} negli altri")
# ---------------------------------------------------------------- (2) iso-nozionale
sez("(2) MIX A ISO-NOZIONALE — la lente INGENUA (w di XSR01 tolto al libro)")
print(f" {'w XSR01':>8} {'drift/a':>9} {'vol/a':>8} {'Sharpe':>8} {'maxDD':>9} "
f"{'perpetua':>10} {'MURO':>13} {'d muro':>10}")
print(" " + "-" * 88)
base_perp = perpetua(lb, aliq, patr)
base_muro = muro_da(base_perp, prelievo)
iso_n = {}
for w in PESI:
m = (1 - w) * lb + w * xs
p = perpetua(m, aliq, patr)
mu = muro_da(p, prelievo)
iso_n[w] = dict(perp=p, muro=mu, drift=m.mean()*365, vol=m.std()*ANN, sh=_sh(m), dd=_dd(m))
dmu = "n/d" if not np.isfinite(mu) or not np.isfinite(base_muro) else f"{mu/base_muro-1:+.1%}"
print(f" {w:>7.0%} {m.mean()*365:>8.2%} {m.std()*ANN:>7.2%} {_sh(m):>8.2f} {_dd(m):>8.1%} "
f"{p:>9.2%} ${mu:>12,.0f} {dmu:>10}")
# ---------------------------------------------------------------- (3) iso-rischio
sez("(3) MIX A ISO-RISCHIO (M6) — la lente OBBLIGATORIA per un diversificatore a basso CAGR")
print(" Ogni mix e' ri-scalato di k = vol(libro)/vol(mix) cosi' che la vol sia IDENTICA a")
print(" quella del libro da solo. E' l'unico confronto che non regala al mix il merito di")
print(" essere semplicemente piu' piccolo (M6, e null del de-levering M5).")
vol_b = lb.std()
print(f"\n {'w XSR01':>8} {'k richiesto':>12} {'drift/a':>9} {'vol/a':>8} {'Sharpe':>8} "
f"{'maxDD':>9} {'perpetua':>10} {'MURO':>13} {'d muro':>10}")
print(" " + "-" * 96)
iso_r = {}
for w in PESI:
m = (1 - w) * lb + w * xs
k = vol_b / m.std()
mk = m * k
p = perpetua(mk, aliq, patr)
mu = muro_da(p, prelievo)
iso_r[w] = dict(k=k, perp=p, muro=mu, drift=mk.mean()*365, sh=_sh(mk), dd=_dd(mk))
dmu = "n/d" if not np.isfinite(mu) or not np.isfinite(base_muro) else f"{mu/base_muro-1:+.1%}"
print(f" {w:>7.0%} {k:>11.3f}x {mk.mean()*365:>8.2%} {mk.std()*ANN:>7.2%} {_sh(mk):>8.2f} "
f"{_dd(mk):>8.1%} {p:>9.2%} ${mu:>12,.0f} {dmu:>10}")
print("\n ⚠️ Il k di questa colonna e' ARITMETICA, non una configurazione: in `config/live.json`")
print(" NON esiste una chiave di scala (§3), e il gradino di leva NON e' autorizzato oggi")
print(" (1,50x BOCCIATO, k max difendibile 1,40). Un k > 1,40 in questa tabella e' un")
print(" numero che il libro **non puo' eseguire**.")
# M8: l'argmax di questa griglia sta al BORDO (il muro scende monotonamente in w) -> non e'
# una decisione, e' il bordo. Il peso che si porta avanti e' il migliore DENTRO il k
# autorizzato (<= 1,40, decisione operatore 23/08); il bordo resta come nota.
bordo = max((w for w in PESI if w > 0), key=lambda w: -iso_r[w]["muro"])
ammessi = [w for w in PESI if w > 0 and iso_r[w]["k"] <= 1.40]
best_w = max(ammessi, key=lambda w: -iso_r[w]["muro"]) if ammessi else min(
w for w in PESI if w > 0)
print(f"\n ⚠️ M8 — l'argmax di questa griglia e' al BORDO (w={bordo:.0%}, k={iso_r[bordo]['k']:.2f}x):")
print(f" il muro scende MONOTONAMENTE in w, quindi la griglia non indica un ottimo, dice")
print(f" 'il piu' possibile'. Cio' che si sta comprando in quella direzione e' il k, non XSR01.")
print(f" => peso portato avanti = il migliore col k AUTORIZZATO (<=1,40x): XSR01 {best_w:.0%} "
f"(k={iso_r[best_w]['k']:.2f}x)")
# ------------------------------------------------------- (3b) da dove viene il guadagno?
sez("(3b) IL NULL — il guadagno a iso-rischio e' di XSR01, o di 'una qualunque cosa scorrelata'?")
print(" A iso-vol vale `drift = Sharpe x vol_libro`: la colonna 'drift' della sezione (3) E' la")
print(" colonna 'Sharpe' ri-etichettata. Quindi tutto il guadagno di muro e' un guadagno di")
print(" SHARPE da diversificazione — e va chiesto se e' XSR01 o la sua sola statistica.")
print(" Tre sostituti, stessa w, stessa ri-scalatura a iso-vol del libro:")
print(" N1 XSR01 MESCOLATO — stessi rendimenti in ordine casuale: stesso drift, stessa vol,")
print(" nessuna relazione col libro giorno per giorno (null M14).")
print(" N2 RUMORE a drift di XSR01 — gaussiano, stessa media e stessa vol, zero struttura.")
print(" N3 RUMORE a drift ZERO — stessa vol, media 0: isola quanta parte e' pura varianza.")
rng = np.random.default_rng(20260825)
print(f"\n {'sostituto':<26} {'drift/a':>9} {'Sharpe':>8} {'perpetua':>10} {'MURO':>13} {'d muro':>10}")
print(" " + "-" * 80)
w0 = best_w
def _riga(nome, sub):
m = (1 - w0) * lb + w0 * sub
m = m * (vol_b / m.std())
pp = perpetua(m, aliq, patr)
mm = muro_da(pp, prelievo)
print(f" {nome:<26} {m.mean()*365:>8.2%} {_sh(m):>8.2f} {pp:>9.2%} ${mm:>12,.0f} "
f"{mm/base_muro-1:>9.1%}")
return mm
m_vero = iso_r[w0]["muro"]
print(f" {'XSR01 (vero)':<26} {iso_r[w0]['drift']:>8.2%} {iso_r[w0]['sh']:>8.2f} "
f"{iso_r[w0]['perp']:>9.2%} ${m_vero:>12,.0f} {m_vero/base_muro-1:>9.1%}")
mescolati = [_riga(f"N1 mescolato (seme {i})", rng.permutation(xs)) for i in range(3)]
n2 = [_riga(f"N2 rumore, drift XSR01 ({i})", rng.normal(xs.mean(), xs.std(), len(xs)))
for i in range(3)]
n3 = [_riga(f"N3 rumore, drift ZERO ({i})", rng.normal(0.0, xs.std(), len(xs)))
for i in range(3)]
# N4: la gamba che nessuno ha messo sul tavolo — un rendimento SENZA rischio e senza venue.
# Se il merito di XSR01 e' 'un drift scorrelato a bassa vol', allora un conto remunerato
# (T-bill / USDC lending) lo fornisce con vol ~0, corr 0 e nessun pavimento d'esecuzione.
n4 = {y: _riga(f"N4 conto remunerato {y:.1%}", np.full(len(xs), y / 365.0))
for y in (0.020, 0.0372, 0.040)}
print(f"\n LETTURA (calcolata, non asserita):")
print(f" XSR01 vero ${m_vero:>10,.0f}")
print(f" N1 mescolato, mediana ${np.median(mescolati):>10,.0f} "
f"-> il MECCANISMO vale {abs(m_vero-np.median(mescolati))/base_muro:.1%} di muro")
print(f" N2 rumore, mediana ${np.median(n2):>10,.0f} "
f"-> (media, vol) da sole bastano: {'SI' if np.median(n2) <= m_vero else 'NO'}")
print(f" N3 drift zero, mediana${np.median(n3):>10,.0f} "
f"-> la sola riduzione di varianza paga: "
f"{'SI' if np.median(n3) < base_muro else 'NO, il muro SALE'}")
print(f" N4 conto remunerato 4,0% ${n4[0.040]:>8,.0f} "
f"-> {'MEGLIO' if n4[0.040] <= m_vero else 'peggio'} di XSR01, "
f"a vol ZERO e senza secondo venue")
print(f"\n drift di XSR01 sulla finestra comune: {xs.mean()*365:+.2%}/anno · SE {se_drift(xs):.2%} "
f"-> t = {xs.mean()*365/se_drift(xs):+.2f}")
# ---------------------------------------------------------------- (4) gate dei pesi
sez("(4) `weights_tilt_null` — il gate obbligatorio per OGNI proposta di cambio pesi (§8.5)")
print(f" proposta testata: XSR01 {best_w:.0%} (il miglior peso a k autorizzato, sezione 3).")
print(f" ⚠️ hold-out del gate = 2025-01-01: su questa finestra la gamba in-sample e' UN SOLO")
print(f" anno (2024). Il gate gira, ma con questa risoluzione va letto come indizio.")
cols = {"LIBRO": pd.Series(lb, index=ix), "XSR01": pd.Series(xs, index=ix)}
try:
g = weights_tilt_null(cols,
{"LIBRO": 1.0, "XSR01": 0.0}, # corrente: XSR01 fuori dal book
{"LIBRO": 1.0 - best_w, "XSR01": best_w},
floor=0.0, n=500, k_seen=len(PESI))
print(f" delta_insample {g['delta_insample']:+.3f} · delta_hold {g['delta_hold']:+.3f} "
f"· pctl_hold {g['pctl_hold']:.1f} · soglia best-of-k {g['bestofk_pctl']:.1f}")
print(f" tilt casuali che battono CURRENT sull'hold-out: {g['frac_random_beat_hold']:.0%}")
print(f" => gate_pass = {g['gate_pass']}")
except Exception as e:
g = None
print(f" NON ESEGUIBILE su questa finestra: {type(e).__name__}: {e}")
# ---------------------------------------------------------------- (5) risoluzione
sez("(5) LA RISOLUZIONE — la differenza misurata e' piu' grande del rumore che la misura?")
se_b = se_drift(lb)
m_best = (1 - best_w) * lb + best_w * xs
m_best = m_best * (vol_b / m_best.std())
se_m = se_drift(m_best)
d_drift = m_best.mean() * 365 - lb.mean() * 365
se_pair = se_drift(m_best - lb)
print(f" drift libro {lb.mean()*365:>8.2%} (SE {se_b:.2%})")
print(f" drift mix {best_w:.0%} {m_best.mean()*365:>8.2%} (SE {se_m:.2%}) iso-rischio")
print(f" DIFFERENZA appaiata (M7: si misura la differenza, non si differenziano le mediane):")
print(f" {d_drift:+.2%}/anno · SE della differenza {se_pair:.2%} -> "
f"t = {d_drift/se_pair if se_pair > 0 else float('nan'):+.2f}")
p1 = perpetua(m_best, aliq, patr, seed=SEED_WALL)
p2 = perpetua(m_best, aliq, patr, seed=SEED_WALL + 1)
p3 = perpetua(m_best, aliq, patr, seed=SEED_WALL + 2)
print(f"\n risoluzione Monte Carlo del muro (M23), stesso mix a tre semi diversi:")
print(f" perpetua {p1:.3%} / {p2:.3%} / {p3:.3%} -> spread {max(p1,p2,p3)-min(p1,p2,p3):.3%}")
print(f" in muro: ${muro_da(p1, prelievo):,.0f} / ${muro_da(p2, prelievo):,.0f} / "
f"${muro_da(p3, prelievo):,.0f}")
# ---------------------------------------------------------------- (6) il vincolo vero
sez("(6) IL VINCOLO CHE NON E' NELLE TABELLE — si puo' COMPRARE questo mix?")
eq = 2066.88
print(f" capitale reale oggi: ${eq:,.0f} (Deribit). XSR01 gira su **Hyperliquid**: e' un")
print(f" SECONDO CONTO, quindi il suo peso e' capitale che ESCE da Deribit, non che si aggiunge.")
print(f"\n {'w XSR01':>8} {'$ su Hyperliquid':>18} {'ticket mediano/gamba':>22} {'eseguibile?':>14}")
print(" " + "-" * 68)
TICKET_MED = 3.33 # XSR-REPRO 22/08, misurato: mediano $3,33 · medio $5,98 · 63% sotto $5
C_STAR = 15_000.0 # pavimento vero del venue misurato (non i ~$3.000 su cui e' tarato il gate)
for w in (0.10, 0.20, 0.30, 0.50):
cap_x = eq * w
tk = TICKET_MED * cap_x / 5_000.0 # il ticket misurato era a taglia $5.000
print(f" {w:>7.0%} ${cap_x:>17,.0f} ${tk:>21,.2f} "
f"{'NO' if cap_x < C_STAR else 'forse':>14}")
print(f"\n E IL COSTO DI ESECUZIONE MANGIA PROPRIO LA COSA CHE SI STA COMPRANDO.")
print(f" Il gate 23/10 chiede 'haircut a $5.000 <= 40%'. Il drift lordo di XSR01 su questa")
print(f" finestra e' {xs.mean()*365:.2%}/anno: e' quello, e solo quello, cio' che il null dice")
print(f" di star comprando. Al netto dell'haircut:")
for h in (0.0, 0.20, 0.40, 0.60):
netto = xs.mean() * 365 * (1 - h)
print(f" haircut {h:>4.0%} -> {netto:>6.2%}/anno netti "
f"{'sopra' if netto > 0.040 else 'SOTTO'} un conto al 4,0% · "
f"{'sopra' if netto > 0.020 else 'SOTTO'} un conto al 2,0%")
h_be = 1 - 0.020 / (xs.mean() * 365)
print(f" pareggio con un conto al 2,0%: haircut {h_be:.0%}. Con un conto al 4,0%: "
f"NON pareggia nemmeno a haircut ZERO.")
print(f" ⚠️ e l'haircut pubblicato ($14,41 di ticket) e' ~2,4x ottimista e senza script"
f" che lo riproduca (XSR-REPRO 22/08).")
print(f"\n C* misurato del venue: ${C_STAR:,.0f}-20.000 (il gate 23/10 e' tarato su ~$3.000, §5.3).")
print(f" Capitale che serve per dare a XSR01 il {best_w:.0%} restando sopra C*: "
f"${C_STAR/best_w:,.0f} sul conto totale.")
# ---------------------------------------------------------------- verdetto
sez("VERDETTO — calcolato a runtime, non scritto a mano (N11)")
mu_n = iso_n[best_w]["muro"]
mu_r = iso_r[best_w]["muro"]
print(f" base (libro solo, finestra comune): perpetua {base_perp:.2%} · muro ${base_muro:,.0f}")
print(f" a ISO-NOZIONALE, XSR01 {best_w:.0%}: muro ${mu_n:,.0f} ({mu_n/base_muro-1:+.1%})")
print(f" a ISO-RISCHIO, XSR01 {best_w:.0%}: muro ${mu_r:,.0f} ({mu_r/base_muro-1:+.1%}) "
f"[k = {iso_r[best_w]['k']:.2f}x]")
aiuta_n = mu_n < base_muro
aiuta_r = mu_r < base_muro
risolto = abs(d_drift) > 2 * se_pair
eseguibile = eq * best_w >= C_STAR
k_ok = iso_r[best_w]["k"] <= 1.40
print(f"\n (a) abbassa il muro a iso-nozionale? {'SI' if aiuta_n else 'NO'}")
print(f" (b) abbassa il muro a iso-rischio? {'SI' if aiuta_r else 'NO'}")
print(f" (c) la differenza e' RISOLTA (|d| > 2 SE)? {'SI' if risolto else 'NO'}")
print(f" (d) il k richiesto e' autorizzato (<= 1,40)? {'SI' if k_ok else 'NO'}")
print(f" (e) e' ESEGUIBILE al capitale di oggi? {'SI' if eseguibile else 'NO'}")
if g is not None:
print(f" (f) `weights_tilt_null` passa? {'SI' if g['gate_pass'] else 'NO'}")
cond = [aiuta_r, risolto, k_ok, eseguibile] + ([g["gate_pass"]] if g is not None else [])
print(f" (g) batte un CONTO REMUNERATO al 4,0% a pari peso? "
f"{'SI' if m_vero < n4[0.040] else 'NO'} "
f"(XSR01 ${m_vero:,.0f} vs conto ${n4[0.040]:,.0f})")
cond.append(m_vero < n4[0.040])
print(f"\n => XSR01 sotto la lente RENDITA: {sum(cond)}/{len(cond)} condizioni.")
if not eseguibile:
print(f" => Il vincolo BINDING non e' il rendimento: e' il CAPITALE. Sotto ${C_STAR/best_w:,.0f}")
print(f" totali la domanda 'serve XSR01?' non ha una risposta comprabile.")
if __name__ == "__main__":
main()