Strasmore Research
Learn am Matt ConnorBy Matt Connor · Updated 2026-07-25 · data as of July 25, 2026 · refreshed weekly

US Stock Market Dey Open Today?

Wetin you need know whether US stock market open today, plus full holiday calendar, early close days, wetin happen to orders when market closed.

Wetin you need know about whether US stock market dey open today

US stock market dey open from Monday go Friday, 9:30am to 4:00pm Eastern Time, except for public holidays wey dem don plan and small number of days wey dem go close early sharp-sharp by 1:00pm — so if you wan know whether market open today, na only three things you gats check: whether today be weekday, whether today dey inside holiday calendar, and where the clock stand inside the trading session. This page dey run all three checks against live exchange records every time you refresh am, and the "data as of" stamp wey dey up na the proof say the info fresh. For the full session-by-session breakdown, see stock market hours; for the complete calendar, see market holidays and early closes.

Stock market dey open now?

The panel for bottom dey calculate the answer for the time wey this page data last refresh. E dey check the weekday, dey look today date inside the exchange holiday feed, and e dey put the Eastern-time clock inside or outside the official windows: premarket from 4:00 am, the regular session from 9:30 am, after-hours from the close until 8:00 pm.

QueryMarket status wey dem compute for this page refresh: weekday check, holiday check, and the ET clock
The exact SQL behind every number
WITH
    toTimeZone(now(), 'America/New_York') AS now_et,
    toDate(now_et) AS today_et,
    toHour(now_et) * 60 + toMinute(now_et) AS min_now,
    (SELECT countDistinct(date) FROM global_markets.stocks_market_holidays
      WHERE date = toDate(toTimeZone(now(), 'America/New_York')) AND status = 'closed') AS today_full_holiday,
    (SELECT countDistinct(date) FROM global_markets.stocks_market_holidays
      WHERE date = toDate(toTimeZone(now(), 'America/New_York')) AND status = 'early-close') AS today_early,
    (SELECT any(name) FROM global_markets.stocks_market_holidays
      WHERE date = toDate(toTimeZone(now(), 'America/New_York'))) AS today_holiday_name,
    if(today_early = 1, 780, 960) AS close_min,
    if(today_early = 1, 1020, 1200) AS after_hours_end,
    (SELECT min(d) FROM (SELECT toDate(toTimeZone(now(), 'America/New_York')) + arrayJoin(range(1, 11)) AS d)
      WHERE toDayOfWeek(d) <= 5
        AND d NOT IN (SELECT date FROM global_markets.stocks_market_holidays WHERE status = 'closed')) AS next_sess_after_today,
    toDayOfWeek(today_et) <= 5 AND today_full_holiday = 0 AS today_is_session
SELECT
    toString(today_et) AS date_checked,
    formatDateTime(today_et, '%W') AS weekday,
    formatDateTime(now_et, '%H:%i') AS time_checked_et,
    multiIf(toDayOfWeek(today_et) >= 6, 'weekend',
            today_full_holiday = 1, concat('holiday — ', today_holiday_name),
            today_early = 1, concat('early close (1:00 pm) — ', today_holiday_name),
            'normal weekday') AS todays_calendar,
    multiIf(NOT today_is_session, 'CLOSED',
            min_now < 240, 'CLOSED (overnight)',
            min_now < 570, 'PREMARKET',
            min_now < close_min, 'OPEN',
            min_now < after_hours_end, 'AFTER-HOURS',
            'CLOSED (overnight)') AS market_status,
    toString(if(today_is_session AND min_now < close_min, today_et, next_sess_after_today)) AS next_regular_session,
    dateDiff('day', today_et, if(today_is_session AND min_now < close_min, today_et, next_sess_after_today)) AS days_to_next_session

As of 09:00 ET on Friday, 2026-07-24, the computed status read PREMARKET, with today's calendar entry "normal weekday". The next regular-session open wey dey the schedule — today itself any time the status read PREMARKET or OPEN — na 2026-07-24. That date don already skip weekends and every full-closure holiday, and e no go ever pass small days, even across one long holiday weekend. You dey read this later pass the stamp? The same three checks go take seconds by hand: weekday, the holiday table for below, the ET clock.

The next scheduled closure — and everything after it

