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
@@ -0,0 +1,172 @@
# 2026-07-26-bis — Ondata: TP01 su barra parziale + i due gate mai costruiti
**Richiesta:** *"fai un'altra ondata di ricerca"*.
**Esito: 0 sleeve nuovi, 1 audit sul libro live, 2 gate codificati, 1 falso positivo del mio
stesso gate su uno sleeve in produzione (catturato e corretto), 1 replica indipendente di un
finding di tre settimane fa.**
**Book, pesi, cron, config: INVARIATI.**
Script: `scripts/research/r0726_tp01_partial_day.py`, `scripts/research/r0726_gates_retro.py`.
Test: `tests/test_gates_implausible_anchor.py` (13). Gate in `scripts/research/alt/altlib.py`.
Da dove nasce: il 26/07 ho misurato che il path live di SKH01 divergeva dal modello su entrambi
i lati (uscite e ingressi) e che **il modello era pessimistico**. Due domande restavano aperte, ed
erano piu' interessanti di un'ennesima caccia al segnale: *lo stesso difetto esiste sullo sleeve
che pesa il 75% del book?* e *perche' i gate che il progetto si e' raccomandato tre volte non
esistono ancora?*
---
## T1 — TP01 nel live legge una barra giornaliera fatta di UN'ORA
**Il fatto, verificato non dedotto.** `resample_tf(..., label="left", closed="left")` non scarta il
giorno in corso; `TrendPortfolio.current_target` prende `target_series(df)[-1]`. Il feed certificato
si ricostruisce alle 00:30 UTC, quindi per tutta la giornata il book vede il giorno corrente come
**1 barra oraria su 24** (misurato: `barre1h=1/24`). Il docstring diceva "ultima barra CHIUSA":
**falso nel live**, ed e' la terza volta in due giorni che un docstring di produzione afferma una
causalita' che il codice non ha.
**Due canali con segno atteso opposto**, quindi vanno separati:
- *esecuzione ritardata* — il modello ribilancia al confine 00:00, il live al primo cron dopo il
rebuild (~01:00);
- *barra parziale* — `c[t]` e' il prezzo delle 01:00 e `r[t]` e' un rendimento di **un'ora** contato
come giornaliero nella finestra di vol a 30 barre → vol sottostimata → **sovra-leva sistematica**.
**Tre path, un grado di liberta' per volta**, su griglia oraria (i confini sono diversi: solo
l'orario li rende confrontabili):
| offset 0 (ancora canonica) | FULL | HOLD | maxDD |
|---|---:|---:|---:|
| MODEL — `tgt[t-1]` dal confine 00:00 | 1.30 | 0.24 | 16.7% |
| CLOSED@+1h — scarta la parziale, ora del live | 1.27 | 0.16 | 17.5% |
| LIVE — `tgt[t]` da barra parziale, +1h | 1.25 | 0.07 | 17.5% |
**Banda delle 24 ancore, mediana delle DIFFERENZE APPAIATE:**
| effetto | FULL | HOLD |
|---|---|---|
| barra parziale (LIVE CLOSED) | **0.031** [0.135,+0.065], pos. 7/24 | **+0.118** [0.230,+0.277], pos. 19/24 |
| ritardo 1h (CLOSED MODEL) | 0.004 [0.053,+0.034], pos. 11/24 | 0.007, pos. 9/24 |
| totale (LIVE MODEL) | 0.046, pos. 7/24 | +0.128, pos. 18/24 |
Leva LIVE/MODEL: **1.004** (mediana, invariata su tutta la banda).
**Verdetto: trascurabile.** Il ritardo d'esecuzione e' letteralmente una moneta (11/24). La barra
parziale muove ±0.03 su FULL e la sua "vittoria" su HOLD (+0.118) e' su una finestra sola e con
segno opposto su FULL — cioe' esattamente il profilo che il progetto ha gia' codificato come
sospetto. La sovra-leva prevista esiste ma vale **0.4%**. Nessun cambio al live.
**⚠️ Da notare: all'ancora canonica il quadro sembra peggiore del vero.** A offset 0 la barra
parziale costa **0.230** sull'hold-out, che e' il **minimo dell'intera banda** — mentre la mediana
e' +0.118. Guardando solo l'ancora canonica avrei concluso "il live degrada TP01 di 0.23 sull'hold-out"
e sarebbe stato l'artefatto di un'ancora. E' la stessa lezione del 26/07 in versione speculare
(li' l'ancora canonica *nascondeva* un vantaggio, qui *inventa* un danno).
**Il risultato trasferibile non e' il numero, e' il perche'.** La parzialita' dell'ultima barra conta
in proporzione a **quanto il segnale pesa la barra piu' recente**:
> SKH01 e' un Donchian breakout su barra 230m: **la barra corrente E' il segnale** → stesso difetto,
> **+0.38** di Sharpe mediano. TP01 e' un TSMOM 30/90/180 giorni: l'ora mancante e' 1/24 di **una**
> osservazione su 30-180 → **±0.03**.
Corollario operativo: la conclusione di uno sleeve su questo tema **non si trasferisce** all'altro,
e la domanda "il mio live legge barre parziali?" ha una risposta diversa per ogni sleeve a seconda
della lunghezza del lookback. Cablato nei docstring di `current_target` e `resample_tf`.
---
## T2 — I due gate raccomandati tre volte e mai scritti
Debito dichiarato: `implausible_sharpe` (raccomandato il 26/06 su CC01, ri-raccomandato "con piu'
forza" il 02/07 su Albimarini) e `anchor_luck_band` (dichiarato "candidato gate futuro" il 02/07,
dopo il timing-luck trovato su 4/4 sleeve ancorati). Tre occorrenze, tre diagnosi a mano, zero codice.
### `implausible_sharpe`
Uno Sharpe/track troppo bello significa che **il rischio e' fuori dal dataset**, non che la strategia
sia buona. Trigger: Sharpe > 3, frazione di barre attive in perdita < 2%, Calmar > 20 o maxDD ~0, e
la **regola del tre** (0 perdite su N trade lascia un tasso vero fino a ~3/N — su un payoff deep-OTM
basta a ribaltare l'expectancy: e' il motivo per cui "0/142" non si legge come "senza rischio").
### `anchor_luck_band` + `anchor_luck_delta`
La griglia di ancore **non e' una griglia di parametri**, quindi il deflated-Sharpe non la conta: e'
multiple-testing invisibile. Il gate riporta la stima onesta (**mediana della banda**) e la fortuna
(canonica mediana). `anchor_luck_delta` codifica l'errore che ho commesso stamattina: fra offset
appaiati la statistica e' la **mediana delle differenze**, non la differenza delle mediane — le due
mediane cadono su offset diversi e il verdetto puo' ribaltarsi.
### ⚠️ Il gate ha segnalato VRP01. Il difetto era MIO.
Prima stesura: perdite contate su **tutte** le barre. VRP01 e' settimanale su griglia giornaliera →
**94.2% di zeri** → "0.96% di perdite, coda sinistra assente" su uno sleeve **in produzione al 12%**.
Sulle barre **ATTIVE** le perdite sono **16.5%**, che e' esattamente la forma attesa di un credit
spread a rischio definito.
Verifica: zeri per sleeve — VRP01 94.2%, SKH01 87.6%, XS01 39.6%, GTAA01 31.9%, TP01 30.7%. Un gate
che conta gli zeri come "non perdite" avrebbe finito per segnalare mezzo book.
Ed e' la parte che vale la pena ricordare: **avevo gia' imparato questa lezione ieri**, cablando la
contabilita' a 3 stati del monitor DVOLSPREAD ("finestra misurata in barre attive, non giorni di
calendario"), e l'ho ripetuta il giorno dopo in un contesto diverso. Ora e' un test.
### Esito dell'applicazione retroattiva — copertura 7/7
| | Sharpe | maxDD | perdite/attive | esito |
|---|---:|---:|---:|---|
| TP01 | 1.29 | 14.3% | 48.7% (1865) | ok |
| XS01 | 1.36 | 10.9% | 46.6% (566) | ok |
| VRP01 | 1.08 | 11.9% | 16.5% (109) | ok |
| SKH01 | 1.45 | 18.1% | 55.6% (333) | ok |
| GTAA01 | 1.01 | 8.9% | 45.2% (1831) | ok |
| XSR01 (monitor) | 1.79 | 2.5% | 47.8% (892) | ok |
| DVOLSPREAD (monitor) | 0.68 | 25.5% | 50.8% (1949) | ok |
Controlli positivi (obbligatori: un gate che non segnala nulla puo' essere semplicemente rotto):
firma CC01 e firma deep-OTM **segnalate** con le motivazioni giuste; rumore a Sharpe 0.62 **non**
segnalato.
**Nota che vale per XSR01**, il cui gate di deploy scade il 23/10: il suo maxDD del 2.5% *non* e'
una coda mancante — il **47.8%** delle barre attive e' in perdita. Il DD basso viene da vol bassa
(2.3%) e dollar-neutrality. Il rischio #1 di XSR01 resta lo slippage non modellato, non un modo di
perdita nascosto.
### Replica indipendente del finding d'ancora del 02/07
Il gate, applicato alla cieca a TP01 sulle 24 ancore orarie, ritrova da solo cio' che il 02/07 era
stato diagnosticato a mano:
> canonica (00:00) **+0.237** = **92° percentile** delle 24 | mediana onesta **+0.056** |
> banda [0.087, +0.247] | fortuna **+0.182**
Il 02/07 riportava mediana 0.04 e banda [0.13, +0.30] con un'implementazione **separata**. Accordo
buono. **Il numero onesto dell'hold-out di TP01 e' ~+0.05, non 0.31.** (Il valore del sleeve resta
quello gia' stabilito e non ancorato: il taglio del drawdown ~6× vs buy&hold.)
---
## Cosa NON e' stato fatto, e perche'
**Il book ricalcolato sul path LIVE.** Sarebbe la sintesi naturale (SKH01 live > modello su entrambi
i lati; TP01 live ≈ modello) e cambierebbe la stima de-luckata del book, che oggi applica un ×0.6
assunto. Non l'ho fatto perche' le due misure vivono su **lenti diverse**: il simulatore di SKH01
compone per-trade a nozionale unitario, lo sleeve di `sleeves.py` e' vol-targeted. Combinarle
produrrebbe un numero che sembra preciso e non lo e'. **Follow-up dichiarato con l'ostacolo nominato:**
serve una versione vol-targeted del path live di SKH01 prima di toccare il fattore di de-luck.
Resta pero' una conseguenza qualitativa gia' solida: il ×0.6 fu scelto assumendo che il live
**degradi**. Su SKH01 e' misurato il contrario, su TP01 e' ~zero. **Il ×0.6 e' probabilmente
conservativo**, e la nota gia' presente in CLAUDE.md ("il ×0.6 sopra il path live rischia di contare
due volte la degradazione SKH01") va letta come confermata, non come cautela ipotetica.
---
## Regole nuove
1. **La parzialita' dell'ultima barra conta in proporzione a quanto il segnale pesa la barra piu'
recente.** Breakout/livelli: massima. Momentum a lookback lungo: ~nulla. Non trasferire la
conclusione fra sleeve.
2. **Ogni statistica di "frazione in perdita" si calcola sulle barre ATTIVE.** Uno sleeve flat la
maggior parte del tempo non ha una coda assente, ha meno osservazioni. (E: una lezione imparata
in un contesto non si applica da sola in un altro — questa era gia' cablata nel monitor
DVOLSPREAD il giorno prima.)
3. **Un gate nuovo si valida su un controllo positivo prima di credere ai suoi "ok".** Un gate rotto
e un gate soddisfatto producono lo stesso output.
4. **Anche un DANNO misurato a un'ancora sola e' fortuna d'ancora.** A offset 0 la barra parziale
sembrava costare 0.23 di hold-out: era il minimo della banda, mediana +0.12.