| # Tick-volume normalization - results (2026-09-30)
|
|
|
| Plan: `VOLNORM_PLAN.md`. Script: `python research/volnorm.py H4|H1`. Broker M1 `.hcc`, 4 indices,
|
| 2022-01..2026-08.
|
|
|
| ## Verdict
|
|
|
| **Test 1 confirmed. Tests 2, 3 and 4 fail as written.** The repair removes the clock from the
|
| feature; it does not make the feature more stable across years and it does not separate paying dips
|
| from failing ones. No EA change is justified by this run beyond the DRY clean-up.
|
|
|
| ## H4 (the book's timeframe)
|
|
|
| | idx | R^2 old | R^2 new | yr-mean sd old | yr-mean sd new | rho old | rho new |
|
| |---|---|---|---|---|---|---|
|
| | SP500 | 0.567 | 0.001 | 0.080 | 0.120 | 0.190 | 0.055 |
|
| | NAS100 | 0.583 | 0.005 | 0.064 | 0.172 | 0.159 | 0.037 |
|
| | US30 | 0.645 | 0.003 | 0.080 | 0.093 | 0.176 | 0.065 |
|
| | DAX40 | 0.705 | 0.014 | 0.080 | 0.228 | 0.045 | 0.057 |
|
|
|
| Dip-z events (n 213-226 per index), top minus bottom tercile of the feature, bp:
|
| new = SP500 -19.9, NAS100 -11.9, US30 -2.5, DAX40 -38.5; **pooled -18.0 [-38.3, +4.5]**.
|
| old pooled +0.3 [-18.3, +22.1]. H1 pooled: old -1.6 [-7.3, 3.9], new -3.6 [-10.1, 2.8].
|
|
|
| ## Reading
|
|
|
| 1. **The defect is real and large.** 57-77% of the variance of today's relative-volume inputs is
|
| which hour of the day the bar is. After same-slot normalization it is 0.1-1.4%. The three inputs
|
| in `SignalNeural`, `WarriorVote::MgmtFeatures` and `FracDiff::VolumeAt` have been feeding the
|
| clock to the models as if it were participation.
|
| 2. **Test 2 fails.** The slot profile is a 60-session median, so it lags any level shift: DAX40's
|
| 2022->2023 tick collapse leaves the yearly mean of the new feature at sd 0.23 against 0.08 for
|
| the old one. Fix candidate (needs its own pre-registration): normalize by the slot's share of a
|
| short trailing daily total instead of a long slot history, so the scale adapts within days.
|
| 3. **Test 3 fails literally, and the test was badly framed.** The old feature's correlation with
|
| next-bar activity (0.16-0.41) is mostly the clock: open bars have both high volume and big
|
| moves. What is left after removing the clock is 0.03-0.07. That is small but it is the honest
|
| number. A within-hour comparison would have been the right control.
|
| 4. **Test 4 fails; a lead, not a finding.** The clock-free feature has the same sign on all four
|
| indices at H4 (high-volume dips pay LESS, -18 bp pooled), but the CI includes 0 (p about 0.1) and
|
| H1 does not repeat it convincingly. Unmodelled: the vol-regime gate is not applied to these
|
| events, and it is itself a volume-adjacent variable.
|
|
|
| ## Consequences
|
|
|
| - Keep the pre-registered outcome: **volume normalization does not improve the dip-buy.**
|
| - Do fix the three duplicated computations into one shared normalizer (DRY) so that any future
|
| volume-dependent model (Wyckoff effort-vs-result, NN inputs) is not confounded by the clock.
|
| - Any re-test of the Wyckoff/NN volume inputs must use the repaired feature; the earlier null
|
| results on those inputs were measured with the clock-contaminated one.
|
| - The negative sign at H4 deserves ONE follow-up, pre-registered before it is run: gated events, and
|
| the short-window normalizer from point 2.
|