#!/usr/bin/env python """r0726_piano_5k500.py — il piano DICHIARATO dall'operatore: €5.000 subito + €500/mese. Non e' una griglia di scenari: e' il calcolo del piano vero, perche' cambia la scala del problema. Il conto oggi e' $597; €5.000 lo portano a ~$6.050 = **9x**, e €500/mese e' il doppio del livello tabulato finora. Tre cose vanno ricalcolate e non estrapolate: 1. la TRAIETTORIA (quando si tocca il capitale-rendita, con che dispersione); 2. quanto vale il VERSAMENTO INIZIALE rispetto agli stessi soldi versati piu' tardi — il 26/07 ha misurato che il calendario vale un fattore 6, quindi un anticipo di €5.000 non e' "un mese in piu'"; 3. le SOGLIE OPERATIVE che si attraversano (GTAA01 a ~$13k, XS01 a ~$117k, XSR01 a ~$5k con gate 23/10), perche' cambiano il book eseguibile. Ipotesi dichiarate: fattore d'ancora ×0.89 MISURATO, book live TP01+SKH01 (i backtest sono a 0.10% RT), fisco 33%, EURUSD 1.09, bersaglio €50/g netti = $272.061. uv run python scripts/research/r0726_piano_5k500.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 r0726_capwall_refresh as WR # noqa: E402 import r0726_deposits as DP # noqa: E402 CONTO_OGGI = 596.92 # equity reale letta dal conto Deribit LUMP_EUR = 5_000.0 MENSILE_EUR = 500.0 N_PATHS = 6000 BLOCK = 20 YEARS = 25 SEED = 20260726 def run(paths: np.ndarray, start: float, dep_usd: float, wall: float, lump_at_day: int | None = 0, lump: float = 0.0) -> dict: """Traiettoria con capitale iniziale, versamento mensile e un eventuale versamento una-tantum.""" n_paths, n_days = paths.shape cap = np.full(n_paths, start) hit = np.full(n_paths, -1, int) snaps = {} for t in range(n_days): if lump and lump_at_day == t: cap += lump cap = cap * (1.0 + paths[:, t]) if t % 30 == 0 and t > 0: cap += dep_usd newly = (hit < 0) & (cap >= wall) hit[newly] = t if (t + 1) % 365 == 0: snaps[(t + 1) // 365] = cap.copy() yrs = np.where(hit >= 0, hit / 365.0, np.nan) return dict(yrs=yrs, snaps=snaps, cap=cap) def main() -> None: print("=" * 100) print(" IL PIANO: €5.000 subito + €500/mese — calcolo dedicato") print("=" * 100) r = DP.deluck_returns() gross = CC.TARGET_EUR_DAY * 365 * CC.EURUSD / (1 - CC.TAX_RATE) _, perp, wall = WR.perp_and_wall(r, 1.0, gross) lump = LUMP_EUR * CC.EURUSD dep = MENSILE_EUR * CC.EURUSD start = CONTO_OGGI + lump print(f" conto oggi ${CONTO_OGGI:,.2f}") print(f" versamento subito €{LUMP_EUR:,.0f} = ${lump:,.0f} -> partenza ${start:,.0f} " f"({start/CONTO_OGGI:.1f}x il conto attuale)") print(f" versamento mensile€{MENSILE_EUR:,.0f} = ${dep:,.0f}") print(f" bersaglio €{CC.TARGET_EUR_DAY:.0f}/g netti = ${wall:,.0f} " f"(rendita perpetua {perp:.2%}, fattore d'ancora ×{DP.DELUCK})") rng = np.random.default_rng(SEED) n_days = 365 * YEARS paths = CC._boot_paths(r, N_PATHS, n_days, BLOCK, rng) # ------------------------------------------------------------------ traiettoria res = run(paths, start, dep, wall) yrs = res["yrs"] fin = yrs[~np.isnan(yrs)] print("\n" + "=" * 100) print(" QUANDO") print("=" * 100) print(f"\n traguardo (${wall:,.0f}): p10 {np.percentile(fin,10):.1f}a " f"MEDIANA {np.percentile(fin,50):.1f}a p90 {np.percentile(fin,90):.1f}a") print(f"\n {'entro':>8}{'probabilita':>14}") for h in (5, 8, 10, 12, 15, 20): print(f" {h:>6}a {float((yrs <= h).sum())/len(yrs):>13.1%}") print(f"\n {'anno':>6}{'capitale p10':>16}{'MEDIANO':>14}{'p90':>16}{'rendita mediana':>18}") for y in (1, 2, 3, 5, 8, 10, 15, 20): s = res["snaps"][y] rent = float(np.median(s)) * perp * (1 - CC.TAX_RATE) / 365.0 / CC.EURUSD print(f" {y:>6}${np.percentile(s,10):>15,.0f}${np.median(s):>13,.0f}" f"${np.percentile(s,90):>15,.0f}{rent:>16.2f} €/g") # ------------------------------------------------------------------ quanto vale l'anticipo print("\n" + "=" * 100) print(" QUANTO VALE VERSARE I €5.000 SUBITO invece che spalmati") print("=" * 100) alt = { "€5.000 subito (il piano)": (start, 0, 0.0), "€5.000 spalmati sul 1° anno": (CONTO_OGGI, None, 0.0), "€5.000 al 5° anno": (CONTO_OGGI, 365 * 5, lump), "niente lump, solo €500/mese": (CONTO_OGGI, None, 0.0), } print(f"\n {'variante':<30}{'mediana traguardo':>20}{f'cap. mediano {YEARS}a':>20}") for lab, (st, day, lp) in alt.items(): if lab == "€5.000 spalmati sul 1° anno": # 12 rate extra da lump/12 nel primo anno cap = np.full(N_PATHS, CONTO_OGGI) hit = np.full(N_PATHS, -1, int) for t in range(n_days): cap = cap * (1.0 + paths[:, t]) if t % 30 == 0 and t > 0: cap += dep + (lump / 12.0 if t <= 365 else 0.0) newly = (hit < 0) & (cap >= wall) hit[newly] = t y = np.where(hit >= 0, hit / 365.0, np.nan) f = y[~np.isnan(y)] print(f" {lab:<30}{np.percentile(f,50):>19.1f}a${np.median(cap):>19,.0f}") continue rr = run(paths, st, dep, wall, lump_at_day=day, lump=lp) f = rr["yrs"][~np.isnan(rr["yrs"])] print(f" {lab:<30}{np.percentile(f,50):>19.1f}a${np.median(rr['cap']):>19,.0f}") # ------------------------------------------------------------------ soglie print("\n" + "=" * 100) print(" SOGLIE OPERATIVE CHE SI ATTRAVERSANO (e quando, al mediano)") print("=" * 100) soglie = [(3_000, "GTAA01 eseguibile (GTAA_MIN_CAPITAL) — ma nel BOOK entra a ~$13k"), (5_000, "XSR01 diventa eseguibile (gate pre-registrato 2026-10-23)"), (13_000, "GTAA01 entra nel book deployable (23% x cap >= $3k)"), (20_000, "SOGLIA DELLA DECISIONE VENUE: si riapre lo split (26/07)"), (117_000, "XS01 eseguibile (~$20k sulla gamba = 19 gambe HL)")] med_by_day = None for lv, nota in soglie: # primo giorno in cui il capitale MEDIANO supera la soglia if med_by_day is None: cap = np.full(N_PATHS, start) med_by_day = np.empty(n_days) for t in range(n_days): cap = cap * (1.0 + paths[:, t]) if t % 30 == 0 and t > 0: cap += dep med_by_day[t] = np.median(cap) idx = np.nonzero(med_by_day >= lv)[0] when = f"{idx[0]/365.0:.1f} anni" if len(idx) else "oltre l'orizzonte" gia = " (GIA' SUPERATA il giorno 1)" if lv <= start else "" print(f" ${lv:>7,} {when:>18}{gia} {nota}") print("\n ⚠️ Le soglie sono attraversate dal capitale MEDIANO: meta' dei percorsi ci arriva") print(" prima, meta' dopo. Non sono date, sono ordini di grandezza.") # ------------------------------------------------------------------ rischio di venue # Tutto quanto sopra assume che il conto ESISTA ancora. Dopo il lavoro del 26/07 quella # non e' un'ipotesi neutra: e' la modalita' dominante di perdere tutto, e va messa dentro. print("\n" + "=" * 100) print(" LO STESSO PIANO, CON IL RISCHIO CHE IL CONTO SPARISCA") print("=" * 100) print(" Le tabelle sopra assumono che Deribit ci sia ancora. Il 26/07 ha misurato che e' la") print(" modalita' DOMINANTE di perdere tutto, non diversificabile dagli sleeve.") print(f"\n {'p annua':>9}{'P(traguardo)':>15}{'P(perso TUTTO)':>17}{'cap. mediano ' + str(YEARS) + 'a':>22}") rng_v = np.random.default_rng(SEED + 99) for p in (0.0, 0.005, 0.01, 0.02, 0.05): haz = 1.0 - (1.0 - p) ** (1.0 / 365.0) alive = np.cumprod(rng_v.random((N_PATHS, n_days)) > haz, axis=1) if p > 0 \ else np.ones((N_PATHS, n_days)) cap = np.full(N_PATHS, start) hit = np.full(N_PATHS, -1, int) for t in range(n_days): cap = cap * (1.0 + paths[:, t]) if t % 30 == 0 and t > 0: cap += dep cap = cap * alive[:, t] newly = (hit < 0) & (cap >= wall) hit[newly] = t print(f" {p:>8.1%}{float((hit >= 0).mean()):>14.1%}" f"{float((alive[:, -1] == 0).mean()):>16.1%}${np.median(cap):>21,.0f}") print("\n Nota: 'perso TUTTO' vuol dire il capitale, non solo i versamenti mancati — e con") print(" un conto solo 'almeno un fallimento' COINCIDE con 'perso tutto'. Il tripwire") print(" cablato oggi copre la parte di questo rischio che ha una FINESTRA (venue gated),") print(" non quella improvvisa (furto di chiavi, sequestro).") print(" ⚠️ E il traguardo cade DOPO la soglia dei $20k: la decisione 'niente split fino a") print(" $20k' ha ora una data, non un'ipotesi.") if __name__ == "__main__": main()