Skip to main content
2026-05-22 · 4 min read · ← 1 · research · regime · negative-result

Disconfirmed: the transition-gate fix didn't recover the regime-filter

what you'll learn · Why the 'gate on change, not level' fix didn't work, and what this tells us about the mismatch between per-symbol vol filtering and cross-sectional momentum on this synthetic.

PR #717 named a candidate fix for vol_regime_filter's underperformance on clustered-vol data: gate on vol CHANGE instead of vol LEVEL. PR #721 ran the experiment. Result: the transition gate underperforms the level gate on BOTH modes by 0.2 Sharpe. The 'gate on change' fix doesn't recover the regime-filter performance. Both interpretations matter.

PR #717’s research note predicted a fix:

The gate’s discipline rule should be: gate on regime transitions, not on current regime state.

PR #719 shipped XsMomentumWithVolRegimeTransitionFilterStrategy on that hypothesis. PR #721 ran the harness comparison.

The result

Mode:                  I.I.D.       Clustered (cluster=0.8)
baseline:              +0.961       +1.348
vol_regime_filter:     +0.791       +0.526
vol_transition_filter: +0.540       +0.329

Hypothesis NOT confirmed. The transition gate underperforms the level gate on BOTH modes by ~0.2 Sharpe. Both gates underperform baseline. The “gate on change, not level” fix doesn’t recover the regime-filter performance.

What this rules out

The hypothesis was that the level gate fails on clustered-vol data because vol_5/vol_60 has persistent state — long runs above the level threshold. The proposed fix: gate on the change-in-vol-state instead, which is naturally mean-reverting even when the level isn’t.

The transition gate WAS naturally mean-reverting on the synthetic — the gate fired less often than the level gate. But the underlying problem — gating cross-sectional momentum on per-symbol vol filtering — wasn’t actually about how often the gate fires. It was about something else.

Two candidate interpretations

The negative result doesn’t tell us WHY the fix failed. Two hypotheses to test in future sessions:

Interpretation A: threshold miscalibration

The transition threshold defaulted to 0.5 (vol changed by 50%+ between consecutive 5-bar windows). On the synthetic’s vol scale, that might be too tight or too loose. A tuning sweep would clarify whether the right threshold exists at all.

Untestable in this PR — would need a --vol-transition-threshold-sweep harness mode or external tuning loop. Out of scope.

Interpretation B: shape mismatch

Per-symbol vol filtering of the cross-sectional ranking may be the wrong shape on this synthetic. The ranking is already robust to single-symbol vol noise (top/bottom quantile sort naturally averages across the universe); the gate’s universe- shrinkage cost may always exceed its noise-reduction benefit on data where the ranking works.

If interpretation B is right, the regime-filter idea is broken at the concept level on this synthetic, not the implementation level. The fix isn’t a different gate shape — it’s a different intervention point entirely. Possibilities:

  • Gate the WEIGHTS (size down regime-transitioning symbols rather than dropping them).
  • Gate the AGGREGATE EXPOSURE (size down the whole portfolio when universe-wide vol transitions).
  • Apply the gate at the score stage (subtract vol-transition penalty from each symbol’s score) rather than as a binary filter.

All three are out of scope; each is a future strategy class.

What this doesn’t rule out

  • Not “regime detection doesn’t work.” Real markets have documented regime structure (Hamilton 1989, etc.); the intervention point might be wrong here, not the underlying thesis.

  • Not “the synthetic is wrong.” The synthetic models clustered vol — a documented real-market feature. The failure-to-help is on the strategy side, not the data side.

  • Not “the level gate is fine.” It’s not. Both level and transition gates underperform baseline. The whole per-symbol-vol-filter approach to gating cross-sectional momentum is suspect on this synthetic.

The discipline rule

When a candidate fix is disconfirmed, name the alternative interpretations explicitly. “It didn’t work” is one bit of information; “it didn’t work AND interpretation A would retest it AND interpretation B is the orthogonal direction” is multiple bits.

A corollary: negative results need notes. The body of work doesn’t lose any work — the unsuccessful candidate becomes research evidence that the underlying problem is harder than the first fix assumed. Future operators see the “tried-and-disconfirmed” tag and don’t repeat the experiment.

What to ship next

Three concrete follow-ups in priority order:

  1. Threshold sweep. A --vol-transition-threshold-sweep mode on the harness, or a notebook that loops over thresholds. If a sweet spot exists, the level/transition distinction isn’t load-bearing; only the threshold value matters.

  2. Score-stage gate. Replace the binary filter with a continuous penalty on each symbol’s score: score(sym) = momentum(sym) - α × vol_transition(sym). Tests interpretation B’s “intervention point” hypothesis.

  3. Portfolio-level gate. Size down the entire portfolio when universe-wide vol_5/vol_60 spikes. Tests whether the intervention should be cross-symbol, not per-symbol.

All three are testable in the existing harness; all three would ship as new arms.

deskgdfindgfstrategiesgsfeaturesgepromotionsgpapigabotgbwritinggw

Shortcuts are no-ops while typing in an input or textarea.