- Introduced `FeatureScale.mqh` with `FeatSquash` function for stateless feature scaling. - Added `RegimeMath.mqh` class for regime arithmetic, including efficiency and variance calculations. - Documented the Mind trading logic in `MIND.md`, detailing the trading process and modes. - Created `VOLNORM_PLAN.md` and `VOLNORM_RESULTS.md` for tick-volume normalization testing. - Implemented `read_book.py` for analyzing trade book data and correlations. - Developed `volnorm.py` for testing tick-volume normalization with new and old methods.
52 行
3.1 KiB
Markdown
52 行
3.1 KiB
Markdown
# 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.
|