Alphanume

Insights

Testing a Market-Regime Filter on Momentum

Alphanume Team · July 21, 2026

Test a market-regime filter on momentum by holding the published monthly basket fixed and varying only the daily exposure rule, then compare drawdown, volatility, return, and filter-induced turnover.

Alphanume Quant Galore Momentum Index publishes 10 ranked stocks at each monthly rebalance. The Momentum Index guide documents the fixed basket clock. S&P 500 Risk Regime publishes a daily binary state, where 0 is risk-on and 1 is risk-off. The combined test asks whether a state-aware exposure rule changes the path of the fixed momentum basket.

The regime label is a volatility-state classification, not a directional forecast. A risk-off value can justify testing less gross exposure because market volatility is elevated. It does not say the basket or the S&P 500 must fall that day.

Align monthly holdings with a daily state

Input

Publication clock

Backtest rule

Momentum basket

Monthly at 4:05 PM New York time

Enter on the next eligible session

Risk regime

Daily at 10:10 AM New York time

Use prior state at the open or same-day state after publication

Daily returns

Defined by the chosen price source

Apply to constituents already in the fixed basket

Rebalance

Next published basket date

Replace names only on the scheduled monthly transition

Expand each monthly 10-stock basket into daily holdings until the next rebalance, then join the regime known at the strategy's decision time. Do not rebuild momentum rankings daily. That would combine a regime filter with an unplanned change in the selection model.

The regime date join needs an observation-time rule. An open strategy uses the prior session's label because today's state arrives at 10:10 AM. A close strategy can use the same-day label after allowing a declared execution delay.

Build the fixed-basket panel

Pull both histories, verify exactly 10 unique ranks per momentum date, and create holding intervals from each rebalance through the day before the next. Then attach survivorship-complete daily prices and the correctly known regime.

import pandas as pd

baskets = pd.DataFrame(momentum_rows).sort_values(["date", "rank"])
regime = pd.DataFrame(regime_rows).sort_values("date")

assert baskets.groupby("date").size().eq(10).all()
assert baskets.groupby("date")["rank"].nunique().eq(10).all()
assert regime["date"].is_unique

# daily_holdings is expanded from each published basket without reranking.
panel = daily_holdings.merge(regime, how="left", on="date", validate="many_to_one")
panel["size_multiplier"] = panel["risk_regime"].map({0: 1.0, 1: 0.5})
panel["filtered_return"] = panel["basket_return"] * panel["size_multiplier"]

The half-exposure rule is an example that must be predeclared. Test the unfiltered baseline first, then one filter. Searching many multipliers, delays, and state-transition rules will overfit a small number of stress periods.

Measure drawdown and turnover together

Metric

Baseline source

Filter effect

Return

Equal-weight fixed basket

Exposure removed or retained by state

Realized volatility

Daily basket returns

Primary state-aware risk result

Maximum drawdown

Chronological portfolio path

Depth and duration change

Basket turnover

Monthly constituent changes

Exists without the regime filter

Overlay turnover

Daily multiplier changes

Additional trading caused by state transitions

A filter can improve drawdown while lowering return, or lower volatility while adding frequent exposure changes. Report both turnover sources. Monthly constituent turnover trades names, while regime turnover changes gross exposure between rebalance dates. They have different spread, tax, and financing consequences.

Calculate drawdown from the full chronological equity curve. Computing state-specific drawdowns after splitting the dates destroys the path and can make the filter look safer than the implementable portfolio.

Specify what the uninvested half earns during risk-off periods. Cash at zero, a dated cash yield, and a hedge each produce different returns and risks. The simplest diagnostic uses zero return on unused notional, then reports financing or cash yield as a separate sensitivity.

Use the proof as a boundary

The Alphanume proof page reports that risk-off days have substantially higher realized and forward volatility while average market direction is similar across states. It also publishes the momentum basket's historical record separately. Neither result proves that the half-exposure overlay improves momentum. The interaction is a new strategy test.

  • Timing leakage. Same-day risk state cannot be used at the open.
  • Concentration. A 10-stock momentum basket has single-name and sector risk that a market-level flag does not describe.
  • State simplicity. A binary label cannot distinguish a marginal risk-off day from a crisis.
  • Execution costs. Regime flips add turnover beyond the monthly rebalance.
  • Missing outcomes. Delisted constituents must remain in the fixed historical basket and return source.

Free access covers a trailing 20-session delayed window and may contain only one momentum basket. A drawdown test needs full histories and enough stress episodes to evaluate the state interaction.

Run one predeclared overlay

Build the unfiltered equal-weight basket with next-session rebalance entry, then apply one 1.0 versus 0.5 exposure rule using the prior regime at the open. Export holdings, state alignment, basket turnover, overlay turnover, equity curves, drawdowns, and missing-price rows. Validate on a later period before considering another multiplier.

Explore the state fields on the S&P 500 Risk Regime page and follow the Risk Regime guide for the daily clock and historical access contract.