ed2532b991
scripts/web/ — motore in JavaScript (engine.js) sui ritorni VERI del book esportati da export_series.py, pagine assemblate da build.py. Da "sistema dinamico dove imposti valore iniziale, mensile e durata, e calcola la best curva fissando il tempo": la simulazione gira nel browser, quindi il motore va riscritto e VA PROVATO che dia la stessa risposta. test_engine.js confronta mediane e probabilita' con r0807_growth_yearly.py su due configurazioni, esige che il versato (deterministico) coincida al centesimo, e include un controllo positivo — un motore col fisco spento DEVE risultare fuori tolleranza, perche' un test che non sa fallire non e' un test. Il risolutore e' validato contro dep_necessario di r0727_tasse.py: -0.4 / -0.6 / -1.1%. smoke.js ESEGUE le pagine con un DOM finto. Serve perche' node --check valida solo la sintassi: ho pubblicato una pagina che lo passava e moriva alla prima riga utile (chiavi Python "0.0" ricostruite in JS come String(0) = "0"; i pesi intermedi funzionavano per caso). Altri due errori che questi strumenti hanno intercettato: - due anni di dati di un grafico scritti A MEMORIA perche' tail aveva troncato l'output -> ora i dati si INIETTANO da JSON (build.py), il passaggio manuale non esiste piu'; - una "distorsione sistematica" del motore JS (+0.75%, 8 semi tutti positivi) che erano 8 estrazioni contro UN punto Python rumoroso. Misurato bene, 8 semi per parte: -0.01%, t = -0.04; ed entrambi i campionatori cadono entro 1.7 SE dall'atteso ANALITICO della media di blocco. Scelta guidata da una misura: la banda del versamento suggerito resta +-1% da 1.200 a 3.000 percorsi -> non domina il Monte Carlo ma la granularita' della bisezione (~5 EUR). Percorsi tenuti bassi e incertezza dichiarata, invece di pagare tempo per una precisione che non arriva. Nessun impatto sulla produzione: non tocca book, pesi, cron o config. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
#!/usr/bin/env python
|
||
"""export_series.py — esporta la serie del book live per il motore nel browser.
|
||
|
||
La pagina interattiva (`pagina_simulatore.html`) simula nel browser, quindi le serve la sequenza
|
||
dei ritorni giornalieri VERI del book: gli stessi che usa `r0807_growth_yearly.py`, cioe' TP01 75%
|
||
+ SKH01 25% alle ancore canoniche, gia' de-luckati x0.89 sul drift da `r0726_venue_risk`.
|
||
|
||
Esporta anche le costanti che il motore deve condividere col Python (bersaglio, cambio, aliquote,
|
||
lunghezza dei blocchi): se una di queste vivesse in due posti, prima o poi divergerebbe.
|
||
|
||
uv run python scripts/web/export_series.py --out /tmp/series.json
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import json
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
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_venue_risk as VR # noqa: E402
|
||
import r0727_lumpsum_split as LS # noqa: E402
|
||
import r0727_tasse as TX # noqa: E402
|
||
|
||
|
||
def main() -> None:
|
||
ap = argparse.ArgumentParser()
|
||
ap.add_argument("--out", required=True)
|
||
a = ap.parse_args()
|
||
|
||
s = VR.venue_series()["Deribit"]
|
||
r = s.values.astype(float)
|
||
|
||
dati = dict(
|
||
n=len(r), start=str(s.index[0].date()), end=str(s.index[-1].date()),
|
||
start_usd=LS.START, target=LS.TARGET, eurusd=CC.EURUSD, deluck=VR.DELUCK,
|
||
tax=0.33, patrimoniale=TX.PATRIMONIALE, carry=TX.CARRY_ANNI, block=20,
|
||
r=[round(x, 8) for x in r],
|
||
)
|
||
Path(a.out).write_text(json.dumps(dati))
|
||
print(f" {len(r)} giorni [{dati['start']} -> {dati['end']}] "
|
||
f"drift {r.mean()*365:.1%} vol {r.std()*365**0.5:.1%}")
|
||
print(f" bersaglio ${LS.TARGET:,.0f} · de-luck ×{VR.DELUCK} · "
|
||
f"scritto {a.out} ({Path(a.out).stat().st_size/1024:.0f} KB)")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|