Explainer
Futures month codes: contract letters, symbols, expiry and rollover
The letter tells you the month. It does not tell you that WTI’s December contract stops trading on 20 November, or that most of WTI’s 5.6% front-month drop on 20 October was the roll.
On this page
- How to read futures month codes in a contract symbol
- Futures contract months: the cycle each product lists
- Futures expiration dates: last trade, first notice and roll window
- Front month futures and how the rollover works
- Continuous futures contracts: raw, back-adjusted, ratio-adjusted, weighted
- Decode futures symbols in Python
- Contract months, roll dates and bars from TickerLayer
- Questions
Key takeaways
- Futures month codes run F, G, H, J, K, M, N, Q, U, V, X, Z for January to December: XYZ26 is the December 2026 contract of root XY.
- H, M, U and Z are the quarterly months: on 28 October 2026, 8 TickerLayer futures products used only those.
- The delivery month is not always the expiry month: WTI’s December 2026 contract stops trading on 20 November, while gold’s runs to 29 December.
- WTIUSD.C1 fell 5.84 (5.63%) when it rolled to December on 20 October 2026; 5.12 of that was the gap between the two months.
- Continuous futures are raw, back-adjusted, ratio-adjusted or weighted; TickerLayer serves raw chains and four weighted roll series, no adjusted ones.
Futures month codes are single letters for the delivery month: F for January, G February, H March, J April, K May, M June, N July, Q August, U September, V October, X November and Z December. A contract symbol is root + letter + year, so XYZ26 is the December 2026 contract of a product with root XY.
| Month | Code | Quarterly |
|---|---|---|
| January | F | |
| February | G | |
| March | H | Yes |
| April | J | |
| May | K | |
| June | M | Yes |
| July | N | |
| August | Q | |
| September | U | Yes |
| October | V | |
| November | X | |
| December | Z | Yes |
How to read futures month codes in a contract symbol
Read a futures symbol from the right: the last digits are the year, the letter before them the month, and the rest the root, which names the product. Roots differ between venues and data feeds; the letters do not. Stock, currency and crypto symbols follow other rules, covered in ticker symbol formats.
- XY: rootThe product. TickerLayer uses plain bases such as
WTIUSDandXAUUSD. - Z: monthDecember: the last of the 12 letters and of the quarterly H, M, U, Z.
- 26: year2026. Some screens print one digit,
XYZ6, and some data files four,XYZ2026. - WTIUSD.DEC26TickerLayer’s dated form: base, dot, three-letter month, two-digit year.
- WTIUSD.C1The front month:
DEC26on 28 October 2026..C2and.C3are the next two. - /XYZ26, XY Z26Display variants with a slash or a space. Strip both before parsing.
A one-digit year is ambiguous: XYZ6 meant December 2016 in data from that year. The decoder below picks the nearest year ending in that digit whose month has not yet passed:
Futures contract months: the cycle each product lists
Most products skip months. Each one has a cycle of contract months, which GET /futures/products returns as chain_months. On 28 October 2026 they followed these cycles:
| Cycle | Letters | Products |
|---|---|---|
| Every month | F G H J K M N Q U V X Z | WTI and Brent crude, natural gas, aluminum |
| Even months | G J M Q V Z | Gold, Gold 24/7, live cattle |
| Five a year | H K N U Z | Silver, copper, corn, wheat |
| Seven a year | F H K N Q U X | Soybeans |
| Quarterly | H M U Z | Palladium, 2-year and 5-year Treasury notes, Treasury bond, three-month rate, US 500, US Tech 100 and US Small Cap 2000 indices |
GET /futures/contracts returned 21 gold months on 28 October, serial months such as NOV26 and JAN27 among them; only the 12 even months carry in_chain: true. Serial months have their own prices but never enter the chain.
Futures expiration dates: last trade, first notice and roll window
TickerLayer’s roll calendar gives each front month a roll window, the moment .C1 moves on and a last trade date:
| Contract | Roll window | C1 moves | Last trade |
|---|---|---|---|
WTIUSD.DEC26 | 6 to 12 Nov | 19 Nov, 18:00 | 20 Nov |
CORNUSD.DEC26 | 6 to 12 Nov | 13 Dec, 18:00 | 14 Dec |
US500.DEC26 | 6 to 12 Nov | 17 Dec, 18:00 | 18 Dec |
XAUUSD.DEC26 | 6 to 12 Nov | 28 Dec, 18:00 | 29 Dec |
The delivery month is not always the expiry month. WTI’s December contract stops trading on Friday 20 November, the month before delivery, while the US 500 index’s runs to Friday 18 December. All four share one .R5 window, set in the month before delivery: business days 5 to 9 of November on the US stock market calendar, open on Veterans Day, 11 November.
First notice day, shown with gold
First notice day is the first day delivery notices can be given on a physically delivered contract, which is why roll schedules for gold, grains and Treasury notes usually finish before it. TickerLayer’s roll calendar sets it by one rule, the last weekday of the month before the contract month; for gold’s December contract, 30 November:
- 27 Oct, 18:00: DEC26 becomes .C1OCT26 leaves the chainDEC26 to .C1
- 6 to 12 Nov: weight +0.2 at each closeprices FEB27 alone after the 12 Nov close
- 30 Nov: first noticeas the roll calendar defines it; .NOTICE switches
- 28 Dec, 18:00: .C1 moves to FEB27
- 29 Dec: last trade
Front month futures and how the rollover works
The front month is the nearest month of the cycle that has not reached its last trade date. TickerLayer’s chain, .C1 to .C3, holds the three nearest at raw prices and moves up one at 18:00 New York the evening before the front’s last trade date: on 28 October gold’s read DEC26, FEB27, APR27. A raw chain jumps at each rotation, as WTI’s did in October:
WTI through its October 2026 roll, daily closes
- .C1
- DEC26
- .R5
USD per barrel
WTIUSD.C1 closed at 103.66 on 19 October, still the November month, and at 97.82 on 20 October, now December: down 5.84, or 5.63%. December itself fell 0.72 that day; the other 5.12 was the gap between the two months at the 19 October close. .R5 was already on December, so it fell only the 0.72.
A return series on raw .C1 records the whole 5.63% as a one-day loss, inflating historical volatility and skewing a backtest.
One front month, five definitions
Ask for the WTI front month on 27 October and TickerLayer has five answers. Each roll series prices (1 - weight) * front + weight * next; only the schedule of the weight differs:
- .C1 · raw chain100.25, the December month. On 12 October: 93.74, still November.
- .R5 · five steps100.25 at weight 0; next window 6 to 12 November. On 12 October: 93.04 at 0.8, four steps in.
- .R5C · continuous100.25. Same window, the weight rising through each session; daily closes match
.R5. - .CYCLE · every weekday99.82, weight 5/23 toward JAN27, one 1/23 step a weekday since 20 October.
- .NOTICE · one switch100.25 at weight 0. It switches on the front’s first notice date; WTI’s front rotated out first, so it matched
.C1on all 22 bars.
Four agree on 27 October because a roll series at weight 0 is the front month; .CYCLE steps every weekday. Inside a window they part: on 12 October .C1 and .R5 were 0.70 apart.
Continuous futures contracts: raw, back-adjusted, ratio-adjusted, weighted
A continuous futures contract stitches successive months into one series for charts and backtests. The methods differ in what they do with the gap at a roll. At the WTI roll after the 19 October close, December stood 5.12, or 4.94%, below November:
| Feature | Raw chain | Back-adjusted | Ratio-adjusted | Weighted roll |
|---|---|---|---|---|
| Built from | Each month’s own prices | Past prices shifted by each roll gap | Past prices scaled by each roll ratio | Front and next, blended by a weight |
| Gap at a roll | In one bar | Removed | Removed | Spread over the window |
| Past values change | ||||
| Keeps % returns | ||||
| Can go negative | If prices do | If prices do | ||
| WTI on 1 Oct | 92.87 | 87.75 | 88.28 | 92.87 |
| 1 to 27 Oct | +7.95% | +14.25% | +13.56% | +7.95% |
| On TickerLayer | .C1 .C2 .C3 | .R5 .R5C .CYCLE .NOTICE |
Back-adjusting keeps the dollar move, +12.50 from 1 to 27 October, but not the percentage: it shows +14.25%. Chaining November’s return to the 19 October close with December’s after it gives +13.56%, the figure the ratio-adjusted series keeps. Build adjusted series yourself from the dated months’ bars.
Whether a roll gap points up or down depends on the curve, the subject of contango and backwardation. Perpetual futures never expire, so they carry no month code and no roll.
Decode futures symbols in Python
futures_month_codes.py decodes codes from the right, maps them to TickerLayer’s .MMMYY form, then lists gold’s months with their letter codes from GET /futures/contracts. It needs Python 3.9 or newer, the standard library and a TICKERLAYER_API_KEY environment variable.
"""Decode futures month codes, then list gold's contract months. Python 3.9+, standard library only."""
import json
import os
import re
import sys
import urllib.error
import urllib.request
from datetime import date
API = "https://api.tickerlayer.com"
KEY = os.environ.get("TICKERLAYER_API_KEY") or sys.exit("Set TICKERLAYER_API_KEY first.")
LETTERS = "FGHJKMNQUVXZ" # January to December
MONTHS = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]
# Read from the right: 1, 2 or 4 year digits, then one month letter; whatever is left is the root.
CODED = re.compile(r"^(?P<root>[A-Z0-9]*?)(?P<letter>[FGHJKMNQUVXZ])(?P<year>\d{4}|\d{2}|\d)$")
DOTTED = re.compile(r"^(?P<root>[A-Z0-9]+)\.(?P<mon>[A-Z]{3})(?P<yy>\d{2})$")
def decode(code, today=None):
"""'XYZ26' -> ('XY', 2026, 12). Four digits are read as written and two digits as 20YY.
One digit is the first year ending in it whose month has not passed yet."""
s = code.strip().upper().lstrip("/").replace(" ", "")
m = DOTTED.match(s)
if m and m["mon"] in MONTHS:
return m["root"], 2000 + int(m["yy"]), MONTHS.index(m["mon"]) + 1
m = CODED.match(s)
if not m:
raise ValueError(f"not a contract code: {code!r}")
month, digits = LETTERS.index(m["letter"]) + 1, m["year"]
if len(digits) == 4:
year = int(digits)
elif len(digits) == 2:
year = 2000 + int(digits)
else:
today = today or date.today()
year = today.year - today.year % 10 + int(digits)
if (year, month) < (today.year, today.month):
year += 10
return m["root"], year, month
def tickerlayer_form(root, year, month):
"""('XY', 2026, 12) -> 'XY.DEC26'"""
return f"{root}.{MONTHS[month - 1]}{year % 100:02d}"
def contracts(base):
"""Every listed month of one product. Any valid key can call it."""
req = urllib.request.Request(f"{API}/futures/contracts?base={base}", headers={"x-api-key": KEY})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return json.load(resp)["contracts"]
except urllib.error.HTTPError as err:
sys.exit(f"HTTP {err.code}: {err.read().decode()}")
print(f"code root month TickerLayer form (decoded on {date.today()})")
for code in ["XYZ26", "XYZ6", "XYQ6", "/XYH27", "XY U2027", "WTIUSD.DEC26"]:
root, year, month = decode(code)
print(f"{code:<14}{root:<8}{year}-{month:02d} {tickerlayer_form(root, year, month)}")
rows = contracts("XAUUSD")
print("\nsymbol code last trade cycle chain")
for c in rows:
year, month = map(int, c["contract_month"].split("-"))
code = f"{LETTERS[month - 1]}{year % 100:02d}"
assert tickerlayer_form("XAUUSD", *decode("XAUUSD" + code)[1:]) == c["symbol"] # round trip
chain = f"C{c['rank']}" if c["rank"] else "-"
print(f"{c['symbol']:<14}{code:<6}{c['last_trade_date']} {'yes' if c['in_chain'] else 'no':<5} {chain}")
print(f"{len(rows)} months listed, {sum(c['in_chain'] for c in rows)} of them in the chain cycle")code root month TickerLayer form (decoded on 2026-10-28)
XYZ26 XY 2026-12 XY.DEC26
XYZ6 XY 2026-12 XY.DEC26
XYQ6 XY 2036-08 XY.AUG36
/XYH27 XY 2027-03 XY.MAR27
XY U2027 XY 2027-09 XY.SEP27
WTIUSD.DEC26 WTIUSD 2026-12 WTIUSD.DEC26
symbol code last trade cycle chain
XAUUSD.OCT26 V26 2026-10-28 yes -
XAUUSD.NOV26 X26 2026-11-25 no -
XAUUSD.DEC26 Z26 2026-12-29 yes C1
XAUUSD.JAN27 F27 2027-01-27 no -
XAUUSD.FEB27 G27 2027-02-24 yes C2
XAUUSD.MAR27 H27 2027-03-29 no -
XAUUSD.APR27 J27 2027-04-28 yes C3
XAUUSD.MAY27 K27 2027-05-26 no -
XAUUSD.JUN27 M27 2027-06-28 yes -
XAUUSD.JUL27 N27 2027-07-28 no -
XAUUSD.AUG27 Q27 2027-08-27 yes -
XAUUSD.SEP27 U27 2027-09-28 no -
XAUUSD.OCT27 V27 2027-10-27 yes -
XAUUSD.NOV27 X27 2027-11-26 no -
XAUUSD.DEC27 Z27 2027-12-29 yes -
XAUUSD.JAN28 F28 2028-01-27 no -
XAUUSD.FEB28 G28 2028-02-25 yes -
XAUUSD.APR28 J28 2028-04-26 yes -
XAUUSD.MAY28 K28 2028-05-26 no -
XAUUSD.JUN28 M28 2028-06-28 yes -
XAUUSD.DEC28 Z28 2028-12-27 yes -
21 months listed, 12 of them in the chain cycleXYQ6 shows the one-digit rule at work: on 28 October 2026, August 2026 had passed, so it reads as 2036. XAUUSD.OCT26 is still listed on its last trade day but has left the chain. One item, field by field:
GET /futures/contracts?base=XAUUSD, one of 21 items
{
"symbol": "XAUUSD.DEC26",
"base": "XAUUSD",
"contract_month": "2026-12",1
"rank": 1,2
"in_chain": true,3
"last_trade_date": "2026-12-29",4
"roll_date": "2026-12-29",
"first_notice_date": "2026-11-30",5
"roll_window_start": "2026-11-05T23:00:00.000Z",6
"roll_window_end": "2026-11-12T22:00:00.000Z",
"days_to_expiry": 62,7
"market_status": "open"
}
contract_monthThe delivery month that the letter Z and the suffix DEC26 both name.rankChain position: 1 is.C1.nullbeyond C3 or out of the chain, as for OCT26 on its last trade day.in_chaintruefor months of the cycle; serial months such as NOV26 sayfalse.last_trade_dateEqual toroll_date:.C1moves to FEB27 at 18:00 New York the evening before.first_notice_dateAs the roll calendar defines it;.NOTICEmoves to FEB27 on this date.roll_window_startThe open of the first.R5window session, 18:00 New York on 5 November; the window ends at the 12 November close.days_to_expiryCalendar days from the 28 October trade date to the last trade.
Contract months, roll dates and bars from TickerLayer
TickerLayer’s Futures CFDs price every symbol form above, with daily and intraday bars. They are calculated reference prices, not futures contracts, not executable and not official settlement prices, and TickerLayer lists, brokers and clears no contract (data notice). Products, contracts and the roll calendar answer any valid key; quotes, curves and bars need the Futures CFDs plan.
Product pages show the curve and roll dates, such as WTI crude oil futures. The oil price API and gold price API guides put spot prices next to futures, and WTI vs Brent compares the two crude benchmarks.
Questions
What are the futures month codes?
Twelve letters, one per delivery month: F January, G February, H March, J April, K May, M June, N July, Q August, U September, V October, X November and Z December. A symbol joins a root, a letter and a year, so XYZ26 is December 2026.
What does Z26 mean in futures?
The December 2026 contract: Z is December and 26 the year. Screens that print one digit show it as Z6, which in older data meant December 2016, so read a one-digit year against the date of the data.
Which futures month codes are quarterly?
H, M, U and Z: March, June, September and December. Among TickerLayer’s futures products, the Treasury notes and bond, the three-month rate, palladium and the three US equity index products use only these months.
What is a futures contract expiration?
The last trade date, after which the month settles in cash or by delivery. It need not fall in the contract month: in TickerLayer’s roll calendar WTI’s December 2026 contract stops on 20 November, while gold’s runs to 29 December.
What is the rollover date for futures contracts?
The day the front month hands over to the next. TickerLayer’s WTIUSD.C1 moves to January at 18:00 New York on 19 November, the evening before WTI’s December contract stops trading; WTIUSD.R5 moves in five steps from 6 to 12 November.
What is a continuous futures contract?
One price series stitched from successive contract months for charts and backtests. It can be raw and jump at each roll, back-adjusted, ratio-adjusted or weighted; TickerLayer serves raw chains such as WTIUSD.C1 and weighted rolls such as WTIUSD.R5.