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

Market Recap: July 8, 2026, The Day in Numbers

A one-day chip bounce the index barely felt: most semis green, NVDA up a second day, MU the heaviest dollar name, and a broad tape more than two-to-one red.

Wednesday, July 8, 2026 was a one-day chip bounce the indexes barely felt. SNDK closed +6.8%, AVGO +4.82%, NVDA +3.66%, a sharp reversal from Tuesday's chip rout, but the index ETFs sat still: SPY -0.31% and QQQ +0.25%. The broad tape ran even more two-to-one red than the day before: 1821 advancers against 4260 decliners, an advancer share of 29.6% after 33.8% the session before. Every number below is read from a stored query, expand any panel for the exact SQL.

The scoreboard

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

QuerySPY / QQQ / DIA / IWM: July 8 vs the July 7 close, regular hours
tickerprior_closeday_openday_closegap_pctintraday_pctpct_changeday_highday_lowshares_traded_m
DIA528.48523.34522.72-0.97-0.12-1.09524.46520.033.2
IWM296.2294.03293.47-0.73-0.19-0.92295.1290.6820.3
QQQ709.5704.95711.3-0.640.90.25712.26700.9129.5
SPY747.66743.16745.31-0.60.29-0.31746.15739.5135.6
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-07 13:30:00' AND window_start < '2026-07-07 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-08 13:30:00' AND window_start < '2026-07-08 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
Run this yourself

The four ETFs gapped down at the open and went different ways from there. DIA opened the session at -0.97% against the prior close and faded further, finishing -1.09%. IWM opened at -0.73% and stayed down, closing -0.92%. SPY opened at -0.6%, ground back through the day, and still closed -0.31%, the recovery off the open was smaller than the gap. QQQ opened at -0.64% and rallied to +0.25% by the close, the only one of the four in positive territory.

Was the day unusual?

The SPY open-to-close move of 0.29% ranked 16 of 22 trailing sessions, a mid-pack day for the index, not an extreme. The QQQ close-over-close move of +0.25% ranked 21 of 22, one of the smallest trailing-month moves for QQQ, consistent with the index's muted print.

