research(goal50): matematica onesta del target 50eur/g + gate deploy pre-registrato statarb
- r0724_goal50_math: muro capitale (73-228k), leva=rovina, Monte Carlo prop-firm sui ritorni reali del book (P(pass) 56-86%, funded 100k mediana 31-42eur/g), vault TVL 1-2M. Unica via 'da mesi' = moltiplicare nozionale gestito. - r0724_statarb_deploy_gate: regola di deploy PRE-REGISTRATA a fwd-day 25 (decisione 2026-09-27, Sh>=0.5, haircut<0.5pp, 1 proroga max) — anti selection-on-forward. - diario roadmap (sezioni web-research da completare). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""r0724_statarb_deploy_gate — gate di deploy PRE-REGISTRATO per STATARB-RESID (2026-07-24).
|
||||
|
||||
PERCHE' PRE-REGISTRATO: la regola si fissa a forward-day 25 (oggi), PRIMA di vedere
|
||||
il giorno 90. Decidere "a occhio" dopo aver visto il numero = selection-on-forward,
|
||||
lo stesso bias che il progetto ha gia' pagato (gate SELECTION-ON-HOLDOUT, 2026-06-29).
|
||||
|
||||
REGOLA (immutabile — ogni modifica va motivata nel diario come violazione):
|
||||
- Data decisione: 2026-09-27 (90 giorni forward dal 2026-06-29). Non prima.
|
||||
- Metrica: Sharpe annualizzato di net_modeled su TUTTA la finestra forward
|
||||
(nessuna sottofinestra), da data/paper_statarb/returns.jsonl.
|
||||
- Esiti:
|
||||
Sharpe >= 0.5 -> CANDIDATO AL DEPLOY: proporre peso {10,15,20}% del book
|
||||
Deribit, giudicato con weights_tilt_null + stima maxDD
|
||||
combinata < 15%. Deploy solo se il tilt-null passa.
|
||||
0 <= Sh < 0.5 -> ESTENDI una sola volta di altri 90g (decisione 2026-12-26).
|
||||
Alla seconda scadenza: o >=0.5 o RITIRO. Niente terza proroga.
|
||||
Sharpe < 0 -> RITIRO dal forward-monitor (l'edge DSR 0.929 non ha confermato).
|
||||
- Guardie accessorie (tutte richieste per il deploy):
|
||||
* fill-haircut cumulato |MODELED - REAL| < 0.5 pp (eseguibilita' reale a $600);
|
||||
* config invariata (W=45, sgn=+1) — ogni ritocco azzera la finestra;
|
||||
* maxDD forward < 10% (coerenza col profilo di ricerca, DD backtest ~11%).
|
||||
|
||||
Uso: `uv run python scripts/research/r0724_statarb_deploy_gate.py`
|
||||
(si puo' lanciare in qualsiasi momento: ricorda la data-decisione e valuta lo stato).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RETURNS = ROOT / "data" / "paper_statarb" / "returns.jsonl"
|
||||
|
||||
START = date(2026, 6, 29) # inizio forward (config congelata)
|
||||
DECISION = date(2026, 9, 27) # 90g forward — PRIMA data utile di decisione
|
||||
DECISION_EXT = date(2026, 12, 26) # unica proroga ammessa
|
||||
SH_DEPLOY = 0.5
|
||||
HAIRCUT_MAX_PP = 0.5
|
||||
DD_MAX = 0.10
|
||||
|
||||
|
||||
def main() -> None:
|
||||
rows = [json.loads(x) for x in RETURNS.read_text().splitlines() if x.strip()]
|
||||
rm = np.array([r["net_modeled"] for r in rows])
|
||||
rr = np.array([r["net_real"] for r in rows])
|
||||
n = len(rm)
|
||||
sh = float(rm.mean() / rm.std() * np.sqrt(365)) if rm.std() > 0 else 0.0
|
||||
eq = np.cumprod(1 + rm)
|
||||
dd = float(np.max((np.maximum.accumulate(eq) - eq) / np.maximum.accumulate(eq)))
|
||||
haircut_pp = abs(float((np.prod(1 + rm) - np.prod(1 + rr)) * 100))
|
||||
today = date.today()
|
||||
|
||||
print("=" * 88)
|
||||
print(" STATARB-RESID — gate di deploy PRE-REGISTRATO (fissato 2026-07-24, forward-day 25)")
|
||||
print("=" * 88)
|
||||
print(f" finestra forward : {rows[0]['dt'][:10]} -> {rows[-1]['dt'][:10]} ({n} barre)")
|
||||
print(f" Sharpe fwd (mod) : {sh:+.2f} (soglia deploy >= {SH_DEPLOY})")
|
||||
print(f" maxDD fwd : {dd:.1%} (guardia < {DD_MAX:.0%})")
|
||||
print(f" fill-haircut cum : {haircut_pp:.2f} pp (guardia < {HAIRCUT_MAX_PP} pp)")
|
||||
print(f" data decisione : {DECISION} (proroga unica: {DECISION_EXT})")
|
||||
if today < DECISION:
|
||||
print(f"\n -> NESSUNA DECISIONE OGGI ({today}): mancano {(DECISION - today).days} giorni.")
|
||||
print(" Il numero corrente NON autorizza deploy anticipato (regola pre-registrata).")
|
||||
else:
|
||||
if sh >= SH_DEPLOY and dd < DD_MAX and haircut_pp < HAIRCUT_MAX_PP:
|
||||
print("\n -> GATE SUPERATO: procedere con weights_tilt_null sui pesi candidati "
|
||||
"{10,15,20}% e stima maxDD combinata (<15%) prima del deploy.")
|
||||
elif sh >= 0:
|
||||
print("\n -> SOTTO SOGLIA ma >=0: estensione unica fino al "
|
||||
f"{DECISION_EXT} (se gia' estesa: RITIRO).")
|
||||
else:
|
||||
print("\n -> Sharpe forward NEGATIVO: RITIRO dal forward-monitor.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user