Strasmore Research
Market Recap Matt ConnorBy Matt Connor · Updated 2026-07-11

Market Recap: July 9, 2026 — The Day in Numbers

Chip equipment gapped up hard and faded, mega-caps gapped down and ripped back, the tape flipped decisively green — and NVDA sat it out, closing red.

Thursday, July 9, 2026 packed its violence into one minute: the opening print. Semiconductor-equipment names opened far above Wednesday's close — KLAC at +8.14%, LRCX at +9.67% — while the hyperscaler mega-caps opened hard the other way, META -3.16% and MSFT -2.25%. Then the day spent six and a half hours partially unwinding its own open: the chip gaps faded, META climbed all the way to +4.69%, and the broad tape finished 71.5% green — the week's broadest session. NVDA, the chip that stayed green through Tuesday's rout, closed red. Every number below is read from a stored query — expand any panel for the exact SQL.

The scoreboard

Every change compares July 9's last regular-session minute bar with Wednesday July 8's — consecutive trading sessions. Rows are alphabetical, so each ETF keeps a fixed position.

QuerySPY / QQQ / DIA / IWM — July 9 vs the July 8 close, regular hours
The exact SQL behind every number
WITH prior AS (
    SELECT ticker, argMax(close, window_start) AS prior_close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ', 'DIA', 'IWM')
      AND window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00'
    GROUP BY ticker
),
sess AS (
    SELECT ticker,
           argMin(open, window_start) AS day_open,
           argMax(close, window_start) AS day_close,
           max(high) AS day_high,
           min(low) AS day_low,
           round(toFloat64(sum(volume)) / 1e6, 1) AS shares_traded_m
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ', 'DIA', 'IWM')
      AND window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'
    GROUP BY ticker
)
SELECT
    s.ticker AS ticker,
    round(toFloat64(p.prior_close), 2) AS prior_close,
    round(toFloat64(s.day_open), 2) AS day_open,
    round(toFloat64(s.day_close), 2) AS day_close,
    round((toFloat64(s.day_open) / toFloat64(p.prior_close) - 1) * 100, 2) AS gap_pct,
    round((toFloat64(s.day_close) / toFloat64(s.day_open) - 1) * 100, 2) AS intraday_pct,
    round((toFloat64(s.day_close) / toFloat64(p.prior_close) - 1) * 100, 2) AS pct_change,
    round(toFloat64(s.day_high), 2) AS day_high,
    round(toFloat64(s.day_low), 2) AS day_low,
    s.shares_traded_m
FROM sess s LEFT JOIN prior p ON s.ticker = p.ticker
ORDER BY ticker

All four index ETFs closed green, and the order tells the day's story. QQQ led at +1.67% — a +0.99% opening gap plus a +0.68% climb. IWM, the small-cap ETF, finished +1.29% — the broad rally reached down-cap. SPY added +0.85% to close at $751.64, and DIA trailed at +0.29%. Growth in front, the Dow in back — the reverse of Wednesday's ordering.

Was the day unusual?

At the index level: no — and that is the most interesting thing about it. QQQ's close-over-close move of +1.67% ranked just 10 of 21 trailing sessions by absolute size; SPY's open-to-close move ranked 8 of 22. The drama happened between the day's groups; the index sat in the middle while they traded places.

