Option Expiration Cycles Explained
Option expiration cycles decide which months appear on a stock's option chain. See how the three cycle groups work and why LEAPS always land in January.
Option expiration cycles are the listing rule that decides which expiration months appear on a stock's option chain. Every optionable US stock is assigned to one of three cycles when its options are first listed, and that assignment, together with a floor of four expiration months at all times, produces the row of dates you see in a broker's chain. The question here is which months get listed. For the date an option actually expires, see when options expire, and for this year's dated list, the 2026 options expiration calendar.
What is an option expiration cycle?
When an exchange first lists options on a stock, it puts that stock in one of three expiration cycles. Each cycle is four months, spaced a quarter apart:
- The January cycle: January, April, July, October
- The February cycle: February, May, August, November
- The March cycle: March, June, September, December
A stock's cycle is set once and stays fixed for the life of the listing. It is a property of the listing, not of the company. The cycle governs the longer dated monthly expirations, the third Friday contracts that sit past the front of the chain. It says nothing about the next few weeks, which a separate rule covers.
Why does every chain show at least four expiration months?
Listing standards set a floor. An optionable stock carries at least four expiration months at any moment, picked in a fixed order. The first two are the near-term months: the current month and the month after it. The next two are the first two months of the stock's own cycle that the near-term pair has not already covered.
Work it through on a February cycle stock in June. The near-term months are June and July. The next unclaimed cycle months are August and November, so the chain reads June, July, August, November. Once June expiration passes, the near-term pair becomes July and August, and the chain reaches out to November and February. The near-term months roll every month. The cycle months roll one notch every three months.
Which expiration months are listed on a real chain?
Four is a floor, and a heavily traded name sits well above it. The panel below lists every expiration on Apple's chain on the most recent session on file, with the number of contracts carried on each date.
| expiry_date | expiration_label | days_out | contract_count |
|---|---|---|---|
| 2026-08-21 | Aug 21, 2026 | 2 | 105 |
| 2026-08-24 | Aug 24, 2026 | 5 | 58 |
| 2026-08-26 | Aug 26, 2026 | 7 | 48 |
| 2026-08-28 | Aug 28, 2026 | 9 | 79 |
| 2026-08-31 | Aug 31, 2026 | 12 | 50 |
| 2026-09-02 | Sep 2, 2026 | 14 | 49 |
| 2026-09-04 | Sep 4, 2026 | 16 | 76 |
| 2026-09-11 | Sep 11, 2026 | 23 | 54 |
| 2026-09-18 | Sep 18, 2026 | 30 | 87 |
| 2026-09-25 | Sep 25, 2026 | 37 | 55 |
| 2026-10-02 | Oct 2, 2026 | 44 | 53 |
| 2026-10-16 | Oct 16, 2026 | 58 | 87 |
| 2026-11-20 | Nov 20, 2026 | 93 | 88 |
| 2026-12-18 | Dec 18, 2026 | 121 | 83 |
| 2027-01-15 | Jan 15, 2027 | 149 | 98 |
| 2027-02-19 | Feb 19, 2027 | 184 | 45 |
| 2027-03-19 | Mar 19, 2027 | 212 | 56 |
| 2027-06-17 | Jun 17, 2027 | 302 | 63 |
| 2027-09-17 | Sep 17, 2027 | 394 | 71 |
| 2027-12-17 | Dec 17, 2027 | 485 | 74 |
The exact SQL behind every number
WITH
(
SELECT max(date)
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date >= today() - 10
) AS chain_date
SELECT
toString(expiration_date) AS expiry_date,
formatDateTime(expiration_date, '%b %e, %Y') AS expiration_label,
toUInt32(max(days_to_expiry)) AS days_out,
countDistinct(ticker) AS contract_count
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date = chain_date
AND expiration_date >= chain_date
GROUP BY expiration_date
ORDER BY expiration_dateThat is 23 separate expiration dates on a single underlying. The nearest, Aug 21, 2026, is 2 days ahead and carries 105 contracts. The farthest, Dec 15, 2028, sits 849 days out with 70 contracts on it. Read the shape between the two ends: dates arrive weekly at the front, thin to roughly one a month through the middle of the year, then stretch to the far dated months at the right edge.
Do weeklies and dailies follow the cycle?
No. The cycle covers monthly expirations only, the third Friday contracts. The rest of a modern chain comes from separate listing programs that sit outside the cycle:
- Weekly options, listed a few weeks ahead and expiring on Fridays that are not the third Friday.
- End of month and quarter end series, pinned to the last trading day of a month or quarter rather than to a Friday.
- Daily options, an expiration for every trading day of the week, carried on a short and specific list of very active underlyings. See which stocks have daily options for that list.
None of those add a cycle month. A stock can show ten weekly dates in a row at the front of its chain and still be a plain four month cycle name behind them. Two chains can look nothing alike while running on identical rules.
Line up several underlyings on the same session and the difference reads as a count of dates.
| symbol | listed_expirations | expirations_within_45d | months_beyond_90d |
|---|---|---|---|
| SPY | 33 | 16 | 10 |
| AAPL | 23 | 11 | 11 |
| MSFT | 22 | 11 | 10 |
| KO | 18 | 7 | 10 |
| HRL | 11 | 7 | 4 |
| CLX | 6 | 2 | 3 |
The exact SQL behind every number
WITH
(
SELECT max(date)
FROM global_markets.options_greeks
WHERE date >= today() - 10
) AS chain_date
SELECT
underlying_symbol AS symbol,
countDistinct(expiration_date) AS listed_expirations,
countDistinctIf(expiration_date, days_to_expiry <= 45) AS expirations_within_45d,
countDistinctIf(toStartOfMonth(expiration_date), days_to_expiry > 90) AS months_beyond_90d
FROM global_markets.options_greeks
WHERE date = chain_date
AND expiration_date >= chain_date
AND underlying_symbol IN ('SPY', 'AAPL', 'MSFT', 'KO', 'CLX', 'HRL')
GROUP BY underlying_symbol
ORDER BY listed_expirations DESCAcross the 6 names in that panel, SPY carries the widest lineup at 33 listed expirations, with 16 of them inside 45 days. That front end density comes from a daily and weekly listing program rather than from the cycle. CLX sits at the other end of the panel with 6 listed dates in total. Past 90 days the picture changes: 10 distinct expiration months on the widest name against 3 on the narrowest. The front of a chain is where lineups differ. The back is where the cycle shows through.
How can I tell which cycle a stock is on?
No lookup table needed. Open the chain, skip the current month and the one after it, and find the first monthly expiration past that pair. That month, and the month three after it, are the stock's cycle months.
The same pattern is visible across the whole listed market at once. The next panel counts, for every third Friday expiration inside the next fourteen months, how many underlyings list it.
| expiry_month_start | month_label | underlyings_listing |
|---|---|---|
| 2026-08-01 | Aug 2026 | 3735 |
| 2026-09-01 | Sep 2026 | 3689 |
| 2026-10-01 | Oct 2026 | 1564 |
| 2026-11-01 | Nov 2026 | 1392 |
| 2026-12-01 | Dec 2026 | 1960 |
| 2027-01-01 | Jan 2027 | 2245 |
| 2027-02-01 | Feb 2027 | 913 |
| 2027-03-01 | Mar 2027 | 1462 |
| 2027-04-01 | Apr 2027 | 50 |
| 2027-05-01 | May 2027 | 72 |
| 2027-07-01 | Jul 2027 | 26 |
| 2027-08-01 | Aug 2027 | 42 |
| 2027-09-01 | Sep 2027 | 318 |
| 2027-10-01 | Oct 2027 | 11 |
The exact SQL behind every number
WITH
(
SELECT max(date)
FROM global_markets.options_greeks
WHERE date >= today() - 10
) AS chain_date
SELECT
toString(toStartOfMonth(expiration_date)) AS expiry_month_start,
formatDateTime(toStartOfMonth(expiration_date), '%b %Y') AS month_label,
countDistinct(underlying_symbol) AS underlyings_listing
FROM global_markets.options_greeks
WHERE date = chain_date
AND expiration_date >= chain_date
AND days_to_expiry <= 430
AND toDayOfWeek(expiration_date) = 5
AND toDayOfMonth(expiration_date) BETWEEN 15 AND 21
AND underlying_symbol NOT IN ('SPCX')
GROUP BY toStartOfMonth(expiration_date)
ORDER BY toStartOfMonth(expiration_date)The nearest third Friday, Aug 2026, is listed by 3735 underlyings. Every name with options carries its front months, and that first point sits close to the entire listed universe. The count then falls away, and it falls unevenly. Past the near-term pair a stock reappears only on the months belonging to its own cycle, so each further month is carried by a slice of the market rather than all of it, with the quarter end months and the January series tending to stand above their neighbours. The far edge of the panel is thinner still: Oct 2027, the last month inside the fourteen month window and more than a year out, is carried by just 11 underlyings. Past twelve months the ladder empties out on every month except the January series, which the LEAPS panel below picks up.
The four March cycle months are also the four triple witching dates of the year, when index and equity contracts expire together on one third Friday.
Why are LEAPS listed in January?
LEAPS, long dated options with more than a year left to run, come from their own listing schedule. On single stocks the long dated series is a January one, whatever cycle the stock sits on. A March cycle stock still gets January LEAPS.
The market wide count makes the anchor plain. This panel takes every third Friday expiration beyond 300 days out and counts the underlyings listing it.
| leaps_series | underlyings_listing |
|---|---|
| Jan 2028 | 1267 |
| Sep 2027 | 318 |
| Dec 2027 | 304 |
| Dec 2028 | 241 |
| Jun 2028 | 113 |
| Aug 2027 | 42 |
| Nov 2027 | 34 |
| Jul 2027 | 26 |
| Mar 2028 | 15 |
| Sep 2028 | 13 |
| Oct 2027 | 11 |
| Feb 2028 | 2 |
| Apr 2028 | 2 |
| Jul 2028 | 1 |
The exact SQL behind every number
WITH
(
SELECT max(date)
FROM global_markets.options_greeks
WHERE date >= today() - 10
) AS chain_date
SELECT
formatDateTime(toStartOfMonth(expiration_date), '%b %Y') AS leaps_series,
countDistinct(underlying_symbol) AS underlyings_listing
FROM global_markets.options_greeks
WHERE date = chain_date
AND days_to_expiry > 300
AND toDayOfWeek(expiration_date) = 5
AND toDayOfMonth(expiration_date) BETWEEN 15 AND 21
AND underlying_symbol NOT IN ('SPCX')
GROUP BY toStartOfMonth(expiration_date)
ORDER BY underlyings_listing DESCJan 2028 is the largest month in that window, listed on 1267 underlyings. The thinnest month in the same window, Jul 2028, appears on 1.
Nothing happens to a January contract as it ages. A January series listed two years out is the same contract that, a year later, is simply the January monthly on the chain: same strike, same third Friday. Only the label falls away at the one year mark. What LEAPS are covers the contract side, and deep in the money LEAPS covers how the long dated end gets used.
Why the cycle decides whether a spread is quotable
Here is where the listing rule meets a real order. A calendar spread buys one expiration and sells another at the same strike. A diagonal does the same across two strikes. Both need two expirations to exist at once on the same underlying.
On a name carrying weeklies and a full cycle, that is easy. On a thinner name, the month you wanted may not be listed at all. A February cycle stock does not list a September expiration until September becomes one of the two near-term months, so a June to September calendar cannot be built on it in June at any price. The same constraint sits behind the concentration of long dated structures on January expirations: a poor man's covered call is a diagonal built on a long dated call, and January is the month every optionable name has in common.
Liquidity is a second filter on top of listing. A month can be listed and still quote wide with little open interest, which turns a two leg structure into a fill problem. The listing rule tells you what exists. The tape tells you what trades.
FAQ
What are the three option expiration cycles?
Three cycles, each named for its first month: the January cycle (January, April, July, October), the February cycle (February, May, August, November) and the March cycle (March, June, September, December). A stock is assigned to one when options on it are first listed, and the assignment does not change afterward.
How many expiration months does a stock have at once?
At least four. Two are the near-term months, the current month and the next one, and two come from the stock's assigned cycle. Actively traded names carry many more once weekly, end of month, quarter end and daily expirations are added on top of that floor.
Do all stocks have the same expiration months?
No. The two near-term months are the same for everyone. The months behind them depend on which of the three cycles the stock was assigned, so two similar companies can carry completely different back months.
Are weekly options part of the expiration cycle?
No. Weeklies are listed under a separate program a few weeks ahead and expire on Fridays other than the third Friday. They do not alter a stock's cycle and they do not count toward the four month floor.
Why are LEAPS listed in January?
Single stock LEAPS are anchored to a January expiration whatever the underlying's cycle, which gives every optionable name a common long dated month. As a January series ages inside one year, it becomes that stock's ordinary January monthly, with no change to the contract itself.
How these panels count
Each panel reads the most recent session on file in the daily contract level options data, and counts an expiration as listed when at least one contract on that expiration carries a record for that session. Monthly expirations are isolated by their date shape: a Friday falling between the 15th and the 21st of a month is the third Friday, which is the expiration the cycle rule governs. Weekly, end of month and daily expirations fail that test and drop out of the two market wide panels by construction, which is why those two counts are lower than the raw number of dates on any real chain. The market wide panels also exclude symbols that vendor feeds have assigned to more than one company over time, so a single ticker never merges two entities into one count.
Every panel here carries the SQL that produced it. Open one, swap the ticker, and the same question runs against any chain you like on the Strasmore terminal.