d5dd6f4b72
- altlib.causality_ok(target_fn, tf): online-consistency guard (ricalcola il target su un prefisso, la coda deve combaciare col full). eval_weights shifta la posizione ma non vede una feature non-causale (finestra centrata/shift(-k)/stat full-sample) -> questa sì. - intra_score integra DUE gate prima/dopo lo scoring: causality (leak -> LEAK, squalificato) e day_boundary_robust (ARTIFACT-RISK -> fuori dagli slot). Effetto sul leaderboard intraday: open_drive + weekly_seasonality + overnight -> CAL-ARTIFACT (da soli, niente skeptic); prevday_range_breakout resta (ROBUST). earns_slot 10 -> 8. - +2 test (causal-ok / leak), suite intera verde. Il lab intraday ora auto-becca leak e artefatti-calendario che ieri richiedevano 3 scettici. Chiude la 3a lezione harness dell'onda intraday. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
89 lines
6.1 KiB
Markdown
89 lines
6.1 KiB
Markdown
# 2026-06-21 — Asse intraday/microstruttura: il lead più vicino al reale, ma NON deployabile
|
||
|
||
## Perché (utente: "cerchiamo qualcosaltro")
|
||
|
||
Direzionale e relative-value su BTC/ETH esauriti (flotte blind + ortho). L'unico asse mai
|
||
sfruttato dopo il reset = il **tempo intraday** (feed certificati 5m/15m/1h; tutto era a 1d).
|
||
Meccanismi diversi da trend e relative-value: bias ora/sessione (perp con funding a 00/08/16 UTC),
|
||
reversione post-evento (vol/volume/gap), breakout del range del giorno prima.
|
||
|
||
## Setup
|
||
|
||
`scripts/research/intraday/intra_score.py`: wrappa `altlib.study_marginal` a un TF a scelta
|
||
(compone i rendimenti intraday a daily, li valuta col **marginal scorer indurito** = multi-cut +
|
||
edge-in-sample + hedge-vs-alpha) e riporta **turnover + fee-sweep a 0.20% RT**. Il muro: a 0.10% RT
|
||
il churn intraday è morte (un flip orario fa 2152 trade/anno → −8.6 Sharpe netto). Vincolo agli
|
||
agenti: **basso turnover**, l'intraday come informazione (timing/sizing/gating), non HFT.
|
||
|
||
## Flotta — 16 agenti
|
||
|
||
16 ipotesi low-turnover. Esito grezzo: 16 riportati, **10 "earns_slot"** (di nuovo gonfiato).
|
||
|
||
## Diagnosi orchestratore — separare ortogonale vero da trend-beta
|
||
|
||
Per corr-a-TP01 (`meta_intra.py`): 2 sono **trend-beta** (close_location 0.81, trend_quality 0.75 —
|
||
Sharpe in-sample alto ma preso in prestito dal trend), 3 **mixed**, **5 genuinamente ortogonali**
|
||
(|corr|<0.4): open_drive (0.13), prevday_range_breakout (0.15), vol_event_revert_15m (−0.1),
|
||
volume_spike_revert (0.14), gap_fill (0.04) — 2 famiglie (breakout-continuation + capitulation-revert),
|
||
mutuamente de-correlate. **Combo dei 5: Sharpe standalone 1.80, corr-TP01 0.17, uplift +0.33/+0.27/
|
||
+0.34/+0.34/+0.53 a OGNI cut** (non solo 2025).
|
||
|
||
## Gauntlet deterministico (`verify_intra.py`) — passa TUTTO ciò che uccise le onde precedenti
|
||
|
||
- **In-sample pre-2025 Sharpe 1.75; uplift pre-2025-ONLY +0.281** (l'ortho faceva +0.027 = null).
|
||
- **Walk-forward selection** (scegli su solo passato, testa avanti): **+0.303 / +0.368** (l'ortho dava −0.07).
|
||
- **Drop-one robusto** (+0.24..+0.31 pre-2025), **fee-robusto a 0.30% RT**, **leak-free**
|
||
(online-consistency: max_tail_diff = 0.0 su tutti e 5). Sembrava IL lead.
|
||
|
||
## Verifica avversariale (3 scettici indipendenti) — il verdetto vero
|
||
|
||
1. **Execution/microstruttura:** **open_drive = ARTEFATTO di etichettatura UTC.** Spostando il
|
||
confine del giorno di 4h l'uplift va NEGATIVO (−0.10); togliendo l'ancora UTC (trailing-8h) Sharpe
|
||
0.01; funziona solo a 00:00 UTC, solo alle ore 3 e 7. **Scartare.** `prevday_range_breakout` invece
|
||
**REGGE** (plateau su k, robusto allo shift del confine, fill eseguibili a close) = unico candidato
|
||
onesto, ma la decorrelazione viene tutta dalla gamba SHORT che si appoggia al regime down 2025-26;
|
||
anchor=1 only. **Caveat $600:** il vol-target fa ~8500 ribilanciamenti/anno, 97-98% < $1 di nozionale
|
||
→ la fee proporzionale modellata su trade infinitesimi è **finzione** a $300/gamba (vale anche per TP01).
|
||
2. **Hedge + tail:** **REFUTED.** L'uplift pre-2025 +0.281 sta al **20-24° percentile del null di un
|
||
asset a corr-zero** (mediana null +0.371) — essendo a corr +0.175 (non 0) e bassa vol, **aggiunge
|
||
MENO del rumore scorrelato**. È **hedge** (corr Sharpe-TP01/uplift −0.57..−0.80; TP01-down uplift
|
||
+0.79 vs TP01-up +0.20) e **tail-luck** (le gambe revert: top-5 giorni = 76-83% del PnL, <10
|
||
eventi/anno, front-loaded 2019-21; combo: metà uplift in ~10 giorni).
|
||
3. **Overfit/robustezza:** **ROBUST-PLATEAU** (243-cell joint grid pre-2025 uplift min +0.134/med
|
||
+0.211, 99% celle >+0.15; ogni anno positivo). MA segnala lui stesso il **null-pctl 0.20**: "il
|
||
beneficio è la matematica di diversificazione di uno stream ortogonale a Sharpe 1.75, NON timing-alpha
|
||
specifico-TP01" + storia corta sulle gambe revert + fill modellati vs reali.
|
||
|
||
## Verdetto
|
||
|
||
**Niente in live.** L'asse intraday ha prodotto il lead **più vicino al reale** di tutta la ricerca,
|
||
ma sotto 3 scettici: **open_drive è artefatto** (UTC-labeling); la combo **fallisce il null a
|
||
corr-zero** (aggiunge meno del rumore), è **hedge-shaped** e **tail-luck**; e lo Sharpe modellato è
|
||
gonfiato dal micro-ribilanciamento sub-dollaro a $600. Lo Sharpe standalone 1.80 NON è affidabile
|
||
(artefatto + coda + finzione di fill). **Resta solo TP01.**
|
||
|
||
**Lead reale (forward-monitor, non deploy):** `prevday_range_breakout` — l'unico segnale sopravvissuto
|
||
allo scettico d'esecuzione (breakout del range del giorno prima, eseguibile, leak-free), con caveat
|
||
short-leg/regime-2025. Trattamento = come `dvol_spread` / XS01 / STA05.
|
||
|
||
### Lezioni harness — CODIFICATE (il vero ritorno)
|
||
|
||
1. ✅ **`altlib.day_boundary_robust(target_fn, tf)`** — shifta il confine del giorno UTC e ri-misura
|
||
l'uplift marginale: INVARIANT (segnale di prezzo, spread 0) / ROBUST (effetto calendario vero,
|
||
resta positivo) / **ARTIFACT-RISK** (l'uplift si inverte = etichettatura). Verificato: riproduce
|
||
da solo il verdetto degli scettici — open_drive → ARTIFACT-RISK (+0.23→−0.33), prevday_breakout
|
||
→ ROBUST. Test `tests/test_harness_realism.py`.
|
||
2. ✅ **`altlib.eval_weights_smallcap(df, target, capital=600, min_order=5)`** — salta i
|
||
ribilanciamenti sub-min_order (la finzione del micro-trading a $600), riporta lo Sharpe haircut
|
||
reale vs modellato. Vale per ogni sleeve a questo capitale, TP01 incluso. Test idem.
|
||
3. ✅ **`altlib.causality_ok(target_fn, tf)`** — guardia look-ahead/online-consistency (ricalcola
|
||
il target su un prefisso e pretende che la coda combaci con il full): eval_weights shifta la
|
||
posizione ma NON vede una feature non-causale (finestra centrata / shift(-k) / stat full-sample).
|
||
Integrata in `intra_score` (un leak è squalificato prima dello scoring). + il calendar-artifact
|
||
gate (`day_boundary_robust`) ora gira dentro `intra_score`: **open_drive/weekly_seasonality/
|
||
overnight → CAL-ARTIFACT, fuori dagli slot da soli**; prevday_breakout resta (ROBUST). Il lab
|
||
intraday ora auto-becca leak e artefatti-calendario che ieri richiedevano gli scettici. Test idem.
|
||
|
||
File: `scripts/research/intraday/{intra_score,meta_intra,verify_intra}.py`,
|
||
`agents/agent_00..15_*.py`, `intra_leaderboard.json`.
|