research(wave-0822): ALT-OPT — l'open interest e la negoziabilita' sono anti-correlati (rho −0,77); corretta la mia inferenza su BTC_USDC

This commit is contained in:
Adriano Dal Pastro
2026-08-22 17:46:13 +00:00
parent 1750b5a93b
commit fe6ad97225
+100 -39
View File
@@ -310,13 +310,30 @@ def b_statarb():
dd_modeled=0.0, dd_real=0.0, n_trades=0) dd_modeled=0.0, dd_real=0.0, n_trades=0)
ps.advance(st0, j) ps.advance(st0, j)
rep = {int(r["ts"]): float(r["net_modeled"]) for r in sink.of("returns.jsonl")} rep = {int(r["ts"]): float(r["net_modeled"]) for r in sink.of("returns.jsonl")}
pairs = [(float(r["net_modeled"]), rep[int(r["ts"])]) for r in rec if int(r["ts"]) in rep] pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
c = compare(np.array([p[0] for p in pairs]), np.array([p[1] for p in pairs])) for r in rec if int(r["ts"]) in rep]
T = pd.DatetimeIndex(pd.to_datetime([p[0] for p in pairs], unit="ms", utc=True))
A = np.array([p[1] for p in pairs]); B = np.array([p[2] for p in pairs])
print("\n pannello: `build_joint('1d')` -> `altlib.get(...,'1d')` -> `resample_tf` " print("\n pannello: `build_joint('1d')` -> `altlib.get(...,'1d')` -> `resample_tf` "
"(ultima riga = 1 barra 1h su 24)") "(ultima riga = 1 barra 1h su 24)")
show("statarb", c) out = show(T, A, B)
RES["paper_statarb"] = dict(parziale="SI", cmp=c, gate="STATARB 2026-09-27", ident = np.abs(A - B) <= 1e-6
src="btc/eth 1h -> resample 1d", cad_h=24.0) if ident.any():
gg = sorted({str(x.date()) for x in T[ident]})
print(f"\n 📌 LE UNICHE BARRE CORRETTE DELLA SERIE VENGONO DA UN GUASTO: le {int(ident.sum())} "
f"identiche\n sono CONSECUTIVE ({gg[0]} -> {gg[-1]}) e cadono dentro l'incidente "
"del feed.")
ev = freeze_evidence()
print(f" Prova indipendente dal log del cron: `rebuild_history` e' abortito in "
f"{len(ev)} giri\n ({', '.join(sorted(ev)[:8])}{'...' if len(ev) > 8 else ''}) — "
"EPERM sul backup, difetto gia' riparato\n nel sorgente. Col feed fermo il monitor "
"non trovava barre nuove; al ripristino ne ha\n recuperate 7 in un colpo solo, di "
"cui 6 GIA' CHIUSE -> coincidono col replay al bit.")
print(" Due conseguenze: (a) il 'min/giorno' globale e' GONFIATO da quelle barre — la")
print(" riga 'ESCLUSO l'incidente' e' la stima onesta; (b) quelle 6 barre sono la prova")
print(" che, su barre chiuse, il codice di produzione riproduce il replay ESATTAMENTE.")
RES["paper_statarb"] = dict(parziale="SI", cmp=out["clean"], gate="STATARB 2026-09-27",
src="btc/eth 1h -> resample 1d", cad_h=24.0, ric="SI (bit-exact)")
def b_dvolspread(): def b_dvolspread():
@@ -337,17 +354,27 @@ def b_dvolspread():
dd_modeled=0.0, dd_real=0.0, n_flips=0, frozen=pv.FROZEN) dd_modeled=0.0, dd_real=0.0, n_flips=0, frozen=pv.FROZEN)
pv.advance(st0, P) pv.advance(st0, P)
rep = {int(r["ts"]): float(r["net_modeled"]) for r in sink.of("returns.jsonl")} rep = {int(r["ts"]): float(r["net_modeled"]) for r in sink.of("returns.jsonl")}
pairs = [(float(r["net_modeled"]), rep[int(r["ts"])]) for r in rec if int(r["ts"]) in rep] pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
c = compare(np.array([p[0] for p in pairs]), np.array([p[1] for p in pairs])) for r in rec if int(r["ts"]) in rep]
T = pd.DatetimeIndex(pd.to_datetime([p[0] for p in pairs], unit="ms", utc=True))
print("\n pannello: `_panel` -> `ortholib.aligned` -> `altlib.get(...,'1d')` -> `resample_tf`") print("\n pannello: `_panel` -> `ortholib.aligned` -> `altlib.get(...,'1d')` -> `resample_tf`")
show("dvolspread", c) print(f" inception {T[0].date()} = dopo l'incidente del feed: finestra gia' pulita, "
"nessuna barra recuperata.")
out = show(T, np.array([p[1] for p in pairs]), np.array([p[2] for p in pairs]))
print("\n ⚠ E' IL PEGGIORE DEI SEI, e non e' un caso: il libro e' uno SPREAD BTC-ETH e su 35")
print(" minuti le due gambe si muovono quasi insieme -> la parte idiosincratica, che e' cio'")
print(" che questo libro tenta di catturare, e' quasi tutta ancora da venire quando la barra")
print(" viene letta. Un libro dollar-neutral perde piu' di un libro direzionale a parita' di")
print(" troncamento — il numero di sopra non e' 35/1440 ma un ordine di grandezza sotto.")
print("\n ⚠ La contabilita' a 3 stati (ATTIVE / flat-da-segnale / flat-SENZA-DATO) e il veto") print("\n ⚠ La contabilita' a 3 stati (ATTIVE / flat-da-segnale / flat-SENZA-DATO) e il veto")
print(" d'integrita' all'80% funzionano e restano validi: contano se il DVOL c'era. Non") print(" d'integrita' all'80% funzionano e restano validi: contano se il DVOL c'era. Non")
print(" possono vedere QUANTO dura la barra su cui il DVOL c'era — sono ortogonali a questo") print(" possono vedere QUANTO dura la barra su cui il DVOL c'era — sono ortogonali a questo")
print(" difetto, ed e' il motivo per cui l'unico monitor con una guardia dedicata e'") print(" difetto, ed e' il motivo per cui l'unico monitor con una guardia dedicata e'")
print(" compromesso quanto quelli senza.") print(" compromesso quanto quelli senza.")
RES["paper_dvolspread"] = dict(parziale="SI", cmp=c, gate="DVOLSPREAD 2026-10-24 / 2027-01-24", RES["paper_dvolspread"] = dict(parziale="SI", cmp=out["clean"],
src="btc/eth 1h -> resample 1d + dvol", cad_h=24.0) gate="DVOLSPREAD 2026-10-24 / 2027-01-24",
src="btc/eth 1h -> resample 1d + dvol", cad_h=24.0,
ric="SI (bit-exact)")
def b_prevday(): def b_prevday():
@@ -370,28 +397,39 @@ def b_prevday():
pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])]) pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
for r in rec if int(r["ts"]) in rep] for r in rec if int(r["ts"]) in rep]
A = np.array([p[1] for p in pairs]); B = np.array([p[2] for p in pairs]) A = np.array([p[1] for p in pairs]); B = np.array([p[2] for p in pairs])
c = compare(A, B) T = pd.DatetimeIndex(pd.to_datetime([p[0] for p in pairs], unit="ms", utc=True))
print("\n pannello: `build_bars` -> `harness.load(asset,'1h')` = il parquet 1h GREZZO, " print("\n pannello: `build_bars` -> `harness.load(asset,'1h')` = il parquet 1h GREZZO, "
"nessun resample") "nessun resample")
show("prevday", c, note=" <- 24 barre/giorno, quindi il conto e' sull'INTERA giornata") out = show(T, A, B, note=" <- 24 barre/giorno, quindi il conto e' sull'INTERA giornata")
diff = np.abs(A - B) > 1e-6 diff = np.abs(A - B) > 1e-6
hh = pd.to_datetime([p[0] for p in pairs], unit="ms", utc=True).hour
print(f"\n DOVE cade la divergenza: {int(diff.sum())} barre su {len(A)} " print(f"\n DOVE cade la divergenza: {int(diff.sum())} barre su {len(A)} "
f"({diff.mean() * 100:.1f}%)") f"({diff.mean() * 100:.1f}%), |scarto| mediano "
vc = pd.Series(hh[diff]).value_counts().sort_index() f"{np.median(np.abs(A - B)[diff]):.2e} su |ritorno| mediano {np.median(np.abs(B)):.2e}")
vc = pd.Series(T.hour[diff]).value_counts().sort_index()
print(" ora UTC delle barre divergenti: " + print(" ora UTC delle barre divergenti: " +
", ".join(f"{int(h):02d}:00 x{int(n)}" for h, n in vc.items())) ", ".join(f"{int(h):02d}:00 x{int(n)}" for h, n in vc.items()))
giorni = len(set(pd.to_datetime([p[0] for p in pairs], unit="ms", utc=True).date)) g = pd.DataFrame(dict(day=T.date, d=diff)).groupby("day")["d"].sum()
print(f" = ESATTAMENTE una barra per giorno su {giorni} giorni, e sempre la barra 00:00 —") z, uno, due = (g == 0), (g == 1), (g == 2)
print(" cioe' quella che il cron delle 00:30 trova aperta da ~35 minuti.") print(f" per giorno: {int(uno.sum())} giorni con 1 barra divergente, {int(due.sum())} con 2, "
print(f"\n ⚠ LA MISURA CHE CONTA E' L'ALTRA META': {int((~diff).sum())} barre su {len(A)} " f"{int(z.sum())} con 0 (totale {len(g)} giorni)")
"coincidono BIT A BIT con") print(f" i {int(due.sum())} giorni con DUE sono sempre 00:00 + 01:00 = il difetto si PROPAGA "
print(" il replay fatto oggi. Non e' un dettaglio contabile: e' la prova indipendente che il") "una barra avanti,")
print(" feed BTC/ETH certificato NON riscrive le barre gia' chiuse (62 giorni di riscritture") print(" perche' il bersaglio calcolato sulla barra parziale e' la posizione TENUTA in quella")
print(" notturne). Senza questa prova la ricostruzione della sezione E sarebbe un'ipotesi.") print(" dopo. (Il docstring di `prevday_breakout.current_target` dice 'ultima barra chiusa':")
RES["paper_prevday"] = dict(parziale="SI", cmp=c, gate="nessuno (lead in monitor)", print(" quinto docstring di produzione che dichiara una causalita' che il codice non ha.)")
src="btc/eth 1h grezzo", cad_h=1.0) zg = [str(x) for x in g[z].index]
print(f" i {int(z.sum())} giorni con ZERO divergenze: {', '.join(zg)}")
print(" = inception + oggi + i 7 giorni dell'incidente del feed (barre recuperate CHIUSE).")
print(f"\n ⚠ LA META' CHE CONTA DI PIU': {int((~diff).sum())} barre su {len(A)} coincidono BIT "
"A BIT col replay")
print(" fatto oggi, dopo 62 notti di riscrittura del parquet. E' la PROVA che il feed BTC/ETH")
print(" certificato non tocca le barre gia' chiuse — senza la quale la ricostruzione della")
print(" sezione E sarebbe un'ipotesi invece di un fatto.")
print(" 📌 E il verdetto operativo e' l'opposto degli altri quattro: su griglia oraria il difetto")
print(" c'e' ma vale ~0.1% della varianza. `paper_prevday` NON e' da rigenerare.")
RES["paper_prevday"] = dict(parziale="SI", cmp=out["clean"], gate="nessuno (lead in monitor)",
src="btc/eth 1h grezzo", cad_h=1.0, ric="SI (bit-exact)")
def b_portfolio(): def b_portfolio():
@@ -402,22 +440,29 @@ def b_portfolio():
dts, eq = read_equity_csv(ROOT / "data" / "paper_portfolio" / "equity.csv") dts, eq = read_equity_csv(ROOT / "data" / "paper_portfolio" / "equity.csv")
_, r = ppf.portfolio_daily() _, r = ppf.portfolio_daily()
ridx = {pd.Timestamp(k): float(v) for k, v in r.items()} ridx = {pd.Timestamp(k): float(v) for k, v in r.items()}
A, B = [], [] A, B, D = [], [], []
for i in range(1, len(dts)): for i in range(1, len(dts)):
d = dts[i] d = dts[i]
if d in ridx: if d in ridx:
A.append(eq[i] / eq[i - 1] - 1.0) A.append(eq[i] / eq[i - 1] - 1.0)
B.append(ridx[d]) B.append(ridx[d])
c = compare(np.array(A), np.array(B)) D.append(d)
T = pd.DatetimeIndex(D)
print("\n serie: `StrategyPortfolio(active_sleeves()).combined_daily()`; i rendimenti " print("\n serie: `StrategyPortfolio(active_sleeves()).combined_daily()`; i rendimenti "
"registrati si\n ricavano da equity.csv (il monitor salva l'equity, non i ritorni)") "registrati si\n ricavano da equity.csv (il monitor salva l'equity, non i ritorni)")
show("portfolio", c) out = show(T, np.array(A), np.array(B))
print("\n ⚠ ULTIMA RIGA ESCLUSA DAL GIUDIZIO? No, e' inclusa, e vale la pena dirlo: la barra di") print("\n ⚠ ULTIMA RIGA ESCLUSA DAL GIUDIZIO? No, e' inclusa, e vale la pena dirlo: la barra di")
print(" OGGI coincide per forza (il replay legge lo stesso disco che il cron ha scritto alle") print(" OGGI coincide per forza (il replay legge lo stesso disco che il cron ha scritto alle")
print(" 00:30 e da allora nessuno lo ha riscritto). Un audit che girasse SOLO sull'ultima") print(" 00:30 e da allora nessuno lo ha riscritto). Un audit che girasse SOLO sull'ultima")
print(" barra concluderebbe 'tutto a posto'. La potenza sta nelle barre di IERI e prima.") print(" barra concluderebbe 'tutto a posto'. La potenza sta nelle barre di IERI e prima.")
RES["paper_portfolio"] = dict(parziale="SI", cmp=c, gate="nessuno (dashboard/book di ricerca)", print(" ⚠ Ricostruzione NON bit-exact per questo monitor: uno dei cinque sleeve e' GTAA01, che")
src="5 sleeve, il piu' recente su 1h->1d e HL 1d", cad_h=24.0) print(" legge `eq_*_1d` da IB con `ADJUSTED_LAST` — ri-aggiustato all'indietro a ogni stacco")
print(" di dividendo (difetto gia' incontrato il 07/08 su TLT). La finestra si ricostruisce,")
print(" ma la parte equity non tornera' identica al centesimo, e va detto.")
RES["paper_portfolio"] = dict(parziale="SI", cmp=out["clean"],
gate="nessuno (dashboard/book di ricerca)",
src="5 sleeve, il piu' recente su 1h->1d e HL 1d", cad_h=24.0,
ric="SI* (equity IB ri-aggiustata)")
def b_combo(): def b_combo():
@@ -428,15 +473,22 @@ def b_combo():
dts, eq = read_equity_csv(ROOT / "data" / "paper_combo" / "equity.csv", col=1) dts, eq = read_equity_csv(ROOT / "data" / "paper_combo" / "equity.csv", col=1)
naked, _ = pc.both_daily() naked, _ = pc.both_daily()
ridx = {pd.Timestamp(k): float(v) for k, v in naked.items()} ridx = {pd.Timestamp(k): float(v) for k, v in naked.items()}
A, B = [], [] A, B, D = [], [], []
for i in range(1, len(dts)): for i in range(1, len(dts)):
d = dts[i] d = dts[i]
if d in ridx: if d in ridx:
A.append(eq[i] / eq[i - 1] - 1.0) A.append(eq[i] / eq[i - 1] - 1.0)
B.append(ridx[d]) B.append(ridx[d])
c = compare(np.array(A), np.array(B)) D.append(d)
A = np.array(A); B = np.array(B); T = pd.DatetimeIndex(D)
print("\n serie: `combo_daily()` = TP01 compoundato sulla griglia dei GIORNI DI BORSA + GTAA") print("\n serie: `combo_daily()` = TP01 compoundato sulla griglia dei GIORNI DI BORSA + GTAA")
show("combo", c) out = show(T, A, B)
dif = np.abs(A - B)
print(f"\n Le barre non identiche NON sono il difetto della barra parziale: |scarto| mediano "
f"{np.median(dif):.2e}\n contro |ritorno| mediano {np.median(np.abs(B)):.2e} "
f"(= {np.median(dif) / np.median(np.abs(B)) * 100:.0f}% del ritorno tipico, massimo "
f"{dif.max():.2e}) e si concentrano\n nella finestra dell'incidente del feed + nei giorni "
"in cui IB ha ri-aggiustato `ADJUSTED_LAST`.")
tp_last = pd.Timestamp(list(ridx.keys())[-1]) tp_last = pd.Timestamp(list(ridx.keys())[-1])
print(f"\n PERCHE' QUESTO E' DIVERSO. La griglia e' `eq.index` (i giorni di borsa di IB),") print(f"\n PERCHE' QUESTO E' DIVERSO. La griglia e' `eq.index` (i giorni di borsa di IB),")
print(f" non il calendario crypto: l'ultima riga della serie e' {tp_last.date()}, mentre il") print(f" non il calendario crypto: l'ultima riga della serie e' {tp_last.date()}, mentre il")
@@ -448,8 +500,9 @@ def b_combo():
print(" chiusa. Se domani GTAA01 venisse allineato al calendario crypto (o se si aggiungesse") print(" chiusa. Se domani GTAA01 venisse allineato al calendario crypto (o se si aggiungesse")
print(" una gamba 24/7 alla griglia), il monitor diventerebbe rotto come gli altri cinque") print(" una gamba 24/7 alla griglia), il monitor diventerebbe rotto come gli altri cinque")
print(" senza che nulla lo segnali.") print(" senza che nulla lo segnali.")
RES["paper_combo"] = dict(parziale="NO", cmp=c, gate="nessuno (paper cross-venue)", RES["paper_combo"] = dict(parziale="NO", cmp=out["clean"], gate="nessuno (paper cross-venue)",
src="TP01 1h->1d su griglia IB", cad_h=24.0) src="TP01 1h->1d su griglia IB", cad_h=24.0,
ric="SI* (equity IB ri-aggiustata)")
# ============================================================================================ # ============================================================================================
@@ -469,15 +522,23 @@ def sezione_C():
print("\n" + "=" * 102) print("\n" + "=" * 102)
print(" C — TABELLA: una riga per monitor") print(" C — TABELLA: una riga per monitor")
print("=" * 102) print("=" * 102)
print("\n Le colonne sono calcolate ESCLUDENDO l'incidente del feed 09-15/07 (le barre")
print(" recuperate a posteriori sono chiuse e attenuerebbero il difetto per la ragione")
print(" sbagliata). 'min/g' = minuti di mercato al giorno effettivamente misurati, su 1440.")
print(f"\n {'monitor':<19}{'parz.':>6}{'ident./tot':>13}{'corr':>9}{'min/g':>9}" print(f"\n {'monitor':<19}{'parz.':>6}{'ident./tot':>13}{'corr':>9}{'min/g':>9}"
f"{'ricostr.':>10} gate dipendente") f"{'ricostruibile':>25} gate dipendente")
for k, v in RES.items(): for k, v in RES.items():
c = v["cmp"] c = v["cmp"]
ratio = "{}/{}".format(c["ident"], c["n"]) ratio = "{}/{}".format(c["ident"], c["n"])
print(f" {k:<19}{v['parziale']:>6}{ratio:>13}{c['corr']:>+9.3f}" print(f" {k:<19}{v['parziale']:>6}{ratio:>13}{c['corr']:>+9.3f}"
f"{c['minuti']:>9,.0f}{'SI':>10} {GATE_INFO[k][0]}") f"{c['minuti']:>9,.0f}{v['ric']:>25} {GATE_INFO[k][0]}")
print("\n 'ricostr.' = la serie CORRETTA sulla stessa finestra forward si puo' ricalcolare oggi") print("\n 'ricostruibile' = la serie CORRETTA sulla stessa finestra forward si puo' ricalcolare")
print(" dai feed su disco: e' letteralmente la colonna 'replay' di questo script (sezione E).") print(" oggi dai feed su disco: e' letteralmente la colonna 'replay' di questo script. '*' =")
print(" ricostruibile ma NON al bit, perche' una gamba viene dal feed equity IB che e'")
print(" ri-aggiustato all'indietro (`ADJUSTED_LAST`).")
print("\n LETTURA IN UNA RIGA: quattro monitor su sei registrano fra 2 e 41 minuti di mercato")
print(" al giorno spacciandoli per 24 ore; i due che non lo fanno sono quello a griglia oraria")
print(" (dove il difetto vale una barra su 24) e quello che aspetta la chiusura di una BORSA.")
# ============================================================================================ # ============================================================================================