QuerySPY / QQQ day move in trailing context (close-over-close, ~22 sessions)
qqq_close_over_close_pctqqq_abs_move_rankqqq_sessions_comparedspy_open_to_close_pctspy_abs_move_rankspy_sessions_comparedfirst_session
0.2521220.2916222026-06-05
The exact SQL behind every number
SELECT
    round(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-08')), 2) AS qqq_close_over_close_pct,
    arrayCount(x -> x > abs(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-08'))), groupArrayIf(abs(cc_pct), ticker = 'QQQ' AND d != toDate('2026-07-08'))) + 1 AS qqq_abs_move_rank,
    countIf(ticker = 'QQQ') AS qqq_sessions_compared,
    round(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-08')), 2) AS spy_open_to_close_pct,
    arrayCount(x -> x > abs(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-08'))), groupArrayIf(abs(oc_pct), ticker = 'SPY' AND d != toDate('2026-07-08'))) + 1 AS spy_abs_move_rank,
    countIf(ticker = 'SPY') AS spy_sessions_compared,
    toString(min(d)) AS first_session
FROM (
    SELECT ticker, d,
           (close_px / lagInFrame(close_px) OVER (PARTITION BY ticker ORDER BY d) - 1) * 100 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-05 13:30:00')
          AND window_start < toDateTime('2026-07-09 00:00:00')
          AND (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199
        GROUP BY ticker, d
    )
)
Run this yourself

Breadth: even more two-to-one red than the day before

QueryLiquid-tape breadth: July 8 advancer share vs July 7, $1M-traded filter
advancersdeclinersunchangedliquid_tickerstraded_both_sessionsdropped_by_liquidity_filteradvancer_pctjul7_advancer_pct
1821426074615511439528429.633.8
The exact SQL behind every number
SELECT
    countIf(close_8 > close_7 AND close_7 > 0 AND dv_8 >= 1000000) AS advancers,
    countIf(close_8 < close_7 AND close_7 > 0 AND dv_8 >= 1000000) AS decliners,
    countIf(close_8 = close_7 AND close_7 > 0 AND dv_8 >= 1000000) AS unchanged,
    countIf(close_7 > 0 AND close_8 > 0 AND dv_8 >= 1000000) AS liquid_tickers,
    countIf(close_7 > 0 AND close_8 > 0) AS traded_both_sessions,
    countIf(close_7 > 0 AND close_8 > 0) - countIf(close_7 > 0 AND close_8 > 0 AND dv_8 >= 1000000) AS dropped_by_liquidity_filter,
    round(100.0 * countIf(close_8 > close_7 AND close_7 > 0 AND dv_8 >= 1000000) / countIf(close_7 > 0 AND close_8 > 0 AND dv_8 >= 1000000), 1) AS advancer_pct,
    round(100.0 * countIf(close_7 > close_6 AND close_6 > 0 AND dv_7 >= 1000000) / countIf(close_7 > 0 AND close_6 > 0 AND dv_7 >= 1000000), 1) AS jul7_advancer_pct
FROM (
    SELECT ticker,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-06 13:30:00' AND window_start < '2026-07-06 20:00:00')) AS close_6,
           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,
           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,
           sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-07 20:00:00') AS dv_7
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= '2026-07-06 13:30:00' AND window_start < '2026-07-08 20:00:00'
    GROUP BY ticker
)
Run this yourself

The gap between advancers (1821) and decliners (4260) put the advancer share at 29.6%, down from 33.8% the session before, the same computation over the same liquidity filter, run for both days. Of the 11439 names with a close on both days, 5284 fell below the $1M-traded filter and are excluded from the count. The chip-led bounce and the index's mixed close sat on top of an even more uniformly negative broad tape.

The chip complex bounced, hard, and on heavy volume

Rows are alphabetical, so each name keeps a fixed position; the Tuesday comparison is computed fresh from the July 7 and July 6 closes in the receipts block below the table.

QueryFourteen chip names: prior close, day close, day range, dollar volume, low/high minute ET
tickerprior_closeday_closepct_chgrange_pctday_lowday_highlow_minute_ethigh_minute_etday_dollar_bn
AMD516.57517.260.134.81498.15522.986835878.93
AVGO370.79388.674.824.91376.89395.095707789.39
INTC110.5110.27-0.215.5104.41110.497139579.48
KLAC216.52221.032.084.2214.3223.46859291.79
LRCX326.12332.932.094.53322.72337.55705872.1
MRVL230.81231.660.375.12224.98236.795705934.57
MU938.95949.371.116.24900.4195957060032.02
NVDA196.93204.143.665.13195.06205.1657093724.17
SNDK1619.261729.46.88.9415901734.6957095916.82
SOXL165.27174.845.7910.82158.87176.755708168.12
SOXS4.824.52-6.22114.464.999295702.97
STX827.4859.683.96.18811.27862.415709593.46
TER343.1351.562.475.6335.06354.276865870.77
WDC532.34550.713.456.91526562.765706003.03
The exact SQL behind every number
WITH per_name AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-07-08 00:00:00')) AS prior_close,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-08 00:00:00')) AS day_close,
        maxIf(toFloat64(high), window_start >= '2026-07-08 00:00:00') AS day_high,
        minIf(toFloat64(low), window_start >= '2026-07-08 00:00:00') AS day_low,
        argMinIf(window_start, (toFloat64(low), toInt64(toUnixTimestamp(window_start))), window_start >= '2026-07-08 00:00:00') AS low_bar,
        argMaxIf(window_start, (toFloat64(high), -toInt64(toUnixTimestamp(window_start))), window_start >= '2026-07-08 00:00:00') AS high_bar,
        round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-08 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-07 13:30:00' AND window_start < '2026-07-07 20:00:00')
        OR (window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00'))
    GROUP BY ticker
)
SELECT
    ticker,
    round(prior_close, 2) AS prior_close,
    round(day_close, 2) AS day_close,
    round((day_close / prior_close - 1) * 100, 2) AS pct_chg,
    round(((day_high - day_low) / prior_close) * 100, 2) AS range_pct,
    round(toFloat64(day_low), 2) AS day_low,
    round(toFloat64(day_high), 2) AS day_high,
    toUInt32(toHour(toTimeZone(low_bar, 'America/New_York')) * 60 + toMinute(toTimeZone(low_bar, 'America/New_York'))) AS low_minute_et,
    toUInt32(toHour(toTimeZone(high_bar, 'America/New_York')) * 60 + toMinute(toTimeZone(high_bar, 'America/New_York'))) AS high_minute_et,
    day_dollar_bn
FROM per_name
ORDER BY ticker
Run this yourself

12 of the fourteen chip names closed green, the reverse of Tuesday's session, when 12 of the fourteen closed red. SNDK led the complex at +6.8% on 16.82B of dollars traded, with AVGO close behind at +4.82%; the other storage names followed, STX +3.9%, WDC +3.45%. The 3x wrapper SOXL ran +5.79% and the inverse SOXS -6.22%, consistent with a one-day recovery in the underlying complex. MU rose a more modest +1.11% but printed 32.02B of dollars, the heaviest dollar-volume name in the panel. NVDA closed +3.66% for a second straight green day: it was one of only 2 names in this panel that closed green through Tuesday's rout (+0.67% that day).

QueryReceipts: July 8 and July 7 green/red counts across the same fourteen names
jul8_greenjul8_redjul7_greenjul7_rednvda_jul7_pctnames_counted
1222120.6714
The exact SQL behind every number
SELECT
    countIf(close_8 > close_7) AS jul8_green,
    countIf(close_8 < close_7) AS jul8_red,
    countIf(close_7 > close_6) AS jul7_green,
    countIf(close_7 < close_6) AS jul7_red,
    round(anyIf((close_7 / close_6 - 1) * 100, ticker = 'NVDA'), 2) AS nvda_jul7_pct,
    count() AS names_counted
FROM (
    SELECT ticker,
           toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-06 13:30:00' AND window_start < '2026-07-06 20:00:00')) AS close_6,
           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
    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-06 13:30:00' AND window_start < '2026-07-08 20:00:00'
    GROUP BY ticker
)
Run this yourself

The other side: defensives and growth mega-caps didn't follow

QueryRotation check: eight names, defensives, mega-caps, biotech
tickerprior_closeday_openday_closegap_pctintraday_pctpct_chgday_dollar_bn
CRNX83.5383.5283.45-0.01-0.08-0.11.38
CVX173.97176.8175.921.63-0.51.121.36
JNJ267.29268.6263.360.49-1.95-1.471.38
LLY1235.641221.11215.87-1.18-0.43-1.62.55
META615.57614.38603.03-0.19-1.85-2.045.86
TSLA402.88399.38393.92-0.87-1.37-2.2211.71
UNH428.18427.14425.56-0.24-0.37-0.611.28
XOM141.65143.44140.961.26-1.73-0.492.08
The exact SQL behind every number
WITH per_name AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-07-08 00:00:00')) AS prior_close_raw,
        toFloat64(argMinIf(open, window_start, window_start >= '2026-07-08 00:00:00')) AS day_open_raw,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-08 00:00:00')) AS day_close_raw,
        round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-08 00:00:00') / 1e9, 2) AS day_dollar_bn
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('CRNX', 'CVX', 'JNJ', 'LLY', 'META', 'TSLA', 'UNH', 'XOM')
      AND ((window_start >= '2026-07-07 13:30:00' AND window_start < '2026-07-07 20:00:00')
        OR (window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00'))
    GROUP BY ticker
)
SELECT
    ticker,
    round(prior_close_raw, 2) AS prior_close,
    round(day_open_raw, 2) AS day_open,
    round(day_close_raw, 2) AS day_close,
    round((day_open_raw / prior_close_raw - 1) * 100, 2) AS gap_pct,
    round((day_close_raw / day_open_raw - 1) * 100, 2) AS intraday_pct,
    round((day_close_raw / prior_close_raw - 1) * 100, 2) AS pct_chg,
    day_dollar_bn
FROM per_name
ORDER BY ticker
Run this yourself

The growth mega-caps moved the other way from the chip complex: TSLA -2.22%, META -2.04%, LLY -1.6%. CVX was the panel's only green close, up +1.12% on an early gap, while XOM opened +1.26% higher and faded to -0.49% by the close. The Wednesday tape thus split in two, chip names up, growth and defensives down, with the indexes sitting still between them. (Rows are alphabetical: CRNX, CVX, JNJ, LLY, META, TSLA, UNH, XOM.)

Where the money traded

QueryTop 6 by dollars traded, top 4 by shares traded: July 8 regular hours
leaderboardtickerdollar_volume_bnshares_mimplied_avg_pricepct_of_board_leader
by dollars tradedMU32.0234.1939100
by dollars tradedSPY26.4935.6744.182.7
by dollars tradedNVDA24.17120.5200.5875.5
by dollars tradedQQQ20.929.5708.4765.3
by dollars tradedSNDK16.8210.11665.3552.5
by dollars tradedTSLA11.7129.7394.2836.6
by shares tradedSOXS2.97636.54.67100
by shares tradedTZA1.37334.84.0952.6
by shares tradedBITO2.29272.48.4142.8
by shares tradedAAL2.79169.316.4826.6
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-08 13:30:00' AND window_start < '2026-07-08 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-08 13:30:00' AND window_start < '2026-07-08 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
Run this yourself

MU ran 32.02B of dollars, the heaviest name on the tape and the only one above the $30B mark. SPY (26.49B), NVDA (24.17B), and QQQ (20.9B) followed, with SNDK at 16.82B and TSLA at 11.71B rounding out the dollar board. The shares board told a different story: the 3x inverse semiconductor ETF SOXS traded 636.5M shares at an implied average price of $4.67, the mechanics of a low-priced 3x wrapper on a heavy chip day.

The shape of the session

QueryShares per 30-minute ET bucket, regular hours, with % of the day's biggest bucket
et_timeshares_bnpct_of_biggest_bucket
09:301.9889.9
10:001.3862.9
10:301.3259.9
11:001.1653
11:301.0145.9
12:000.9342.2
12:300.9242
13:000.7534.1
13:300.7634.5
14:000.7734.9
14:300.7534.3
15:000.941.1
15:302.2100
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-08 13:30:00' AND window_start < '2026-07-08 20:00:00'
GROUP BY et_time
ORDER BY et_time
Run this yourself

Volume drew a textbook U-shape: the open bucket ran at 89.9% of the day's biggest bucket and faded through the morning, bottoming at 34.1% in the 1:00–1:30 pm ET slot. The closing half-hour (15:30 ET) was the day's biggest bucket at 2.2B shares, larger than the open's 1.98B, the standard pattern for a regular session.

The options tape

QueryOptions tape: prints, contracts, call %, 0DTE share vs Tuesday, top contract
option_prints_mcontracts_mjul7_contracts_mcall_pct_of_volumepct_0dtejul7_pct_0dtespy_regular_closetop1_undtop1_striketop1_typetop1_contractstop1_avg_pxtop1_is_0dtetop1_moneyness
10.4463.2661.1355.438.731.2745.31SPY745C6779810.8751-0.31
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) = '260708', 1, 0) AS is_0dte
            FROM global_markets.options_trades
            WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00'
            GROUP BY ticker
            ORDER BY vol DESC
            LIMIT 2
        )
    ) AS top2,
    (
        SELECT round(toFloat64(argMax(close, window_start)), 2)
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY' AND window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00'
    ) AS spy_regular_close,
    (
        SELECT round(toFloat64(sum(size)) / 1e6, 2)
        FROM global_markets.options_trades
        WHERE sip_timestamp >= '2026-07-07 00:00:00' AND sip_timestamp < '2026-07-08 00:00:00'
    ) AS jul7_contracts_m,
    (
        SELECT round(100.0 * sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260707') / sum(size), 1)
        FROM global_markets.options_trades
        WHERE sip_timestamp >= '2026-07-07 00:00:00' AND sip_timestamp < '2026-07-08 00:00:00'
    ) AS jul7_pct_0dte
SELECT
    round(count() / 1e6, 2) AS option_prints_m,
    round(toFloat64(sum(size)) / 1e6, 2) AS contracts_m,
    jul7_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) = '260708') / sum(size), 1) AS pct_0dte,
    jul7_pct_0dte,
    spy_regular_close,
    top2.1[1] AS top1_und, top2.2[1] AS top1_strike, top2.3[1] AS top1_type, top2.4[1] AS top1_contracts, top2.5[1] AS top1_avg_px, top2.6[1] AS top1_is_0dte,
    round(toFloat64(top2.2[1]) - spy_regular_close, 2) AS top1_moneyness
