ee5c6ed539
Giornata partita da "stato trades" e finita sul disegno del sistema. Versamento di 1.400 USDC atterrato alle 11:03:35Z (equity $667,88 -> $2.066,88); il giro delle 11:47 ha ribilanciato correttamente e ha ripiazzato i disaster-SL alla taglia nuova -- prima volta che il ramo riparato stamattina gira sul serio. (1) PIANO A 10 ANNI DAL CONTO VERO -- r0825_piano_10a_500.py (nuovo) Le tabelle pubblicate partono da $600/$635: rifatte su $2.067, lente L3 CONGIUNTA. Replica superata: chiede EUR 1.718/m dove la tabella da $635 chiedeva EUR 1.733. EUR 500/mese per 10 anni -> mediana $114.934, rendita 18,35 EUR/g, P(>=50 EUR/g) = 0,0% su 3.000 traiettorie. Il bersaglio con EUR 500/m arriva al 17o anno. L'EQUIVALENZA CHE ORDINA IL PIANO: EUR 100/mese in piu' == +4,07%/anno di drift, cioe' +27% su TUTTO il drift del libro. A 10 anni i bonifici fanno il 59%. Tutta la leva autorizzabile vale quanto EUR 100-150/mese: k=1,25 (+15,6%) vale MENO di EUR 100/mese in piu' (+19,1%), e si porta dietro il peggior giorno al 21,48%. E il libro a k=1 rende MENO dell'S&P (15,19% vs 17,40%): il vantaggio sta nello Sharpe (1,35 vs 0,89) e senza leva NON si converte in rendimento. Senza leva il libro non si giustifica come veicolo di ACCUMULO -- si giustifica come veicolo di RENDITA, dove serve 2,5x meno capitale ($254k contro $646k) perche' la perpetua vive sul DD. (2) "ETF QUANDO IL LIBRO E' FLAT" -- SCARTATO, r0825_capitale_fermo.py (nuovo) Il libro e' flat il 28,0% dei giorni (2,7% nel 2021, 77,0% nel 2022, 75,6% nel 2026); live, esposto 14 giorni su 64, leva lorda mediana 0,00x e max 0,52x su un tetto di 1,0x -- il cap non ha mai morso, il vincolo e' il segnale. A ISO-RISCHIO il dinamico PERDE: Sharpe 1,01 contro 1,40 del 50/50 e 1,35 del libro. E il null a maschera casuale (400 estrazioni, stessa quota, blocchi 20g) lo mette al 30o percentile: fa PEGGIO di commutare a caso. A iso-nozionale sembrava vincere (drift 17,09%, il piu' alto) perche' aveva la vol piu' alta: e' la trappola di M6, il de-levering e' il PRIMO test. E IL MECCANISMO CHE SEMBRAVA OVVIO NON ESISTE. Aggregato: SPY 4,91% nei giorni flat contro 21,48% negli altri (-16,57%), e la storia si scrive da sola. FALSA: scomposta per anno il segno ALTERNA (3 su, 4 giu') e il 2022 -- l'anno che doveva reggerla -- ha il segno OPPOSTO. Artefatto di composizione: i giorni flat stanno negli ANNI brutti per l'azionario, non nei GIORNI brutti. M9 ha fatto il suo lavoro su di me. (3) SLIPPAGE RIFATTO ALLA TAGLIA VERA -- r0822_slip_audit.py riparato 26 fill (erano 18), $6-$319. I due piu' grandi mai eseguiti sono di oggi e hanno preso 1,01% e 0,54% della loro barra 5m, con il print a meta' del range (q=0,50). Il caso peggiore resta un fill da $74 del 18/07 al 21,9%: un sabato, nastro inesistente. L'attrito non e' funzione della TAGLIA ma di taglia/volume-della-barra -- l'estrapolazione lineare che prevedeva ~71% a questo capitale e' refutata dalla misura diretta. NB non e' "assente", e' "non ancora testato": manca un fill grande in una barra sottile, e il weekend e' dove TP01 fa il 38% del proprio gross. DIFETTO P1 RIPARATO: l'equity era CABLATA a 636.0 con un commento che diceva di leggerla dal watermark. Il giorno del versamento avrebbe stampato $636 sbagliando di 3,3x proprio la sezione che esiste per dire QUANDO la misura scade. Riparata leggendo il watermark -- e poi riparata di nuovo, perche' i fill del campione sono stati eseguiti a conti diversi ($597-$2.067) e una base sola e' sbagliata comunque la si scelga. Ora la normalizzazione e' PER FILL, e a $600 riproduce il 22,0% originale. DUE ERRORI MIEI, CATTURATI PRIMA DI PUBBLICARLI - maschera VUOTA vestita da risultato: la prima stesura di r0825_capitale_fermo prendeva i giorni flat dalla serie DE-LUCKATA, ma `deluck` sottrae una costante e lo zero esatto sparisce -> maschera vuota, dinamico identico al book, e lo script ha stampato tabelle piene e un p-value. Lo ha rivelato solo la riga "0 = 0.0%". REGOLA: stampare la CARDINALITA' di una maschera prima di usarla. - il meccanismo falso della (2), demolito dalla scomposizione per anno. Suite: 730 passati, 1 fallito -- quello gia' noto di 5.9 (deriva dati, non codice). Watermark del libro live sopravvissuto intatto alla suite (fixture autouse di stamattina). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
154 lines
7.9 KiB
Python
154 lines
7.9 KiB
Python
"""r0825_piano_10a_500.py — €500/mese per 10 anni, dal conto VERO di oggi.
|
||
|
||
DOMANDA (operatore, 2026-08-25): *"dammi strategia a 10 anni con 500 al mese"*.
|
||
|
||
PERCHE' NON BASTAVA CITARE LA TABELLA. Le tabelle pubblicate del piano partono da **$600/$635**.
|
||
Oggi il conto e' **$2.067** (versamento di 1.400 USDC atterrato alle 11:03:35Z). Il lump e' la
|
||
leva piu' grande misurata dopo il versamento mensile stesso (*"€10.000 oggi + €250/m porta P(20a)
|
||
da 14% a 45%"*), quindi la riga vecchia sottostima il caso di oggi e non si puo' riusare.
|
||
|
||
LENTE: **L3 CONGIUNTA** di `r0822d_piano_vero` — libro live 75/25, **funding esatto dentro la
|
||
serie**, ancora de-luckata x0.89, **fisco d'accumulo** ogni anno dentro il portafoglio (33% sulla
|
||
variazione annua di valore, minusvalenze in carry 4 anni, patrimoniale 0,2%). E' la piu' severa
|
||
che il progetto abbia, ed e' quella che ha prodotto muro $313k e *"€1.733/mese per 10 anni"*.
|
||
|
||
⚠️ DIFETTI EREDITATI, dichiarati perche' vanno **a favore del piano** (registrati il 23/08):
|
||
1. `PN.accumula` versa ogni **30 giorni** -> a 10 anni sono **121** versamenti, non 120 (+0,83%);
|
||
2. il contatore `versato` e' uno **scalare che non si ferma al traguardo** -> il "versato" a
|
||
denominatore e' quello dell'INTERO orizzonte, non quello fino all'arrivo.
|
||
Non li ho riparati qui: ripararli cambierebbe i numeri di riferimento e li renderebbe non
|
||
confrontabili con tutto il resto della memoria. Vanno LETTI, non dimenticati.
|
||
|
||
⚠️ E IL NUMERO DA NON DIMENTICARE MAI accanto a questi: la SE del drift L3 e' **5,151%/anno**, e
|
||
il muro e' `prelievo/perpetua` = un **1/x su una quantita' che va a zero** -> la banda e'
|
||
esplosiva e **asimmetrica verso l'alto**: $187k (p90) · **$313k (punto)** · $1,14M (p10) ·
|
||
a **−2 SE il traguardo non esiste a nessun capitale**. Percio' la regola del progetto:
|
||
**il piano si dimensiona sul VERSAMENTO, che e' certo, non sul muro** (N1).
|
||
|
||
uv run python scripts/research/r0825_piano_10a_500.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
|
||
|
||
# --- lo stato VERO di oggi, non un nominale -------------------------------------------------
|
||
START_OGGI = 2066.88 # equity Deribit letta alle 11:47:01Z del 2026-08-25
|
||
START_PUBBL = PV.START # 635.0 — la base delle tabelle pubblicate, per il confronto
|
||
DEP = 500.0 # EUR/mese
|
||
ORIZZONTI = (5, 10, 15, 20)
|
||
N_PATHS = 3000
|
||
SEED = PV.SEED_TRAJ # 725: stesso seme delle traiettorie pubblicate
|
||
BLOCK = PV.BLOCK # 20 giorni
|
||
|
||
|
||
def rendita_eur_giorno(cap: np.ndarray, perp: float) -> np.ndarray:
|
||
"""€/giorno NETTI da un capitale, alla perpetua della lente.
|
||
|
||
⚠️ La perpetua L3 (6,35%) ha gia' le imposte dentro: **non si lordizza una seconda volta**
|
||
(errore corretto il 07/08)."""
|
||
return cap * perp / 365.0 / CC.EURUSD
|
||
|
||
|
||
def main() -> None:
|
||
print("=" * 100)
|
||
print(" r0825 — €500/MESE PER 10 ANNI, dal conto vero di oggi ($2.067)")
|
||
print("=" * 100)
|
||
|
||
B = PV.costruisci_serie()
|
||
r = PV.deluck(B["fund"].values.astype(float)) # L3 CONGIUNTA, ancora x0.89
|
||
lente = PV.Lente("L3 congiunta", r, lordizza=False)
|
||
lente.perp, lente.muro = PV.muro_di(lente)
|
||
|
||
print(f"\n serie: {len(r)} giorni · drift {lente.drift:.2%}/anno · vol {lente.vol:.2%}/anno")
|
||
print(f" perpetua {lente.perp:.2%} · MURO ${lente.muro:,.0f} "
|
||
f"[banda del progetto: $187k (p90) — $1,14M (p10); a −2 SE non esiste]")
|
||
print(f" bersaglio di rendita: €{CC.TARGET_EUR_DAY:.0f}/giorno netti")
|
||
|
||
print(f"\n{'='*100}\n (1) €{DEP:.0f}/MESE DA ${START_OGGI:,.0f} — cosa consegna, per orizzonte"
|
||
f"\n{'='*100}")
|
||
print(f" {'oriz.':>6} {'capitale mediano':>18} {'p10':>12} {'p90':>13} "
|
||
f"{'€/g mediani':>13} {'P(≥50 €/g)':>12} {'versato':>11} {'fin/vers':>9}")
|
||
print(" " + "-" * 98)
|
||
righe = {}
|
||
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]
|
||
out = PN.accumula(paths, DEP, lente.muro, lente.aliq, lente.patr, start=START_OGGI)
|
||
cap, versato = out["cap"], out["versato"]
|
||
eur = rendita_eur_giorno(cap, lente.perp)
|
||
p50 = float((eur >= CC.TARGET_EUR_DAY).mean())
|
||
righe[anni] = dict(med=np.median(cap), eur=np.median(eur), p50=p50, versato=versato)
|
||
print(f" {anni:>4}a ${np.median(cap):>16,.0f} ${np.percentile(cap,10):>10,.0f} "
|
||
f"${np.percentile(cap,90):>11,.0f} {np.median(eur):>12.2f} {p50:>11.1%} "
|
||
f"${versato:>9,.0f} {np.median(cap)/versato:>8.2f}x")
|
||
|
||
print(f"\n{'='*100}\n (2) COSA HA COMPRATO IL VERSAMENTO DI OGGI — $635 (tabelle pubbl.) vs "
|
||
f"$2.067 (reale)\n{'='*100}")
|
||
print(f" {'oriz.':>6} {'da $635':>14} {'da $2.067':>14} {'guadagno':>11} "
|
||
f"{'€/g da $635':>13} {'€/g da $2.067':>15}")
|
||
print(" " + "-" * 78)
|
||
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_PUBBL)["cap"]
|
||
b = PN.accumula(paths, DEP, lente.muro, lente.aliq, lente.patr, start=START_OGGI)["cap"]
|
||
ea, eb = rendita_eur_giorno(a, lente.perp), rendita_eur_giorno(b, lente.perp)
|
||
print(f" {anni:>4}a ${np.median(a):>12,.0f} ${np.median(b):>12,.0f} "
|
||
f"{np.median(b)/np.median(a)-1:>10.1%} {np.median(ea):>12.2f} {np.median(eb):>14.2f}")
|
||
|
||
print(f"\n{'='*100}\n (3) QUANDO ARRIVA IL BERSAGLIO (€50/g = ${lente.muro:,.0f})"
|
||
f"\n{'='*100}")
|
||
rng = np.random.default_rng(SEED)
|
||
ii = DT.boot_idx(len(r), N_PATHS, 25 * 365, BLOCK, rng)
|
||
paths25 = r[ii]
|
||
for dep in (0, 250, 500, 800, 1_000):
|
||
out = PN.accumula(paths25, float(dep), lente.muro, lente.aliq, lente.patr,
|
||
start=START_OGGI)
|
||
d = PV.leggi(out["colpito"], anni_sim=25)
|
||
med = "mai" if not np.isfinite(d["med"]) else f"{d['med']:.1f}a"
|
||
cond = "n/d" if not np.isfinite(d["med_cond"]) else f"{d['med_cond']:.1f}a"
|
||
print(f" €{dep:>5}/m -> mediana {med:>6} (condizionata all'arrivo {cond:>6}, "
|
||
f"arriva il {d['p_arr']:.0%}) · P(entro 20a) {d['p20']:>5.0%}")
|
||
|
||
print(f"\n{'='*100}\n (4) IL VERSAMENTO CHE SERVE DAVVERO PER €50/g, da ${START_OGGI:,.0f}"
|
||
f"\n{'='*100}")
|
||
for anni in (10, 15, 20):
|
||
rng = np.random.default_rng(PV.SEED_DEP)
|
||
ii = DT.boot_idx(len(r), PV.N_DEP, anni * 365, BLOCK, rng)
|
||
p = r[ii]
|
||
riga = []
|
||
for conf in (0.50, 0.75, 0.90):
|
||
d, tot = PV.dep_per_conf(p, lente, conf, start=START_OGGI)
|
||
riga.append(f"P={conf:.0%}: €{d:,.0f}/m" + (f" (tot ${tot:,.0f})" if conf == 0.90 else ""))
|
||
print(f" {anni:>2} anni -> " + " · ".join(riga))
|
||
|
||
print(f"\n{'='*100}\n VERDETTO (calcolato a runtime, non scritto a mano)\n{'='*100}")
|
||
d10 = righe[10]
|
||
print(f" €500/mese per 10 anni da ${START_OGGI:,.0f}:")
|
||
print(f" capitale mediano ${d10['med']:,.0f} · rendita mediana {d10['eur']:.2f} €/giorno")
|
||
print(f" P(≥50 €/g a 10 anni) = {d10['p50']:.1%}")
|
||
print(f" versato ${d10['versato']:,.0f} -> il rendimento fa il "
|
||
f"{max(0.0, 1 - d10['versato']/d10['med']):.0%} del risultato, i bonifici il resto")
|
||
verdetto = ("CENTRA" if d10["p50"] >= 0.5 else "NON CENTRA")
|
||
print(f"\n => a 10 anni €500/mese {verdetto} il bersaglio €50/giorno.")
|
||
print(f" => quello che centra a 10 anni sta nella sezione (4); quello che €500/mese centra,")
|
||
print(f" e quando, sta nella (3).")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|