QuerySPY / QQQ day move in trailing context (~22 sessions)
The exact SQL behind every number
SELECT
    round(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-09')), 2) AS qqq_close_over_close_pct,
    arrayCount(x -> x > abs(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-09'))), groupArrayIf(abs(cc_pct), ticker = 'QQQ' AND d != toDate('2026-07-09'))) + 1 AS qqq_abs_move_rank,
    countIf(ticker = 'QQQ' AND isFinite(cc_pct)) AS qqq_sessions_compared,
    round(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-09')), 2) AS spy_open_to_close_pct,
    arrayCount(x -> x > abs(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-09'))), groupArrayIf(abs(oc_pct), ticker = 'SPY' AND d != toDate('2026-07-09'))) + 1 AS spy_abs_move_rank,
    countIf(ticker = 'SPY') AS spy_sessions_compared,
    toString(min(d)) AS first_session
FROM (
    SELECT ticker, d,
           if(isFinite(close_px / lagInFrame(close_px) OVER (PARTITION BY ticker ORDER BY d) - 1),
              (close_px / lagInFrame(close_px) OVER (PARTITION BY ticker ORDER BY d) - 1) * 100, NULL) AS cc_pct,
           oc_pct
    FROM (
        SELECT ticker, toDate(toTimeZone(window_start, 'America/New_York')) AS d,
               argMax(toFloat64(close), window_start) AS close_px,
               (argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100 AS oc_pct
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker IN ('SPY', 'QQQ')
          AND window_start >= toDateTime('2026-06-08 13:30:00')
          AND window_start < toDateTime('2026-07-10 00:00:00')
          AND (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199
        GROUP BY ticker, d
    )
)

Breadth: the tape flipped from one-in-three green to seven-in-ten

QueryLiquid-tape breadth: July 9 advancer share vs July 8, $1M-traded filter
The exact SQL behind every number
SELECT
    countIf(close_9 > close_8 AND close_8 > 0 AND dv_9 >= 1000000) AS advancers,
    countIf(close_9 < close_8 AND close_8 > 0 AND dv_9 >= 1000000) AS decliners,
    countIf(close_9 = close_8 AND close_8 > 0 AND dv_9 >= 1000000) AS unchanged,
    countIf(close_8 > 0 AND close_9 > 0 AND dv_9 >= 1000000) AS liquid_tickers,
    countIf(close_8 > 0 AND close_9 > 0) AS traded_both_sessions,
    countIf(close_8 > 0 AND close_9 > 0) - countIf(close_8 > 0 AND close_9 > 0 AND dv_9 >= 1000000) AS dropped_by_liquidity_filter,
    round(100.0 * countIf(close_9 > close_8 AND close_8 > 0 AND dv_9 >= 1000000) / countIf(close_8 > 0 AND close_9 > 0 AND dv_9 >= 1000000), 1) AS advancer_pct,
    round(100.0 * countIf(close_8 > close_7 AND close_7 > 0 AND dv_8 >= 1000000) / countIf(close_8 > 0 AND close_7 > 0 AND dv_8 >= 1000000), 1) AS jul8_advancer_pct
FROM (
    SELECT ticker,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-07 20:00:00')) AS close_7,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00')) AS close_8,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00')) AS close_9,
           sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00') AS dv_9,
           sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00') AS dv_8
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-09 20:00:00'
    GROUP BY ticker
)

4263 advancers against 1631 decliners — an advancer share of 71.5%, after 29.6% on Wednesday: the same computation over the same $1M-traded filter, flipped from decisively red to decisively green in one session. (5385 of 11351 names with closes on both days fell below the filter and are excluded.)

The day's highlight: the semiconductor open, and the fade that followed

The panel below carries two extra columns worth reading together: gap_pct (the opening print against Wednesday's close) and intraday_pct (the rest of the day, open to close). Rows are alphabetical, so each name keeps a fixed position.

QueryFourteen chip names: gap at the open vs the rest of the day, July 9
The exact SQL behind every number
WITH per_name AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-07-09 00:00:00')) AS prior_close,
        toFloat64(argMinIf(open, window_start, window_start >= '2026-07-09 00:00:00')) AS day_open,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-09 00:00:00')) AS day_close,
        maxIf(toFloat64(high), window_start >= '2026-07-09 00:00:00') AS day_high,
        minIf(toFloat64(low), window_start >= '2026-07-09 00:00:00') AS day_low,
        round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-09 00:00:00') / 1e9, 2) AS day_dollar_bn
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AMD', 'AVGO', 'INTC', 'KLAC', 'LRCX', 'MRVL', 'MU', 'NVDA', 'SNDK', 'SOXL', 'SOXS', 'STX', 'TER', 'WDC')
      AND ((window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00')
        OR (window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'))
    GROUP BY ticker
)
SELECT
    ticker,
    round(prior_close, 2) AS prior_close,
    round(day_open, 2) AS day_open,
    round(day_close, 2) AS day_close,
    round((day_open / prior_close - 1) * 100, 2) AS gap_pct,
    round((day_close / day_open - 1) * 100, 2) AS intraday_pct,
    round((day_close / prior_close - 1) * 100, 2) AS pct_chg,
    day_dollar_bn
FROM per_name
ORDER BY ticker

The equipment names carried the wildest opens: KLAC printed its first regular bar +8.14% above Wednesday's close and then gave back -3.98% through the day; LRCX opened +9.67% and faded -3.26%; TER (+7.87%) and WDC (+7.89%) opened with the same shape. MU gapped +7.07%, slid -2.56% from the open, and still closed +4.33% on 33.56B of dollars — the heaviest name on the whole tape for a second straight session (Wednesday's recap documents the first). AMD was the exception to the fade, adding 1.75% after its +3.87% open to finish +5.68%. The 3x wrapper SOXL opened +14.28% and closed +10.07%; its inverse SOXS closed -9.96%.

And then there is NVDA: a +0.16% open — no gap at all — and a -0.68% close. The biggest chip name on the tape sat out its own sector's celebration entirely:

QueryReceipts: July 9 green/red counts across the fourteen names, and NVDA's two-day turn
The exact SQL behind every number
SELECT
    countIf(close_9 > close_8) AS jul9_green,
    countIf(close_9 < close_8) AS jul9_red,
    countIf(close_8 > close_7) AS jul8_green,
    round(anyIf((close_9 / close_8 - 1) * 100, ticker = 'NVDA'), 2) AS nvda_jul9_pct,
    round(anyIf((close_8 / close_7 - 1) * 100, ticker = 'NVDA'), 2) AS nvda_jul8_pct,
    count() AS names_counted
FROM (
    SELECT ticker,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-07 20:00:00')) AS close_7,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00')) AS close_8,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00')) AS close_9
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AMD', 'AVGO', 'INTC', 'KLAC', 'LRCX', 'MRVL', 'MU', 'NVDA', 'SNDK', 'SOXL', 'SOXS', 'STX', 'TER', 'WDC')
      AND window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-09 20:00:00'
    GROUP BY ticker
)

12 of the fourteen closed green; the 2 red closes were the inverse wrapper — structural on an up day — and NVDA at -0.68%, one day after closing +3.66%. NVDA was also the day's most-covered ticker in the news feed (the calendar panel below carries that count), which makes the red close the stranger fact — heavy attention, no gap, mild fade.

The other side: mega-caps opened down and spent the day climbing back

QueryEight mega-caps and defensives: gap at the open vs the rest of the day, July 9
The exact SQL behind every number
WITH per_name AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-07-09 00:00:00')) AS prior_close,
        toFloat64(argMinIf(open, window_start, window_start >= '2026-07-09 00:00:00')) AS day_open,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-09 00:00:00')) AS day_close,
        round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-09 00:00:00') / 1e9, 2) AS day_dollar_bn
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL', 'AMZN', 'CVX', 'GOOGL', 'JNJ', 'META', 'MSFT', 'TSLA')
      AND ((window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00')
        OR (window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'))
    GROUP BY ticker
)
SELECT
    ticker,
    round(prior_close, 2) AS prior_close,
    round(day_open, 2) AS day_open,
    round(day_close, 2) AS day_close,
    round((day_open / prior_close - 1) * 100, 2) AS gap_pct,
    round((day_close / day_open - 1) * 100, 2) AS intraday_pct,
    round((day_close / prior_close - 1) * 100, 2) AS pct_chg,
    day_dollar_bn
FROM per_name
ORDER BY ticker

Seven of the eight names opened below Wednesday's close; what happened next separates them. META opened -3.16% down and climbed +8.1% from that open — a 4.69% close, the single most violent open-to-close reversal in either panel. MSFT opened -2.25% down and recovered to +0.33%; AMZN and AAPL traced the same shape to +1.4% and +0.93%. TSLA never gapped and simply climbed to +3.21%. The names that stayed down were not growth at all: GOOGL (-0.76%), CVX (-1.06%), and JNJ (-1.62%). Opening and closing prices disagreed about nearly every name on this page — why stocks gap overnight walks through the mechanic on calmer data.

Where the money traded

QueryTop 6 by dollars traded, top 4 by shares traded — July 9 regular hours
The exact SQL behind every number
SELECT leaderboard, ticker, dollar_volume_bn, shares_m,
    round(1000 * dollar_volume_bn / shares_m, 2) AS implied_avg_price,
    round(100 * if(leaderboard = 'by dollars traded', dollar_volume_bn, shares_m)
        / max(if(leaderboard = 'by dollars traded', dollar_volume_bn, shares_m)) OVER (PARTITION BY leaderboard), 1) AS pct_of_board_leader
FROM (
    SELECT
        'by dollars traded' AS leaderboard,
        ticker,
        round(sum(toFloat64(close) * toFloat64(volume)) / 1e9, 2) AS dollar_volume_bn,
        round(sum(toFloat64(volume)) / 1e6, 1) AS shares_m
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'
      AND ticker NOT IN ('SPCX')
    GROUP BY ticker
    ORDER BY dollar_volume_bn DESC
    LIMIT 6
    UNION ALL
    SELECT
        'by shares traded' AS leaderboard,
        ticker,
        round(sum(toFloat64(close) * toFloat64(volume)) / 1e9, 2) AS dollar_volume_bn,
        round(sum(toFloat64(volume)) / 1e6, 1) AS shares_m
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'
      AND ticker NOT IN ('SPCX')
    GROUP BY ticker
    ORDER BY shares_m DESC
    LIMIT 4
)
ORDER BY leaderboard, pct_of_board_leader DESC

MU topped the dollar board again at 33.56B, ahead of SPY (24.37B), NVDA (21.28B), and SNDK (20.59B) — memory names holding two of the top four dollar slots. QQQ (20.04B) and META (12.69B) rounded out the board, META's slot earned by its reversal day. On the shares board, the inverse-semiconductor wrapper SOXS led at 558.1M shares (implied average price $3.91), followed by the bitcoin-futures ETF BITO at 326.2M — low-priced wrappers doing wrapper things.

The shape of the session

QueryShares per 30-minute ET bucket, regular hours, with % of the day's biggest bucket
The exact SQL behind every number
SELECT
    formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE), '%H:%i') AS et_time,
    round(sum(toFloat64(volume)) / 1e9, 2) AS shares_bn,
    round(100 * sum(toFloat64(volume)) / max(sum(toFloat64(volume))) OVER (), 1) AS pct_of_biggest_bucket
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'
GROUP BY et_time
ORDER BY et_time

A textbook U: the open bucket ran 1.79B shares (91.4% of the day's biggest), the midday trough sat near 0.64B, and the closing half-hour was the day's biggest bucket at 1.96B. Even on a day defined by its open, the volume finished at the close.

The options tape

QueryOptions tape: prints, contracts, call %, 0DTE share vs Wednesday, top contracts
The exact SQL behind every number
WITH
    (
        SELECT (groupArray(und), groupArray(strike), groupArray(typ), groupArray(vol), groupArray(avg_px), groupArray(is_0dte))
        FROM (
            SELECT any(underlying_symbol) AS und, any(toFloat64(strike_price)) AS strike, any(option_type) AS typ,
                   sum(size) AS vol, round(avg(toFloat64(price)), 3) AS avg_px,
                   if(substring(ticker, length(ticker) - 14, 6) = '260709', 1, 0) AS is_0dte
            FROM global_markets.options_trades
            WHERE sip_timestamp >= '2026-07-09 00:00:00' AND sip_timestamp < '2026-07-10 00:00:00'
            GROUP BY ticker
            ORDER BY vol DESC
            LIMIT 3
        )
    ) AS top3,
    (
        SELECT round(toFloat64(argMax(close, window_start)), 2)
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY' AND window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00'
    ) AS spy_regular_close,
    (
        SELECT round(toFloat64(sum(size)) / 1e6, 2)
        FROM global_markets.options_trades
        WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00'
    ) AS jul8_contracts_m,
    (
        SELECT round(100.0 * sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260708') / sum(size), 1)
        FROM global_markets.options_trades
        WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00'
    ) AS jul8_pct_0dte
SELECT
    round(count() / 1e6, 2) AS option_prints_m,
    round(toFloat64(sum(size)) / 1e6, 2) AS contracts_m,
    jul8_contracts_m,
    round(100.0 * sumIf(size, option_type = 'C') / sum(size), 1) AS call_pct_of_volume,
    round(100.0 * sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260709') / sum(size), 1) AS pct_0dte,
    jul8_pct_0dte,
    spy_regular_close,
    top3.1[1] AS top1_und, top3.2[1] AS top1_strike, top3.3[1] AS top1_type, top3.4[1] AS top1_contracts, top3.5[1] AS top1_avg_px, top3.6[1] AS top1_is_0dte,
    top3.1[2] AS top2_und, top3.2[2] AS top2_strike, top3.3[2] AS top2_type, top3.6[2] AS top2_is_0dte,
    top3.1[3] AS top3_und, top3.2[3] AS top3_strike, top3.3[3] AS top3_type, top3.6[3] AS top3_is_0dte,
    round(toFloat64(top3.2[1]) - spy_regular_close, 2) AS top1_moneyness
FROM global_markets.options_trades
WHERE sip_timestamp >= '2026-07-09 00:00:00' AND sip_timestamp < '2026-07-10 00:00:00'

The consolidated tape carried 9.99M prints and 58.85M contracts — below Wednesday's 63.26M, computed from the same tape over Wednesday's window. Calls ran 58% of volume, and the 0DTE share fell to 28.7% from 38.7% — on a day with no weekly expiry cliff in sight, the same-day crowd took a smaller slice. The three busiest contracts on the entire tape were all same-day SPY calls — the 751C (846566 contracts at an average $0.526), the 752C, and the 750C — a call ladder bracketing SPY's eventual $751.64 close, with the busiest strike finishing -0.64 from it. 0DTE options covers the product.

The quote tape

QueryStocks NBBO update count: July 9 vs July 8, with named-ticker updates (millions)
The exact SQL behind every number
SELECT
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09')) / 1e6, 2) AS jul9_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08')) / 1e6, 2) AS jul8_updates_m,
    round((countIf(toDate(sip_timestamp) = toDate('2026-07-09')) / countIf(toDate(sip_timestamp) = toDate('2026-07-08')) - 1) * 100, 1) AS day_over_day_pct,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09') AND ticker = 'SPY') / 1e6, 2) AS jul9_spy_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09') AND ticker = 'QQQ') / 1e6, 2) AS jul9_qqq_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09') AND ticker = 'NVDA') / 1e6, 2) AS jul9_nvda_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09') AND ticker = 'TSLA') / 1e6, 2) AS jul9_tsla_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-09') AND ticker = 'MU') / 1e6, 2) AS jul9_mu_updates_m