FROM global_markets.options_trades
WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00'
Run this yourself

The consolidated options tape carried 10.44M prints and 63.26M contracts, above Tuesday's 61.13M, computed from the same tape over Tuesday's window. Calls ran 55.4% of total volume, a moderate call lean. 0DTE contracts (same-day expiry, 260708) took 38.7% of contract volume, up from 31.2% on Tuesday. The busiest single contract was SPY 745C, 677981 contracts at an average price of $0.875, a same-day expiry essentially at the money against SPY's $745.31 regular close.

The quote tape

QueryStocks NBBO update count: July 8 vs July 7, with named-ticker updates (millions)
jul8_updates_mjul7_updates_mday_over_day_pctjul8_spy_updates_mjul8_qqq_updates_mjul8_nvda_updates_mjul8_tsla_updates_mjul8_mu_updates_m
530.55492.767.74.936.531.80.720.6
The exact SQL behind every number
SELECT
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08')) / 1e6, 2) AS jul8_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-07')) / 1e6, 2) AS jul7_updates_m,
    round((countIf(toDate(sip_timestamp) = toDate('2026-07-08')) / countIf(toDate(sip_timestamp) = toDate('2026-07-07')) - 1) * 100, 1) AS day_over_day_pct,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08') AND ticker = 'SPY') / 1e6, 2) AS jul8_spy_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08') AND ticker = 'QQQ') / 1e6, 2) AS jul8_qqq_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08') AND ticker = 'NVDA') / 1e6, 2) AS jul8_nvda_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08') AND ticker = 'TSLA') / 1e6, 2) AS jul8_tsla_updates_m,
    round(countIf(toDate(sip_timestamp) = toDate('2026-07-08') AND ticker = 'MU') / 1e6, 2) AS jul8_mu_updates_m
