Futures research guide

Futures Contract Months, Expiration, and Trading Sessions Explained

Decode futures month symbols, distinguish expiration from last trade, handle Chicago sessions and DST, and follow liquidity across contract rolls.

Published · 1,490 words

Read the contract code as a dated identity

A futures symbol combines a product root, a delivery-month code, and a year. For a root such as ES, the month letter identifies the contract month; the year disambiguates which occurrence of that month is meant. ESH6 and ESH7 therefore name different dated contracts, not two versions of one permanent instrument. Roots and code conventions are product-specific, so use the exchange specification rather than inferring tick size, termination rules, or listed years from the root alone.

The standard month letters are:

CodeMonthCodeMonthCodeMonth
FJanuaryGFebruaryHMarch
JAprilKMayMJune
NJulyQAugustUSeptember
VOctoberXNovemberZDecember

Quarterly equity-index examples often use H, M, U, and Z, but a quarterly pattern is not a universal listing rule. One-digit year suffixes also repeat by decade. Resolve them against the dataset date and contract metadata; never treat the suffix alone as a complete timestamp.

Work through a symbol audit

In a 2026 research sample, ESH6 normally denotes the March 2026 E-mini S&P 500 contract; the same shorthand in a 2016 sample would denote March 2016. That resolution supplies an identity, not an expiration date. The next steps are to verify the exchange listing, obtain the contract specification, and locate the applicable trading calendar. Only then should the analysis assign session labels or schedule a roll.

Apply the same discipline when files use two-digit years or alternate symbol formatting. Normalize identifiers into explicit root, month, and year fields while preserving the original symbol for joins. Test for accidental collisions after normalization, especially where histories span a decade boundary. If a symbol cannot be resolved unambiguously, quarantine it rather than guessing from the nearest active month.

Separate dated contracts from continuous series

A dated contract is the tradable identity: its quotes, trades, volume, and termination rules belong to that specific month and year. A continuous symbol is a derived research series that stitches selected contracts together under a stated roll policy. It is not an additional listed contract, and its long history does not imply that one instrument traded throughout that period.

This distinction affects every join and chart. Query the dated file when auditing an actual session, reconstructing executable prices, or checking volume around expiry. Use a continuous file when a strategy needs an uninterrupted signal history, while retaining the underlying contract identity for orders and accounting. In the derived continuous datasets here, price = price_raw + back_adjustment; the adjusted field supports comparable historical signals, while price_raw preserves the original contract price scale.

Browse available instruments and histories on the dataset browser, and read the dataset documentation before mixing schemas. The companion guide to continuous futures contracts explains why roll dates and adjustment choices must be explicit.

Do not equate expiry, last trade, and settlement

“Expiration” is useful calendar shorthand, but it is not a sufficient execution rule. A contract can have a last trading time, a settlement procedure, and related delivery or cash-settlement provisions that occur at different points. Products may stop trading before a final settlement value is determined; physically delivered and financially settled contracts also have different obligations. Options on futures add another calendar.

Avoid universal claims such as “the Z contract always ends on the third Friday.” The applicable date can depend on product rules, weekdays, holidays, exchange notices, and the contract year. Consult the exchange calendar and specification for that exact dated contract. Record the source rule and its effective version in research notes rather than encoding a remembered weekday formula.

For a backtest, define when new positions are prohibited, when existing positions must be closed or rolled, and whether settlement exposure is permitted. Those strategy deadlines should occur early enough to be operationally feasible. A model that exits at a theoretical terminal print has not demonstrated an executable exit.

Understand the Chicago 17:00 session boundary

Many CME futures trading days are organized around a 17:00 Chicago boundary, with an evening opening followed by the next calendar day’s daytime activity. Consequently, the date attached to a trading session need not equal the UTC calendar date of every observation in it. A Sunday-evening trade in Chicago can belong to Monday’s session; late-afternoon Friday activity and Sunday evening activity are separated by the weekend break.

Product schedules matter. Maintenance breaks, early closes, holidays, and product-specific hours can shorten or move a session. “Daily” should therefore mean a defined exchange session, not blindly grouping by UTC midnight. In the derived bars documented here, intraday intervals are epoch-aligned in UTC, whereas daily bars use the Chicago 17:00 session with daylight-saving handling. Empty intervals are omitted, not emitted as zero-volume bars.

