research(wave-0822): ORTHO-SCREEN 7/7 scartato (e uno screen largo non puo' passare il proprio DSR); XS-LITE falsifica il muro dei 20k di XS01
This commit is contained in:
@@ -360,7 +360,10 @@ def sezione2(curve: pd.DataFrame) -> dict:
|
||||
|
||||
print("\n (c) IL CONFOUND DI QUESTO FILONE — la pendenza e' informazione NUOVA o RV riciclata?")
|
||||
rvp = (r1.rolling(24).std() * np.sqrt(24 * 365) * 100).reindex(idx)
|
||||
rvf = (r1.shift(-24).rolling(24).std().shift(-23) * np.sqrt(24 * 365) * 100).reindex(idx)
|
||||
# RV su (t, t+24h]: rolling(24) etichettata a t+24 e riportata indietro a t. (Una prima
|
||||
# stesura aveva uno shift di troppo e misurava la finestra (+24h, +47h): corretto in
|
||||
# sessione confrontando con una seconda implementazione a serie rovesciata.)
|
||||
rvf = (r1.rolling(24).std().shift(-24) * np.sqrt(24 * 365) * 100).reindex(idx)
|
||||
cf = curve[curve.asset == a].copy()
|
||||
cf["hr"] = pd.to_datetime(cf["hr"], utc=True).dt.as_unit("ns")
|
||||
ivf = cf.set_index("hr")[f"iv_{FRONT}"].reindex(idx)
|
||||
@@ -563,9 +566,14 @@ def sezione3(chain: pd.DataFrame, atm_exp: pd.DataFrame, curve: pd.DataFrame) ->
|
||||
f"({prem/CAPITALE:.0%} del conto), vega ${vega:.2f}/pt-vol, fee ${fee:.2f}/gamba")
|
||||
print(f" carry lordo ${carry_g:+.3f}/giorno per struttura; attrito per giro "
|
||||
f"${friz:.2f} => {friz/carry_g:.0f} giorni per andare in pari")
|
||||
print(f"\n Un calendar spread e' DUE gambe: a $635 una sola struttura ETH impegna il")
|
||||
print(f" ~15-30% del conto e rende centesimi al giorno. BTC e' fuori dal lotto minimo.")
|
||||
print(f" Il bersaglio dichiarato e' 50 EUR/giorno: qui si parla di due ordini di grandezza sotto.")
|
||||
print("\n Un calendar spread e' DUE gambe. Cio' che la tabella mostra e' il PREMIO di UNA")
|
||||
print(" gamba al lotto minimo: BTC 26% del conto, ETH 10%. Il premio non e' tutto il")
|
||||
print(" fabbisogno — la gamba CORTA vuole margine, e la misura del 2026-07-30 su una")
|
||||
print(" struttura BTC a rischio definito dava $6.210 di collaterale per lotto. Quindi:")
|
||||
print(" BTC resta fuori per il margine, ETH entra ma una sola struttura impegna il")
|
||||
print(" 10-25% del conto per un carry LORDO di centesimi al giorno.")
|
||||
print(" Il bersaglio dichiarato e' 50 EUR/giorno: qui siamo 2-3 ordini di grandezza sotto,")
|
||||
print(" e il conto non regge la SECONDA struttura che servirebbe per diversificare.")
|
||||
TRIALS.append(("Q2: 2 asset x eseguibilita' al lotto minimo", 2))
|
||||
|
||||
|
||||
@@ -671,17 +679,31 @@ def sezione4(curve: pd.DataFrame) -> None:
|
||||
hold = tgt.shift(1).fillna(0.0)
|
||||
net = (hold * d["r"] - A.FEE_SIDE * hold.diff().abs().fillna(0.0)).dropna()
|
||||
dd_c = A._dd_ret(net)
|
||||
# ⚠️ il k giusto e' il PIU' GRANDE che sta sotto il DD del candidato, non il primo che
|
||||
# trovi salendo da 0.05: partendo dal basso si confronta il candidato con un baseline
|
||||
# quasi spento, che ha un DD ridicolo e uno Sharpe gonfiato dal rapporto. (Errore
|
||||
# commesso e corretto in sessione: dava "candidato sopra il null" con k=0.05.)
|
||||
ks = np.arange(0.05, 3.01, 0.05)
|
||||
best = None
|
||||
for k in np.arange(0.05, 1.01, 0.05):
|
||||
for k in ks[::-1]:
|
||||
b = k * d["r"].reindex(net.index)
|
||||
if A._dd_ret(b) <= dd_c:
|
||||
best = (k, A._sh(b), A._dd_ret(b))
|
||||
best = (float(k), A._sh(b), A._dd_ret(b))
|
||||
break
|
||||
print(f" {a}: candidato Sharpe {A._sh(net):+.2f} maxDD {dd_c:.2%} | "
|
||||
+ (f"buy&hold de-leverato k={best[0]:.2f} -> stesso DD ({best[2]:.2%}) con Sharpe "
|
||||
f"{best[1]:+.2f} => {'IL CANDIDATO NON SOPRAVVIVE' if best[1] >= A._sh(net) else 'candidato sopra il null'}"
|
||||
if best else "nessun k<=1 raggiunge quel DD"))
|
||||
TRIALS.append((f"Q3 {a}: 20 valori di k nel null de-levering", 20))
|
||||
sh_c = A._sh(net)
|
||||
if best is None:
|
||||
print(f" {a}: candidato Sharpe {sh_c:+.2f} maxDD {dd_c:.2%} | nessun k in "
|
||||
f"[0.05,3.00] raggiunge quel DD")
|
||||
else:
|
||||
verdict = ("IL CANDIDATO NON SOPRAVVIVE (il de-levering fa meglio)"
|
||||
if best[1] >= sh_c else "candidato sopra il null di de-levering")
|
||||
print(f" {a}: candidato Sharpe {sh_c:+.2f} maxDD {dd_c:.2%} | buy&hold a leva "
|
||||
f"k={best[0]:.2f} -> stesso o minor DD ({best[2]:.2%}) con Sharpe {best[1]:+.2f}"
|
||||
f" => {verdict}")
|
||||
imp = A.implausible_sharpe(net)
|
||||
print(f" implausible_sharpe sul candidato di finestra: implausible="
|
||||
f"{imp['implausible']} {imp['reasons']}")
|
||||
TRIALS.append((f"Q3 {a}: 60 valori di k nel null de-levering", 60))
|
||||
|
||||
|
||||
# ===========================================================================================
|
||||
@@ -745,15 +767,24 @@ def sezione5(curve: pd.DataFrame) -> None:
|
||||
if k in rep:
|
||||
print(f" {k:20s} = {rep[k]}")
|
||||
imp = A.implausible_sharpe(era)
|
||||
print(f" implausible_sharpe: flagged={imp.get('flagged')} ({imp.get('reasons')})")
|
||||
print(f" implausible_sharpe (proxy, era DVOL): implausible={imp['implausible']} "
|
||||
f"{imp['reasons']}")
|
||||
print(f" earns_slot = (assoluto non-FAIL) AND (marginale ADDS): qui il marginale e' "
|
||||
f"{rep.get('marginal_verdict')} -> **earns_slot = False**.")
|
||||
TRIALS.append(("Sez.5: 2 varianti proxy (long-only, L/S) x 1 soglia", 2))
|
||||
|
||||
sub("(c) il precedente che questo replica")
|
||||
print(" `dvol_directional.py` (2026-06-29) testo' VRP-Z = z-score causale di (IV-RV) come")
|
||||
print(" segnale DIREZIONALE su 5 anni, con la griglia completa: verdetto **HEDGE,")
|
||||
print(" earns_slot=False** — paga solo quando TP01 e' debole, quindi non e' alpha.")
|
||||
print(" La pendenza della term structure e', su questa lente, la stessa variabile con la")
|
||||
print(" gamba realizzata sostituita da una implicita. Il filone non e' nuovo: e' quello.")
|
||||
print(" earns_slot=False**. Qui, con la variante a SOGLIA BINARIA invece che a z-score,")
|
||||
print(" il verdetto misurato e' NEUTRAL con uplift NEGATIVO — un verdetto diverso, la")
|
||||
print(" stessa conclusione (earns_slot=False in entrambi). La differenza sta nella")
|
||||
print(" variante, non nell'esito, e va riportata cosi': non sto dichiarando una replica")
|
||||
print(" che non ho fatto.")
|
||||
print(" Il punto strutturale resta: la pendenza e' il premio di vol con la gamba")
|
||||
print(" REALIZZATA sostituita da una IMPLICITA (SEZIONE 2c: corr(pendenza, RV passata)")
|
||||
print(" = -0.50/-0.57). Non e' una variabile nuova per questo progetto: e' quella, con")
|
||||
print(" un rumore di misura piu' basso e 5 anni di storia in meno.")
|
||||
|
||||
|
||||
# ===========================================================================================
|
||||
@@ -778,7 +809,6 @@ def sezione6() -> None:
|
||||
|
||||
def main() -> None:
|
||||
hr("r0822_term_structure — TERM STRUCTURE DELLA VOL IMPLICITA BTC/ETH")
|
||||
print(__doc__.split("METODO.")[0].strip()[:0] or "", end="")
|
||||
chain = load_quoted_chain()
|
||||
sezione0(chain)
|
||||
atm_exp = build_atm_by_expiry(chain)
|
||||
|
||||
Reference in New Issue
Block a user