research: traiettoria di accumulo ricalcolata col fattore de-luck corretto

Il fattore agisce DUE volte e i due effetti pesano quasi uguale: alza il drift (si
accumula prima) E abbassa il bersaglio (il muro scende da $495k a $272k). Le colonne
li separano invece di sommarli alla cieca.

Mediana degli anni da $600 al capitale-rendita (block bootstrap, 3000 path, 25 anni):

  dep./mese   x0.60 muro $495k   x0.89 muro $495k   x0.89 muro $272k
              (25/07)            (solo drift)       (26/07)
     0        mai                mai                mai
     250      22.4a  (8% <20a)   19.6a  (53%)       16.2a  (91%)
     500      19.6a  (48%)       15.7a  (94%)       12.4a  (100%)
     1000     14.8a  (95%)       12.0a  (100%)       9.0a  (100%)
     2000     10.0a  (100%)       8.5a  (100%)       6.0a  (100%)

VALIDAZIONE: la colonna x0.60 riproduce ESATTAMENTE i numeri pubblicati il 25/07
(500/m -> 19.6a, 1000/m -> 14.8a) -> la replica e' fedele e le altre due colonne sono
confrontabili con quelle.

A 500 EUR/mese: dei ~7 anni guadagnati, ~4 vengono dal drift e ~3 dal bersaglio.

CIO' CHE NON CAMBIA: senza depositi il capitale-rendita non si raggiunge MAI (0% dei
path a 20 anni, a ogni fattore). L'accumulo viene dai versamenti, non dal rendimento:
correggere il x0.6 accorcia i tempi, non crea una via che non c'era.

Book, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-07-26 17:05:49 +00:00
parent 75713a5ec4
commit 825bf081f4
3 changed files with 99 additions and 3 deletions
+57
View File
@@ -67,6 +67,33 @@ def perp_and_wall(r: np.ndarray, k: float, gross_needed: float) -> tuple[float,
return lo2, perp, cap
def trajectory(r: np.ndarray, cap_needed: float, n_paths: int = 3000,
years: int = 25, seed: int = 725) -> dict:
"""Da $600 al capitale-rendita, stocastico (block bootstrap): stessa logica di
r0725_capcurve.part_d, parametrizzata sul fattore e sul bersaglio."""
rng = np.random.default_rng(seed)
n_days = 365 * years
paths = CC._boot_paths(r, n_paths, n_days, 20, rng)
out = {}
for dep_eur in (0, 250, 500, 1_000, 2_000):
dep = dep_eur * CC.EURUSD
cap = np.full(n_paths, 600.0)
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
newly = (hit < 0) & (cap >= cap_needed)
hit[newly] = t
yrs = np.where(hit >= 0, hit / 365.0, np.nan)
fin = yrs[~np.isnan(yrs)]
out[dep_eur] = dict(
p50=float(np.percentile(fin, 50)) if len(fin) > 100 else float("nan"),
p10=float(np.percentile(fin, 10)) if len(fin) > 100 else float("nan"),
p20y=float((yrs <= 20).sum() / len(yrs)))
return out
def main() -> None:
print("=" * 100)
print(" r0726 — MURI DI CAPITALE col fattore de-luck MISURATO (era ×0.6 a occhio)")
@@ -123,6 +150,36 @@ def main() -> None:
print("\n (a questa taglia la differenza fra ×0.6 e ×0.89 sono centesimi al giorno:")
print(" il fattore conta per il MURO e per le soglie prop, non per il conto attuale.)")
# ---------------------------------------------------------------- traiettoria
print("\n" + "=" * 100)
print(" TRAIETTORIA da $600 al capitale-rendita (block bootstrap, 3000 path, 25 anni)")
print("=" * 100)
print(" Il fattore agisce DUE VOLTE: alza il drift (si accumula piu' in fretta) E abbassa")
print(" il bersaglio (serve meno capitale). Le due colonne centrali separano gli effetti.")
cap_old = res[(0.60, 1.0)][2]
cap_new = res[(0.89, 1.0)][2]
scen = [
(0.60, cap_old, f"×0.60, muro ${cap_old:,.0f} (25/07)"),
(0.89, cap_old, f"×0.89, muro ${cap_old:,.0f} (solo drift)"),
(0.89, cap_new, f"×0.89, muro ${cap_new:,.0f} (26/07)"),
]
T = {}
for f, capn, lab in scen:
r = (base - (1.0 - f) * mu).values.astype(float)
T[lab] = trajectory(r, capn)
for dep in (0, 250, 500, 1_000, 2_000):
print(f"\n deposito {dep:,}/mese")
print(f" {'scenario':<34}{'p10':>8}{'MEDIANA':>10}{'P(entro 20a)':>14}")
for _f, _c, lab in scen:
d = T[lab][dep]
fm = (lambda v: f"{v:.1f}a" if np.isfinite(v) else "")
print(f" {lab:<34}{fm(d['p10']):>8}{fm(d['p50']):>10}{d['p20y']:>13.0%}")
print("\n ⚠️ Restano vere le due cose che non dipendono dal fattore: senza depositi il")
print(" capitale-rendita non si raggiunge, e la mediana e' una MEDIANA (meta' dei")
print(" path arriva dopo, e una quota non arriva affatto).")
if __name__ == "__main__":
main()