{"slug":"stock-market-hours","qid":"options_hours","label":"Single-name vs. ETF options at the 4:00 p.m. bell: AAPL and SPY options trades around the close (same session)","post_title":"Stock Market Hours: Open 9:30, Close 4:00 ET","post_url":"/blog/stock-market-hours#q-options_hours","columns":["contract","session_date","trades_345_to_400","trades_400_to_415","last_trade_et","last_trade_minute_of_day"],"rows":[{"contract":"AAPL options (single name)","session_date":"2026-08-19","trades_345_to_400":7402,"trades_400_to_415":0,"last_trade_et":"15:59","last_trade_minute_of_day":959},{"contract":"SPY options (ETF)","session_date":"2026-08-19","trades_345_to_400":53682,"trades_400_to_415":16238,"last_trade_et":"16:15","last_trade_minute_of_day":975}],"shape":"series","sql":"WITH\n(\n    SELECT max(d)\n    FROM\n    (\n        SELECT\n            toDate(toTimeZone(window_start, 'America/New_York')) AS d,\n            countIf((toHour(toTimeZone(window_start, 'America/New_York')) * 60\n                     + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570\n                AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n                     + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960) AS rth_bars\n        FROM global_markets.delayed_stocks_minute_aggs\n        WHERE ticker = 'SPY'\n          AND window_start >= today() - 21\n          AND window_start < today() - 2\n        GROUP BY d\n        HAVING rth_bars = 390\n    )\n) AS session_day\nSELECT\n    if(startsWith(ticker, 'O:SPY'), 'SPY options (ETF)', 'AAPL options (single name)') AS contract,\n    toString(session_day)                                                              AS session_date,\n    countIf(sip_timestamp >= toDateTime(concat(toString(session_day), ' 15:45:00'), 'America/New_York')\n        AND sip_timestamp <  toDateTime(concat(toString(session_day), ' 16:00:00'), 'America/New_York')) AS trades_345_to_400,\n    countIf(sip_timestamp >= toDateTime(concat(toString(session_day), ' 16:00:00'), 'America/New_York')\n        AND sip_timestamp <  toDateTime(concat(toString(session_day), ' 16:15:00'), 'America/New_York')) AS trades_400_to_415,\n    formatDateTime(toTimeZone(max(sip_timestamp), 'America/New_York'), '%H:%i') AS last_trade_et,\n    toHour(toTimeZone(max(sip_timestamp), 'America/New_York')) * 60\n    + toMinute(toTimeZone(max(sip_timestamp), 'America/New_York'))              AS last_trade_minute_of_day\nFROM global_markets.options_trades\nWHERE (startsWith(ticker, 'O:SPY') OR startsWith(ticker, 'O:AAPL'))\n  AND match(ticker, '^O:(SPY|AAPL)[0-9]{6}[CP][0-9]{8}$')\n  AND sip_timestamp >= toDateTime(concat(toString(session_day), ' 15:45:00'), 'America/New_York')\n  AND sip_timestamp <  toDateTime(concat(toString(session_day), ' 23:00:00'), 'America/New_York')\nGROUP BY contract\nORDER BY contract","computed_at":"2026-08-22T04:22:18.051813+00:00","elapsed":0.176939652}