Files
Adriano Dal Pastro d597fc64e8 monitor: advance() consuma solo barre CHIUSE — serie rigenerate, guardia PREMATURO, 4 debiti chiusi
S5.1 RIPARATO E RIGENERATO. Filtro condiviso src/live/paper_guard.py (barra
open-labeled chiusa = ts + cadenza <= adesso) importato da tutti e 6 i monitor;
serie rigenerate dallo stesso start_ts con scripts/live/paper_regen.py (evidenza
in *.pre_regen_20260826.*): statarb +1,95 -> -1,61 (il ribaltamento del gate
27/09 previsto dall'audit), dvolspread -14,73 -> -4,41, xsr -4,98 -> -2,72,
prevday invariato. Nessuna data di gate si sposta. Guardia cablata in
monitor_health: stato PREMATURO (ultima barra che chiude dopo l'mtime, grazia
5 min, open_labeled=False per collect_chain) — sul dato vivo segnala i 5 rotti
e tace sui 2 sani; dopo la rigenerazione 7/7 OK. paper_portfolio non rigenerato
(GTAA su ADJUSTED_LAST: replay != serie registrata, P12), tolta la coda non
chiusa. D6 pagata di nuovo nel fix: asi8 in pandas 3 e' in us, non ns —
blindata con test su tre risoluzioni.

S5.12 ESTESO: conftest devia anche trades.db (wrapper su connect: il default
e' catturato alla definizione) e docs/journal/; book_executions.jsonl
sorvegliato con impronta inizio/fine suite.

S5.5 FATTO: test_leva_massima cancellato con nota (misurava frac*n_asset:
con una chiave di scala avrebbe continuato a passare smettendo di controllare).

S5.9 INDAGATO E RIPARATO (r0826_skh_band_drift): il dato regge (taglio 02/07
riproduce l'audit 1,6376, in-sample identico su ogni taglio); la deriva era la
finestra hold-out — e la sola settimana 15-22/08 vale +0,35 di Sharpe hold-out.
Il test ora taglia il feed al 02/07 e verifica la riproduzione stretta.

Suite: 751 passati, 0 falliti.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 10:12:23 +00:00

112 lines
5.1 KiB
Python

"""r0826_skh_band_drift.py — si guarda SOTTO il test rosso §5.9 prima di toccare la banda.
IL FATTO. `test_t1_canonical_riproduce_il_backtest_ufficiale` fallisce dal ~24-25/08:
Sharpe hold-out SKH01 `canonical` = 1,9223 contro la banda cablata `1.3 < h < 1.9`
(scritta il 25/07 sull'audit del 02/07: ~1,64). Il codice non e' cambiato; `data/raw/`
e' gitignored e il cron lo ricostruisce ogni notte -> la finestra si allunga e il numero
deriva. Lezione 07/08: un test che fallisce senza che il codice sia cambiato sta
segnalando QUALCOSA — si misura cosa, non si allarga la banda a occhio.
LA MISURA. Stesso codice di produzione (`r0726_skh_onbook.skh_series`), stesso `sh3`,
ma col feed TAGLIATO a date crescenti: se il numero alla data dell'audit riproduce
~1,64 e la curva sale in modo regolare con le barre aggiunte, la deriva e' CRESCITA
DELLA FINESTRA (hold-out 2025+ che si allunga con settimane favorevoli), non un dato
corrotto ne' un codice cambiato. Se invece il taglio all'epoca NON riproduce il numero
dell'epoca, il problema e' nel DATO RICOSTRUITO e la banda e' l'ultima delle questioni.
COSA MI ASPETTO PRIMA DI MISURARE (M12): riproduzione al taglio 02/07 dentro ±0,05;
curva monotona o quasi verso 1,92 (ago 2026 e' stato un rally forte, BTC +21%/30g,
e SKH01 era long ETH da meta' agosto).
uv run python scripts/research/r0826_skh_band_drift.py
"""
from __future__ import annotations
import sys
from pathlib import Path
import pandas as pd
ROOT = Path(__file__).resolve().parents[2]
for p in (ROOT, ROOT / "scripts" / "research", ROOT / "scripts" / "research" / "alt"):
sys.path.insert(0, str(p))
import r0702_anchor_skh01 as r02 # noqa: E402
import r0726_skh_onbook as ob # noqa: E402
TAGLI = ("2026-07-02", # la data dell'audit che ha scritto ~1,64
"2026-07-25", # il giorno in cui la banda e' stata cablata nel test
"2026-08-01", "2026-08-08", "2026-08-15", "2026-08-22",
None) # oggi: deve riprodurre l'1,9223 del test rosso
_GET5M_VERO = r02.get5m.__wrapped__ # la funzione nuda, senza lru_cache
def _taglia(cut_ms: int | None):
"""Rimpiazza get5m con una versione tagliata e svuota TUTTE le cache a valle."""
if cut_ms is None:
def g(asset: str):
return _GET5M_VERO(asset)
else:
def g(asset: str):
df = _GET5M_VERO(asset)
return df[df["timestamp"] < cut_ms].reset_index(drop=True)
r02.get5m = g
# ⚠️ run_asset non usa lru_cache: memoizza in un DICT di modulo (`_CACHE`) — svuotare
# solo le lru_cache serviva a niente e la prima stesura di questo script ha misurato
# SETTE volte la stessa finestra (tutte le righe identiche). Si svuota il dict.
r02._CACHE.clear()
r02.skh_port.cache_clear()
def main() -> None:
print("=" * 96)
print(" SKH01 canonical — Sharpe (full / in-sample / HOLD-OUT) in funzione della finestra dati")
print(" hold-out = barre >= 2025-01-01: si ALLUNGA ogni notte col cron")
print("=" * 96)
print(f" {'taglio':>12} {'barre HO (g)':>13} {'full':>7} {'in-s':>7} {'HOLD-OUT':>9} "
f"{'maxDD':>8} nota")
print(" " + "-" * 90)
esiti = {}
for cut in TAGLI:
cut_ms = None if cut is None else int(pd.Timestamp(cut, tz="UTC").value // 10**6)
_taglia(cut_ms)
s, _ = ob.skh_series(0, "canonical")
full, is_, hold, dd = ob.sh3(s)
n_ho = int((s.index >= r02.HOLDOUT).sum())
nota = ""
if cut == "2026-07-02":
nota = "<- deve riprodurre ~1,64 (audit 02/07)"
elif cut == "2026-07-25":
nota = "<- il giorno della banda 1.3<h<1.9"
elif cut is None:
nota = "<- deve riprodurre l'1,9223 del test rosso"
lab = cut or "oggi"
esiti[lab] = hold
print(f" {lab:>12} {n_ho:>13} {full:>7.3f} {is_:>7.3f} {hold:>9.4f} {dd:>7.1%} {nota}")
print("\n" + "=" * 96)
print(" VERDETTO (runtime)")
print("=" * 96)
rip_audit = abs(esiti["2026-07-02"] - 1.64) < 0.05
rip_oggi = abs(esiti["oggi"] - 1.9223) < 0.01
serie = [esiti[k] for k in esiti]
mono = all(b >= a - 0.03 for a, b in zip(serie, serie[1:]))
print(f" taglio 02/07 riproduce l'audit (~1,64)? {'SI' if rip_audit else 'NO'} "
f"({esiti['2026-07-02']:.4f})")
print(f" nessun taglio riproduce -> dato cambiato: "
f"{'no, il dato regge' if rip_audit else 'SI - INDAGARE IL FEED'}")
print(f" oggi riproduce il numero del test rosso? {'SI' if rip_oggi else 'NO'} "
f"({esiti['oggi']:.4f})")
print(f" la curva sale con la finestra (quasi-monot.)? {'SI' if mono else 'NO'}")
if rip_audit and rip_oggi:
print("\n => La deriva e' CRESCITA DELLA FINESTRA, non corruzione ne' codice: il test")
print(" confronta un numero che si muove col feed contro una banda scritta su una")
print(" finestra congelata. La riparazione giusta e' ancorare il test alla finestra")
print(" su cui la banda fu scritta (taglio fisso), non allargare la banda — una")
print(" banda che insegue il feed non riproduce niente (N11).")
if __name__ == "__main__":
main()