FROM global_markets.cache_stocks_quotes
WHERE sip_timestamp >= '2026-07-07 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00'
Run this yourself

The stock-quote tape carried 530.55M NBBO updates on July 8, +7.7% vs the prior session. QQQ's 6.53M updates led the named tickers, ahead of SPY's 4.93M. NVDA (1.8M), TSLA (0.72M), and MU (0.6M) round out the named counts.

QuerySPY / QQQ / NVDA / TSLA / MU / SNDK / AVGO: RTH median quoted spread in basis points
tickermedian_spread_bps
SPY0.27
QQQ0.71
NVDA1.52
TSLA2.28
AVGO3.63
MU5.66
SNDK12.21
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-08 13:30:00' AND sip_timestamp < '2026-07-08 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
Run this yourself

Across the seven named tickers, the SPY RTH median quoted spread was 0.27 bps, at the floor of ordinary for the most-liquid US ETF. QQQ quoted at 0.71 bps, NVDA at 1.52 bps. The wider tail of the table belongs to the names with thinner quoting: MU at 5.66 bps and SNDK at 12.21 bps.

QuerySPY's RTH average quoted spread in trailing-month context
jul8_avg_spread_centstightness_ranksessions_comparedtightest_session_centswidest_session_centsfirst_sessiondropped_invalid_quotes
2.20211221.8092.8652026-06-0542783
The exact SQL behind every number
SELECT
    round(anyIf(avg_spread_cents, d = toDate('2026-07-08')), 3) AS jul8_avg_spread_cents,
    arrayCount(x -> x < anyIf(avg_spread_cents, d = toDate('2026-07-08')), groupArrayIf(avg_spread_cents, d != toDate('2026-07-08'))) + 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,
    sum(dropped_invalid) AS dropped_invalid_quotes
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,
           countIf(NOT (bid_price > 0 AND ask_price >= bid_price)) AS dropped_invalid
    FROM global_markets.cache_stocks_quotes
    WHERE ticker = 'SPY'
      AND sip_timestamp >= toDateTime('2026-06-05 00:00:00')
      AND sip_timestamp < toDateTime('2026-07-09 00:00:00')
      AND (toHour(sip_timestamp) * 60 + toMinute(sip_timestamp)) BETWEEN 810 AND 1199
    GROUP BY d
)
Run this yourself