Session label: Monday
Sunday 18:30 Chicago  -> same session
Monday 09:35 Chicago  -> same session
Monday 16:20 Chicago  -> same session, if the product schedule permits

The example illustrates grouping, not a promise that every product is open at those times.

Convert UTC and local time deliberately

Store source timestamps in UTC and apply an explicit timezone database when displaying exchange-local time. Chicago switches between Central Standard Time (UTC−6) and Central Daylight Time (UTC−5). A fixed “subtract six hours” rule will mislabel part of the year and can move observations into the wrong session.

2026-01-15 23:00 UTC -> 2026-01-15 17:00 America/Chicago
2026-07-15 22:00 UTC -> 2026-07-15 17:00 America/Chicago

Do not convert by manually adding an hour throughout summer: the transition dates are calendar rules, and other jurisdictions need not change on the same dates. Use timezone-aware conversion at the boundary where local session labels are needed; keep the original UTC value for ordering and reproducibility. In the per-contract tick derived datasets, ts and recv_time are equal UTC timestamps and event_time is null, so there is no separate event timestamp available for alternative sequencing.

Test conversion around both seasonal transitions and around 17:00. Assert that local formatting never changes the underlying instant, and investigate duplicated or skipped local wall-clock labels without deduplicating valid UTC observations.

Treat overnight, weekend, and holiday gaps as structure

The interval between adjacent prints is not necessarily a trading interruption. Overnight maintenance, weekends, holidays, and scheduled early closes create legitimate gaps. A missing bar inside an empty bucket may instead mean no eligible trades occurred. Classify the calendar first; do not forward-fill prices across every closure and manufacture a continuous opportunity to trade.

Overnight risk also belongs in execution assumptions. An order left through a closure cannot be assumed to fill at the last displayed price, and the next available trade may be far away. Evaluate stops and time-based exits against when the market actually reopens. Weekend gap scenarios should alter both price and liquidity assumptions, not just add a calendar annotation.

For diagnostics, report gaps by expected session state: scheduled closure, open-but-inactive interval, and unexplained activity gap. Preserve empty-bucket omission when reading derived bars, and use the applicable exchange schedule before calling an absence corrupt. Holiday calendars should be year-specific and versioned alongside the analysis.

Follow liquidity as expiration approaches

Volume and open interest commonly migrate from a nearby contract to a later month before the nearby contract’s final trading time. There is no universal roll day: the timing varies by product, market participants, and event risk. A calendar-only switch can leave a model trading a thinning contract or switching after the new leadership has already formed.

Inspect dated-contract volume, trade frequency, spreads where available, and the intended holding period. Define a roll rule using information available at decision time, then apply it consistently. If volume determines the next active contract, avoid using completed future-session volume to justify an earlier switch. Simultaneously trading both contracts during a deliberate transition requires positions and costs in both.

In these derived tick data, bid_sz and ask_sz are executed volume at bid and ask, not resting book sizes; oi is zero because open interest is unavailable. They cannot support a claim about queue depth or actual open-interest migration. Use executed activity for the diagnostics it can support and document the remaining uncertainty.

Use a pre-trade and research checklist

  1. Resolve root, month code, full year, exchange, and exact dated contract.
  2. Read that contract’s current specification and calendar; distinguish last trade, settlement, and any delivery provisions.
  3. Record the strategy’s roll, order-cutoff, and forced-exit rules separately.
  4. Keep timestamps in UTC, convert with America/Chicago, and test both DST transitions.
  5. Define session labels and verify early closes, weekends, holidays, and maintenance breaks.
  6. Choose dated data for executable-contract analysis and continuous data for signals; preserve the mapping between them.
  7. Check where activity is migrating without interpreting executed bid/ask volume as book depth.
  8. Model closures and roll costs explicitly, and reject fills that occur while the selected contract is closed.

A sound workflow can therefore answer three different questions without conflating them: which instrument is being analyzed, which session contains an observation, and which contract an order could actually have used.