IWM ed EFA avevano uno split NON aggiustato il 2005-06-09 (IWM 2:1 = -49.5%,
EFA 3:1 = -66.5%): IB ADJUSTED_LAST non li aveva aggiustati.
La certificazione non li vedeva per un punto cieco STRUTTURALE: l'unica guardia
sui salti era `maxret > 50% -> SPIKE?` e uno split 2:1 fa esattamente -50%, cioe'
cade sul filo della soglia (IWM passava a 49.5% con status OK).
IWM e' una delle 6 gambe di GTAA01, sleeve in PRODUZIONE. Impatto misurato:
GTAA6 FULL Sharpe 0.61 -> 0.64, IS (<2015) 0.49 -> 0.54; OOS 2015+ e maxDD
INVARIATI (l'artefatto e' nel 2005, fuori hold-out) -> il difetto SOTTOSTIMAVA
lo sleeve: nessuna decisione presa va rivista.
Discriminante split-vs-crollo: NON il rapporto (SLV 2026-01-30 ha rapporto
1.3994, a 4bps da 1.4, ma e' un crollo vero: GLD -10.3% lo stesso giorno) ma il
RANGE INTRADAY — lo split apre gia' al nuovo livello con range normale (IWM:
open 47.00, range 1.7%), il crollo si muove DENTRO la barra (SLV: range 33%).
- src/data/eq_splits.py: detect_unadjusted_splits() a 3 condizioni congiunte
(|ret|>20% AND rapporto ~ fattore comune AND range intraday <5%) + repair_splits()
con split multipli componibili;
- riparazione in LETTURA in src/portfolio/gtaa.py::_close (produzione) e
scripts/research/eqlib.py::load_eq (ricerca);
- fetch_ib_equities.certify(): nuovo status SPLIT-NON-AGG + elenco split rilevati;
- tests/test_eq_splits.py: 8 casi, inclusi il falso positivo SLV e un crollo -50%
esatto con range grande.
Regola nuova: ogni soglia di certificazione tarata su un valore tondo va
controllata contro il difetto che genera esattamente quel valore.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>