research: ondata 26/07-bis — TP01 su barra parziale + i 2 gate mai costruiti

0 sleeve nuovi. Book, pesi, cron, config INVARIATI.

T1 — anche TP01 legge una barra giornaliera PARZIALE nel live, ma non conta.
Stesso fatto strutturale di SKH01: resample_tf non scarta il giorno in corso e
current_target prende [-1]; il feed si ricostruisce alle 00:30 UTC, quindi per
tutta la giornata il book vede oggi come 1 barra oraria su 24 (verificato).
Il docstring "ultima barra CHIUSA" era falso: corretto.

Tre path a un grado di liberta' per volta, 24 ancore, differenze appaiate:
  barra parziale   ΔFULL -0.031 (pos 7/24)  ΔHOLD +0.118 (pos 19/24)
  ritardo 1h       ΔFULL -0.004 (pos 11/24 = moneta)
  leva LIVE/MODEL  1.004
-> trascurabile, nessun cambio al live.

All'ancora canonica sembra peggio del vero: a offset 0 la parziale costa -0.230
di hold-out, che e' il MINIMO della banda (mediana +0.118). Speculare alla
lezione del 26/07: li' l'ancora canonica nascondeva un vantaggio, qui inventa
un danno.

REGOLA: la parzialita' dell'ultima barra conta in proporzione a quanto il
segnale pesa la barra piu' recente. Donchian breakout su 230m (la barra corrente
E' il segnale) -> +0.38; TSMOM 30/90/180g -> ±0.03. Non si trasferisce.

T2 — implausible_sharpe e anchor_luck_band codificati in altlib (debito
raccomandato 3 volte e mai scritto), piu' anchor_luck_delta che codifica
l'errore di stamattina (mediana delle differenze appaiate, non differenza
delle mediane).

Il gate ha segnalato VRP01 e il difetto era MIO: perdite contate su tutte le
barre, ma VRP01 e' settimanale su griglia giornaliera (94.2% di zeri) -> "0.96%,
coda assente" su uno sleeve in produzione. Sulle barre ATTIVE e' 16.5%, la forma
giusta di un credit spread a rischio definito. La lezione era gia' cablata il
giorno prima nel monitor DVOLSPREAD ("barre attive, non giorni di calendario").

Applicazione retroattiva 7/7 tutti ok, con controlli positivi obbligatori
superati (firme CC01 e deep-OTM segnalate, rumore Sh 0.62 no).

Replica indipendente del finding d'ancora del 02/07: il gate applicato alla
cieca a TP01 ritrova canonica +0.237 = 92 pctl delle 24, mediana onesta +0.056,
fortuna +0.182 — contro mediana 0.04 misurata il 02/07 con implementazione
separata. L'hold-out onesto di TP01 e' ~+0.05, non 0.31.

