calendar_2026
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-10-01, from when-do-vix-futures-expire.
| settlement_date | settlement_label | vix_contract | spx_anchor_friday | days_from_equity_expiry |
|---|---|---|---|---|
| 2026-01-21 | Wed Jan 21 | VX Jan 2026 | Feb 20 | 5 |
| 2026-02-18 | Wed Feb 18 | VX Feb 2026 | Mar 20 | -2 |
| 2026-03-18 | Wed Mar 18 | VX Mar 2026 | Apr 17 | -2 |
| 2026-04-15 | Wed Apr 15 | VX Apr 2026 | May 15 | -2 |
| 2026-05-19 | Tue May 19 | VX May 2026 | Jun 18 | 4 |
| 2026-06-17 | Wed Jun 17 | VX Jun 2026 | Jul 17 | -2 |
| 2026-07-22 | Wed Jul 22 | VX Jul 2026 | Aug 21 | 5 |
| 2026-08-19 | Wed Aug 19 | VX Aug 2026 | Sep 18 | -2 |
| 2026-09-16 | Wed Sep 16 | VX Sep 2026 | Oct 16 | -2 |
| 2026-10-21 | Wed Oct 21 | VX Oct 2026 | Nov 20 | 5 |
| 2026-11-18 | Wed Nov 18 | VX Nov 2026 | Dec 18 | -2 |
| 2026-12-16 | Wed Dec 16 | VX Dec 2026 | Jan 15 | -2 |
- Rows × columns
- 12 × 5
- Period covered
- to
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
settlement_date |
date | 2026-01-21 to 2026-12-16 | |
settlement_label |
text | 12 distinct values (Tue May 19, Wed Apr 15, Wed Aug 19…) | |
vix_contract |
text | 12 distinct values (VX Apr 2026, VX Aug 2026, VX Dec 2026…) | |
spx_anchor_friday |
text | 12 distinct values (Apr 17, Aug 21, Dec 18…) | |
days_from_equity_expiry |
number | -2 to 5 |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
Run it yourself
This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.
WITH
traded AS
(
SELECT groupArray(session_day) AS session_days
FROM
(
SELECT date AS session_day
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= toDate('2014-11-01')
GROUP BY session_day
)
),
closures_ahead AS
(
SELECT groupArray(date) AS closed_days
FROM global_markets.stocks_market_holidays
WHERE status = 'closed'
)
SELECT
toString(settlement) AS settlement_date,
formatDateTime(settlement, '%a %b %e') AS settlement_label,
concat('VX ', formatDateTime(contract_month, '%b %Y')) AS vix_contract,
formatDateTime(spx_anchor, '%b %e') AS spx_anchor_friday,
toInt32(dateDiff('day', equity_monthly, settlement)) AS days_from_equity_expiry
FROM
(
SELECT
a.contract_month AS contract_month,
a.equity_monthly AS equity_monthly,
if(((a.ref_friday <= toDate(arrayMax(t.session_days))) AND (NOT has(t.session_days, a.ref_friday)))
OR has(h.closed_days, a.ref_friday),
addDays(a.ref_friday, -1),
a.ref_friday) AS spx_anchor,
addDays(spx_anchor, -30) AS wednesday_target,
if(((wednesday_target <= toDate(arrayMax(t.session_days))) AND (NOT has(t.session_days, wednesday_target)))
OR has(h.closed_days, wednesday_target),
addDays(wednesday_target, -1),
wednesday_target) AS settlement
FROM
(
SELECT
contract_month,
addMonths(contract_month, 1) AS ref_month,
addDays(ref_month, ((5 - toInt32(toDayOfWeek(ref_month)) + 7) % 7) + 14) AS ref_friday,
addDays(contract_month, ((5 - toInt32(toDayOfWeek(contract_month)) + 7) % 7) + 14) AS equity_monthly
FROM
(
SELECT addMonths(toDate('2026-01-01'), toInt32(arrayJoin(range(12)))) AS contract_month
)
) AS a
CROSS JOIN traded AS t
CROSS JOIN closures_ahead AS h
)
ORDER BY settlement ASC
Work with this data in your AI assistant
Opens ready to query, with this page's data. Free, no account.