FROM global_markets.cache_stocks_quotes
WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-10 00:00:00'

The day's quietest fact: the stock-quote tape carried 383.44M NBBO updates — -27.7% versus Wednesday. The violence lived in the price levels, not in churn at the touch. QQQ led the named tickers at 4.35M updates, ahead of SPY's 2.71M, NVDA's 1.83M, and MU's 0.72M.

QuerySPY / QQQ / NVDA / TSLA / MU / SNDK / AVGO: RTH median quoted spread in basis points
The exact SQL behind every number
SELECT
    ticker,
    round(quantileExact(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000), 2) AS median_spread_bps
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('SPY', 'QQQ', 'NVDA', 'TSLA', 'MU', 'SNDK', 'AVGO')
  AND sip_timestamp >= '2026-07-09 13:30:00' AND sip_timestamp < '2026-07-09 20:00:00'
  AND bid_price > 0 AND ask_price > 0 AND ask_price > bid_price
GROUP BY ticker
ORDER BY median_spread_bps ASC

SPY's RTH median quoted spread printed 0.27 bps, QQQ 0.42 bps, NVDA 0.99 bps — ordinary numbers all. The wider tail: MU at 4.23 bps and SNDK at 8.79 bps, the two names carrying the most memory-trade freight.

QuerySPY's RTH average quoted spread in trailing-month context
The exact SQL behind every number
SELECT
    round(anyIf(avg_spread_cents, d = toDate('2026-07-09')), 3) AS jul9_avg_spread_cents,
    arrayCount(x -> x < anyIf(avg_spread_cents, d = toDate('2026-07-09')), groupArrayIf(avg_spread_cents, d != toDate('2026-07-09'))) + 1 AS tightness_rank,
    count() AS sessions_compared,
    round(min(avg_spread_cents), 3) AS tightest_session_cents,
    round(max(avg_spread_cents), 3) AS widest_session_cents,
    toString(min(d)) AS first_session