SPY's RTH average quoted spread of 2.202 cents ranked 11 of 22 trailing sessions, a mid-pack day for spread tightness, with the trailing-month range running from 1.809 cents (the tightest) to 2.865 cents (the widest). No air pocket, no liquidity event, an ordinary session for SPY's quoted spread.

QueryOptions NBBO tape: total updates vs the stock tape, plus the SPY root slice
jul8_options_bnoptions_to_stock_ratiojul8_spy_options_m
9.6218.1422
The exact SQL behind every number
WITH
    (SELECT count() FROM global_markets.cache_options_quotes WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00') AS jul8_options_rows,
    (SELECT count() FROM global_markets.cache_stocks_quotes WHERE sip_timestamp >= '2026-07-08 00:00:00' AND sip_timestamp < '2026-07-09 00:00:00') AS jul8_stock_quote_rows
SELECT
    round(jul8_options_rows / 1e9, 2) AS jul8_options_bn,
    round(jul8_options_rows / jul8_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-08 13:30:00' AND sip_timestamp < '2026-07-08 20:00:00') / 1e6, 0) AS jul8_spy_options_m
Run this yourself

The options tape carried 9.62 billion NBBO updates, 18.1× the stock-quote tape's count. The SPY-options slice alone ran 422 million updates during regular hours.

Rates: the curve barely moved

QueryTreasury yields: July 8 vs July 7, populated maturities + 2s10s
curve_pointjul8_yield_pctsession_change_bp
1 month3.67-2
3 month3.871
1 year4.060
2 year4.212
5 year4.314
10 year4.561
30 year5.061
2s10s spread0.35-1
The exact SQL behind every number
SELECT
    t.1 AS curve_point,
    round(t.2, 2) AS jul8_yield_pct,
    round((t.2 - t.3) * 100) AS session_change_bp
FROM (
    SELECT arrayJoin([
        ('1 month',  toFloat64(d.yield_1_month),  toFloat64(p.yield_1_month)),
        ('3 month',  toFloat64(d.yield_3_month),  toFloat64(p.yield_3_month)),
        ('1 year',   toFloat64(d.yield_1_year),   toFloat64(p.yield_1_year)),
        ('2 year',   toFloat64(d.yield_2_year),   toFloat64(p.yield_2_year)),
        ('5 year',   toFloat64(d.yield_5_year),   toFloat64(p.yield_5_year)),
        ('10 year',  toFloat64(d.yield_10_year),  toFloat64(p.yield_10_year)),
        ('30 year',  toFloat64(d.yield_30_year),  toFloat64(p.yield_30_year)),
        ('2s10s spread', toFloat64(d.yield_10_year - d.yield_2_year), toFloat64(p.yield_10_year - p.yield_2_year))
    ]) AS t
    FROM (SELECT * FROM global_markets.treasury_yields WHERE date = '2026-07-08') AS d,
         (SELECT * FROM global_markets.treasury_yields WHERE date = '2026-07-07') AS p
)
Run this yourself

The 5-year led the session's moves at +4 bp; the 2-year ended +2 bp higher, and no other maturity moved more than 2 bp in either direction. That left the 2s10s spread at 0.35% (-1 bp on the session), within its recent range. The muted rates move sat alongside the muted index move.

The calendar behind the day

QueryEx-divs, splits, SEC filings, news attention
ex_dividend_recordssplits_executedreverse_splitsforward_splitsfil_424b2fil_form4fil_8kfil_totalnews_articlesnews_publisherstop_news_tickertop_news_ntop_news_lead_over_next
8110152777516337311923MU170
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-08'
    ) 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-08'
            )
            WHERE t != 'SPCX'
            GROUP BY t
        )
    ) AS top_news
