research(wave-0822): TERM-STRUCTURE e OI-PIN scartati — la catena ereditata ha 74 giorni utili, non 3,7 mesi
This commit is contained in:
@@ -12,6 +12,8 @@ null de-levering superato + eseguibilita' al capitale dichiarato.
|
||||
| 3 | XS-LITE | **SCARTATO** (come sleeve) + **1 soglia pubblicata falsificata** | concentrare XS01 non crea uno sleeve nuovo (corr 0.81-0.96 col canonico, DSR FAIL, de-levering non superato) — ma il muro *"XS01 serve ~$20k"* e' misurato su una diagnostica di TURNOVER: il ribilancio vero smette di passare sotto **~$109 di sleeve (~$730 di book), 27x piu' in basso** |
|
||||
| 10 | FLOW-SQUEEZE | **SCARTATO** (2 motivi indipendenti) | meta' dell'ipotesi **non esiste nel dato** (`liquidation_*_risk` = una sola categoria in 17.229/17.229 righe); l'altra meta' e' sotto la propria soglia di potenza **dichiarata prima** (MDE 1,056% vs effetto 0,402%) ed e' comunque **morta alla nascita** (la colonna non e' ricostruibile) |
|
||||
| 11 | VRP-QUOTE-VERE | **SCARTATO** + **1 difetto di RACCOLTA in produzione** | il campione contiene l'**astensione** della strategia (0/19 settimane passano IV-rank>0.30) e il titolo non sopravvive all'ora d'ingresso; ma soprattutto: **`collect_chain.py` raccoglie la famiglia di contratti che il conto NON puo' marginare** |
|
||||
| 7 | TERM-STRUCTURE | **SCARTATO** + 1 LEAD stretto (decisione 2027-02-01) | la pendenza e' un **termometro contemporaneo** (picco CCF a lag −1h/0h); il carry non paga il bid-ask (**18,6 giorni di roll-down per pagare UN round-trip**); come gate e' la **5ª occorrenza** della ridondanza col trend |
|
||||
| 6 | OI-PIN | **SCARTATO** | il max-pain batte uno strike casuale ma **non batte mai (0/24) la media a 7 giorni dello spot**, un livello che non usa NESSUN dato di opzioni: non e' pinning, e' reversione verso il centro recente con l'OI come stimatore rumoroso di quel centro |
|
||||
|
||||
## Note che sopravvivono ai singoli filoni
|
||||
|
||||
@@ -189,3 +191,53 @@ SOL_USDC 341, XRP_USDC 250, HYPE_USDC 172, AVAX_USDC 146 strumenti con OI>=100.
|
||||
- ⚠️ L'agente ha **refutato in corsa una propria conclusione**: spostare l'ora d'ingresso cambia
|
||||
QUALI STRIKE corrispondono al delta obiettivo -> non e' lo stesso trade un'ora dopo, e' **un'altra
|
||||
struttura**; la media BTC **cambia segno** fra le ancore (−1,35% -> +11,22%).
|
||||
|
||||
### 7 — TERM-STRUCTURE (r0822_term_structure.py, 312 trial dichiarati)
|
||||
🚨 **MURO DEL DATO, e vale per ogni filone che usa la catena ereditata: prima del 2026-06-09
|
||||
`bite_archive` raccoglieva UNA SOLA SCADENZA per giro** (mediana 1, max 1) -> **la curva non
|
||||
esiste**. La finestra utilizzabile non e' "3,7 mesi": e' **74 giorni**, SE(Sharpe) ~ 2,2.
|
||||
✅ **Ricostruzione certificata contro due riferimenti indipendenti:** vs il logger `vol_term_*`
|
||||
corr **0,992-0,997** (scarto 0,00-0,30 pt-vol); vs DVOL corr 0,94 con bias −2,2/−2,8 pt-vol = il
|
||||
segno atteso (DVOL integra lo smile).
|
||||
- **Il test piu' informativo e' quello di RISOLUZIONE:** l'unica correlazione col futuro che sembrava
|
||||
qualcosa (h=5g: +0,29/+0,32, 94°/98° pctl vs null a blocchi) **cambia SEGNO togliendo l'ultima
|
||||
settimana** (−0,22/−0,17). Sette giorni su 70. Nella regressione controllata per il ritorno
|
||||
passato il t di Newey-West sta **sotto 1,0 a ogni orizzonte**.
|
||||
- **Il confronto che uccide il candidato: il buy&hold sulla stessa finestra.** Mediana appaiata su
|
||||
24 ancore vs B&H = **+0,14 (14/24) su BTC** e **−0,65 (1/24) su ETH**. La banda d'ancora
|
||||
`gate_pass=True` in isolamento e' **inutile: il B&H passa lo stesso gate**.
|
||||
- Confound proprio del filone, misurato: corr(pendenza, RV **passata**) −0,50/−0,57 contro RV
|
||||
**futura** −0,39/−0,38 -> la pendenza e' il premio di vol con la gamba realizzata sostituita da
|
||||
una implicita = la variabile di `dvol_directional` (gia' HEDGE, earns_slot=False su 5 anni).
|
||||
- **`deflated_sharpe` NON girato, e la motivazione e' il risultato:** su 74 osservazioni
|
||||
l'incertezza di CAMPIONE domina di un ordine di grandezza quella da SELEZIONE — deflazionare 312
|
||||
trial darebbe un numero preciso e privo di senso.
|
||||
- 📌 **LEAD stretto e pre-registrato** (l'unico numero non banale: corr(pendenza, RV futura) −0,39):
|
||||
la term structure come previsore di **VOL, non di ritorni**. Decisione **2027-02-01**, si riapre
|
||||
solo se (a) corr <= −0,30 su entrambi gli asset **E** (b) batte il **DVOL a tenore singolo** in R²
|
||||
incrementale **E** (c) supera il null del de-levering. **Se (b) fallisce, il filone si chiude.**
|
||||
- ⚠️ **Tre bug propri catturati in sessione**, tutti del tipo che passa i test pigri: il null del
|
||||
de-levering cercava il **primo** k salendo invece del **piu' grande**; la RV futura aveva **uno
|
||||
shift di troppo**; l'ATM vettorializzato e' stato verificato contro il prototipo (23.544/23.545
|
||||
righe identiche).
|
||||
|
||||
### 6 — OI-PIN (r0822_oi_pin.py, 516 trial dichiarati, 73 scadenze/asset)
|
||||
✅ **Potenza dichiarata PRIMA di guardare** (e questa e' la ragione per cui il verdetto e' credibile):
|
||||
MDE a hte 12 = **0,46%/trade**; effetto max-pain osservato **+0,273% = SOTTO il proprio MDE**.
|
||||
📌 **Il null che decide: il placebo senza opzioni.** La cella migliore fa Sharpe 5,59 e batte gli
|
||||
strike casuali (6/72 contro ~2 attesi), ma **0/24 contro la media a 7 giorni dello spot**, con cui
|
||||
condivide il **68-77% del segno**. Non e' pinning verso uno strike: e' reversione verso il centro
|
||||
recente, e l'OI e' solo uno stimatore rumoroso di quel centro.
|
||||
- DSR **0,290** (288 trial): lo **Sharpe-null atteso e' 6,79 > 5,59 osservato** — su 75 giorni il
|
||||
massimo del rumore batte il risultato. `implausible_sharpe` scatta. I **5 giorni migliori valgono
|
||||
il 61% del log-equity**.
|
||||
- ⚠️ `marginal_vs_tp01` **non puo' dare ADDS per costruzione** su questa finestra: `multicut` vuole
|
||||
>=2 tagli annuali da >=120g e `has_insample_edge` e' True *per default* perche' non esiste
|
||||
pre-2025. Un NEUTRAL qui non e' un giudizio.
|
||||
- Haircut a $600: **+0,000** (si esegue sul perp) — 2ª conferma che l'eseguibilita' non e' piu' il
|
||||
vincolo binding di questa ondata.
|
||||
- ⚠️ **REGOLA NUOVA (difetto proprio, trovato e corretto in sessione): un placebo si controlla per
|
||||
BILANCIAMENTO DEL SEGNO prima di usarlo.** Il placebo `jit` concordava in segno con la propria
|
||||
regola solo nel **14%** dei casi (5% per `jit_gex`): non era un null, era **la strategia
|
||||
invertita**, e usarlo fabbricava 3 celle "significative" e un contrasto spettacolare (−8,6 di
|
||||
Sharpe). Un null pulito sta a ~0,50; sotto ~0,35 il suo delta va letto come **~2x il segnale**.
|
||||
|
||||
@@ -440,12 +440,19 @@ def main() -> None:
|
||||
rec = {"TP01": _crypto(1.0, 0.0)["R"], "SKH01": _crypto(0.0, 1.0)["R"],
|
||||
"XS01": pc.xsec_daily_tuples()["R"], "VRP01": vrp_daily_tuples()["R"],
|
||||
"GTAA01": gtaa_daily_tuples()["R"]}
|
||||
print("\n sanity — la ricostruzione (R) deve coincidere con lo sleeve ufficiale sulla chiusura:")
|
||||
print("\n sanity — ricostruzione vs sleeve ufficiale. XS01/VRP01/GTAA01 devono coincidere")
|
||||
print(" BARRA PER BARRA; TP01/SKH01 no per costruzione (il recon e' un mark-to-market ORARIO,")
|
||||
print(" lo sleeve marca a fine-trade) -> per loro il controllo giusto e' il log-totale.")
|
||||
print(f" {'sleeve':>8} {'max|delta| barra':>18} {'log-tot recon':>15} "
|
||||
f"{'log-tot sleeve':>16} {'scarto':>9}")
|
||||
for nm in SLEEVES:
|
||||
com = off[nm].index.intersection(rec[nm].index)
|
||||
dmax = float(np.abs(off[nm].reindex(com).values - rec[nm].reindex(com).values).max())
|
||||
note = "" if nm not in ("TP01", "SKH01") else " (recon MTM orario: lente diversa per costruzione)"
|
||||
print(f" {nm:>7}: max|delta| = {dmax:.2e} {'OK' if dmax < 1e-9 else 'DIVERGE'}{note}")
|
||||
a = off[nm].reindex(com).values
|
||||
b = rec[nm].reindex(com).values
|
||||
dmax = float(np.abs(a - b).max())
|
||||
la, lb = float(np.log1p(a).sum()), float(np.log1p(b).sum())
|
||||
flag = "OK" if dmax < 1e-9 else ("lente MTM" if nm in ("TP01", "SKH01") else "DIVERGE")
|
||||
print(f" {nm:>8} {dmax:>18.2e} {lb:>15.4f} {la:>16.4f} {lb-la:>+9.4f} {flag}")
|
||||
|
||||
hr("A. PROFILO DEGLI SLEEVE SOTTO BARRIERA — cio' che conta non e' lo Sharpe, e si vede qui")
|
||||
print(f" {'sleeve':>8} {'Sharpe':>7} {'vol a':>7} {'drift a':>8} {'skew':>7} "
|
||||
@@ -520,6 +527,22 @@ def main() -> None:
|
||||
f"{row['p_pass']:>8.1%} {row['p_alive']:>11.1%} {row['sharpe']:>7.2f} "
|
||||
f"{row['vol']:>6.1%} {row['e_payout']:>9,.0f}$ {row['t_pass']:>10.0f}")
|
||||
|
||||
dA, seA = paired_delta(w_argmax_dict := dict(zip(CRYPTO_PROP, [int(x)/100 for x in best["w"].split("/")])),
|
||||
float(best["lev"]),
|
||||
dict(zip(CRYPTO_PROP, [int(x)/100 for x in best_sh["w"].split("/")])),
|
||||
float(best_sh["lev"]), "HYRO", ev_idx, fu_idx)
|
||||
dB, seB = paired_delta(w_argmax_dict, float(best["lev"]),
|
||||
{"TP01": 0.75, "SKH01": 0.25}, float(best_live["lev"]),
|
||||
"HYRO", ev_idx, fu_idx)
|
||||
print(f"\n DIFFERENZE APPAIATE (stessi indici di bootstrap; un livello di J ha SE ~0.01, "
|
||||
f"una differenza molto meno):")
|
||||
print(f" argmax J - argmax SHARPE : {dA:+.4f} +- {seA:.4f} "
|
||||
f"-> {'INDISTINGUIBILI' if abs(dA) < 2*seA else 'differenza reale'}")
|
||||
print(f" argmax J - libro LIVE : {dB:+.4f} +- {seB:.4f} "
|
||||
f"-> {'INDISTINGUIBILI' if abs(dB) < 2*seB else 'differenza reale'}")
|
||||
print(" La prima riga E' il risultato del filone: progettare per la barriera invece che")
|
||||
print(" per lo Sharpe NON sposta i pesi. La seconda dice dove sta il guadagno vero.")
|
||||
|
||||
print("\n Le prime 8 celle per J:")
|
||||
print(f" {'#':>3} {'pesi':>16} {'leva':>6} {'J':>7} {'P(pass)':>8} {'P(vivo)':>8} "
|
||||
f"{'Sharpe':>7} {'E[pay/a]':>10}")
|
||||
@@ -566,8 +589,13 @@ def main() -> None:
|
||||
f"max {Jr.max():.3f} | frazione sopra il LIVE 75/25 = {(Jr > best_live['J']).mean():.0%}")
|
||||
print(f" percentile dell'argmax fra i casuali = {pctl:.1f}° contro la firma best-of-"
|
||||
f"{len(grid)} = {bestofk:.1f}°")
|
||||
print(f" -> {'DENTRO' if pctl <= bestofk else 'SOPRA'} la firma del massimo-di-k: "
|
||||
f"{'nessuna evidenza che quel vettore sia speciale' if pctl <= bestofk else 'vettore particolare'}")
|
||||
print(f" ⚠ RISOLUZIONE: con {len(rw)} estrazioni un percentile vale a passi di "
|
||||
f"{100/len(rw):.1f} punti -> {pctl:.1f}° e {bestofk:.1f}° NON sono distinguibili.")
|
||||
print(f" E il fatto che decide: il MASSIMO dei {len(rw)} pesi casuali e' {Jr.max():.3f} contro"
|
||||
f" {best['J']:.3f} dell'argmax")
|
||||
print(f" della griglia -> un vettore estratto a caso lo {'EGUAGLIA' if Jr.max() >= best['J'] - 1e-9 else 'non lo raggiunge'}."
|
||||
f" NESSUNA evidenza che quel vettore di pesi sia speciale:")
|
||||
print(" cio' che conta non e' QUALE punto del simplesso, ma STARE nella regione diversificata.")
|
||||
print(f" (la meta' bassa del null e' pero' informativa: il LIVE 75/25 e' battuto dal "
|
||||
f"{(Jr > best_live['J']).mean():.0%} dei pesi CASUALI)")
|
||||
|
||||
|
||||
@@ -549,6 +549,28 @@ def main() -> None:
|
||||
print(" -> il massimo in avanti e' quello che il rumore produce da solo. LAG INDIETRO:")
|
||||
print(f" |t| minimo = {LL[LL['minuti'] < 0]['t_dRR'].abs().min():.2f} su "
|
||||
f"{int((LL['minuti'] < 0).sum())} test, tutti dello STESSO segno.")
|
||||
print("\n Robustezza — il COLLETTORE cambia a meta' campione (cerbero-bite: ~10 giri/ora,")
|
||||
print(" fino al 2026-07-30; raccolta nostra: 1 giro/ora al minuto :25). Stessa misura sui due")
|
||||
print(" tronconi, piu' la copertura oraria (il guasto quote-vuote del 29-30/07 e' qui dentro):")
|
||||
TAGLIO = pd.Timestamp("2026-07-30 20:00", tz="UTC")
|
||||
for a in ASSETS:
|
||||
S = cm30[a]
|
||||
for nome, m in (("bite ", S.index < TAGLIO), ("nostra ", S.index >= TAGLIO)):
|
||||
sub = S[m]
|
||||
if len(sub) < 100:
|
||||
continue
|
||||
L2 = leadlag(sub, a)
|
||||
av = L2[L2["minuti"].isin([5, 15, 60])]["corr_dRR"].to_numpy()
|
||||
ind = L2[L2["minuti"].isin([-15, -60])]["corr_dRR"].to_numpy()
|
||||
gg = len(np.unique(pd.DatetimeIndex(sub.index).date))
|
||||
print(f" {a} {nome} ore={len(sub):5d} giorni={gg:3d} ({len(sub)/max(gg,1):.1f} ore/giorno)"
|
||||
f" avanti(+5/+15/+60m) {np.round(av,3)} indietro(-15/-60m) {np.round(ind,3)}")
|
||||
gio = pd.Series(1, index=pd.DatetimeIndex(cm30[ASSETS[0]].index)).groupby(
|
||||
pd.DatetimeIndex(cm30[ASSETS[0]].index).date).sum()
|
||||
peggio = gio.nsmallest(4)
|
||||
print(f" giorni con MENO ore di superficie ricostruibile (BTC): "
|
||||
f"{ {str(k): int(v) for k, v in peggio.items()} } su 24 attese")
|
||||
|
||||
print("\n Controllo POSITIVO — la stessa misura con l'ancora ASSUNTA a :30 dell'ora:")
|
||||
FF = pd.concat([leadlag_ancora_sbagliata(cm30[a], a) for a in ASSETS], ignore_index=True)
|
||||
print(FF.to_string(index=False))
|
||||
|
||||
Reference in New Issue
Block a user