{"slug":"when-do-vix-futures-expire","qid":"tuesday_settlements","label":"tuesday_settlements","post_title":"when-do-vix-futures-expire","post_url":"/blog/when-do-vix-futures-expire#q-tuesday_settlements","columns":["settlement_date","settlement_weekday","vix_contract","closed_day_in_the_way"],"rows":[{"settlement_date":"2019-03-19","settlement_weekday":"Tuesday","vix_contract":"VX Mar 2019","closed_day_in_the_way":"Fri Apr 19, 2019"},{"settlement_date":"2022-03-15","settlement_weekday":"Tuesday","vix_contract":"VX Mar 2022","closed_day_in_the_way":"Fri Apr 15, 2022"},{"settlement_date":"2024-06-18","settlement_weekday":"Tuesday","vix_contract":"VX Jun 2024","closed_day_in_the_way":"Wed Jun 19, 2024"},{"settlement_date":"2025-03-18","settlement_weekday":"Tuesday","vix_contract":"VX Mar 2025","closed_day_in_the_way":"Fri Apr 18, 2025"},{"settlement_date":"2026-05-19","settlement_weekday":"Tuesday","vix_contract":"VX May 2026","closed_day_in_the_way":"Fri Jun 19, 2026"}],"shape":"table","sql":"WITH\n    traded AS\n    (\n        SELECT groupArray(session_day) AS session_days\n        FROM\n        (\n            SELECT date AS session_day\n            FROM global_markets.stocks_daily_aggs\n            WHERE ticker = 'SPY'\n              AND date >= toDate('2014-11-01')\n            GROUP BY session_day\n        )\n    ),\n    closures_ahead AS\n    (\n        SELECT groupArray(date) AS closed_days\n        FROM global_markets.stocks_market_holidays\n        WHERE status = 'closed'\n    )\nSELECT\n    toString(settlement)                                    AS settlement_date,\n    formatDateTime(settlement, '%W')                        AS settlement_weekday,\n    concat('VX ', formatDateTime(contract_month, '%b %Y'))  AS vix_contract,\n    formatDateTime(if(friday_closed, ref_friday, wednesday_target), '%a %b %e, %Y') AS closed_day_in_the_way\nFROM\n(\n    SELECT\n        a.contract_month AS contract_month,\n        a.ref_friday     AS ref_friday,\n        ((a.ref_friday <= toDate(arrayMax(t.session_days))) AND (NOT has(t.session_days, a.ref_friday)))\n            OR has(h.closed_days, a.ref_friday)             AS friday_closed,\n        if(friday_closed, addDays(a.ref_friday, -1), a.ref_friday) AS spx_anchor,\n        addDays(spx_anchor, -30)                            AS wednesday_target,\n        ((wednesday_target <= toDate(arrayMax(t.session_days))) AND (NOT has(t.session_days, wednesday_target)))\n            OR has(h.closed_days, wednesday_target)         AS target_closed,\n        if(target_closed, addDays(wednesday_target, -1), wednesday_target) AS settlement\n    FROM\n    (\n        SELECT\n            contract_month,\n            addMonths(contract_month, 1)                                             AS ref_month,\n            addDays(ref_month, ((5 - toInt32(toDayOfWeek(ref_month)) + 7) % 7) + 14) AS ref_friday\n        FROM\n        (\n            SELECT addMonths(toDate('2015-01-01'), toInt32(arrayJoin(range(144)))) AS contract_month\n        )\n    ) AS a\n    CROSS JOIN traded AS t\n    CROSS JOIN closures_ahead AS h\n)\nWHERE toDayOfWeek(settlement) <> 3\nORDER BY settlement ASC","computed_at":"2026-10-01T15:14:22.280125+00:00","elapsed":0.216448758}