NON fatto: il book ricalcolato sul path live, bloccato da incompatibilita' di
lenti (simulatore per-trade vs sleeve vol-targeted). Follow-up dichiarato.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-07-25 22:36:40 +00:00
parent 6d0813a399
commit 37be1df838
7 changed files with 947 additions and 2 deletions
+134
View File
@@ -0,0 +1,134 @@
"""I due gate MAI COSTRUITI, ora codificati e applicati RETROATTIVAMENTE (ondata 2026-07-26-bis, T2).
Debito dichiarato dal progetto e mai saldato:
`implausible_sharpe` — raccomandato il 26/06 (CC01: Sharpe modellato 11-13, maxDD 0.3%, passa
OGNI gate del marginal scorer -> "punto cieco") e RI-raccomandato "con piu' forza" il 02/07
(celle Albimarini deep-OTM: 0 perdite su 142 trade; meta' della griglia VRP a 288 strutture con
la stessa firma). Tre occorrenze, tre diagnosi a mano, zero codice.
`anchor_luck_band` — dichiarato "candidato gate futuro" il 02/07, dopo che il timing-luck
d'ancora era stato trovato su 4/4 sleeve ancorati. Motivo per cui serve un gate DEDICATO: la
griglia di ancore non e' una griglia di parametri, quindi **il deflated-Sharpe non la conta**.
Questo script (a) prova che i gate FUNZIONANO su controlli positivi noti, poi (b) li passa su
tutto cio' che oggi e' nel book o in forward-monitor. Un gate che non segnala nulla non e' una
buona notizia finche' non si e' dimostrato che sa segnalare.
"""
from __future__ import annotations
import sys
from pathlib import Path
import numpy as np
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 altlib as al # noqa: E402
from src.portfolio import sleeves as sl # noqa: E402
def line(t: str) -> None:
print("\n" + "-" * 100 + f"\n {t}\n" + "-" * 100)
def show(name: str, rep: dict) -> None:
flag = "*** IMPLAUSIBILE ***" if rep.get("implausible") else "ok"
if "sharpe" in rep:
print(f" {name:<16} Sh {rep['sharpe']:>6.2f} DD {rep['maxdd']*100:>5.2f}% "
f"perdite/attive {rep['loss_frac']*100:>5.1f}% ({rep['n_active']} att.) Calmar {rep['calmar']:>7.2f} {flag}")
else:
print(f" {name:<16} {rep.get('reasons')} {flag}")
for r in rep.get("reasons", []):
print(f" - {r}")
def main() -> None:
print("=" * 100)
print(" T2 — `implausible_sharpe` e `anchor_luck_band`: codificati e applicati retroattivamente")
print("=" * 100)
# ------------------------------------------------------------------ controlli positivi
line("0. CONTROLLI POSITIVI — il gate DEVE segnalare questi, sennò e' rotto")
idx = pd.date_range("2020-01-01", periods=900, freq="1D", tz="UTC")
rng = np.random.default_rng(726)
# (a) firma CC01: cashflow liscio, quasi nessuna perdita, DD ~0
cc = pd.Series(0.0006 + rng.normal(0, 0.00012, len(idx)), index=idx)
show("CC01-like", al.implausible_sharpe(cc))
# (b) firma Albimarini deep-OTM: 0 perdite su 142 trade
alb = pd.Series(np.abs(rng.normal(0.0008, 0.0003, len(idx))), index=idx)
show("deepOTM-like", al.implausible_sharpe(alb, n_trades=142, n_losing_trades=0))
# (c) controllo NEGATIVO: rumore normale a Sharpe ~1 non deve essere segnalato
ok = pd.Series(rng.normal(0.0006, 0.011, len(idx)), index=idx)
show("rumore Sh~1", al.implausible_sharpe(ok))
# ------------------------------------------------------------------ book + monitor
line("1. `implausible_sharpe` su TUTTO cio' che e' nel book o in forward-monitor")
series: dict[str, pd.Series] = {}
for nm, fn in (("TP01", sl._tp01_returns), ("XS01", sl._xsec_returns),
("VRP01", sl._vrp_combo_returns), ("SKH01", sl._skyhook_returns),
("GTAA01", sl._gtaa_daily_returns)):
try:
series[nm] = fn()
except Exception as e: # uno sleeve rotto non ferma l'audit
print(f" {nm:<16} non valutabile: {type(e).__name__}: {e}")
for nm, s in series.items():
show(nm, al.implausible_sharpe(s))
# candidati in forward-monitor, ricostruiti dai rispettivi script di scoperta
line("2. `implausible_sharpe` sui CANDIDATI in forward-monitor")
try:
import r0725_statarb_basket_gate as xg # XSR01 = versione DEMEANATA
P, S = xg.pair_frames()
show("XSR01", al.implausible_sharpe(xg.basket_from_positions(P, S, demean=True)))
except Exception as e:
print(f" XSR01 non ricostruibile qui: {type(e).__name__}: {e}")
try:
import r0726_dvolspread_gate as dg
# config ONESTA congelata nel monitor (`paper_dvolspread.FROZEN`), non la cella pubblicata
show("DVOLSPREAD", al.implausible_sharpe(
dg.daily_returns(zwin=180, tanh_k=2.0, lw=0.6, zw=1.1, tgt=0.17, svw=60)))
except Exception as e:
print(f" DVOLSPREAD non ricostruibile qui: {type(e).__name__}: {e}")
# ------------------------------------------------------------------ anchor band
line("3. `anchor_luck_band` — ri-verifica del finding 02/07 col gate ORA CODIFICATO")
print(" TP01 sulle 24 ancore orarie (metrica: Sharpe hold-out, il numero che il 02/07 era")
print(" risultato il MIGLIORE delle 24). Se il gate e' giusto deve ritrovarlo da solo.")
import r0726_tp01_partial_day as pd_mod
cache: dict[int, dict] = {}
def model_at(off: int) -> pd.Series:
if off not in cache:
cache[off] = pd_mod.evaluate(off)
s = cache[off]["MODEL"]
return s[s.index >= pd_mod.HOLDOUT]
band = al.anchor_luck_band(model_at, range(24), canonical=0,
metric=lambda s: pd_mod.sharpe(s))
print(f"\n canonica (00:00) {band['canonical']:+.3f} | pctl nella banda "
f"{band['canonical_pctl']*100:.0f}° | mediana {band['median']:+.3f} "
f"| banda [{band['lo']:+.3f},{band['hi']:+.3f}]")
print(f" positiva in {band['frac_positive']*100:.0f}% delle ancore | "
f"fortuna = canonica - mediana = {band['luck']:+.3f} | gate_pass={band['gate_pass']}")
print("\n E il confronto APPAIATO fra due varianti (live con barra parziale vs modello):")
delta = al.anchor_luck_delta(
lambda o: cache.setdefault(o, pd_mod.evaluate(o))["LIVE"],
lambda o: cache.setdefault(o, pd_mod.evaluate(o))["MODEL"],
range(24), metric=lambda s: pd_mod.sharpe(s))
print(f" mediana delle DIFFERENZE appaiate {delta['median_paired']:+.3f} "
f"[{delta['lo']:+.3f},{delta['hi']:+.3f}] positiva in "
f"{delta['n_positive']}/{delta['n_anchors']} gate_pass={delta['gate_pass']}")
print()
if __name__ == "__main__":
main()