Skip to content

What this answers

39 asked the owner to decide on two rules, citing the 2009–2026 proxy Tier-1 table

(2026-09-27-vrp-threshold-characterisation-tables.md):

  1. Transition lockout. On the proxy, transition days (53%) realised better than settled days.
  2. VRP sign. Within calm-contango, vrp- (premium selling blocked) realised better than vrp+ (allowed).

48 asked whether either survives on canonical SPY ATM IV30, the measure the 1 Nov

cutover (#18) would put on the VRP axis. Short answer: neither finding survives. On the same 2022–2026 days, (1) is not established under either measure, and (2) reverses: on canonical IV30 the VRP sign is informative in the direction the mapping assumes.

Nothing here changes mapping_version, regime_config.json or any rule. Those decisions belong to #18 / #15 / #39.

Method

  • Days: every FRED trading day with VIX + VIX3M that also has a canonical IV30 value: 1,184 days, 2022-01-03 → 2026-09-22. Both variants use exactly these days.
  • Variants: only the VRP axis differs.
  • proxy: VRP = VIX/100 − forecast_rv30 (production today)
  • canonical: VRP = chain-inverted SPY ATM IV30 − forecast_rv30 (backtest/out/iv30-spy-chain-inverted-2022-2026.csv, the 2026-09-30 arbiter series)
  • canonical-svi: the same, from the SVI surface (robustness; same chains)
  • Labels come from production's pure functions (band_vix, band_term, step_hysteresis, the HAR functions via replay.har_payload), composed in backtest/replay_variants.py. Fidelity is checked: the proxy variant was compared with production main() (via replay.replay) on all 7 label fields for all 1,184 days. 0 mismatches. The run refuses to write anything on a single mismatch.
  • Outcome, per variant, on that variant's own measure: vrp_realised = iv_t − rv_fwd_30 (forward 30-trading-day realised vol on SPY closes). It is joined in a separate pass, as in Tier 1.
  • Uncertainty: 30-day forward windows overlap, so row counts overstate the evidence. Both contrasts carry 95% moving-block bootstrap intervals (block = 30 trading days, 2,000 resamples, seed 48).
  • Consistency check: the VRP sign differs between the variants on 483/1,182 = 40.9% of labelled days, against 40.7% in the 2026-09-30 measurement. Different code paths agree.

Results

The two contrasts

variant contrast n (a / b) mean diff 95% CI hit-rate diff 95% CI
proxy transition − settled 743 / 412 −0.0045 [−0.0226, +0.0102] −4.3 pp [−14.8, +4.4]
proxy calm-contango: vrp− minus vrp+ 282 / 440 −0.0125 [−0.0245, +0.0007] +1.2 pp [−8.1, +14.1]
canonical transition − settled 551 / 604 −0.0005 [−0.0269, +0.0187] +0.2 pp [−14.9, +13.9]
canonical calm-contango: vrp− minus vrp+ 637 / 85 −0.0139 [−0.0253, −0.0021] −16.8 pp [−29.4, −2.9]
canonical-svi transition − settled 565 / 589 −0.0015 [−0.0270, +0.0172] +1.0 pp [−13.6, +14.5]
canonical-svi calm-contango: vrp− minus vrp+ 633 / 88 −0.0135 [−0.0258, −0.0018] −13.7 pp [−29.0, +2.7]

Calm-contango by VRP sign

variant label n mean hit rate worst
proxy calm-contango-vrp+ 440 0.0369 0.882 −0.2458
proxy calm-contango-vrp- 282 0.0244 0.894 −0.2622
canonical calm-contango-vrp+ 85 0.0200 0.882 −0.1500
canonical calm-contango-vrp- 637 0.0061 0.714 −0.2814

On the proxy over these years, hit rate within calm-contango-vrp+ rises with ex-ante VRP (0.843 at [0,1) → 0.972 at [3,4)). That is the opposite of the 2009–2026 table, where it fell.

Lockout: share of labelled days in transition

variant 2022 2023 2024 2025 2026 (to 09-22) all confirmed-label changes VRP-sign changes
proxy 75.3% 59.2% 69.0% 70.6% 34.3% 63.3% 156 164
canonical 72.9% 39.2% 32.1% 38.7% 52.5% 46.8% 112 144

Full per-label, per-bucket and SVI tables: 2026-10-04-tier1-canonical-iv30-tables.md.

What this means for the open decisions

#39: both findings were artifacts of window and measure, not robust evidence.

  • Transition lockout: on 2022–2026 there is no established difference between transition and settled days under either measure (all four intervals straddle 0 widely). The 2009–2026 proxy result does not reproduce here. The lockout is neither supported nor refuted by Tier 1; there is no evidence to remove it on.
  • VRP sign: the "vrp- beats vrp+" inversion does not hold on these years even on the proxy, and on canonical IV30 it reverses. vrp+ realises better on mean (interval excludes 0, chain and SVI) and on hit rate (excludes 0 on chain; marginal on SVI). On the measure the cutover adopts, the sign axis carries information in the direction the mapping assumes. Option (a) in #39, dropping the sign from the label, is not supported.

#18 (cutover): two consequences to weigh, beyond the known −2.6 pt level shift.

  1. Premium-selling eligibility becomes rare. Canonical calm-contango-vrp+ occurred on 85 of 722 calm-contango days (~18/year), against 440 on the proxy. Its realisation is better per day, but the book would be eligible to sell premium far less often.
  2. Lockout falls overall (63% → 47%) but rises in the current regime. 2026 is 52.5% on canonical vs 34.3% on the proxy, because canonical VRP sits near zero and flips (34 sign changes in 2026 vs 9). That matches what the live gate showed 09-22 → 10-01.

#15 (θ): canonical calm-contango-vrp+ mean realisation is +2.0 vol pts before costs (median +2.2), and all canonical regimes together average +0.7. That is close to the "< ~1 vol pt after costs is not worth it" line in the 10-03 strategy note. Any θ on the canonical measure has very little room.

Limitations

  1. Short window. ~4.7 years, one hiking cycle, one bear market (2022). The calm-contango-vrp+ canonical cell is 85 days ≈ 3 non-overlapping 30-day windows of independent information. The bootstrap interval is the honest statement of that, and it is wide.
  2. Overlapping outcomes. Read n as an upper bound.
  3. Entry richness, not P&L. iv − rv_fwd is not the P&L of any traded structure; Tier 2 is still blocked.
  4. Partly mechanical. The label's VRP and the outcome share iv_t. That's the definition of VRP, and identical in both variants, so the comparison is fair. But some of any sign effect is the HAR forecast's skill at predicting realised vol.
  5. One underlying, one canonical source (SVI is the same chains, not an independent check).
  6. Hysteresis starts empty on 2022-01-03 in both variants.

Inputs (committed, PR #51 review fix)

The canonical series are committed under backtest/data/ so the canonical half can be re-derived from the repo:

file sha256 (as committed, LF line endings)
iv30-spy-chain-inverted-2022-2026.csv 7a5411ebe7654040f5a6eb9a6afcce07704cf93871ca9f99550e5d3096d800d5
iv30-spy-svi-2022-2026.csv ca93b252047cef26f16da0c8deb029f8b1b530c7460351df5aa8ecfed84f8cb5

Hashes are of the committed bytes. .gitattributes normalises text to LF, and the 09-30 originals were CRLF (sha256 79c751af… / 0591422e…); the CSV values are identical. A fresh checkout of this branch reproduces every number in this receipt exactly (contrasts-48.json compared byte-for-byte as JSON).

Produced 2026-09-30 by backtest/iv30_from_chain.py / iv30_from_svi.py from the VolSurfAE store (data/odifs/volsurfae.duckdb, SVI parquet), which is not on hermes. Regenerating the CSVs needs that store; re-deriving every table from the CSVs does not. Use an interpreter with numpy (on hermes: /usr/bin/python3). The fidelity replay's runtime varies by host, from about 1 min to about 8 min.

Source audit (2026-10-05, #53)

The committed chain CSV was regenerated from its source, the VolSurfAE store (ai-rig.local:~/src/VolSurfAE/data/odifs/volsurfae.duckdb, opened read-only), with the committed backtest/iv30_from_chain.py unchanged except for a private output path.

  • 1,182 of 1,189 dates byte-identical across all 6 columns. 7 dates differ by at most 0.136 vol pts, each on one expiry of an unchanged expiry pair, consistent with source quotes revised after 2026-09-30. No date is missing from either side.
  • Every result in this receipt is unchanged on the regenerated series: same days, the same 483 sign flips, and the same n, means and 95% intervals for all four proxy and canonical contrasts. The only change is canonical calm-contango vrp− minus vrp+ mean −0.0139 → −0.0138 (interval unchanged).
  • The committed CSV is kept as-is, since it is the artifact this receipt describes. A regeneration's sha256 will differ from the one recorded above wherever the store has revised a row.
  • The store extends the series past this receipt (through 2026-10-02 at the time of the audit), which is what the #18 same-date level check (#58) uses.

Reproduce

cd backtest
# needs cache/fred_vix_vix3m.csv, cache/spy_closes.json (hermes, 2026-09-27)
    python3 characterise_canonical.py --boot 2000
python3 test_backtest.py

Writes out/characterisation-48-canonical.md, out/contrasts-48.json and out/features-48-{proxy,canonical,canonical-svi}.jsonl. Runtime about 70 s.