37be1df838
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>
173 lines
9.8 KiB
Markdown
173 lines
9.8 KiB
Markdown
# 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.
|