{"slug":"stock-market-hours","qid":"half_day_split","label":"The most recent early-close session on the SPY tape, split by session window","post_title":"Stock Market Hours: Open 9:30, Close 4:00 ET","post_url":"/blog/stock-market-hours#q-half_day_split","columns":["session_date","weekday","morning_session_bars","last_bar_et","last_bar_minute_of_day","total_shares_m","premarket_pct","regular_pct","post_close_30min_pct","evening_pct","first_30min_pct","last_30min_pct","close_minus_open_pct"],"rows":[{"session_date":"2025-12-24","weekday":"Wednesday","morning_session_bars":210,"last_bar_et":"16:59","last_bar_minute_of_day":1019,"total_shares_m":35.6,"premarket_pct":1.3,"regular_pct":95.5,"post_close_30min_pct":3.1,"evening_pct":0.1,"first_30min_pct":12.2,"last_30min_pct":23.8,"close_minus_open_pct":11.6}],"shape":"scalar","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() - 400\n          AND window_start < today() - 2\n        GROUP BY d\n        HAVING rth_bars >= 150 AND rth_bars <= 240\n    )\n) AS half_day\nSELECT\n    toString(half_day)                          AS session_date,\n    formatDateTime(half_day, '%W')              AS weekday,\n    countIf(et_min >= 570 AND et_min < 780)     AS morning_session_bars,\n    formatDateTime(max(et_ts), '%H:%i')         AS last_bar_et,\n    max(et_min)                                 AS last_bar_minute_of_day,\n    round(sum(volume) / 1e6, 1)                 AS total_shares_m,\n    round(100.0 * sumIf(volume, et_min < 570) / sum(volume), 1)                    AS premarket_pct,\n    round(100.0 * sumIf(volume, et_min >= 570 AND et_min < 780) / sum(volume), 1)  AS regular_pct,\n    round(100.0 * sumIf(volume, et_min >= 780 AND et_min < 810) / sum(volume), 1)  AS post_close_30min_pct,\n    round(100.0 * sumIf(volume, et_min >= 810) / sum(volume), 1)                   AS evening_pct,\n    round(100.0 * sumIf(volume, et_min >= 570 AND et_min < 600) / sum(volume), 1)  AS first_30min_pct,\n    round(100.0 * sumIf(volume, et_min >= 750 AND et_min < 780) / sum(volume), 1)  AS last_30min_pct,\n    round(100.0 * sumIf(volume, et_min >= 750 AND et_min < 780) / sum(volume)\n        - 100.0 * sumIf(volume, et_min >= 570 AND et_min < 600) / sum(volume), 1)  AS close_minus_open_pct\nFROM\n(\n    SELECT\n        volume,\n        toTimeZone(window_start, 'America/New_York') AS et_ts,\n        toHour(toTimeZone(window_start, 'America/New_York')) * 60\n        + toMinute(toTimeZone(window_start, 'America/New_York')) AS et_min\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= today() - 400\n      AND toDate(toTimeZone(window_start, 'America/New_York')) = half_day\n)","computed_at":"2026-08-22T04:22:18.719812+00:00","elapsed":0.457968841}