SELECT
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-07-08') AS ex_dividend_records,
    (SELECT count() FROM global_markets.stocks_splits WHERE execution_date = '2026-07-08') AS splits_executed,
    (SELECT countIf(toFloat64(split_from) > toFloat64(split_to)) FROM global_markets.stocks_splits WHERE execution_date = '2026-07-08') AS reverse_splits,
    (SELECT countIf(toFloat64(split_to) > toFloat64(split_from)) FROM global_markets.stocks_splits WHERE execution_date = '2026-07-08') AS forward_splits,
    (SELECT countIf(form_type = '424B2') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-08') AS fil_424b2,
    (SELECT countIf(form_type = '4') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-08') AS fil_form4,
    (SELECT countIf(form_type = '8-K') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-08') AS fil_8k,
    (SELECT count() FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-08') 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
Run this yourself

The calendar was light on the day: 81 ex-dividend records, 1 forward split executed, and 3731 SEC filings overall (with 775 Form 4 insider trades, 527 424B2 prospectuses, and 163 8-K current reports). News coverage carried 192 articles across 3 publishers, with MU among the most-mentioned tickers at 17 articles. No household-name corporate action stood out in the day's flow, the tape's narrative was the chip complex itself.

The session, verified

QuerySession verification: first/last SPY bar ET, regular-bar count, holiday receipts, next closure
first_spy_bar_etlast_spy_bar_etspy_minute_barsregular_session_barsday_sessionsjul8_holiday_rowsnext_closure_datenext_closure_name
04:0019:59919390102026-09-07Labor Day
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-08 13:30:00' AND window_start < '2026-07-08 20:00:00') AS regular_session_bars,
    uniqExactIf(toDate(toTimeZone(window_start, 'America/New_York')), window_start >= '2026-07-08 13:30:00' AND window_start < '2026-07-08 20:00:00') AS day_sessions,
    (SELECT count() FROM global_markets.stocks_market_holidays WHERE date = '2026-07-08') AS jul8_holiday_rows,
    (SELECT toString(min(date)) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-08' AND status = 'closed') AS next_closure_date,
    (SELECT argMin(name, date) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-08' AND status = 'closed') AS next_closure_name
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-08 00:00:00' AND window_start < '2026-07-09 00:00:00'
Run this yourself

The session ran a full extended-hours window, first SPY bar at 04:00 ET, last at 19:59 ET, with 390 regular-hours minute bars and 1 trading session in the window (no half-day; the holiday table has no 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 8, 2026 are filtered as sip_timestamp / window_start between 2026-07-08 13:30:00 and 2026-07-08 20:00:00, which corresponds to 9:30 am–4:00 pm New York time. Decimal prices are cast to Float64 before any division. Named per-ticker panels (scoreboard, chip complex, rotation) are ordered alphabetically by ticker so each prose reference points at a fixed row; leaderboards (volume, quote snapshot) are value-ordered, and every positional claim they make is encoded as a sanity bound on that position. Every Tuesday comparison on this page, breadth share, chip green/red counts, options contracts and 0DTE share, quote-update counts, is computed fresh from July 7 (and July 6 where a prior close is needed) in the same query block, never quoted from an earlier post.

Full data notes

The breadth panel counts names with a regular-hours close on both sessions and at least $1M traded on the measured day; the dropped count (5284 of 11439) makes the excluded tail visible. The chip complex's day_low/day_high timing columns use the argMin/argMaxIf(..., (value, timestamp)) pattern so ties resolve deterministically. The volume-smile bucket labels are ET (%H:%i), computed with toTimeZone in the SELECT list only. The options-tape panel detects same-day expiry with the OCC-ticker substring match (substring(ticker, length(ticker) - 14, 6)) rather than options_trades.expiration_date (that column is broken, per the standing preflight note). Symbols in KNOWN_AMBIGUOUS_TICKERS are excluded in the volume-leaders and news-attention SQL so "most X" callouts fall through to verifiable names. The top-news ticker uses a deterministic tie-break (argMax(t, (n, t))); top_news_lead_over_next = 0 marks a tie, which is why the prose says "among the most-mentioned". The treasury panel joins two daily snapshot rows; a missing snapshot for either date yields zero rows and the row_count bound holds the post. The stocks-quote and options-quote counts are whole-tape scans over day partitions; named-ticker counts are reported in millions to match their column units. Spread medians use quantileExact (deterministic); the trailing spread panel is an average (avgIf), labeled as such.

Methodology

  • Market data source: consolidated tape, delayed_stocks_minute_aggs for index and per-name 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 clock labels are 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 (the session-verification panel), not calendar arithmetic.
  • Spread definition: (ask - bid) / midpoint × 10,000 in basis points on valid two-sided quotes for the snapshot; the trailing-month panel is an average width in cents, labeled as an average.
  • Prior-session comparisons: computed in-query from July 7 (and July 6 for Tuesday's own day-over-day), never carried over from a previous post.
  • Deterministic aggregates: quantileExact, tuple-keyed argMin/argMax, and a deterministic news tie-break for stable regenerations.
  • Warehouse as-of date: July 10, 2026 (T+2 for the period); both sessions' tapes are fully ingested at this depth.

Cross-links: July 7, 2026 recap, options trading costs, bid-ask spread basics, 0DTE options, and relative volume.