The forward calendar dey come straight from the exchange feed. One nuance wey you suppose know: the table dey include today anytime today be holiday or early close — the query dey ask for every closure from today go forward, no be strictly after am — so on holiday morning the first row and the status panel for top go agree with each other.

QueryEvery NYSE closure and early close wey dey ahead for the calendar feed, plus countdown
The exact SQL behind every number
SELECT toString(date) AS closure_date,
       formatDateTime(date, '%a') AS falls_on,
       any(name) AS holiday,
       any(status) AS day_status,
       any(if(status = 'early-close', formatDateTime(toTimeZone(close, 'America/New_York'), '%H:%i'), '')) AS closes_at_et,
       dateDiff('day', today(), date) AS days_away
FROM global_markets.stocks_market_holidays
WHERE exchange = 'NYSE' AND date >= today()
GROUP BY date
ORDER BY date
LIMIT 16

The next scheduled interruption na Labor Day on 2026-09-07 (closed), 45 days from the refresh stamp. Any weekday wey no dey inside this table na normal 9:30–4:00 session. Early-close days go end regular trading at 1:00 pm Eastern and dem dey cluster around Thanksgiving, Christmas Eve, and the Fourth of July; the closing auction still dey run on those days — e just dey print three hours early.

How many days is the market closed each year?

"About nine or ten holidays a year" na the stock answer — this page fit count instead of estimate. The exchange feed only dey carry closures wey still dey ahead, so the ones wey don already pass, dem dey recover them from the tape: any weekday wey SPY print zero regular-session minute bars na full closure, and the one wey print roughly half session (about 210 bars instead of 390) na early close.

QueryThis calendar year closures: the ones wey don pass (counted from the tape) plus the ones wey still dey ahead (from the calendar)
The exact SQL behind every number
WITH day_bars AS (
    SELECT cal.day AS day, ifNull(t.bars, 0) AS bars
    FROM (SELECT makeDate(toYear(today()), 1, 1) + arrayJoin(range(370)) AS day) AS cal
    LEFT JOIN (
        SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d, count() AS bars
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY'
          AND window_start >= toDateTime(makeDate(toYear(today()), 1, 1), 'America/New_York')
          AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
        GROUP BY d
    ) AS t ON t.d = cal.day
    WHERE toDayOfWeek(cal.day) BETWEEN 1 AND 5
      AND cal.day <= today() - 4
),
past AS (
    SELECT countIf(bars = 0) AS past_full, countIf(bars BETWEEN 120 AND 330) AS past_early
    FROM day_bars
),
ahead AS (
    SELECT countDistinctIf(date, status = 'closed') AS ahead_full,
           countDistinctIf(date, status = 'early-close') AS ahead_early
    FROM global_markets.stocks_market_holidays
    WHERE date > today() - 4 AND toYear(date) = toYear(today())
)
SELECT category, already_passed, still_ahead, already_passed + still_ahead AS total, toString(toYear(today())) AS calendar_year
FROM (
    SELECT 'full closure' AS category, past.past_full AS already_passed, ahead.ahead_full AS still_ahead, 1 AS ord FROM past, ahead
    UNION ALL
    SELECT 'early close (1:00 pm)' AS category, past.past_early AS already_passed, ahead.ahead_early AS still_ahead, 2 AS ord FROM past, ahead
)
ORDER BY ord

2026 dey carry 10 full closures7 don already pass, 3 still dey ahead — plus 2 scheduled 1:00 pm early closes, 2 of them still dey come. (One closure wey inside the last few days fit sit briefly for neither count while the tape ingest lag dey clear; the split go self-correct on the next refresh.) Weekends dey do the rest of the closing: subtract the roughly 104 weekend days and these holidays from 365, and one year go leave about 250 trading sessions.

Tape receipt: di last session

Calendar dey tell you wetin suppose happen; tape na im dey show wetin actually happen. Di panel below dey pull di last session wey our SPY minute-bar tape actually see, im bar count, di number of SPY option trades wey print for di same day, and di last half-day any place for di trailing tape.

