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:
@@ -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.")
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================================
|
# ============================================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user