research(wave-0822): DEPEG — XS01-OOS sopravvive al falsificatore di venue; il caso peggiore non e' il depeg ma il 2025-10-10

This commit is contained in:
Adriano Dal Pastro
2026-08-22 21:17:36 +00:00
parent aaa32daff7
commit 74539db8b8
2 changed files with 243 additions and 9 deletions
+63
View File
@@ -693,6 +693,7 @@ stessi hanno nominato senza poterli eseguire**. Stesso contratto di consegna, st
| # | filone | domanda che decide | verdetto | | # | filone | domanda che decide | verdetto |
|---|---|---|---| |---|---|---|---|
| 21 | XS01-OOS | il vantaggio del PROP-ALLOC poggia sul drift di XS01 misurato sulla sua finestra di scoperta: regge fuori? | **LEAD** — regge, ed e' PIU' GRANDE fuori | | 21 | XS01-OOS | il vantaggio del PROP-ALLOC poggia sul drift di XS01 misurato sulla sua finestra di scoperta: regge fuori? | **LEAD** — regge, ed e' PIU' GRANDE fuori |
| 28 | DEPEG | il falsificatore che l'autore di 21 ha nominato contro se stesso: il depeg USDT contamina il ranking? | **SOPRAVVIVE** — il venue sposta 0,01 di Sharpe |
| 22 | MAKER | l'esecuzione passiva e' una fonte di ritorno, al netto del costo di non essere eseguiti? | **SCARTATO** — il segno dipende da `<` contro `<=` | | 22 | MAKER | l'esecuzione passiva e' una fonte di ritorno, al netto del costo di non essere eseguiti? | **SCARTATO** — il segno dipende da `<` contro `<=` |
| 23 | BOCPD | un rilevatore di cambio di regime vero batte il miglior lookback COSTANTE? | **SCARTATO** — filone chiuso definitivamente | | 23 | BOCPD | un rilevatore di cambio di regime vero batte il miglior lookback COSTANTE? | **SCARTATO** — filone chiuso definitivamente |
| 24 | CRITICO | cosa NON e' stato misurato, e quale singola misura mancante vale di piu' | **3 correzioni all'ondata**, 1 regola mia ritirata | | 24 | CRITICO | cosa NON e' stato misurato, e quale singola misura mancante vale di piu' | **3 correzioni all'ondata**, 1 regola mia ritirata |
@@ -1094,3 +1095,65 @@ verificato contro l'osservato su **6.578 coppie: |errore| mediano 0,023%, p95 0,
1,000000** → rende la superficie utilizzabile su tutti i 75 giorni invece che 23. 1,000000** → rende la superficie utilizzabile su tutti i 75 giorni invece che 23.
**Terza convergenza indipendente sul muro del dato** (75 giorni di superficie); e lo **smile** **Terza convergenza indipendente sul muro del dato** (75 giorni di superficie); e lo **smile**
che i filoni SKEW/TERM non usavano — esiste invece su **113 giorni dal 2026-05-01**. che i filoni SKEW/TERM non usavano — esiste invece su **113 giorni dal 2026-05-01**.
---
## 28 — DEPEG (il falsificatore di XS01-OOS, eseguito)
`scripts/research/r0822b_depeg.py` (811 righe, **18 s**, offline dalla cache, **due corse
byte-identiche**). **112 configurazioni**, e **nessuna e' una selezione**: e' un confronto **appaiato**
dello stesso meccanismo congelato su due fonti di prezzo.
**Perche':** l'autore di §21 aveva dichiarato contro se stesso che la sua validazione di venue gira
**solo sul 2024+**, cioe' proprio il periodo **senza depeg USDT**, mentre il fuori campione contiene
il **maggio 2022**. La soglia — `corr fra i due sleeve >= 0,99` — era **dichiarata da lui, non
dall'esecutore del test**.
**Il dato, e il primo limite:** su 13 asset **10 hanno un prezzo USD** che copre la finestra (9
Coinbase + **XRP da Bitstamp**, perche' Coinbase l'aveva sospeso). **BNB non esiste in USD prima del
2025-10** — e' il token nativo del venue sotto esame. AVAX parte 2021-09-30 → il test **non copre il
2021**, ma copre **esattamente cio' che l'obiezione nomina: maggio 2022 e FTX**.
📌 **Divergenza SCOMPOSTA nelle due componenti che sono domande diverse** (824 giorni, 8.240
osservazioni appaiate): **(a) comune** med 3,2 bps / max 76,7 — quella che lo z-score annulla;
**(b) idiosincratica** med **2,1 bps** / p95 11,2 / max 116,5 — quella che cambia il ranking.
Nel depeg (07→20 maggio 2022) il comune arriva a **39 bps** ma l'idiosincratico sale solo a med
**3,6** / max **33,8 bps** contro 2,0 / 10,9 fuori.
**TEST 1** (meccanismo congelato, 10 asset, 10 fasi, 2021-09→2023-12): **corr mediana 0,9992, minima
0,9921 → PASS**; **dSharpe appaiato 0,000** [0,056, +0,036]; divario di equity cumulato su 2,25
anni **+0,07%**. **Il canale del danno, guardato direttamente:** 734 ribilanciamenti, **10 con gambe
diverse (1,36%)**, tutti a sovrapposizione 4/5, **ZERO dentro la finestra del depeg**; Spearman dello
score mediana **1,0000**.
**TEST 2** (finestra intera di §21): il numero di testa **+1,12 → +1,11**, delta appaiato 0,003.
**VERDETTO: `IL RISULTATO XS01-OOS: SOPRAVVIVE`** — il venue sposta il titolo di §21 di **0,01 di
Sharpe** e **non cambia una sola gamba dentro il depeg**.
**Controllo positivo girato** (obbligatorio, o "corr 0,99" potrebbe essere uno sfasamento): USD
ritardato di 1 giorno → corr mediana **0,011**.
**Tre cose trovate che vanno registrate:**
1. 📌 **L'unica corr sotto soglia e' ATTRIBUITA, e non e' il prezzo.** Col **gate di dispersione
spento** su entrambi i venue la minima passa **0,9674 → 0,9977**. Il gate `disp >= percentile` e'
**binario**, quindi pochi bps cadono ai due lati → **4 intervalli da 10 giorni** in cui uno sleeve
e' pieno e l'altro **flat**, piu' una coda di ~30 giorni in cui la `rv30` del vol-target resta
diversa. **Una scansione di ranking non lo vede.** ✅ Converge con §21 (*"il gate p30 fuori campione
vale ZERO"*): **non porta edge e amplifica il rumore** — ⚠️ non e' una proposta di cambiarlo,
cambiarlo guardando questo numero sarebbe selezione.
2. 🚨 **Il caso peggiore dell'intero campione NON e' il depeg: e' il 2025-10-10** (cascata di
liquidazioni sulle coppie /USDT) — **INJ 1.981 bps**, ADA 315, LTC 201, AAVE 136 mentre BTC/ETH
stanno a 21-22. **Il meccanismo temuto dall'obiezione e' REALE**; semplicemente non e' accaduto nel
2021-2023 ed e' caduto nella finestra di **scoperta**, non nel fuori campione. Nel depeg le
peggiori divergenze sono **AVAX subito dopo la quotazione = book sottile, non stablecoin**.
3. ⚠️ **BNB resta non controllabile** e toglierlo costa **0,75** di mediana di fase (+1,12 → +0,37)
— ✅ **replica esatta del leave-one-out di §21 con implementazione separata**. Contesto onesto:
nella LOO di §21 **LTC (+0,20), BTC (+0,33) e XRP (+0,33) pesano di piu'**, e quelle tre **sono
coperte** dal controllo USD.
**Smentitore residuo dichiarato:** la divergenza del 2025-10-10 e' di **chiusura**; un evento
**intra-giornaliero** della stessa natura sposterebbe il ranking **senza lasciare traccia sulle
chiusure**, e i close giornalieri non lo vedrebbero.
⚠️ *Nota di attribuzione: il file risultava `M` in git perche' **io** (coordinatore) l'avevo incluso
in un commit mentre l'agente ci stava ancora lavorando — non un altro agente. Un `git add -A` durante
un'ondata cattura il lavoro in corso.*
+180 -9
View File
@@ -191,7 +191,12 @@ def certify_usd(asset: str, d: pd.DataFrame, a: str, b: str) -> dict:
flat=float("nan"), zero_vol=float("nan")) flat=float("nan"), zero_vol=float("nan"))
v = series_of(d.assign(close=d["volume"])) v = series_of(d.assign(close=d["volume"]))
v = v[(v.index >= pd.Timestamp(a, tz="UTC")) & (v.index < pd.Timestamp(b, tz="UTC"))] v = v[(v.index >= pd.Timestamp(a, tz="UTC")) & (v.index < pd.Timestamp(b, tz="UTC"))]
attesi = (pd.Timestamp(b, tz="UTC") - s.index.min()).days # ⚠️ la copertura si misura sulla finestra RICHIESTA, non sulla prima barra disponibile:
# contando dal proprio inizio, un asset quotato a meta' finestra esce con gap=0 e "OK", e il
# conteggio degli usabili contraddirebbe la riga sotto che lo esclude. E' lo stesso difetto
# che il progetto ha gia' incontrato due volte (serie TRONCATA che passa ogni controllo
# interno): un controllo che guarda solo DENTRO la serie non vede cio' che la serie non copre.
attesi = (pd.Timestamp(b, tz="UTC") - pd.Timestamp(a, tz="UTC")).days
c = s.values c = s.values
flat = float(np.mean(c[1:] == c[:-1])) if len(c) > 1 else float("nan") flat = float(np.mean(c[1:] == c[:-1])) if len(c) > 1 else float("nan")
zv = float(np.mean(v.values == 0.0)) if len(v) else float("nan") zv = float(np.mean(v.values == 0.0)) if len(v) else float("nan")
@@ -294,19 +299,83 @@ def ranking_scan(PB: pd.DataFrame, PU: pd.DataFrame, phases: list[int],
if ov < 1.0: if ov < 1.0:
diff = sorted(set(PB.columns[list(hiB ^ hiU)]) | set(PB.columns[list(loB ^ loU)])) diff = sorted(set(PB.columns[list(hiB ^ hiU)]) | set(PB.columns[list(loB ^ loU)]))
rows.append(dict(fase=ph, data=PB.index[i], overlap=ov, gambe=",".join(diff))) rows.append(dict(fase=ph, data=PB.index[i], overlap=ov, gambe=",".join(diff)))
D = pd.DataFrame(rows) D = pd.DataFrame(rows, columns=["fase", "data", "overlap", "gambe"])
print(f" [{label}] {tot} ribilanciamenti su {len(phases)} fasi; specchio verificato " print(f" [{label}] {tot} ribilanciamenti su {len(phases)} fasi; specchio verificato "
f"contro il motore in {checked}/{checked} con posizione") f"contro il motore in {checked}/{checked} con posizione")
print(f" [{label}] Spearman dello score fra i venue: mediana {np.median(sp):.4f} " print(f" [{label}] Spearman dello score fra i venue: mediana {np.median(sp):.4f} "
f"min {np.min(sp):.4f}") f"min {np.min(sp):.4f}")
print(f" [{label}] ribilanciamenti con gambe DIVERSE: {len(D)}/{tot} " print(f" [{label}] ribilanciamenti con gambe DIVERSE: {len(D)}/{tot} "
f"({len(D)/max(tot,1)*100:.2f}%)") f"({len(D)/max(tot,1)*100:.2f}%)")
for _, r in D.iterrows(): if len(D):
print(f" fase {int(r['fase'])} {r['data'].date()} " pre = D[D["data"] < pd.Timestamp(T2_END, tz="UTC")]
f"sovrapposizione {r['overlap']*100:3.0f}% gambe scambiate: {r['gambe']}") print(f" [{label}] di cui NELLA finestra fuori campione ({T2_START}..{T2_END}): "
f"{len(pre)} — elencati qui sotto; quelli dal 2024 in poi non sono la domanda")
for _, r in pre.iterrows():
print(f" fase {int(r['fase'])} {r['data'].date()} "
f"sovrapposizione {r['overlap']*100:3.0f}% gambe scambiate: {r['gambe']}")
return D return D
def gate_flips(PB: pd.DataFrame, PU: pd.DataFrame, ph: int) -> list[tuple]:
"""Il SECONDO canale, che una scansione di ranking non vede: il gate di dispersione e' BINARIO
(`disp_i >= percentile espandente`) e quindi DISCONTINUO due prezzi che differiscono di
pochi bps possono cadere ai due lati della soglia, e allora uno sleeve resta pienamente
investito per 10 giorni mentre l'altro sta FLAT. Non e' un cambio di ranking: e' un
interruttore. Ritorna gli intervalli in cui i due venue non sono d'accordo su acceso/spento."""
dB: dict = {}
dU: dict = {}
X.xsec_engine(PB, phase=ph, detail=dB)
X.xsec_engine(PU, phase=ph, detail=dU)
gb = np.abs(dB["W"]).sum(axis=1) > 1e-9
gu = np.abs(dU["W"]).sum(axis=1) > 1e-9
idx = PB.index
flip = np.flatnonzero(gb != gu)
runs, i0 = [], None
for j, i in enumerate(flip):
if i0 is None:
i0 = i
if j + 1 == len(flip) or flip[j + 1] != i + 1:
runs.append((idx[i0], idx[i], int(i - i0 + 1), bool(gb[i0])))
i0 = None
return runs
def autopsia(PB: pd.DataFrame, PU: pd.DataFrame, ph: int, D: pd.DataFrame, label: str) -> None:
"""La fase con la corr piu' bassa NON si riassume, si guarda: una corr di 0,97 o e' un
ribaltamento di ranking (il guasto che sto cercando) o e' un singolo giorno di rumore su una
gamba sottile (che non e' un guasto). Sono conclusioni opposte a partire dallo stesso numero."""
a, b = pair(alive(X.xsec_engine(PU, phase=ph)), alive(X.xsec_engine(PB, phase=ph)))
g = (a - b)
top = g.abs().sort_values(ascending=False).head(4)
dph = D[D["fase"] == ph] if len(D) else D
runs = gate_flips(PB, PU, ph)
print(f" autopsia della fase peggiore ({label}, fase {ph}): i 4 giorni di scarto maggiore")
for t, v in top.items():
prev = dph[dph["data"] <= t]["data"]
near = (t - prev.iloc[-1]).days if len(prev) else None
inflip = [r for r in runs if r[0] <= t <= r[1]]
# ⚠️ la coda: dopo una discordanza del gate uno dei due sleeve ha 10 giorni di ZERI in
# piu' nella finestra rv30 del vol-target -> la LEVA dei due resta diversa per ~30 giorni
# dopo che la discordanza e' finita. Chiamare "rumore di prezzo" un giorno dentro quella
# coda attribuirebbe al venue un effetto che e' della soglia binaria.
tail = [r for r in runs if r[1] < t and (t - r[1]).days <= 30]
if inflip:
r = inflip[0]
tag = (f"GATE DISCORDE {r[0].date()}..{r[1].date()}: "
f"{'USDT investito, USD flat' if r[3] else 'USD investito, USDT flat'}")
elif tail:
tag = (f"coda del vol-target: gate discorde fino al {tail[-1][1].date()}, "
f"{(t - tail[-1][1]).days}g fa -> rv30 diversa, LEVA diversa")
elif near is not None and near <= XS_CFG["H"]:
tag = f"ultimo ribilanciamento con gambe diverse {near} giorni prima"
else:
tag = "stesse gambe, stesso gate: solo rumore di prezzo"
print(f" {t.date()} scarto {g.loc[t]*1e4:+8.0f} bps ({tag})")
print(f" scarto quadratico totale della fase: {float((g**2).sum())**0.5*1e4:.0f} bps; "
f"i 4 giorni sopra ne spiegano "
f"{float((top**2).sum())/float((g**2).sum())*100:.0f}%")
def score_at(P: pd.DataFrame, i: int, lookbacks) -> tuple[np.ndarray, np.ndarray]: def score_at(P: pd.DataFrame, i: int, lookbacks) -> tuple[np.ndarray, np.ndarray]:
"""Specchio della riga di score del motore (z-score medio sui lookback). Serve per confrontare """Specchio della riga di score del motore (z-score medio sui lookback). Serve per confrontare
i RANKING fra venue; la sezione [4] verifica che i top-k/bottom-k che ne derivano coincidano i RANKING fra venue; la sezione [4] verifica che i top-k/bottom-k che ne derivano coincidano
@@ -494,6 +563,35 @@ def main() -> None:
(D1["data"] < pd.Timestamp(DEPEG[1], tz="UTC"))] (D1["data"] < pd.Timestamp(DEPEG[1], tz="UTC"))]
print(f" di cui dentro la finestra del depeg: {len(ind)}") print(f" di cui dentro la finestra del depeg: {len(ind)}")
# ---------------------- [4b] il SECONDO canale: il gate binario, e l'attribuzione
print("\n[4b] IL GATE DI DISPERSIONE E' UN INTERRUTTORE — e una scansione di ranking non lo")
print(" vede. `disp_i >= percentile espandente` e' una soglia: pochi bps di differenza di")
print(" prezzo possono cadere ai due lati, e per 10 giorni uno sleeve e' pieno e l'altro")
print(" e' FLAT. E' l'unico modo in cui una differenza di venue microscopica puo'")
print(" produrre una differenza di P&L macroscopica.")
for label_, Pb_, Pu_ in (("TEST 1 / U10", PB, PU),):
tot_fl = 0
for ph in PHASES:
for a_, b_, nd, bfirst in gate_flips(Pb_, Pu_, ph):
tot_fl += 1
print(f" [{label_}] fase {ph}: {a_.date()} .. {b_.date()} ({nd}g) — "
f"{'USDT investito / USD FLAT' if bfirst else 'USD investito / USDT FLAT'}")
if tot_fl == 0:
print(f" [{label_}] nessuna discordanza del gate su 10 fasi")
else:
print(f" [{label_}] {tot_fl} intervalli di discordanza su 10 fasi")
print("\n ATTRIBUZIONE — stesso confronto con il gate SPENTO su ENTRAMBI i venue")
print(" (diagnostica, NON una proposta di cambiare il meccanismo: serve a separare")
print(" 'il prezzo e' diverso' da 'la soglia binaria amplifica una differenza minuscola'):")
cg = []
for ph in PHASES:
a_, b_ = pair(alive(X.xsec_engine(PU, phase=ph, disp_pct=0)),
alive(X.xsec_engine(PB, phase=ph, disp_pct=0)))
cg.append(float(a_.corr(b_)))
print(f" [TEST 1] corr con gate SPENTO: mediana {np.median(cg):.4f} minima {np.min(cg):.4f}"
f" (col gate acceso: mediana {R['corr'].median():.4f}, minima {R['corr'].min():.4f})")
# ------------------------------- [5] TEST 2 — U13 ibrido, finestra INTERA di §21 # ------------------------------- [5] TEST 2 — U13 ibrido, finestra INTERA di §21
print(f"\n[5] TEST 2 — U13 IBRIDO (USD dove esiste, USDT altrove), {T2_START} .. {T2_END}") print(f"\n[5] TEST 2 — U13 IBRIDO (USD dove esiste, USDT altrove), {T2_START} .. {T2_END}")
print(" Domanda operativa: sostituendo TUTTO il prezzo in dollari che esiste, il titolo") print(" Domanda operativa: sostituendo TUTTO il prezzo in dollari che esiste, il titolo")
@@ -537,6 +635,24 @@ def main() -> None:
print("\n E il ranking, sull'ibrido (la fase con la corr piu' bassa va GUARDATA, non") print("\n E il ranking, sull'ibrido (la fase con la corr piu' bassa va GUARDATA, non")
print(" riassunta: una corr di 0,97 su una fase o e' un ribaltamento vero o e' un giunto):") print(" riassunta: una corr di 0,97 su una fase o e' un ribaltamento vero o e' un giunto):")
D2 = ranking_scan(PBh, PUh, PHASES, "TEST 2 / U13-IBRIDO") D2 = ranking_scan(PBh, PUh, PHASES, "TEST 2 / U13-IBRIDO")
print("\n Discordanze del GATE binario sull'ibrido (finestra fuori campione):")
nfl = 0
for ph in PHASES:
for a_, b_, nd, bfirst in gate_flips(PBh, PUh, ph):
if a_ >= pd.Timestamp(T2_END, tz="UTC"):
continue
nfl += 1
print(f" fase {ph}: {a_.date()} .. {b_.date()} ({nd}g) — "
f"{'USDT investito / USD FLAT' if bfirst else 'USD investito / USDT FLAT'}")
print(f" totale {nfl} intervalli su 10 fasi (su ~204 ribilanciamenti per fase)")
cg2 = []
for ph in PHASES:
a_, b_ = pair(win(alive(X.xsec_engine(PUh, phase=ph, disp_pct=0)), T2_START, T2_END),
win(alive(X.xsec_engine(PBh, phase=ph, disp_pct=0)), T2_START, T2_END))
cg2.append(float(a_.corr(b_)))
print(f" ATTRIBUZIONE [TEST 2] corr con gate SPENTO: mediana {np.median(cg2):.4f} "
f"minima {np.min(cg2):.4f} (col gate acceso: mediana {R2['corr'].median():.4f}, "
f"minima {R2['corr'].min():.4f})")
# ------------------------------- [5b] le gambe che NESSUN venue USD puo' controllare # ------------------------------- [5b] le gambe che NESSUN venue USD puo' controllare
print("\n[5b] LE TRE GAMBE NON CONTROLLABILI — quanto del risultato di §21 ci passa?") print("\n[5b] LE TRE GAMBE NON CONTROLLABILI — quanto del risultato di §21 ci passa?")
@@ -588,15 +704,44 @@ def main() -> None:
f"T2 fase {int(worst2['ph'])} corr {worst2['corr']:.4f}") f"T2 fase {int(worst2['ph'])} corr {worst2['corr']:.4f}")
print(f" peggior FASE per dSharpe: T1 fase {int(wd1['ph'])} {wd1['d']:+.3f} | " print(f" peggior FASE per dSharpe: T1 fase {int(wd1['ph'])} {wd1['d']:+.3f} | "
f"T2 fase {int(wd2['ph'])} {wd2['d']:+.3f}") f"T2 fase {int(wd2['ph'])} {wd2['d']:+.3f}")
autopsia(PB, PU, int(worst1["ph"]), D1, "TEST 1")
autopsia(PBh, PUh, int(worst2["ph"]), D2, "TEST 2")
st = idio.abs().stack().sort_values(ascending=False) st = idio.abs().stack().sort_values(ascending=False)
print(" le 8 divergenze IDIOSINCRATICHE piu' grandi della finestra (bps di livello):") print(" le 8 divergenze IDIOSINCRATICHE piu' grandi della finestra del TEST 1 (bps):")
for (t, s), v in st.head(8).items(): for (t, s), v in st.head(8).items():
indep = "DEPEG" if pd.Timestamp(DEPEG[0], tz="UTC") <= t < pd.Timestamp(DEPEG[1], tz="UTC") else "" indep = "DEPEG" if pd.Timestamp(DEPEG[0], tz="UTC") <= t < pd.Timestamp(DEPEG[1], tz="UTC") else ""
print(f" {str(t.date()):<12}{s:<6}{v:8.0f} bps (comune quel giorno " print(f" {str(t.date()):<12}{s:<6}{v:8.0f} bps (comune quel giorno "
f"{common.loc[t]:+.0f} bps) {indep}") f"{common.loc[t]:+.0f} bps) {indep}")
print(" -> se le peggiori NON cadono nel depeg, il rumore di venue e' book sottile,") print(" -> le peggiori NON cadono nel depeg e sono quasi tutte AVAX nelle settimane subito")
print(" non contaminazione da stablecoin: due cause diverse, due implicazioni diverse.") print(" dopo la sua quotazione su Coinbase: book sottile, non contaminazione da")
print(" stablecoin. Due cause diverse e due implicazioni diverse.")
# --------- il caso peggiore su TUTTO il campione, non solo sulla finestra del test
print("\n ⚠️ E ORA LA DOMANDA GIUSTA, allargata: dove divergono di piu' i due venue in")
print(" TUTTO il campione 2021-2026? (cercare il caso peggiore solo dentro la finestra")
print(" che si sta difendendo e' un modo di non trovarlo)")
have = [s for s in U13 if USD_SRC[s] is not None]
Bf = bin_panel(have)
Uf = usd_panel(have).reindex(Bf.index)
bo = Bf.notna() & Uf.notna()
Df = (1e4 * np.log(Uf / Bf)).where(bo)
idf = Df.sub(Df.median(axis=1), axis=0)
worst_day = idf.abs().max(axis=1).sort_values(ascending=False)
print(f" {'giorno':<12}{'|idio| max':>11}{'asset':>7}{'comune':>9} finestra")
for t in worst_day.head(6).index:
s = idf.loc[t].abs().idxmax()
w = "fuori campione" if t < pd.Timestamp(T2_END, tz="UTC") else "scoperta 2024+"
print(f" {str(t.date()):<12}{idf.loc[t, s]:>11.0f}{s:>7}{Df.loc[t].median():>9.0f} {w}")
tw = worst_day.index[0]
print(f" il giorno peggiore in assoluto e' il {tw.date()}: scarto per asset (bps)")
print(" " + " ".join(f"{s}:{idf.loc[tw, s]:.0f}" for s in have
if np.isfinite(idf.loc[tw, s])))
print(" 📌 E' un fatto che va detto per intero: la divergenza idiosincratica PUO'")
print(" esplodere — qui di due ordini di grandezza — ma e' successo in una CASCATA DI")
print(" LIQUIDAZIONI sulle coppie /USDT, non in un depeg, e cade nella finestra di")
print(" SCOPERTA (2024+, dove lo sleeve gira su Hyperliquid), non nel fuori campione.")
print(" Il meccanismo temuto dall'obiezione e' REALE; non e' accaduto nel 2021-2023.")
# il giorno peggiore: dove il P&L dei due sleeve si stacca di piu' # il giorno peggiore: dove il P&L dei due sleeve si stacca di piu'
a0 = alive(X.xsec_engine(PU, phase=0)); b0 = alive(X.xsec_engine(PB, phase=0)) a0 = alive(X.xsec_engine(PU, phase=0)); b0 = alive(X.xsec_engine(PB, phase=0))
@@ -615,7 +760,11 @@ def main() -> None:
print(f" TEST 1 U10 congelato : corr mediana {R['corr'].median():.4f}, minima " print(f" TEST 1 U10 congelato : corr mediana {R['corr'].median():.4f}, minima "
f"{R['corr'].min():.4f} -> {'PASS' if R['corr'].min() >= CORR_SOGLIA else 'FAIL'}") f"{R['corr'].min():.4f} -> {'PASS' if R['corr'].min() >= CORR_SOGLIA else 'FAIL'}")
print(f" TEST 2 U13 ibrido : corr mediana {R2['corr'].median():.4f}, minima " print(f" TEST 2 U13 ibrido : corr mediana {R2['corr'].median():.4f}, minima "
f"{R2['corr'].min():.4f} -> {'PASS' if R2['corr'].min() >= CORR_SOGLIA else 'FAIL'}") f"{R2['corr'].min():.4f} -> {'PASS' if R2['corr'].min() >= CORR_SOGLIA else 'FAIL'}"
f" (una fase su 10; col gate spento minima {np.min(cg2):.4f} = PASS)")
print(f" ⚠️ il TEST 2 e' MIO, non quello dichiarato: e' piu' severo per costruzione")
print(f" (le gambe cambiano venue in date diverse) e la sua unica fase sotto soglia")
print(f" e' attribuita al gate binario, non al prezzo.")
print(f" riferimento 2024+ di §21 (Binance vs Hyperliquid): 0,9991 / dSharpe -0,025") print(f" riferimento 2024+ di §21 (Binance vs Hyperliquid): 0,9991 / dSharpe -0,025")
su = alive(X.xsec_engine(PUh, phase=0)) su = alive(X.xsec_engine(PUh, phase=0))
mg = A.marginal_vs_tp01(win(su, T2_START, T2_END)) mg = A.marginal_vs_tp01(win(su, T2_START, T2_END))
@@ -633,6 +782,28 @@ def main() -> None:
print(" null de-levering: NON PERTINENTE (nessun claim di 'meno drawdown').") print(" null de-levering: NON PERTINENTE (nessun claim di 'meno drawdown').")
print(" anchor: girato per costruzione — ogni numero sopra e' su tutte e 10 le fasi.") print(" anchor: girato per costruzione — ogni numero sopra e' su tutte e 10 le fasi.")
# ------------------------------------------------------------ [8] verdetto
print("\n[8] VERDETTO")
print(f" Il TEST DICHIARATO (meccanismo congelato, stesso sottoinsieme, stessa finestra,")
print(f" USD contro USDT) PASSA: corr mediana {R['corr'].median():.4f}, minima "
f"{R['corr'].min():.4f} >= {CORR_SOGLIA}, dSharpe appaiato {R['d'].median():+.3f}.")
print(f" Il titolo di §21 ricalcolato in dollari si muove di {R2['sh_usd'].median()-R2['sh_usdt'].median():+.2f} "
f"({R2['sh_usdt'].median():+.2f} -> {R2['sh_usd'].median():+.2f} di mediana di fase).")
print(f" Nella finestra del depeg la componente idiosincratica sale (med {idm.median():.1f} bps "
f"contro {idio[~dm].abs().stack().median():.1f}) ma resta due ordini di grandezza sotto")
print(f" la vol giornaliera di un alt, e ZERO ribilanciamenti cambiano gambe li' dentro.")
print(f" L'unica corr sotto soglia (TEST 2, fase 2: {R2['corr'].min():.4f}) e' attribuita:")
print(f" col gate di dispersione SPENTO la minima diventa {np.min(cg2):.4f} -> non e' il")
print(f" prezzo, e' la soglia BINARIA che amplifica pochi bps in 10 giorni di flat.")
print( " -> IL RISULTATO XS01-OOS SOPRAVVIVE al controllo di venue.")
print( " Cio' che NON e' stato controllato, e va citato insieme al verdetto: BNB non ha un")
print( " prezzo USD nel 2021-23 (e' il token nativo del venue sotto esame), e toglierlo")
print( " costa -0.75 di mediana di fase. Il test copre 10-12 gambe su 13, non 13.")
print(f" E il caso peggiore di divergenza dell'INTERO campione ({tw.date()}, "
f"{idf.loc[tw].abs().max():.0f} bps su una gamba)")
print( " dimostra che il meccanismo temuto e' reale: semplicemente non e' accaduto nella")
print( " finestra fuori campione. Non e' 'non puo' succedere', e' 'non e' successo li''.")
print(f"\n[fine] {time.time()-t0:.1f}s") print(f"\n[fine] {time.time()-t0:.1f}s")