FROM (
    SELECT toDate(toTimeZone(sip_timestamp, 'America/New_York')) AS d,
           avgIf(toFloat64(ask_price - bid_price), bid_price > 0 AND ask_price >= bid_price) * 100 AS avg_spread_cents
    FROM global_markets.cache_stocks_quotes
    WHERE ticker = 'SPY'
      AND sip_timestamp >= toDateTime('2026-06-08 00:00:00')
      AND sip_timestamp < toDateTime('2026-07-10 00:00:00')
      AND (toHour(sip_timestamp) * 60 + toMinute(sip_timestamp)) BETWEEN 810 AND 1199
    GROUP BY d
)

SPY's RTH average quoted spread of 2.071 cents ranked 10 of 22 trailing sessions — mid-pack, inside a trailing range of 1.809 to 2.865 cents. No stress in the quote, even at the open that repriced the chip complex.

QueryOptions NBBO tape: total updates vs the stock tape, plus the SPY root slice
The exact SQL behind every number
WITH
    (SELECT count() FROM global_markets.cache_options_quotes WHERE sip_timestamp >= '2026-07-09 00:00:00' AND sip_timestamp < '2026-07-10 00:00:00') AS jul9_options_rows,
    (SELECT count() FROM global_markets.cache_stocks_quotes WHERE sip_timestamp >= '2026-07-09 00:00:00' AND sip_timestamp < '2026-07-10 00:00:00') AS jul9_stock_quote_rows
