- Implemented `catalog.py` to define instrument metadata and price scaling checks. - Developed `sqx.py` for decoding SQX tick .dat files, handling scaling and volume adjustments. - Created `sqxbars.py` to decode SQX bar files, ensuring price integrity against known ranges. - Introduced `volume_gate.py` for relative volume analysis on D1 bars, facilitating backtesting strategies.
4.7 KiB
Macro-state gates on the D1 4-index dip-z book (2026-10-08)
Pre-registered in macro_gates.py (N=6 trials: VIX/VIX3M, VRP=VIX-RV10, BAA10Y 5d change, each both ways).
Data: CBOE VIX/VIX3M, FRED BAA10Y (FRED's ICE HY OAS is truncated to 2023-10 -- confirmed), macro_data/.
Book: SP500/NAS100/US30/DAX40 D1, z20<-1.5 long, exit at mean, 3 ATR stop, risk 0.5%. D1 starts Aug 2008 (2008-09 window is thin).
Verdict under the pre-registered survival rule: all six REJECTED
Base: 634 trades, ret/DD 8.64, maxDD 5.5%. Base LOSES in 2008-09 (-134 bp/trade) and is flat in 2022 (-0.01R).
The one lead: G2a, VRP = VIX - RV10 > 5 (allow entry)
- FULL: +99 bp/trade vs +2 bp for the complement G2b (VRP<=5). Welch t = 3.49, p = 0.0005; G2a alone t = 6.30.
- G2a > G2b in all 5 eras (2008-13, 13-17, 17-21, 21-24, 24+) and all 4 indices (SP500 +105 vs -4, US30 +82 vs -64).
- Improves ret/DD in 2008-09, 2022, IS; fails OOS2017+ only on drawdown (7.0% vs 5.5%; return and bp are higher).
- H4 2021+ (independent) does NOT confirm: G2a 16.0 bp vs G2b 13.6 bp, ret/DD 2.79 vs 3.48 (base 5.68). Cadence on H4 is ~12/mo so the gate costs trades and gains nothing there.
- Reading: on D1 the book's money is made when implied vol exceeds realized (post-shock reversal); on H4 the horizon is too short for a daily VRP to matter. Consistent with the earlier vol-regime finding, not new alpha.
Not adopted. Next step if pursued
Gate stays an observation until a pre-registered D1 forward test (data after 2026-08) or another index family (Europe/Asia, own vol index) confirms. No re-thresholding of 5. Any new variant increments N (now 6). Untested still: SKEW/VVIX, T10Y2Y, DXY, event calendar, forex carry, metals real yields, energy curve, crypto funding.
Update 2 (2026-10-08): D1-vs-H4 discrepancy RESOLVED, and round 2 (DIX/GEX)
H4 VRP: the earlier H4 non-confirmation was a test-design artefact (prior-day value applied to every intraday bar).
H4 entering on the LAST bar of each day only, with that day's VRP (macro_gates + inline diagnostic, counted as a post-hoc trial, N=7):
BASE 22 bp / ret/DD 7.53 (n 776), G2a (VRP>5) 28 bp / 8.39 (n 518), G2b 9 bp / 0.98 (n 276). D1 2021+: G2a 103 bp / 4.44 vs G2b 38 / 0.31.
So VRP>5 confirms on both D1 and daily-close H4, 2021+. Incidental: last-bar-only H4 entries beat all-bar H4 entries (ret/DD 7.5 vs 5.7) -- intraday dips dilute. NOT yet tested as a rule; do not adopt without a pre-registered check.
Round 2 (macro_gates2.py, pre-registered, N=11): DIX (SqueezeMetrics, 2011+) > trailing-252d median, and GEX > 0, each both ways. ALL REJECTED.
Notable: LOW DIX (G4b) beats high DIX -- 94.5 vs 47.3 bp, 2022 ret/DD 4.86 -- the opposite of the "dark-pool buying confirms the dip" brief, again "pay for stress"; fails only OOS2017+ ret/DD (3.40 vs 3.58) at 53% cadence-kept. GEX adds nothing (G5a worse than base).
Update 3: last-bar-of-day entry rule (lastbar_check.py, pre-registered, N=12) -- SURVIVES
H4 2021+, 4 indices: all-bar 1243 trades 15.4 bp, ret/DD 5.68, DD 8.2% -> last-bar 776 trades (62%) 21.5 bp, ret/DD 7.53, DD 5.7%. 4/4 indices better (SP500 24.5 vs 16.4, NAS100 26.9 vs 20.0, US30 11.9 vs 8.1, DAX40 23.7 vs 17.2); 4/6 years better (WORSE in 2022: 3.5 vs 13.4 bp and 2023: 5.7 vs 16.7 -- the rule is not uniform; passed the >=4/6 bar narrowly). Holding: H4 mean 7.1-7.6 bars (~1.2-1.3 d), exits 46-49% target (close back at the 20-bar mean) / 32-39% time (10 bars) / 15-19% 3-ATR stop. D1 book: mean 6.3 days, 57% target / 23% time / 19% stop. Not yet in the EA; needs an MQL5 session-aware "last bar" check + a tester run.
Update 4: relative-value ratio divergence (pairs_scan.py, pre-registered, 15 pairs x 1 config) -- NULL
Log ratio (beta 1), 60d z, enter |z|>=2, exit at z=0, stop |z|>=4, 30d max, both legs' spread paid. D1, 1994/2008-2026. Indices (9 pairs), XAU/XAG, WTI/Brent, EURUSD/GBPUSD, AUDUSD/NZDUSD, EURJPY/GBPJPY, BTC/ETH, JPN225/HSI. 0 survivors (t>=3 bar). Best t: WTI/Brent 1.7 (89 bp but 22% DD, roll artefacts likely); UK100/F40 1.1; SP500/US30 1.1. ~0.4 trades/mo/pair (cadence fails alone). Gross edge is ~0 on average (several pairs strongly negative: BTC/ETH, JPN225/HSI, DAX40/CAC/EuroStoxx). Swap/carry not modelled.
Update 5: relative-volume gate on the dip-z book (volume_gate.py, pre-registered, N=13) -- NO EDGE
rv = volume / mean(prior 20 bars), broker D1 (tick-count regimes jump, so ratio only). FULL: base 59.4 bp ret/DD 8.64; rv>=1 (n 596) 62.3 bp / 8.20; rv<1 (n 244) 81.3 bp / 6.68. High-volume dips are NOT better than the book; low-volume dips pay slightly more per trade (DAX40 138 vs 68 bp) but at 40% of the cadence and lower ret/DD. No volume gate improves ret/DD in IS and OOS. SQX sq_futures data are encrypted (see memory); not used.