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)
ps.advance(st0, j)
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]
c = compare(np.array([p[0] for p in pairs]), np.array([p[1] for p in pairs]))
pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
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` "
"(ultima riga = 1 barra 1h su 24)")
show("statarb", c)
RES["paper_statarb"] = dict(parziale="SI", cmp=c, gate="STATARB 2026-09-27",
src="btc/eth 1h -> resample 1d", cad_h=24.0)
out = show(T, A, B)
ident = np.abs(A - B) <= 1e-6
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():
@@ -337,17 +354,27 @@ def b_dvolspread():
dd_modeled=0.0, dd_real=0.0, n_flips=0, frozen=pv.FROZEN)
pv.advance(st0, P)
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]
c = compare(np.array([p[0] for p in pairs]), np.array([p[1] for p in pairs]))
pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
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`")
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(" 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(" difetto, ed e' il motivo per cui l'unico monitor con una guardia dedicata e'")
print(" compromesso quanto quelli senza.")
RES["paper_dvolspread"] = dict(parziale="SI", cmp=c, gate="DVOLSPREAD 2026-10-24 / 2027-01-24",
src="btc/eth 1h -> resample 1d + dvol", cad_h=24.0)
RES["paper_dvolspread"] = dict(parziale="SI", cmp=out["clean"],
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():
@@ -370,28 +397,39 @@ def b_prevday():
pairs = [(int(r["ts"]), float(r["net_modeled"]), rep[int(r["ts"])])
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])
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, "
"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
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)} "
f"({diff.mean() * 100:.1f}%)")
vc = pd.Series(hh[diff]).value_counts().sort_index()
f"({diff.mean() * 100:.1f}%), |scarto| mediano "
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: " +
", ".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))
print(f" = ESATTAMENTE una barra per giorno su {giorni} giorni, e sempre la barra 00:00 —")
print(" cioe' quella che il cron delle 00:30 trova aperta da ~35 minuti.")
print(f"\n ⚠ LA MISURA CHE CONTA E' L'ALTRA META': {int((~diff).sum())} barre su {len(A)} "
"coincidono BIT A BIT con")
print(" il replay fatto oggi. Non e' un dettaglio contabile: e' la prova indipendente che il")
print(" feed BTC/ETH certificato NON riscrive le barre gia' chiuse (62 giorni di riscritture")
print(" notturne). Senza questa prova la ricostruzione della sezione E sarebbe un'ipotesi.")
RES["paper_prevday"] = dict(parziale="SI", cmp=c, gate="nessuno (lead in monitor)",
src="btc/eth 1h grezzo", cad_h=1.0)
g = pd.DataFrame(dict(day=T.date, d=diff)).groupby("day")["d"].sum()
z, uno, due = (g == 0), (g == 1), (g == 2)
print(f" per giorno: {int(uno.sum())} giorni con 1 barra divergente, {int(due.sum())} con 2, "
f"{int(z.sum())} con 0 (totale {len(g)} giorni)")
print(f" i {int(due.sum())} giorni con DUE sono sempre 00:00 + 01:00 = il difetto si PROPAGA "
"una barra avanti,")
print(" perche' il bersaglio calcolato sulla barra parziale e' la posizione TENUTA in quella")
print(" dopo. (Il docstring di `prevday_breakout.current_target` dice 'ultima barra chiusa':")
print(" quinto docstring di produzione che dichiara una causalita' che il codice non ha.)")
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():
@@ -402,22 +440,29 @@ def b_portfolio():
dts, eq = read_equity_csv(ROOT / "data" / "paper_portfolio" / "equity.csv")
_, r = ppf.portfolio_daily()
ridx = {pd.Timestamp(k): float(v) for k, v in r.items()}
A, B = [], []
A, B, D = [], [], []
for i in range(1, len(dts)):
d = dts[i]
if d in ridx:
A.append(eq[i] / eq[i - 1] - 1.0)
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 "
"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(" 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(" 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)",
src="5 sleeve, il piu' recente su 1h->1d e HL 1d", cad_h=24.0)
print(" ⚠ Ricostruzione NON bit-exact per questo monitor: uno dei cinque sleeve e' GTAA01, che")
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():
@@ -428,15 +473,22 @@ def b_combo():
dts, eq = read_equity_csv(ROOT / "data" / "paper_combo" / "equity.csv", col=1)
naked, _ = pc.both_daily()
ridx = {pd.Timestamp(k): float(v) for k, v in naked.items()}
A, B = [], []
A, B, D = [], [], []
for i in range(1, len(dts)):
d = dts[i]
if d in ridx:
A.append(eq[i] / eq[i - 1] - 1.0)
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")
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])
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")
@@ -448,8 +500,9 @@ def b_combo():
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(" senza che nulla lo segnali.")
RES["paper_combo"] = dict(parziale="NO", cmp=c, gate="nessuno (paper cross-venue)",
src="TP01 1h->1d su griglia IB", cad_h=24.0)
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,
ric="SI* (equity IB ri-aggiustata)")
# ============================================================================================
@@ -469,15 +522,23 @@ def sezione_C():
print("\n" + "=" * 102)
print(" C — TABELLA: una riga per monitor")
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}"
f"{'ricostr.':>10} gate dipendente")
f"{'ricostruibile':>25} gate dipendente")
for k, v in RES.items():
c = v["cmp"]
ratio = "{}/{}".format(c["ident"], c["n"])
print(f" {k:<19}{v['parziale']:>6}{ratio:>13}{c['corr']:>+9.3f}"
f"{c['minuti']:>9,.0f}{'SI':>10} {GATE_INFO[k][0]}")
print("\n 'ricostr.' = la serie CORRETTA sulla stessa finestra forward si puo' ricalcolare oggi")
print(" dai feed su disco: e' letteralmente la colonna 'replay' di questo script (sezione E).")
f"{c['minuti']:>9,.0f}{v['ric']:>25} {GATE_INFO[k][0]}")
print("\n 'ricostruibile' = la serie CORRETTA sulla stessa finestra forward si puo' ricalcolare")
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.")
# ============================================================================================