SELECT
    round(jul9_options_rows / 1e9, 2) AS jul9_options_bn,
    round(jul9_options_rows / jul9_stock_quote_rows, 1) AS options_to_stock_ratio,
    round((SELECT count() FROM global_markets.cache_options_quotes WHERE ticker >= 'O:SPY26' AND ticker < 'O:SPY27' AND sip_timestamp >= '2026-07-09 13:30:00' AND sip_timestamp < '2026-07-09 20:00:00') / 1e6, 0) AS jul9_spy_options_m

The options-quote tape carried 6.9 billion NBBO updates — 18× the stock tape — with the SPY root alone at 242 million regular-hours updates.

Rates: the July 9 print, still in transit

QueryTreasury print status: July 9 rows on record, and the July 8 curve (latest at authoring)
The exact SQL behind every number
SELECT
    (SELECT count() FROM global_markets.treasury_yields WHERE date = '2026-07-09') AS jul9_print_rows,
    toString(any(date)) AS latest_print_date,
    round(toFloat64(any(yield_2_year)), 2) AS latest_2y_pct,
    round(toFloat64(any(yield_10_year)), 2) AS latest_10y_pct,
    round(toFloat64(any(yield_30_year)), 2) AS latest_30y_pct,
    round(toFloat64(any(yield_10_year)) - toFloat64(any(yield_2_year)), 2) AS latest_2s10s_pct