QueryThe most recent session for the tape — bar count, same-day SPY options prints, and the last half-day wey dem observe
The exact SQL behind every number
WITH rth AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d, count() AS bars
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= today() - 450
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
last_sess AS (
    SELECT max(d) AS last_d
    FROM rth
    WHERE bars >= 120 AND d < toDate(toTimeZone(now(), 'America/New_York'))
),
opt AS (
    SELECT round(count() / 1e3, 0) AS spy_option_prints_thousands
    FROM global_markets.options_trades
    WHERE ticker >= 'O:SPY2' AND ticker < 'O:SPY3'
      AND sip_timestamp >= toDateTime((SELECT last_d FROM last_sess), 'America/New_York')
      AND sip_timestamp < toDateTime((SELECT last_d FROM last_sess) + 1, 'America/New_York')
),
last_early AS (
    SELECT toString(max(d)) AS last_early_close_date,
           argMax(bars, d) AS its_bars
    FROM rth WHERE bars BETWEEN 120 AND 330
)
SELECT toString((SELECT last_d FROM last_sess)) AS most_recent_session,
       formatDateTime((SELECT last_d FROM last_sess), '%W') AS weekday,
       (SELECT bars FROM rth WHERE d = (SELECT last_d FROM last_sess)) AS regular_minute_bars,
       (SELECT spy_option_prints_thousands FROM opt) AS spy_option_prints_thousands,
       (SELECT last_early_close_date FROM last_early) AS last_early_close,
       (SELECT its_bars FROM last_early) AS early_close_bars

Di last session for our tape na 2026-07-22 (Wednesday), wey print 390 regular-session minute bars — full day dey run about 390, early close dey run about 210. Di same session carry roughly 1302 thousand separate SPY option trades: options market dey follow equity calendar, holidays and half-days inclusive, and expirations wey land for closed Friday go shift up one day. Di last early close for tape na 2025-12-24, at 211 minute bars — di shape wey 1:00 pm half-day dey show. One front-edge note: this warehouse dey ingest with one-to-two-day lag, so "last session" for here fit trail di actual latest session by one day or two.

When market close sharp-sharp without warning

The ones wey dey calendar, dem plan am. The ones wey no dey calendar? Dem no get any sign. Dem no common — like three, four times for ten years — but the tape still dey show proof: one weekday wey suppose print 390 bars, but nothing show.

QueryUnscheduled closures for the tape: zero regular-session bars for ordinary weekday
The exact SQL behind every number
WITH events AS (
    SELECT arrayJoin([
        (toDate('2012-10-29'), 'Hurricane Sandy — day 1'),
        (toDate('2012-10-30'), 'Hurricane Sandy — day 2'),
        (toDate('2012-10-31'), 'Reopening after Sandy'),
        (toDate('2018-12-05'), 'Mourning — George H. W. Bush'),
        (toDate('2025-01-09'), 'Mourning — Jimmy Carter')
    ]) AS e
),
tape AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d, count() AS bars
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND ((window_start >= '2012-10-29 00:00:00' AND window_start < '2012-11-01 12:00:00')
        OR (window_start >= '2018-12-05 00:00:00' AND window_start < '2018-12-06 12:00:00')
        OR (window_start >= '2025-01-09 00:00:00' AND window_start < '2025-01-10 12:00:00'))
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
)
SELECT toString(e.1) AS closure_date,
       formatDateTime(e.1, '%a') AS falls_on,
       e.2 AS name,
       toUInt32(ifNull(t.bars, 0)) AS spy_regular_session_bars
FROM events
LEFT JOIN tape AS t ON t.d = events.e.1
ORDER BY e.1

Hurricane Sandy make both major exchanges dark for 2012-10-29 and 2012-10-30 — na the first multi-day weather closure since 1888 — and the session wey reopen for 2012-10-31 print full 390 bars. National days of mourning close market for 2018-12-05 (President George H. W. Bush) and 2025-01-09 (President Jimmy Carter). The longest unscheduled closure for modern era — September 11 through 14, 2001, four sessions back-to-back — happen before our minute data, wey start from 2003. Each closure wey dey up there show for tape as 0 regular-session bars: nothing trade.

Wetin happen to order wey person place when market don close?

Nothing dey execute when market don close. Order wey person submit on Saturday, public holiday, or 2:00 am go just dey queue for broker side until next session, and market order wey don queue go transact at any price wey opening auction discover — days after you don click. The gap between one session close and next session first print na the exposure wey you accept, and e dey measurable:

QuerySPY across recent weekends and holiday weekends: Friday close vs. the reopening print
The exact SQL behind every number
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           round(argMin(toFloat64(open), window_start), 2) AS open_px,
           round(argMax(toFloat64(close), window_start), 2) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= today() - 75
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
paired AS (
    SELECT d,
           open_px,
           lagInFrame(d) OVER (ORDER BY d) AS prev_d,
           lagInFrame(close_px) OVER (ORDER BY d) AS prev_close
    FROM daily
)
SELECT concat(formatDateTime(prev_d, '%a '), toString(prev_d)) AS last_session_before,
       concat(formatDateTime(d, '%a '), toString(d)) AS reopening_session,
       dateDiff('day', prev_d, d) AS days_dark,
       toString(prev_close) AS close_before_break,
       toString(open_px) AS reopening_print,
       round((open_px - prev_close) / prev_close * 100, 2) AS gap_pct
FROM paired
WHERE prev_close > 0 AND dateDiff('day', prev_d, d) >= 3
ORDER BY d

The table cover the last 10 weekends and long weekends — the days_dark column mark the four-day holiday breaks. The most recent one run from Fri 2026-07-17 to Mon 2026-07-20 (3 calendar days dark): SPY regular-session close before the break na $743.2, the reopening print $747.060.52% gap wey queued market order for accept sight unseen. Limit order cap the price instead, at the cost of say e fit no fill; why stocks gap overnight cover the mechanics behind these moves.

Time zones, bond market, and the rest of the world

Three mismatches dey cause most of the remaining "is it open" wahala. Time zones: official hours na Eastern — 9:30 am ET na 6:30 am Pacific and 2:30 pm London for most of the year — and the market dates na ET dates, so one reader for Asia fit get im own "today" waka pass two US sessions. The bond market: Treasuries dey trade on SIFMA calendar, no be NYSE own — e dey observe every stock-market holiday plus two more, and im early closes na 2:00 pm recommendations wey dey come pass the stock market own 1:00 pm half-days. The full-day difference dey show for the data:

QueryWeekdays for the trailing year when stocks trade but no Treasury yield print
The exact SQL behind every number
WITH stock_days AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= today() - 370
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
    HAVING count() >= 100
)
SELECT toString(d) AS session_date,
       formatDateTime(d, '%W') AS weekday
FROM stock_days
WHERE d <= (SELECT max(date) FROM global_markets.treasury_yields)
  AND d NOT IN (SELECT date FROM global_markets.treasury_yields WHERE date >= today() - 370)
ORDER BY d

For the trailing year, exactly 2 weekdays dey where the stock market hold full session and no Treasury yield print — 2025-10-13 and 2025-11-11, one for October and one for November: Columbus Day and Veterans Day, the two federal holidays wey equities dey work straight through. The rest of the world: overseas exchanges dey keep their own calendars, and index futures dey trade nearly round the clock — na so one headline fit talk say "stocks dey fall" by 3:00 am ET when every US stock exchange don close. Extended hours around each US session dey run 4:00 am to 9:30 am and 4:00 pm to 8:00 pm ET, thinner and wider-spread; the mechanics dey inside the extended-hours guide.

Stock market dey open now?

From the time wey dis page last refresh data — 09:00 ET for 2026-07-24 — the computer say the status na PREMARKET. After dat time, the rule simple: weekdays 9:30 am to 4:00 pm ET, minus the dates for the holiday table wey dey for top.

Stock market go open tomorrow?

Tomorrow na normal session unless e be Saturday, Sunday, or one of the dates for the close table wey dey for top. The next regular session for the calendar as at when dis page refresh — today dey inside if market open — na 2026-07-24.

Stock market go open for Christmas Eve?

Any time December 24 fall for weekday, US stock exchanges dey do short session wey go close 1:00 pm ET; if e fall for weekend, no session at all. Christmas Day always be full close — this year exact dates dey for the calendar table for top.

Stock market go open for Black Friday?

Yes. The Friday after Thanksgiving na half-day wey dem schedule: normal trading go end 1:00 pm ET, not 4:00 pm — about 210 minute bars for the tape, not 390.

Bond market dey open today?

Normally when stocks dey — but no be always. Treasury market dey follow SIFMA calendar: every stock-market holiday plus Columbus Day and Veterans Day, with early close wey dey happen more (and earlier, 2:00 pm). For the past one year, the tape show 2 weekdays wey stock trade but Treasury yields no print.


Every panel for top na stored, versioned query with the exact SQL underneath — open any panel to check am. To check any date, session, or gap yourself, ask am for plain English for the Strasmore terminal.