research(wave-0822): versione finale di r0822_term_structure (sezione 7 + tre fix dell'agente)

This commit is contained in:
Adriano Dal Pastro
2026-08-22 17:21:24 +00:00
parent 110f894bdf
commit aa72e0c9ed
4 changed files with 749 additions and 16 deletions
+26 -13
View File
@@ -550,26 +550,39 @@ def main() -> None:
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):")
print(" fino al 2026-07-30; raccolta nostra: 1 giro/ora al minuto :25) e il campione contiene")
print(" UN evento enorme (BTC +26% nella settimana al 21/08). Le due cose vanno separate:")
TAGLIO = pd.Timestamp("2026-07-30 20:00", tz="UTC")
RALLY = pd.to_datetime(["2026-08-19", "2026-08-20", "2026-08-21", "2026-08-22"]).tz_localize("UTC")
for a in ASSETS:
S = cm30[a]
for nome, m in (("bite ", S.index < TAGLIO), ("nostra ", S.index >= TAGLIO)):
sub = S[m]
gg_rally = pd.DatetimeIndex(S.index).normalize().isin(RALLY)
for nome, m in (("bite ", S.index < TAGLIO),
("nostra ", S.index >= TAGLIO),
("nostra SENZA rally", (S.index >= TAGLIO) & ~gg_rally)):
sub = S[m].sort_values("ts_max")
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)}")
px = px5m(a, sub.index.min())
anc = pd.Series(px.reindex(pd.DatetimeIndex(sub["ts_max"]), method="ffill").to_numpy(),
index=sub.index)
d = sub["rr"].diff()
av = []
for mins in (5, 15, 60):
p2 = pd.Series(px.reindex(pd.DatetimeIndex(sub["ts_max"]) + pd.Timedelta(minutes=mins),
method="ffill").to_numpy(), index=sub.index)
j = pd.concat({"d": d, "r": np.log(p2 / anc)}, axis=1).dropna()
av.append((round(float(j["d"].corr(j["r"])), 3),
round(float(j["d"].corr(j["r"], method="spearman")), 3)))
print(f" {a} {nome} n={len(sub):5d} avanti +5/+15/+60m (pearson,spearman): {av}")
print(" -> l'unica cella con un lead in avanti apparente (BTC, raccolta nostra, +5/+15m)")
print(" PERDE i due terzi togliendo 4 giorni su 24: era il rally, non un meccanismo.")
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(f" copertura: giorni con meno ore di superficie (BTC) "
f"{ {str(k): int(v) for k, v in gio.nsmallest(4).items()} } su 24 attese "
f"(il guasto quote-vuote del 29-30/07 e' dentro il campione e NON crea un buco: le")
print(" quote assenti erano gia' escluse dal filtro 'quotato').")
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)