Market Recap: July 2, 2026, The Day in Numbers
Holiday-eve rotation: green breadth under a falling Nasdaq, tech last of the eleven sector funds, memory-rout day two, and the split that faked a crash.
Thursday, July 2, 2026, the last session before the Independence Day closure, was a rotation day wearing a selloff's headline. QQQ printed -1.71% while DIA rose 1.04%, and breadth was POSITIVE: 3398 liquid names rose against 2758, 54.6% of the tape green while the growth index fell. Eight of eleven sector funds closed higher; the selling sat in tech and the memory complex that broke the day before.
The scoreboard
| ticker | prior_close | day_open | day_close | pct_change | day_high | day_low | shares_traded_m |
|---|---|---|---|---|---|---|---|
| DIA | 522.41 | 525.49 | 527.83 | 1.04 | 528.26 | 523.73 | 3 |
| IWM | 299.31 | 300.54 | 297.53 | -0.59 | 302.23 | 294.98 | 18.5 |
| QQQ | 725.16 | 725.58 | 712.74 | -1.71 | 730.83 | 707.56 | 43.7 |
| SPY | 745.69 | 747.4 | 744.8 | -0.12 | 751.31 | 740.03 | 43.9 |
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-01 13:30:00' AND window_start < '2026-07-01 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-02 13:30:00' AND window_start < '2026-07-02 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_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 AS shares_traded_m
FROM sess s
JOIN prior p ON s.ticker = p.ticker
ORDER BY s.tickerDIA at 1.04% against QQQ at -1.71% is the day in one line, industrials and growth nearly three points of daily return apart. SPY split the difference at -0.12%; IWM closed -0.59%.
Was the day unusual?
Two lenses in one panel: SPY's open-to-close move and QQQ's close-over-close move, each ranked against the trailing month by absolute size (rank 1 = biggest).
| spy_open_to_close_pct | spy_abs_move_rank | spy_sessions_compared | qqq_close_over_close_pct | qqq_abs_move_rank | qqq_sessions_compared | first_session |
|---|---|---|---|---|---|---|
| -0.35 | 15 | 22 | -1.71 | 9 | 21 | 2026-06-02 |
The exact SQL behind every number
WITH per_day AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
(argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100 AS oc_pct,
argMax(toFloat64(close), window_start) AS rth_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'QQQ')
AND window_start >= toDateTime('2026-06-02 00:00:00')
AND window_start < toDateTime('2026-07-03 00:00:00')
AND (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199
GROUP BY ticker, d
),
with_prev AS (
SELECT ticker, d, oc_pct,
lagInFrame(rth_close) OVER (PARTITION BY ticker ORDER BY d) AS prev_close,
(rth_close / lagInFrame(rth_close) OVER (PARTITION BY ticker ORDER BY d) - 1) * 100 AS cc_pct
FROM per_day
)
SELECT
round(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-02')), 2) AS spy_open_to_close_pct,
arrayCount(x -> x > abs(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-07-02'))),
groupArrayIf(abs(oc_pct), ticker = 'SPY' AND d != toDate('2026-07-02'))) + 1 AS spy_abs_move_rank,
countIf(ticker = 'SPY') AS spy_sessions_compared,
round(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-02')), 2) AS qqq_close_over_close_pct,
arrayCount(x -> x > abs(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-07-02'))),
groupArrayIf(abs(cc_pct), ticker = 'QQQ' AND d != toDate('2026-07-02') AND isFinite(cc_pct) AND prev_close > 0)) + 1 AS qqq_abs_move_rank,
countIf(ticker = 'QQQ' AND isFinite(cc_pct) AND prev_close > 0) AS qqq_sessions_compared,
toString(minIf(d, ticker = 'SPY')) AS first_session
FROM with_prevAt the index level, no. SPY's -0.35% open-to-close ranks 15 of 22 trailing sessions, the bottom half. QQQ was louder but still not extreme: its -1.71% close-over-close ranks 9 of 21 sessions with a defined prior close, back to 2026-06-02, a mid-pack bad day for the growth index. The single-name tape is where July 2 was loud.
Breadth: green tape, red growth index
| advancers | decliners | unchanged | liquid_tickers | tickers_traded_both_sessions | dropped_by_liquidity_filter | advancer_pct | advancers_fmt | decliners_fmt | dropped_by_liquidity_filter_fmt | tickers_traded_both_sessions_fmt |
|---|---|---|---|---|---|---|---|---|---|---|
| 3398 | 2758 | 63 | 6219 | 11536 | 5317 | 54.6 | 3,398 | 2,758 | 5,317 | 11,536 |
The exact SQL behind every number
WITH per_ticker AS (
SELECT
ticker,
toFloat64(argMaxIf(close, window_start, window_start < '2026-07-02 00:00:00')) AS prior_close,
toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-02 00:00:00')) AS day_close,
sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-02 00:00:00') AS day_dollar_volume
FROM global_markets.delayed_stocks_minute_aggs
WHERE (window_start >= '2026-07-01 13:30:00' AND window_start < '2026-07-01 20:00:00')
OR (window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00')
GROUP BY ticker
)
SELECT
countIf(day_close > prior_close AND day_dollar_volume >= 1000000) AS advancers,
countIf(day_close < prior_close AND day_dollar_volume >= 1000000) AS decliners,
countIf(day_close = prior_close AND day_dollar_volume >= 1000000) AS unchanged,
countIf(day_dollar_volume >= 1000000) AS liquid_tickers,
count() AS tickers_traded_both_sessions,
count() - countIf(day_dollar_volume >= 1000000) AS dropped_by_liquidity_filter,
round(100.0 * countIf(day_close > prior_close AND day_dollar_volume >= 1000000)
/ countIf(day_dollar_volume >= 1000000), 1) AS advancer_pct,
reverse(arrayStringConcat(extractAll(reverse(toString(countIf(day_close > prior_close AND day_dollar_volume >= 1000000))), '[0-9]{1,3}'), ',')) AS advancers_fmt,
reverse(arrayStringConcat(extractAll(reverse(toString(countIf(day_close < prior_close AND day_dollar_volume >= 1000000))), '[0-9]{1,3}'), ',')) AS decliners_fmt,
reverse(arrayStringConcat(extractAll(reverse(toString(count() - countIf(day_dollar_volume >= 1000000))), '[0-9]{1,3}'), ',')) AS dropped_by_liquidity_filter_fmt,
reverse(arrayStringConcat(extractAll(reverse(toString(count())), '[0-9]{1,3}'), ',')) AS tickers_traded_both_sessions_fmt
FROM per_ticker
WHERE prior_close > 0 AND day_close > 03,398 advancers, 2,758 decliners, 63 unchanged, 54.6% of the liquid tape rose while QQQ fell. Cap-weighted indexes and equal-count breadth answered differently; days like this are why both get a panel. The filter drops 5,317 of 11,536 dual-session tickers under $1 million traded.
Sector by sector: where the green tape sat
Breadth counts names; it does not say which kind. The eleven SPDR sector funds cut the session by industry, and the gap between best and worst is the day's dispersion in one number.
| ticker | prior_close | day_close | pct_chg | pts_above_worst_sector | day_dollar_bn |
|---|---|---|---|---|---|
| XLB | 51 | 51.99 | 1.94 | 4.65 | 0.57 |
| XLC | 109.74 | 109.6 | -0.13 | 2.58 | 0.83 |
| XLE | 52.82 | 53.23 | 0.78 | 3.48 | 1.46 |
| XLF | 54.79 | 55.61 | 1.5 | 4.2 | 2.36 |
| XLI | 183.41 | 183.91 | 0.27 | 2.98 | 1.15 |
| XLK | 185.54 | 180.52 | -2.71 | 0 | 2.43 |
| XLP | 83.33 | 85 | 2 | 4.71 | 1.33 |
| XLRE | 44.18 | 44.69 | 1.15 | 3.86 | 0.22 |
| XLU | 44.76 | 45.76 | 2.23 | 4.94 | 1.05 |
| XLV | 159.57 | 163.77 | 2.63 | 5.34 | 2.01 |
| XLY | 118.07 | 117.11 | -0.81 | 1.89 | 1.2 |
The exact SQL behind every number
WITH per_etf AS (
SELECT
ticker,
toFloat64(argMaxIf(close, window_start, window_start < '2026-07-02 00:00:00')) AS prior_close,
toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-02 00:00:00')) AS day_close,
round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-02 00:00:00') / 1e9, 2) AS day_dollar_bn
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('XLB', 'XLC', 'XLE', 'XLF', 'XLI', 'XLK', 'XLP', 'XLRE', 'XLU', 'XLV', 'XLY')
AND ((window_start >= '2026-07-01 13:30:00' AND window_start < '2026-07-01 20:00:00')
OR (window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 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_close / prior_close - 1) * 100 - min((day_close / prior_close - 1) * 100) OVER (), 2) AS pts_above_worst_sector,
day_dollar_bn
FROM per_etf
ORDER BY tickerHealth care (XLV) topped the board at 2.63%, then utilities 2.23%, staples 2%, materials 1.94%. Technology (XLK) finished last at -2.71%, the only sector down more than a point; consumer discretionary (-0.81%) and communication services (-0.13%) were the other red funds, the remaining eight green. Best-to-worst dispersion: 5.34 percentage points. The DIA-up/QQQ-down split ran across the market, not just four megacaps, which is why a green advance-decline line under a falling Nasdaq is no contradiction.
The day's highlight: memory rout, day two
The complex that broke Wednesday fell harder Thursday, magnitude and co-movement, not cause.
| ticker | prior_close | day_close | pct_chg | day_high | day_high_et | day_low | day_low_et | range_pct | day_dollar_bn |
|---|---|---|---|---|---|---|---|---|---|
| MU | 1033.29 | 975.77 | -5.57 | 1064.64 | 10:03 | 950.28 | 15:26 | 12.03 | 51.4 |
| SNDK | 2035.07 | 1743.59 | -14.32 | 2052.54 | 09:35 | 1693 | 15:26 | 21.24 | 26.57 |
| STX | 915.25 | 820.25 | -10.38 | 923.06 | 09:53 | 795.66 | 14:23 | 16.01 | 4.74 |
| WDC | 598.37 | 538.99 | -9.92 | 609.46 | 09:35 | 525.84 | 13:59 | 15.9 | 4.31 |
The exact SQL behind every number
WITH per_name AS (
SELECT
ticker,
toFloat64(argMaxIf(close, window_start, window_start < '2026-07-02 00:00:00')) AS prior_close,
toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-02 00:00:00')) AS day_close,
maxIf(toFloat64(high), window_start >= '2026-07-02 00:00:00') AS day_high,
minIf(toFloat64(low), window_start >= '2026-07-02 00:00:00') AS day_low,
argMinIf(window_start, toFloat64(low), window_start >= '2026-07-02 00:00:00') AS low_bar,
argMaxIf(window_start, toFloat64(high), window_start >= '2026-07-02 00:00:00') AS high_bar,
round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-02 00:00:00') / 1e9, 2) AS day_dollar_bn
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('MU', 'SNDK', 'STX', 'WDC')
AND ((window_start >= '2026-07-01 13:30:00' AND window_start < '2026-07-01 20:00:00')
OR (window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 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, 2) AS day_high,
formatDateTime(toTimeZone(high_bar, 'America/New_York'), '%H:%i') AS day_high_et,
round(day_low, 2) AS day_low,
formatDateTime(toTimeZone(low_bar, 'America/New_York'), '%H:%i') AS day_low_et,
round((day_high / day_low - 1) * 100, 2) AS range_pct,
day_dollar_bn
FROM per_name
ORDER BY tickerSanDisk printed -14.32%, Seagate -10.38%, Western Digital -9.92%, MU -5.57%, on $51.4 billion of MU turnover, roughly one-and-a-half times SPY's. MU and SanDisk printed their lows late (15:26, 15:26 ET), Seagate and Western Digital earlier (14:23, 13:59). Context: Wednesday and the MU deep-dive.
The rotation's other half, in the megacaps:
| ticker | prior_close | day_close | pct_chg | day_high | day_high_et | day_low | day_low_et | range_pct | day_dollar_bn |
|---|---|---|---|---|---|---|---|---|---|
| AAPL | 294.25 | 308.22 | 4.75 | 309.42 | 15:57 | 293.68 | 09:30 | 5.36 | 18.36 |
| MSFT | 384.22 | 389.62 | 1.41 | 392.2 | 15:11 | 383.7 | 09:35 | 2.22 | 12.58 |
| NVDA | 197.58 | 194.51 | -1.55 | 200.06 | 10:03 | 192.35 | 13:40 | 4.01 | 21.18 |
| TSLA | 425.34 | 392.81 | -7.65 | 432.35 | 09:31 | 389.3 | 15:23 | 11.06 | 25.41 |
The exact SQL behind every number
WITH per_name AS (
SELECT
ticker,
toFloat64(argMaxIf(close, window_start, window_start < '2026-07-02 00:00:00')) AS prior_close,
toFloat64(argMaxIf(close, window_start, window_start >= '2026-07-02 00:00:00')) AS day_close,
maxIf(toFloat64(high), window_start >= '2026-07-02 00:00:00') AS day_high,
minIf(toFloat64(low), window_start >= '2026-07-02 00:00:00') AS day_low,
argMinIf(window_start, toFloat64(low), window_start >= '2026-07-02 00:00:00') AS low_bar,
argMaxIf(window_start, toFloat64(high), window_start >= '2026-07-02 00:00:00') AS high_bar,
round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-07-02 00:00:00') / 1e9, 2) AS day_dollar_bn
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'TSLA')
AND ((window_start >= '2026-07-01 13:30:00' AND window_start < '2026-07-01 20:00:00')
OR (window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 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, 2) AS day_high,
formatDateTime(toTimeZone(high_bar, 'America/New_York'), '%H:%i') AS day_high_et,
round(day_low, 2) AS day_low,
formatDateTime(toTimeZone(low_bar, 'America/New_York'), '%H:%i') AS day_low_et,
round((day_high / day_low - 1) * 100, 2) AS range_pct,
day_dollar_bn
FROM per_name
ORDER BY tickerAAPL rose 4.75% in a one-way line, low at 09:30 ET, high at 15:57, three minutes before the close, while TSLA ran the mirror image at -7.65%. MSFT added 1.41%; NVDA closed -1.55%. Same index, opposite days.
Where the money traded
| ticker | leaderboard | dollar_volume_bn | dollar_value_m | shares_m | pct_of_board_leader |
|---|---|---|---|---|---|
| MU | by dollars traded | 51.4 | None | 51.9 | 100 |
| SPY | by dollars traded | 32.7 | None | 43.9 | 63.6 |
| QQQ | by dollars traded | 31.3 | None | 43.7 | 60.9 |
| SNDK | by dollars traded | 26.57 | None | 14.6 | 51.7 |
| TSLA | by dollars traded | 25.41 | None | 63.6 | 49.4 |
| NVDA | by dollars traded | 21.18 | None | 108.6 | 41.2 |
| SOXS | by shares traded | 3.24 | None | 748.2 | 100 |
| TZA | by shares traded | 1.27 | None | 325.7 | 43.5 |
| LIMN | by shares traded | 0.04 | 42 | 245.7 | 32.8 |
| BITO | by shares traded | 1.71 | None | 204.9 | 27.4 |
The exact SQL behind every number
SELECT ticker, leaderboard, dollar_volume_bn, if(dollar_volume_bn < 1, dollar_volume_m, NULL) AS dollar_value_m, shares_m,
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(close) * toFloat64(volume)) / 1e6, 0) AS dollar_volume_m,
round(sum(toFloat64(volume)) / 1e6, 1) AS shares_m
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 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(close) * toFloat64(volume)) / 1e6, 0) AS dollar_volume_m,
round(sum(toFloat64(volume)) / 1e6, 1) AS shares_m
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00'
AND ticker NOT IN ('SPCX')
GROUP BY ticker
ORDER BY shares_m DESC
LIMIT 4
)
ORDER BY leaderboard ASC, if(leaderboard = 'by dollars traded', dollar_volume_bn, shares_m) DESCMU's $51.4 billion led the tape for a fourth straight session (Monday, Tuesday, Wednesday) against SPY's $32.7 billion, and SanDisk's $26.57 billion put a second memory name in the top four. SOXS, the 3x-inverse semiconductor ETF, topped the share board at 748.2 million: cheap shares dominate a share count, expensive ones a dollar count, and relative volume compares either against a name's own norm. Basis: July 2 regular hours, one reused-symbol listing excluded (receipts).
| et_time | shares_bn | pct_of_biggest_bucket |
|---|---|---|
| 09:30 | 2.13 | 60.5 |
| 10:00 | 1.64 | 46.4 |
| 10:30 | 1.64 | 46.5 |
| 11:00 | 1.41 | 40 |
| 11:30 | 1.05 | 29.7 |
| 12:00 | 1.03 | 29.2 |
| 12:30 | 0.96 | 27.3 |
| 13:00 | 0.87 | 24.7 |
| 13:30 | 0.85 | 24.2 |
| 14:00 | 0.89 | 25.3 |
| 14:30 | 0.81 | 23.1 |
| 15:00 | 1.05 | 29.8 |
| 15:30 | 3.53 | 100 |
The exact SQL behind every number
SELECT
et_time,
round(sum(shares) / 1e9, 2) AS shares_bn,
round(100 * sum(shares) / max(sum(shares)) OVER (), 1) AS pct_of_biggest_bucket
FROM
(
SELECT
formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE), '%H:%i') AS et_time,
toFloat64(volume) AS shares
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00'
UNION ALL
SELECT
'15:30' AS et_time,
toFloat64(size) AS shares
FROM global_markets.stocks_trades
WHERE sip_timestamp >= '2026-07-02 20:00:00' AND sip_timestamp < '2026-07-02 20:15:00'
AND has(conditions, 8)
)
GROUP BY et_time
ORDER BY et_time2.13 billion shares in the opening half hour, a 0.81 billion trough at 14:30, 3.53 billion into the holiday-eve close, the final bucket the day's biggest, as the closing auction pulls resting orders into one print.
The options tape: the shifted weekly lands
| option_prints_m | contracts_m | call_pct_of_volume | same_day_expiry_pct | thu_jul2_expiry_contracts_m | fri_jul3_expiry_prints | jul10_weekly_contracts_m | jul17_monthly_contracts_m | spy_contracts_m | qqq_contracts_m | top_contract_underlying | top_contract_strike | top_contract_type | top_contract_expiry | top_contract_volume | top_contract_volume_fmt | top_contract_avg_price | top_strike_minus_spy_close | spy_close_minus_strike |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13.15 | 80.96 | 58.4 | 47.4 | 38.38 | 0 | 9.64 | 8.82 | 13.96 | 8.5 | SPY | 740 | P | 2026-07-02 | 540403 | 540,403 | 0.499 | -4.8 | 4.8 |
The exact SQL behind every number
WITH
(
SELECT (any(underlying_symbol), any(toFloat64(strike_price)), any(option_type),
any(toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6)))),
sum(size), count(), round(avg(toFloat64(price)), 3))
FROM global_markets.options_trades
WHERE sip_timestamp >= '2026-07-02 00:00:00' AND sip_timestamp < '2026-07-03 00:00:00'
GROUP BY ticker
ORDER BY sum(size) DESC
LIMIT 1
) AS top_contract,
(
SELECT round(toFloat64(argMax(close, window_start)), 2)
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00'
) AS spy_regular_close
SELECT
round(count() / 1e6, 2) AS option_prints_m,
round(toFloat64(sum(size)) / 1e6, 2) AS 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) = '260702') / sum(size), 1) AS same_day_expiry_pct,
round(toFloat64(sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260702')) / 1e6, 2) AS thu_jul2_expiry_contracts_m,
countIf(substring(ticker, length(ticker) - 14, 6) = '260703') AS fri_jul3_expiry_prints,
round(toFloat64(sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260710')) / 1e6, 2) AS jul10_weekly_contracts_m,
round(toFloat64(sumIf(size, substring(ticker, length(ticker) - 14, 6) = '260717')) / 1e6, 2) AS jul17_monthly_contracts_m,
round(toFloat64(sumIf(size, underlying_symbol = 'SPY')) / 1e6, 2) AS spy_contracts_m,
round(toFloat64(sumIf(size, underlying_symbol = 'QQQ')) / 1e6, 2) AS qqq_contracts_m,
top_contract.1 AS top_contract_underlying,
top_contract.2 AS top_contract_strike,
top_contract.3 AS top_contract_type,
top_contract.4 AS top_contract_expiry,
top_contract.5 AS top_contract_volume,
reverse(arrayStringConcat(extractAll(reverse(toString(assumeNotNull(top_contract.5))), '[0-9]{1,3}'), ',')) AS top_contract_volume_fmt,
round(top_contract.7, 3) AS top_contract_avg_price,
round(top_contract.2 - spy_regular_close, 2) AS top_strike_minus_spy_close,
round(spy_regular_close - top_contract.2, 2) AS spy_close_minus_strike
FROM global_markets.options_trades
WHERE sip_timestamp >= '2026-07-02 00:00:00' AND sip_timestamp < '2026-07-03 00:00:00'Options traded 80.96 million contracts across 13.15 million prints, and 47.4% of that volume expired the same Thursday. No contract with a July 3 expiration code printed all day (0 prints), so Thursday carried the daily expiry and the week's shifted weekly at once. The busiest contract was the same-day SPY $740 put, 540,403 contracts at an average $0.499 premium, SPY closing 4.8 dollars above the strike: out of the money, and a put atop a board where Tuesday and Wednesday had calls. Calls still took 58.4% of volume; the next weekly drew 9.64 million contracts, the July monthly 8.82 million (expiry mechanics).
The quote tape: what it cost to trade
Prices say what happened; quotes say what it cost. The bid-ask spread is the toll on every round trip, in basis points of the mid-price (a basis point is a hundredth of a percent). We measure it every session, ordinary or not, which is what makes "spreads blew out" a falsifiable claim.
| jul2_updates_m | jul1_updates_m | day_over_day_pct | jul2_spy_updates_m | jul2_qqq_updates_m | jul2_mu_updates_m |
|---|---|---|---|---|---|
| 597.22 | 449.15 | 33 | 5.42 | 7.56 | 1.01 |
The exact SQL behind every number
SELECT
round(countIf(toDate(sip_timestamp) = toDate('2026-07-02')) / 1e6, 2) AS jul2_updates_m,
round(countIf(toDate(sip_timestamp) = toDate('2026-07-01')) / 1e6, 2) AS jul1_updates_m,
round((countIf(toDate(sip_timestamp) = toDate('2026-07-02')) / countIf(toDate(sip_timestamp) = toDate('2026-07-01')) - 1) * 100, 1) AS day_over_day_pct,
round(countIf(toDate(sip_timestamp) = toDate('2026-07-02') AND ticker = 'SPY') / 1e6, 2) AS jul2_spy_updates_m,
round(countIf(toDate(sip_timestamp) = toDate('2026-07-02') AND ticker = 'QQQ') / 1e6, 2) AS jul2_qqq_updates_m,
round(countIf(toDate(sip_timestamp) = toDate('2026-07-02') AND ticker = 'MU') / 1e6, 2) AS jul2_mu_updates_m
FROM global_markets.cache_stocks_quotes
WHERE sip_timestamp >= '2026-07-01 00:00:00' AND sip_timestamp < '2026-07-03 00:00:00'The national best bid and offer, the top of the consolidated book, was rewritten 597.22 million times on July 2 against 449.15 million on July 1: a 33% jump into the closure. QQQ took 7.56 million, above SPY's 5.42 million; MU 1.01 million.
| ticker | median_spread_bps | median_spread_cents | times_the_spy_spread | rth_updates_m | invalid_quotes_dropped |
|---|---|---|---|---|---|
| SPY | 0.27 | 2 | 1 | 4.98 | 19064 |
| QQQ | 0.83 | 6 | 3.1 | 6.03 | 5934 |
| NVDA | 1.03 | 2 | 3.8 | 2.55 | 20398 |
| AAPL | 1.62 | 5 | 6 | 1.91 | 5193 |
| TSLA | 2.29 | 9 | 8.5 | 0.85 | 2699 |
| MU | 5.52 | 55 | 20.4 | 0.92 | 2442 |
| SNDK | 10.4 | 189 | 38.5 | 0.26 | 163 |
| WDC | 10.79 | 60 | 40 | 0.14 | 83 |
The exact SQL behind every number
SELECT
ticker,
round(med_bps, 2) AS median_spread_bps,
round(med_dollars * 100, 1) AS median_spread_cents,
round(med_bps / min(med_bps) OVER (), 1) AS times_the_spy_spread,
round(quote_updates / 1e6, 2) AS rth_updates_m,
invalid_quotes_dropped
FROM (
SELECT
ticker,
quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000,
toFloat64(bid_price) > 0 AND toFloat64(ask_price) > toFloat64(bid_price)) AS med_bps,
quantileExactIf(0.5)(toFloat64(ask_price) - toFloat64(bid_price),
toFloat64(bid_price) > 0 AND toFloat64(ask_price) > toFloat64(bid_price)) AS med_dollars,
count() AS quote_updates,
countIf(NOT (toFloat64(bid_price) > 0 AND toFloat64(ask_price) > toFloat64(bid_price))) AS invalid_quotes_dropped
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('SPY', 'QQQ', 'AAPL', 'TSLA', 'NVDA', 'MU', 'SNDK', 'WDC')
AND sip_timestamp >= '2026-07-02 13:30:00' AND sip_timestamp < '2026-07-02 20:00:00'
GROUP BY ticker
)
ORDER BY median_spread_bps ASCSPY quoted a median 0.27 basis points wide: about 2 cents on a $744.8 ETF. QQQ came in at 0.83 bps, NVDA 1.03. The names doing the falling were the expensive ones to trade: MU 5.52 bps, SanDisk 10.4, Western Digital 10.79, 40x SPY's spread. Crossing a basket of memory names cost multiples of crossing the index, before any price impact. Invalid quotes (one-sided, crossed) are counted per name, not hidden.
| jul2_median_spread_bps | trailing_median_bps | jul2_minus_trailing_bps | wider_rank | sessions_compared | widest_session_bps |
|---|---|---|---|---|---|
| 0.27 | 0.27 | 0 | 11 | 22 | 0.409 |
The exact SQL behind every number
WITH per_day AS (
SELECT toDate(sip_timestamp) AS d,
quantileExact(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000) AS med_bps
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'SPY'
AND sip_timestamp >= '2026-06-02 00:00:00' AND sip_timestamp < '2026-07-03 00:00:00'
AND (toHour(sip_timestamp) * 60 + toMinute(sip_timestamp)) BETWEEN 810 AND 1199
AND toFloat64(bid_price) > 0 AND toFloat64(ask_price) > toFloat64(bid_price)
GROUP BY d
)
SELECT
round(anyIf(med_bps, d = toDate('2026-07-02')), 3) AS jul2_median_spread_bps,
round(quantileExact(0.5)(med_bps), 3) AS trailing_median_bps,
round(anyIf(med_bps, d = toDate('2026-07-02')) - quantileExact(0.5)(med_bps), 3) AS jul2_minus_trailing_bps,
arrayCount(x -> x > anyIf(med_bps, d = toDate('2026-07-02')), groupArrayIf(med_bps, d != toDate('2026-07-02'))) + 1 AS wider_rank,
count() AS sessions_compared,
round(max(med_bps), 3) AS widest_session_bps
FROM per_dayAn ordinary day for liquidity, and that is the finding: SPY's median spread of 0.27 bps sits 0 bps from the trailing month's median (0.27 bps), ranking 11 of 22 sessions by wideness, nowhere near the month's widest at 0.409 bps. A concentrated rout under a green tape did not stress the plumbing.
Rates: the July 2 print, landed
| jul2_rows | jul1_rows |
|---|---|
| 1 | 1 |
The exact SQL behind every number
SELECT
(SELECT count() FROM global_markets.treasury_yields WHERE date = '2026-07-02') AS jul2_rows,
(SELECT count() FROM global_markets.treasury_yields WHERE date = '2026-07-01') AS jul1_rowsThe treasury feed runs a day or two behind the tape: at first publication the July 2 close had zero rows on file, and this page said so instead of guessing. The print has since landed, 1 row for July 2, 1 for July 1, so the panel below carries the session's own curve.
| curve_point | jul2_yield_pct | one_day_change_bp |
|---|---|---|
| 1 month | 3.7 | 3 |
| 3 month | 3.82 | -3 |
| 1 year | 3.96 | -4 |
| 2 year | 4.14 | -3 |
| 5 year | 4.23 | -1 |
| 10 year | 4.49 | 1 |
| 30 year | 4.98 | 1 |
| 2s10s spread | 0.35 | 4 |
The exact SQL behind every number
SELECT
t.1 AS curve_point,
round(t.2, 2) AS jul2_yield_pct,
round((t.2 - t.3) * 100) AS one_day_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-02') AS d,
(SELECT * FROM global_markets.treasury_yields WHERE date = '2026-07-01') AS p
)At the close the 10-year sat at 4.49%, the 2s10s spread at 0.35 points.
The calendar behind the day
| ex_dividend_records | splits_executed | forward_splits | reverse_splits | split_records | ipos_listed | sec_filings | insider_form4_filings | filings_8k | ipo_names | news_articles | news_publishers | most_covered_ticker | most_covered_articles | crwd_split_from | crwd_split_to | crwd_prev_close | crwd_day_close | crwd_dollar_m | split_names_with_bars |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 322 | 8 | 5 | 3 | CRWD 4-for-1; FBIP 4-for-1; FNCSF 110-for-100; GMEX 1-for-9; GTCDF 1-for-5; SMTOY 8-for-1; UBYH 1-for-10; VLNT 10-for-1 | 2 | 5203 | 2109 | 258 | MIACU — Meridian3 Industrials Acquisition Corp.; VIIU — Viking Acquisition Corp. II | 201 | 3 | NVDA | 18 | 1 | 4 | 772.45 | 193.67 | 1473.51 | 2 |
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-02'
) AS news,
(
SELECT (argMax(t, n), max(n))
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-02'
)
WHERE t != 'SPCX'
GROUP BY t
)
) AS top_news,
(
SELECT (count(), countIf(split_to > split_from), countIf(split_to < split_from),
arrayStringConcat(groupArray(concat(ticker, ' ', toString(split_to), '-for-', toString(split_from))), '; '))
FROM global_markets.stocks_splits
WHERE execution_date = '2026-07-02' AND ticker NOT IN ('SPCX')
) AS splits
SELECT
(SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-07-02') AS ex_dividend_records,
splits.1 AS splits_executed,
splits.2 AS forward_splits,
splits.3 AS reverse_splits,
splits.4 AS split_records,
(SELECT count() FROM global_markets.stocks_ipos WHERE listing_date = '2026-07-02') AS ipos_listed,
(SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-02') AS sec_filings,
(SELECT uniqExactIf(accession_number, form_type = '4') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-02') AS insider_form4_filings,
(SELECT uniqExactIf(accession_number, form_type = '8-K') FROM global_markets.stocks_sec_edgar_index WHERE filing_date = '2026-07-02') AS filings_8k,
(SELECT arrayStringConcat(groupArray(concat(ticker, ' — ', issuer_name)), '; ') FROM (
SELECT ticker, issuer_name FROM global_markets.stocks_ipos WHERE listing_date = '2026-07-02' ORDER BY ticker
)) AS ipo_names,
news.1 AS news_articles,
news.2 AS news_publishers,
top_news.1 AS most_covered_ticker,
top_news.2 AS most_covered_articles,
(SELECT any(split_from) FROM global_markets.stocks_splits WHERE ticker = 'CRWD' AND execution_date = '2026-07-02') AS crwd_split_from,
(SELECT any(split_to) FROM global_markets.stocks_splits WHERE ticker = 'CRWD' AND execution_date = '2026-07-02') AS crwd_split_to,
(SELECT round(toFloat64(argMax(close, window_start)), 2) FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'CRWD' AND window_start >= '2026-07-01 13:30:00' AND window_start < '2026-07-01 20:00:00') AS crwd_prev_close,
(SELECT round(toFloat64(argMax(close, window_start)), 2) FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'CRWD' AND window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00') AS crwd_day_close,
(SELECT round(sum(toFloat64(close) * toFloat64(volume)) / 1e6, 2) FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'CRWD' AND window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00') AS crwd_dollar_m,
(SELECT count() FROM (
SELECT ticker FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN (SELECT ticker FROM global_markets.stocks_splits WHERE execution_date = '2026-07-02')
AND window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00'
GROUP BY ticker
)) AS split_names_with_bars322 dividend records went ex-dividend, 2 new listings arrived (MIACU — Meridian3 Industrials Acquisition Corp.; VIIU — Viking Acquisition Corp. II), and the SEC index logged 5203 filings into the holiday, 2109 Form 4s, 258 8-Ks. The news feed carried 201 articles from 3 publishers (NVDA most-covered, 18 of them).
The splits trap anyone reading raw closes. CRWD ran a 4-for-1 forward split, so the unadjusted tape shows $772.45 on Wednesday and $193.67 on Thursday, a fake decline that is really four new shares for each old one. It was not alone: 8 split records executed, 5 forward and 3 reverse (the split_records column lists them), and a reverse split fakes the opposite artifact, a raw price that leaps overnight. Only 2 of those names traded on our tape; CRWD's $1473.51 million of turnover is the one big enough to contaminate a screen, and every mover screen here excludes it.
On deck
Calendar fact, not forecast, what the tables held about the next sessions.
| jul6_spy_regular_bars | exdiv_records_jul6 | household_exdivs_jul6 | splits_jul6 | next_scheduled_closure | next_closure_name | next_closure_status | latest_si_settlement | si_settlement_age_days |
|---|---|---|---|---|---|---|---|---|
| 390 | 119 | JPM | 15 | 2026-09-07 | Labor Day | closed | 2026-06-30 | 2 |
The exact SQL behind every number
SELECT
(SELECT count() FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-06 13:30:00' AND window_start < '2026-07-06 20:00:00') AS jul6_spy_regular_bars,
(SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-07-06') AS exdiv_records_jul6,
(SELECT arrayStringConcat(groupArray(ticker), ', ') FROM global_markets.stocks_dividends
WHERE ex_dividend_date = '2026-07-06'
AND ticker IN ('AAPL', 'MSFT', 'JPM', 'JNJ', 'XOM', 'KO', 'PG', 'WMT', 'CVX', 'HD')) AS household_exdivs_jul6,
(SELECT count() FROM global_markets.stocks_splits WHERE execution_date = '2026-07-06') AS splits_jul6,
(SELECT toString(min(date)) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-02') AS next_scheduled_closure,
(SELECT any(name) FROM global_markets.stocks_market_holidays
WHERE date = (SELECT min(date) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-02')) AS next_closure_name,
(SELECT any(status) FROM global_markets.stocks_market_holidays
WHERE date = (SELECT min(date) FROM global_markets.stocks_market_holidays WHERE date > '2026-07-02')) AS next_closure_status,
(SELECT toString(max(settlement_date)) FROM global_markets.stocks_short_interest
WHERE settlement_date <= '2026-07-02') AS latest_si_settlement,
(SELECT dateDiff('day', max(settlement_date), toDate('2026-07-02')) FROM global_markets.stocks_short_interest
WHERE settlement_date <= '2026-07-02') AS si_settlement_age_daysMonday July 6 reopened with a full 390-bar session, verified from its own bars. It carried 119 ex-dividend records, one household name among the ten we probe (JPM), and 15 split executions. Next scheduled closure: Labor Day, 2026-09-07 (closed). Short interest was old news, as always, newest settlement on file 2026-06-30, 2 days back, publication trailing settlement by about two weeks (why).
The session, verified, and the Friday that wasn't
| first_spy_bar_et | last_spy_bar_et | spy_minute_bars | regular_session_bars | day_sessions | jul3_spy_bars |
|---|---|---|---|---|---|
| 04:00 | 19:59 | 886 | 390 | 1 | 0 |
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-02 13:30:00' AND window_start < '2026-07-02 20:00:00') AS regular_session_bars,
uniqExactIf(toDate(toTimeZone(window_start, 'America/New_York')), window_start >= '2026-07-02 13:30:00' AND window_start < '2026-07-02 20:00:00') AS day_sessions,
(SELECT count() FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-03 00:00:00' AND window_start < '2026-07-04 00:00:00') AS jul3_spy_bars
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-07-02 00:00:00' AND window_start < '2026-07-03 00:00:00'July 2 was a full session, not an early close: SPY's bars run 04:00 to 19:59 New York time (pre-market and after-hours bars included), with exactly 390 regular-window bars. Friday July 3 printed 0 SPY bars, a full closure for Independence Day, July 4 falling on a Saturday. The four-session week: the week recap.
FAQ
Why did the Dow rise while the Nasdaq fell on July 2, 2026?
The two indexes hold different companies: DIA closed 1.04%, QQQ -1.71%. The sector board carries the same split, health care, utilities and staples on top, technology last at -2.71%, a 5.34-point gap best to worst.
Was the stock market open the Friday of Independence Day week?
No. Independence Day fell on a Saturday, and the exchanges observed it with a full Friday closure the day after this session: our tape shows 0 SPY minute bars for it.
What does a forward stock split do to the share price?
It multiplies the share count by four and divides the price by four; the position's value is unchanged. CRWD, July 2: an unadjusted $772.45 close on Wednesday, $193.67 on Thursday, a fake decline on any screener that skips the split.
How wide were bid-ask spreads on July 2, 2026?
SPY's median quoted spread was 0.27 basis points of the mid-price in regular hours, 11 of 22 trailing sessions by wideness, an ordinary day. Single names ran wider: MU 5.52 bps, WDC 10.79.
Data notes
- Dollar volume is a per-minute proxy, close × volume, summed per bar.
- The volume panel's closing half hour counts the closing auction prints. The one-minute bars leave every auction print out, so the half-hour panel adds each trade carrying the closing-print sale condition, stamped 4:00 to 4:15 p.m. ET on the consolidated tape, to its final bucket.
- The July 2 treasury print landed after first publication, the original note disclosed its absence with a row-count receipt; this revision carries the print, receipt shown.
- CRWD's raw close change is a split artifact, excluded from mover screens.
Full data notes
- The sector board is the eleven SPDR Select Sector funds (XLB, XLC, XLE, XLF, XLI, XLK, XLP, XLRE, XLU, XLV, XLY), a fixed, disclosed basket, not a vendor sector field.
- Quote-tape counts bucket by the UTC date of the SIP timestamp; a summer session falls inside one UTC day.
- One reused-symbol June listing is excluded from the leaderboards (receipts); forensic tick work lives in the deep-dives.
Methodology
- The period is one trading session (1 session, verified from observed bars). Timestamps are stored in UTC and converted to New York time inside the queries; "close" means the last regular-session minute bar, and day changes compare July 2 with July 1. The July 3 closure was verified from bars, never assumed.
- Spreads are quoted (ask minus bid) in basis points of the mid-price, median across regular-hours NBBO updates, on a deterministic quantile. Decimals are cast to floats before ratio arithmetic; option expiries are re-parsed from the OCC ticker. Every panel is read once, at authoring time, through the gated read-only path.
Chart, table, and SQL are one object. Paste any panel into the Strasmore terminal and make it your own. Previous session: July 1. The week: the four-session holiday week.