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:
Adriano Dal Pastro
2026-08-22 17:12:15 +00:00
parent 14c1a75a7e
commit bd5b634209
6 changed files with 256 additions and 79 deletions
+96 -27
View File
@@ -382,13 +382,19 @@ def main() -> None:
thr = float(np.quantile(vals[:-1], 0.30))
last_open = ser[ser > 0.30]
since = (V.index[-1] - last_open.index[-1]).days if len(last_open) else None
inwin = ser[(ser.index >= puts["ts"].min()) & (ser.index <= puts["ts"].max())]
near = inwin.max() if len(inwin) else float("nan")
print(f" {a}: quota di giorni col gate APERTO per anno — "
+ " ".join(f"{y}:{v:.0%}" for y, v in per_year.items()))
print(f" DVOL oggi {vals[-1]:.1f} · serve DVOL > {thr:.1f} "
f"(+{thr / vals[-1] - 1:.0%}) per riaprire il gate · ultimo giorno aperto "
f"{last_open.index[-1]:%Y-%m-%d} ({since} giorni fa)")
print(f" quanto vicino c'e' andato DENTRO la finestra: IV-rank max "
f"{near:.4f} il {inwin.idxmax():%Y-%m-%d}"
f"{'mancato per ' + format(0.30 - near, '.4f') if near <= 0.30 else 'aperto'}")
print(" → il campione non e' 'sfortunato': cade dentro un regime di vol bassa lungo e\n"
" persistente. La misura giusta si potra' rifare quando quel numero sara' superato,\n"
" persistente. Ma il margine NON e' comodo: il gate ha sfiorato l'apertura, e\n"
" bastano ~+10% di DVOL per riaprirlo. La misura giusta si potra' rifare quando quel numero sara' superato,\n"
" e da allora servira' comunque un anno di settimane per avere un campione.")
ret = {a: (canon[a]["ST"].iloc[-1] / canon[a]["spot"].iloc[0] - 1.0) for a in ASSETS}
@@ -668,6 +674,23 @@ def main() -> None:
f"MEDIANA ONESTA {band['median']:.2f} · banda [{band['lo']:.2f}, {band['hi']:.2f}] · "
f"positiva in {band['frac_positive']:.0%} di {band['n_anchors']} ancore · "
f"fortuna {band['luck']:+.2f}")
# DOVE vive l'instabilita': nel numeratore (il guadagno) o nel denominatore (la vol)?
det = []
for o in offsets:
w = by_off(o)
if len(w) > 2 and w.std(ddof=1) > 0:
det.append((o, float(w.mean()), float(w.std(ddof=1)), len(w)))
if det:
mm = np.array([d[1] for d in det])
ss = np.array([d[2] for d in det])
print(f" media settimanale fra le ancore: [{mm.min():+.2%}, {mm.max():+.2%}] "
f"(rapporto {mm.max() / max(mm.min(), 1e-9):.1f}x) · "
f"deviazione standard: [{ss.min():.2%}, {ss.max():.2%}] "
f"(rapporto {ss.max() / max(ss.min(), 1e-9):.1f}x)")
print(f" → l'ancora NON cambia quanto si guadagna, cambia il DENOMINATORE: con\n"
f" {det[0][3]} settimane e nessuna perdita la vol campionaria e' quasi\n"
f" arbitraria, e lo Sharpe con lei. Non e' che le 08:00 siano un'ora\n"
f" magica — e' che questa statistica non porta informazione.")
print("\n (d) null del de-levering / beta — 'e' reddito da volatilita' o crypto travestito?'")
print(" Lo spread ha delta positivo (≈ +0.18 all'ingresso): in un campione che sale del")
@@ -697,8 +720,15 @@ def main() -> None:
dly = comb.resample("1D").sum().fillna(0.0)
rep = A.marginal_vs_tp01(dly)
act = int((dly != 0).sum())
print(f" verdetto={rep.get('verdict')} corr={rep.get('corr'):.3f} "
f"(barre ATTIVE {act}/{len(dly)} = {act / len(dly):.0%})")
def _f(k):
v = rep.get(k)
return f"{v:.3f}" if isinstance(v, (int, float)) and v is not None else str(v)
print(f" verdetto={rep.get('verdict')} corr={_f('corr')} "
f"insample_edge={rep.get('has_insample_edge')} robust_oos={rep.get('robust_oos')} "
f"is_hedge={rep.get('is_hedge')}")
print(f" barre ATTIVE {act}/{len(dly)} = {act / len(dly):.0%} — un `None` qui non e'\n"
f" un bug: le sotto-misure che richiedono un hold-out non hanno dati per\n"
f" esistere, e la funzione lo dichiara invece di inventare un numero.")
print(f" ⚠️ {len(comb)} settimane su un hold-out che non esiste: il verdetto e' "
f"rumore, si riporta per non ometterlo.")
except Exception as exc: # noqa: BLE001
@@ -719,36 +749,75 @@ def main() -> None:
# ------------------------------------------------------------ §7 VERDETTO
hr("§7 VERDETTO")
print(""" SCARTATO — su questi dati la domanda non e' decidibile, e i tre motivi sono
indipendenti l'uno dall'altro:
print(""" SCARTATO — su questi dati la domanda non e' decidibile. Quattro motivi, indipendenti
l'uno dall'altro: ciascuno da solo basterebbe.
1. IL CAMPIONE NON CONTIENE LA STRATEGIA. 0 settimane su 19 passano il gate IV-rank>0.30
che E' l'alpha di VRP01. Il campione e' vol implicita al 24-28 percentile E un rialzo
forte del sottostante: il regime migliore possibile per vendere put, non uno neutro.
Le 10 settimane per asset (non 16: prima del 2026-06-09 la finestra 4-10 DTE non
esiste) danno 10/10 vincenti su BTC. La lente giusta non e' lo Sharpe, e' la regola
del tre: 0 perdite su 10 lascia un tasso vero fino al 30%, su un payoff che perde
~7x il credito.
che E' l'alpha di VRP01 — il sleeve sarebbe stato FLAT per l'intero campione. La DVOL
mediana sta al 7 (BTC) / 11 (ETH) percentile della storia 2021+, e il sottostante e'
salito del +25% / +44%: vol implicita bassa E rialzo forte = il regime MIGLIORE
possibile per vendere put, non uno neutro. Le settimane sono 10 per asset, non 16
(prima del 2026-06-09 l'archivio seguiva solo la finestra 13-20 DTE: quella 4-10 DTE
non esiste). Esito: 10/10 vincenti su BTC, e la lente giusta non e' lo Sharpe ma la
regola del tre — 0 perdite su 10 lascia un tasso vero fino al 30%, su un payoff che
perde ~7x il credito.
⚠️ Sfumatura che va detta: il gate non e' lontano. Ha mancato l'apertura per 0.0002 di
IV-rank il 2026-06-07, e bastano ~+10% di DVOL per riaprirlo. Il campione e' dentro un
regime di vol bassa persistente, non davanti a un muro.
2. LA FAMIGLIA CHE HA STORIA NON E' QUELLA CHE SI PUO' ESEGUIRE. Le quote raccolte
sono le opzioni INVERSE (margine e regolamento in BTC/ETH); il conto e' in USDC.
La famiglia USDC-lineare esiste per BTC ed ETH ed ha un lotto minimo 10x piu' piccolo
(BTC 0.01 invece di 0.1) — quindi il muro «BTC fuori a $3.000» del 30/07, congelato
in un test, e' misurato sulla famiglia sbagliata. Ma di quella famiglia abbiamo ZERO
ore di storia e l'open interest e' ~0.
2. IL TITOLO E' QUASI TUTTO FORTUNA D'ANCORA. L'ora d'ingresso e' un max-of-k mai
dichiarato, ed e' la prima volta che si misura su questa struttura: su 9 ancore lo
Sharpe canonico BTC 32.58 sta all'89 percentile e la MEDIANA ONESTA e' 1.45, con la
banda che tocca il NEGATIVO (-0.35). Fortuna +31.13. Su ETH 3.90 -> 2.41.
Il numero da citare per BTC e' 1.45, non 32.58 — e a quel punto non c'e' piu' niente
di straordinario da spiegare.
3. LO SPREAD E' IL COSTO DOMINANTE E NON E' MODELLABILE DA UN MID. Attraversare il
bid/ask costa da solo una quota grossa del credito, e l'ala che si COMPRA e' la gamba
dove il libro e' piu' largo — lo stesso meccanismo che il 30/07 misurava come f=0.73.
3. LA FAMIGLIA CHE HA STORIA NON E' QUELLA CHE SI PUO' ESEGUIRE. Le quote raccolte sono
le opzioni INVERSE (margine e regolamento in BTC/ETH); il conto e' in USDC e il book
esegue sui perpetual lineari USDC. Esiste una famiglia USDC-lineare per BTC ed ETH col
lotto minimo 10x piu' piccolo (BTC 0.01 = $773 di nozionale invece di 0.1 = $7.728),
quindi il muro «BTC fuori a $3.000» del 30/07 — congelato in
tests/test_vrp_profit_take.py — e' misurato sulla famiglia che il conto non margina.
E' la 3a occorrenza della stessa forma dopo fee_watch (21/08) e la taratura di
venue_watch: un numero puntato su una configurazione diversa da quella che gira.
Ma di quella famiglia abbiamo ZERO ore di storia.
Cio' che NON si conclude: che la struttura non funzioni. Non e' stata osservata nel regime
in cui lavora. La regola «niente short-vol da MODELLO in deploy» NON diventa «short-vol da
QUOTE»: le quote ora ci sono, ma sono quote della famiglia sbagliata, in un regime solo.
4. LO SPREAD E' IL COSTO DOMINANTE, E SULLA FAMIGLIA ESEGUIBILE E' PEGGIO. Attraversare
il bid/ask costa ~10% del credito sugli INVERSE; nella regione di strike che serve lo
spread relativo mediano e' 24-37% sugli inverse e 29-59% sulle USDC, con open interest
~0. Il f del credito netto si replica indipendentemente a 0.714 (IC95 [0.690, 0.779],
0/19 osservazioni >= 1.0) — conferma dello 0.73 del 30/07 su un campione piu' lungo e
con un percorso diverso.
AZIONE RACCOMANDATA (non eseguita — tocca la produzione, e la decisione e' dell'operatore):
far raccogliere a `collect_chain.py` anche `currency=USDC` (famiglie BTC_USDC/ETH_USDC).
Costa ~2 chiamate in piu' per giro; senza, fra sei mesi ci ritroveremo con un anno di
storia della famiglia che non possiamo tradare e zero di quella che potremmo.""")
CIO' CHE NON SI CONCLUDE: che la struttura non funzioni. Non e' stata osservata nel regime
in cui lavora. E un risultato a favore c'e', va detto: su BTC il null «e' solo crypto
travestito» e' REFUTATO (beta +0.019, t=0.18) — il PnL non viene dal rialzo. Non basta,
perche' il punto 2 toglie il titolo comunque.
LA REGOLA NON CAMBIA. «Niente short-vol da MODELLO in deploy» non diventa «short-vol da
QUOTE»: le quote adesso ci sono, ma sono quote della famiglia sbagliata, in un regime solo,
e con l'ancora che spiega il risultato. La sostituzione della regola resta NON DIMOSTRATA.
DUE AZIONI, NESSUNA ESEGUITA (toccano la produzione o il conto: decide l'operatore).
(A) DATO — far raccogliere a `collect_chain.py` anche `currency=USDC`. Costo MISURATO col
filtro OI>=100 gia' in vigore: ETH_USDC porterebbe 119 strumenti per giro (+21% di
chiamate, da ~570 a ~690), BTC_USDC ne porterebbe 5 su 686 (0.7%) = nulla di
utilizzabile. Cioe': l'unica struttura USDC-regolata con un libro vero e' su ETH,
lotto minimo 0.1 ETH = $242. Senza questa raccolta, fra sei mesi avremo un anno di
storia della famiglia che non possiamo marginare e zero di quella che potremmo — che
e' esattamente la posizione di oggi, un'ondata dopo l'altra.
(B) CONTO — una domanda che nessun dato pubblico chiude e che viene PRIMA di ogni
backtest: un saldo in USDC puo' marginare un'opzione INVERSE? Se no, la famiglia con
3 mesi di storia non e' negoziabile da questo conto a nessun capitale, e il punto 3
smette di essere un dettaglio di lotto per diventare un muro. Si risolve come si
risolse il PRIIPs il 26/07: guardando il conto, non i dati.
SE E QUANDO RIAPRIRLO. Non «quando ci sara' un crash» (criterio senza numero) ma: DVOL BTC
> 48.3 o ETH > 62.8 in modo persistente, PIU' ~un anno di settimane raccolte in quel
regime sulla famiglia eseguibile. Prima di allora ogni misura su questa struttura
descrivera' la sua astensione.""")
if __name__ == "__main__":