FROM global_markets.treasury_yields
WHERE date = '2026-07-08'

The July 9 treasury print had 0 rows on record at authoring — the daily yield file lands on roughly a one-session lag, so this is expected, and this section is written as a receipt rather than a story. The latest curve on record (2026-07-08): 2-year 4.21%, 10-year 4.56%, 30-year 5.06%, 2s10s at 0.35 points. When the July 9 print lands, regeneration will hold this post until the section is rewritten with the actual curve — the same tripwire that caught the July 2 and July 7 prints.

The calendar behind the day

QueryEx-divs, splits, SEC filings, news attention
The exact SQL behind every number
WITH
    (
        SELECT (count(), uniqExact(publisher))
        FROM global_markets.stocks_news
        WHERE toDate(toTimeZone(published_utc, 'America/New_York')) = '2026-07-09'
    ) AS news,
    (
        SELECT (argMax(t, (n, t)), max(n), max(n) - arraySort(x -> -x, groupArray(n))[2])
        FROM (
            SELECT t, count() AS n
            FROM (
                SELECT arrayJoin(tickers) AS t
                FROM global_markets.stocks_news
                WHERE toDate(toTimeZone(published_utc, 'America/New_York')) = '2026-07-09'
            )
            WHERE t != 'SPCX'
            GROUP BY t
        )
    ) AS top_news
