Files
PythagorasGoal/scripts/research/r0726_piano_5k500.py
T
Adriano Dal Pastro 1227b2baab research: il piano dichiarato EUR 5.000 + EUR 500/mese, e la strozzatura del cap
L'operatore ha dato i numeri veri: EUR 5.000 subito + EUR 500/mese. Cambia la scala
(conto da $597 a $6.047 = 10.1x), quindi ricalcolato in dedicata invece che estrapolato.

QUANDO: traguardo EUR 50/g ($272.061) a p10 9.4a / MEDIANA 11.6a / p90 14.4a;
P(entro 15a) 94%, P(entro 20a) 100%. Rendita mediana: EUR 6.37/g a 3 anni, EUR 11.57/g a
5, EUR 35.18/g a 10, EUR 87.63/g a 15.

VALIDAZIONE INCROCIATA: la variante "solo EUR 500/mese da $600" da' 12.4 anni = esattamente
il numero pubblicato il 25/07 con macchineria diversa.

IL LUMP VALE 0.8 ANNI (12.4 -> 11.6), MENO di quanto suggerisse il "fattore 6" del
calendario, e la ragione e' aritmetica: EUR 5.000 sono ~10 mesi di versamenti a EUR 500,
quindi comprano ~10 mesi. Anticipare vale in proporzione a quanto si anticipa. La mia
aspettativa era piu' alta ed e' corretta.

SOGLIE: $3k e $5k superate il giorno 1 (GTAA01 e XSR01 diventano eseguibili); $13k a ~0.9
anni (GTAA01 entra nel book deployable); $20k a ~1.6 anni = LA DECISIONE VENUE DEL 26/07
SMETTE DI ESSERE UN'IPOTESI E DIVENTA UNA DATA (~19 mesi); $117k a ~7.6 anni (XS01).
Le soglie superate subito NON autorizzano ad anticipare il gate XSR01 del 23/10.

CON IL RISCHIO DI VENUE: P(traguardo) 100% -> 88% a p=1% (P(perso tutto) 23.2%); a p=5% il
capitale mediano e' ZERO. Il piano regge fino a p=2%.

⚠️ AZIONE OPERATIVA TROVATA (non eseguita, e' config su soldi veri): `book._cap` ripiega su
max_notional_per_asset_usd=$300 quando l'equity reale non e' leggibile. A $597 il fallback
era INERTE (equity/2 = $298 ~ $300); dopo il versamento equity/2 vale ~$3.023, quindi un
fallback strozzerebbe il book al ~10% del target, in silenzio. E' l'azione gia'
pre-registrata il 2026-07-02 ("al deposito alzare il cap a equity/2"). Cablato
test_il_cap_fisso_diventa_una_strozzatura_dopo_un_deposito, che FALLISCE se si deposita
senza adeguare il cap.

Aggiunta anche la sezione (F) frontiera di sostenibilita' a r0726_deposits.py: capitale e
rendita per (importo x anni sostenuti), e il confronto "tirare poco tempo vs comodo a
lungo" — EUR 400/m per 5a batte EUR 200/m per 20a, ma EUR 600/m per 3a perde contro
EUR 250/m per 15a.

Book, pesi, cron, config INVARIATI. 380 test verdi (+3).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 20:34:00 +00:00

201 lines
9.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()