Mattheus Public Preview

Join Waitlist

Mattheus Public Preview

Current Blog

How to Model Trading Halts in a Backtest

A halt-aware backtest separates limit states, regulatory halts, quote resumption, and trade resumption instead of treating the gap as continuous trading.

Published Updated
Cobalt and violet market data blocks pause at a warm cream gate before resuming in an orderly line

By alyc

This article was prepared with AI assistance and checked through automated editorial and source review. No named human review is recorded.

A trading-halt backtest should stop the execution clock when the market stops trading. It should not fill an order from a bar that spans the halt, interpolate prices across the gap, or assume that the last quote remains executable. The model needs separate events for a limit state, an announced halt, quote resumption, trade resumption, and the reopening auction.

Store each event with the symbol, venue, reason code, source timestamp, effective timestamp, time zone, and source record. Then attach every simulated order and fill decision to that timeline. If the dataset cannot distinguish a quote-only period from resumed trading, mark the interval as uncertain and do not invent an execution.

Start with the official event sequence

The Limit Up-Limit Down Plan is designed to prevent trades in NMS stocks outside specified price bands during regular trading hours. Its operating site explains that the Securities Information Processors calculate upper and lower bands from a reference price. A security can enter a Limit State before a trading pause is declared.

That distinction matters. A Limit State is not the same record as a halt. During a Limit State, one side of the market can be marked non-executable and a quotation can sit at a price band. If the market does not exit the state within the plan's stated window, the primary listing exchange can declare a trading pause. The backtest should consume the disseminated state and halt messages rather than infer them only from price movement.

Use the exact plan and venue rules that applied on the historical date. Rules and technical procedures change. Keep the rule version beside the market data instead of applying today's thresholds to an older sample.

Do not collapse every halt into one code

Nasdaq's official trading halt code reference lists fields for halt time, reason code, pause threshold price, resumption quote time, and resumption trade time. It also distinguishes causes such as news pending, extraordinary market activity, regulatory concern, and volatility pauses.

A backtest should preserve that reason code. A volatility pause can have a different order and reopening path from a news halt or an operational halt. The reason may also determine whether an order remains accepted, is repriced, is canceled, or must wait for an auction. Do not use one generic rule unless the data truly provides nothing more specific, and label that fallback clearly.

Freeze fills without erasing order state

When a halt becomes effective, reject any simulated fill with an execution timestamp inside the halted interval. Freeze time-to-fill and other execution clocks if the metric is meant to measure active trading time. Keep wall-clock time separately so the run can still report how long the investor waited.

An outstanding order does not automatically disappear. Its state depends on the venue, broker instructions, order type, and the applicable rule. Store at least accepted quantity, filled quantity, remaining quantity, limit price, time in force, venue, last acknowledgement, and any cancel or replace message. Resume eligibility only when the evidence says trading can resume.

This is where a detailed limit-order fill model matters. A reopening auction print is not proof that every resting order at that price participated. Use auction allocation or execution messages when available. With weaker data, apply a declared conservative assumption.

Worked halt and reopening example

Consider a synthetic example in Eastern Time. A stock's last executable quote is $48.00 bid and $48.10 offered. An announced halt begins at 10:03:12.250. A strategy submits a buy decision at 10:03:15 with a $47.00 limit, but the broker and venue acceptance state is unknown. Quotations are scheduled to resume at 10:08:10, and trading is scheduled to resume at 10:08:30. The reopening auction prints at $44.20.

The backtest records no fill between 10:03:12.250 and 10:08:30. It also does not fill the $47.00 order at the pre-halt offer or at an interpolated price. If later evidence shows the order was accepted and eligible for the auction, the fill model evaluates the $44.20 auction under its allocation rules. If acceptance cannot be established, the conservative result is no fill.

This example uses US dollars and Eastern Time. It assumes one listed equity, one announced halt, no broker-side rejection message, and a known reopening print. It is illustrative, not an empirical result.

Separate quote resumption from trade resumption

Nasdaq publishes distinct resumption quote and trade times because a quotation-only period can precede trading. A strategy may observe new indicative prices during that interval, but it should not create regular-way fills before trade resumption.

Represent the sequence as states such as continuous, limit_state, halted, quote_only, and continuous_after_reopen. Each transition needs a timestamp and source. Align all events through the same market calendar and time-zone policy. Milliseconds matter when an order and a halt message arrive close together.

Avoid bar-level leakage

A one-minute bar can contain trades from before a halt and after a reopening. Its high, low, close, and volume do not reveal when the market was unavailable. Filling from that aggregate can place an execution inside the halt or use the reopening price before it was known.

Split bars at halt boundaries when the source permits it. Otherwise, exclude the affected bar from execution decisions and record why. Never use the completed bar to decide whether an order placed earlier should have filled. That would introduce the same look-ahead bias that invalidates other event-driven tests.

Validate the halt state machine

The SEC's April 2026 Rule 605 FAQ treats announced trading halts as distinct periods and says a non-marketable limit order should not be considered to have first become executable while trading is halted. The reporting rule is not a backtest specification, but its event distinctions are useful checks on a simulation.

Test at least these invariants.

  • No simulated execution occurs after halt effectiveness and before trade resumption.

  • Quote-only messages can update observable state but cannot create regular fills.

  • Active-trading duration and wall-clock duration are stored separately.

  • An order received during a halt has an explicit acceptance assumption.

  • A reopening fill cites an eligible auction or post-resumption event.

  • The halt reason and resumption timestamps are preserved in data lineage.

  • Removing halt data cannot silently improve the strategy's fill rate.

Run cases for a limit state that clears without a pause, a volatility pause, a news halt, a quote-only reopening, a delayed reopening, an order accepted just before the halt, and missing resumption data. If the model cannot explain its action at every boundary, the result is not ready for strategy comparison.

Explore Markets with Infinite Context.

Explore Markets with Infinite Context.

Browse the public preview. Join the waitlist for gated trading features.

Browse the public preview. Join the waitlist for gated trading features.

Browse the public preview. Join the waitlist for gated trading features.

Dashboard interface preview