SELECT
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-07-09') AS ex_dividend_records,
    (SELECT count() FROM global_markets.stocks_splits WHERE execution_date = '2026-07-09') AS splits_executed,
    (SELECT countIf(toFloat64(split_from) > toFloat64(split_to)) FROM global_markets.stocks_splits WHERE execution_date = '2026-07-09') AS reverse_splits,
    (SELECT countIf(toFloat64(split_to) > toFloat64(split_from)) FROM global_markets.stocks_splits WHERE execution_date = '2026-07-09') AS forward_splits,
    (SELECT countIf(form_type = '424B2') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-09') AS fil_424b2,
    (SELECT countIf(form_type = '4') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-09') AS fil_form4,
    (SELECT countIf(form_type = '8-K') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-09') AS fil_8k,
    (SELECT count() FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-09') AS fil_total,
    news.1 AS news_articles, news.2 AS news_publishers,
    top_news.1 AS top_news_ticker, top_news.2 AS top_news_n, top_news.3 AS top_news_lead_over_next,
    if(top_news.1 = 'NVDA', 1, 0) AS top_news_is_nvda

A routine calendar under an unroutine open: 127 ex-dividend records, 5 reverse splits and 1 forward split executed, and 2947 SEC filings (623 Form 4 insider trades, 606 424B2 prospectuses, 149 8-K current reports). The news feed carried 184 articles across 3 publishers, and the most-covered ticker was NVDA at 20 articles, 8 clear of the next name — the same NVDA that closed red.

The session, verified

QuerySession verification: first/last SPY bar ET, regular-bar count, holiday receipts, next closure
The exact SQL behind every number
SELECT
    formatDateTime(min(toTimeZone(window_start, 'America/New_York')), '%H:%i') AS first_spy_bar_et,
    formatDateTime(max(toTimeZone(window_start, 'America/New_York')), '%H:%i') AS last_spy_bar_et,
    count() AS spy_minute_bars,
    countIf(window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00') AS regular_session_bars,
    uniqExactIf(toDate(toTimeZone(window_start, 'America/New_York')), window_start >= '2026-07-09 13:30:00' AND window_start < '2026-07-09 20:00:00') AS day_sessions,
    (SELECT count() FROM global_markets.stocks_market_holidays WHERE date = '2026-07-09') AS jul9_holiday_rows,
    (SELECT toString(min(date)) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-09' AND status = 'closed') AS next_closure_date,
    (SELECT argMin(name, date) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-09' AND status = 'closed') AS next_closure_name
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-09 00:00:00' AND window_start < '2026-07-10 00:00:00'

A full ordinary session: first SPY bar at 04:00 ET, last at 19:59 ET, 390 regular-hours minute bars, 1 trading session in the window, and no holiday-table row for the date. The next scheduled closure is Labor Day on 2026-09-07.

Data notes

All timestamps are stored in UTC; regular hours on July 9, 2026 are filtered as sip_timestamp / window_start between 2026-07-09 13:30:00 and 2026-07-09 20:00:00 (9:30 am–4:00 pm New York time). Named per-ticker panels are ordered alphabetically by ticker so each prose reference points at a fixed row; leaderboards are value-ordered, with every positional claim encoded as a sanity bound. Every Wednesday comparison is computed fresh from July 8 (and July 7 where a prior close is needed) in the same query block, never quoted from an earlier post.

Full data notes

Gap columns divide the first regular-session bar's open by the prior session's last regular-session close; the July 9 tape is complete at authoring depth (390 regular bars for every name checked), so opens are true opens, not the partial-ingest artifacts that have faked gaps at the front edge before. The breadth panel requires a close on both sessions plus $1M traded on the measured day, with the dropped tail reported. Same-day expiry detection uses the OCC-ticker substring, not options_trades.expiration_date (broken column, standing preflight note). KNOWN_AMBIGUOUS_TICKERS are excluded in leaderboard and news SQL; the news tie-break is deterministic. The treasury section is deliberately a lag receipt: jul9_print_rows is bounded to exactly 0, so the July 9 print's arrival holds the post for a rewrite instead of silently changing the section. Spread medians use quantileExact; the trailing spread panel is an average, labeled as such.

Methodology

  • Market data source: consolidated tape — delayed_stocks_minute_aggs for prices and volumes, cache_stocks_quotes for NBBO counts and quoted spreads, cache_options_quotes and options_trades for the options tape.
  • Time zone handling: all stored timestamps are UTC; ET labels computed with toTimeZone(..., 'America/New_York') in SELECT lists only; WHERE clauses use raw UTC literals.
  • Regular-hours window: 13:30–20:00 UTC, verified against observed SPY minute bars in the session-verification panel.
  • Gap definition: first regular-session bar open ÷ prior regular-session close − 1, the same convention as our overnight-gap explainer.
  • Prior-session comparisons: computed in-query from July 8 (and July 7 where needed) — never carried over from a previous post.
  • Deterministic aggregates: quantileExact, tuple-keyed tie-breaks, and a deterministic news tie-break for stable regenerations.
  • Warehouse as-of date: July 11, 2026 (T+2 for the period); the equity, options, and quote tapes are fully ingested at this depth. The treasury print for the period is pending, as receipted above.

Cross-links: July 8, 2026 recap, why stocks gap overnight, 0DTE options, relative volume, and market orders vs limit orders.