Strasmore Research
Market recaps wey dey break am down Matt ConnorBy Matt Connor · Updated 2026-07-25

Market Recap June 29 2026 — Di Day in Numbers

June 29, 2026 in numbers: growth-led index gain, four-point sector spread, memory-stock round trip, 0DTE tape, penny-tight quotes and rates movement.

Monday, June 29, 2026 na growth-led up day wey get narrow leadership band: QQQ gain 2.57%, SPY 1.62%, 3968 liquid names rise against 2327 decliners — but almost half of sector baskets close red. Every number dey read from stored query; expand any panel for di SQL. Di tick-by-tick layer of di same session: di June 29 microstructure deep dive.

Di scoreboard

Every change dey compare June 29 last regular-session minute bar with Friday June 26 one.

QuerySPY / QQQ / DIA / IWM — June 29 vs June 26 close, regular hours
The exact SQL behind every number
WITH friday AS (
    SELECT ticker, argMax(close, window_start) AS friday_close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ', 'DIA', 'IWM')
      AND window_start >= '2026-06-26 13:30:00' AND window_start < '2026-06-26 20:00:00'
    GROUP BY ticker
),
monday AS (
    SELECT ticker,
           argMin(open, window_start) AS monday_open,
           argMax(close, window_start) AS monday_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-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'
    GROUP BY ticker
)
SELECT
    m.ticker AS ticker,
    toFloat64(f.friday_close) AS jun26_close,
    toFloat64(m.monday_open) AS jun29_open,
    toFloat64(m.monday_close) AS jun29_close,
    round((toFloat64(m.monday_close) / toFloat64(f.friday_close) - 1) * 100, 2) AS pct_change,
    round(100 * (toFloat64(m.monday_close) / toFloat64(f.friday_close) - 1) / max(toFloat64(m.monday_close) / toFloat64(f.friday_close) - 1) OVER (), 1) AS pct_of_best_change,
    toFloat64(m.day_high) AS day_high,
    toFloat64(m.day_low) AS day_low,
    m.shares_traded_m AS shares_traded_m
FROM monday m
JOIN friday f ON m.ticker = f.ticker
ORDER BY m.ticker

SPY open at $736.525 against Friday $729.09 close and finish at $740.88, under im $741.56 high. QQQ +2.57% against DIA +0.81% show say na growth-and-tech day; small-cap IWM add 0.45%.

Was the day unusual?

A percentage move no mean anything if you no get something to measure am with. This panel dey rank June 29 against the one month wey don pass by how big the close-to-close move be.

QueryQQQ and SPY: June 29 rank for the trailing month of sessions (rank 1 = biggest absolute move)
The exact SQL behind every number
SELECT
    round(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-06-29')), 2) AS qqq_close_over_close_pct,
    arrayCount(x -> x > abs(anyIf(cc_pct, ticker = 'QQQ' AND d = toDate('2026-06-29'))), groupArrayIf(abs(cc_pct), ticker = 'QQQ' AND d != toDate('2026-06-29'))) + 1 AS qqq_abs_move_rank,
    countIf(ticker = 'QQQ') AS qqq_sessions_compared,
    round(max(if(ticker = 'QQQ', abs(cc_pct), 0)), 2) AS qqq_biggest_move_of_month_pct,
    countIf(ticker = 'QQQ' AND cc_pct > 0) AS qqq_up_sessions,
    round(anyIf(cc_pct, ticker = 'SPY' AND d = toDate('2026-06-29')), 2) AS spy_close_over_close_pct,
    arrayCount(x -> x > abs(anyIf(cc_pct, ticker = 'SPY' AND d = toDate('2026-06-29'))), groupArrayIf(abs(cc_pct), ticker = 'SPY' AND d != toDate('2026-06-29'))) + 1 AS spy_abs_move_rank,
    countIf(ticker = 'SPY') AS spy_sessions_compared,
    round(anyIf(oc_pct, ticker = 'SPY' AND d = toDate('2026-06-29')), 2) AS spy_open_to_close_pct,
    concat(monthName(min(d)), ' ', toString(toDayOfMonth(min(d))), ', ', toString(toYear(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-05-28 00:00:00')
          AND window_start < toDateTime('2026-06-30 00:00:00')
          AND (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199
        GROUP BY ticker, d
    )
)
WHERE isFinite(cc_pct)

Big, but no be record: QQQ 2.57% move dey rank 5 out of the 21 sessions since May 29, 2026, inside one month wey the biggest single move reach 4.76%; SPY 1.62% dey rank 4 out of 21. Where the move come from matter: SPY open-to-close grind na only 0.59%, so most of the gain come inside the overnight gap, before any regular-hours bar print. QQQ close higher for 10 out of those sessions: na coin-flip month.

Breadth: how wide was the rally?

An advancer na ticker wey im Monday close pass Friday own, among names wey dem trade at least $1 million — one filter wey drop 5,108 of 11,475 dual-session tickers.

QueryAdvancers vs decliners among tickers wey get at least $1M traded on June 29
The exact SQL behind every number
WITH per_ticker AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-06-27 00:00:00')) AS friday_close,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-06-29 00:00:00')) AS monday_close,
        sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-06-29 00:00:00') AS monday_dollar_volume
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE (window_start >= '2026-06-26 13:30:00' AND window_start < '2026-06-26 20:00:00')
       OR (window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00')
    GROUP BY ticker
)
SELECT
    countIf(monday_close > friday_close AND monday_dollar_volume >= 1000000) AS advancers,
    countIf(monday_close < friday_close AND monday_dollar_volume >= 1000000) AS decliners,
    countIf(monday_close = friday_close AND monday_dollar_volume >= 1000000) AS unchanged,
    countIf(monday_dollar_volume >= 1000000) AS liquid_tickers,
    count() AS tickers_traded_both_sessions,
    reverse(arrayStringConcat(extractAll(reverse(toString(count())), '[0-9]{1,3}'), ',')) AS tickers_traded_both_sessions_label,
    count() - countIf(monday_dollar_volume >= 1000000) AS dropped_by_liquidity_filter,
    reverse(arrayStringConcat(extractAll(reverse(toString(count() - countIf(monday_dollar_volume >= 1000000))), '[0-9]{1,3}'), ',')) AS dropped_by_liquidity_filter_label,
    round(100.0 * countIf(monday_close > friday_close AND monday_dollar_volume >= 1000000)
        / countIf(monday_dollar_volume >= 1000000), 1) AS advancer_pct
FROM per_ticker
WHERE friday_close > 0 AND monday_close > 0

3968 advancers, 2327 decliners, 72 unchanged: 62.3% of the liquid tape rise — dem count one name at a time, one wide day.

Sector by sector: di rally narrow pass wetin e look like

To count names equally na one view. To weight dem by company size na another one. Di eleven SPDR sector ETFs na di shortcut for di second one — one market-value-weighted basket per sector of di S&P 500. Dem no gree sharp-sharp with di breadth count.

QueryThe eleven sector baskets: June 29 vs June 26 close, regular hours
The exact SQL behind every number
WITH per_etf AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-06-27 00:00:00')) AS friday_close,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-06-29 00:00:00')) AS monday_close,
        maxIf(toFloat64(high), window_start >= '2026-06-29 00:00:00') AS day_high,
        minIf(toFloat64(low), window_start >= '2026-06-29 00:00:00') AS day_low,
        round(sumIf(toFloat64(close) * toFloat64(volume), window_start >= '2026-06-29 00:00:00') / 1e6, 0) AS dollar_volume_m
    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-06-26 13:30:00' AND window_start < '2026-06-26 20:00:00')
        OR (window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'))
    GROUP BY ticker
)
SELECT
    sector,
    ticker,
    round((monday_close / friday_close - 1) * 100, 2) AS pct_change,
    round((day_high / day_low - 1) * 100, 2) AS range_pct,
    dollar_volume_m,
    round((monday_close / friday_close - 1) * 100 - min((monday_close / friday_close - 1) * 100) OVER (), 2) AS pct_above_worst_sector
FROM (
    SELECT *,
        multiIf(ticker = 'XLB', 'Materials',
                ticker = 'XLC', 'Communication services',
                ticker = 'XLE', 'Energy',
                ticker = 'XLF', 'Financials',
                ticker = 'XLI', 'Industrials',
                ticker = 'XLK', 'Technology',
                ticker = 'XLP', 'Consumer staples',
                ticker = 'XLRE', 'Real estate',
                ticker = 'XLU', 'Utilities',
                ticker = 'XLV', 'Health care',
                'Consumer discretionary') AS sector
    FROM per_etf
)
ORDER BY pct_change DESC

Technology lead at 2.52%. Consumer discretionary follow at 2.37%. Materials close -1.82%. Real estate -0.64%. Di best minus di worst — di day sector dispersion — measure 4.34 percentage points. Utilities, staples, energy, real estate and materials all red for day wey di index rise. Wide by name count, narrow by weight: na dat be wetin index fund gain fit hide.

The day's highlight: memory and storage

Four names trade di same theme but di outcome no be di same — na co-movement and size wey we dey talk; di data no tell us why.

QueryMemory/storage names: change vs Friday close and intraday range
The exact SQL behind every number
WITH per_name AS (
    SELECT
        ticker,
        toFloat64(argMaxIf(close, window_start, window_start < '2026-06-27 00:00:00')) AS friday_close,
        toFloat64(argMaxIf(close, window_start, window_start >= '2026-06-29 00:00:00')) AS monday_close,
        maxIf(toFloat64(high), window_start >= '2026-06-29 00:00:00') AS day_high,
        minIf(toFloat64(low), window_start >= '2026-06-29 00:00:00') AS day_low,
        argMinIf(window_start, toFloat64(low), window_start >= '2026-06-29 00:00:00') AS low_bar,
        argMaxIf(window_start, toFloat64(high), window_start >= '2026-06-29 00:00:00') AS high_bar
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('MU', 'SNDK', 'STX', 'WDC')
      AND ((window_start >= '2026-06-26 13:30:00' AND window_start < '2026-06-26 20:00:00')
        OR (window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'))
    GROUP BY ticker
)
SELECT
    ticker,
    round(friday_close, 2) AS jun26_close,
    round(monday_close, 2) AS jun29_close,
    round((monday_close / friday_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
FROM per_name
ORDER BY ticker

MU na di textbook case of range versus net change: 12.22% intraday range — $1023.65 low for 10:18 ET, $1148.79 high for 15:59 — but still close 1.97% above Friday. Western Digital rise 11.15% and Seagate 8.17%; SanDisk close -1.9% across 10.33% range — na im be di only one for di cluster wey close lower. One close fit hide wetin holders don pass through.

Wia the money take trade

By dollars wey dem trade, Micron (MU) pass everybody, even index funds: $58.47 billion against SPY $33.97 billion. But by share count, na different day be that.

QueryVolume leaders two ways: top 6 by dollars traded, top 4 by shares traded
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-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'
    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-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'
    GROUP BY ticker
    ORDER BY shares_m DESC
    LIMIT 4
)
ORDER BY leaderboard ASC, if(leaderboard = 'by dollars traded', dollar_volume_bn, shares_m) DESC

Share-count boards dey mislead. The share leaders na SOXS, one 3x-leveraged inverse semiconductor ETF (695.3 million shares), and INLF, one penny stock wey 353.8 million shares no reach pass $23 million all day. Dollar volume dey show wia money move. relative volume dey show whether the activity of one name dey abnormal pass im normal level.

For 30-minute New York buckets, June 29 dey trace the classic volume "smile":

QueryShares traded per 30-minute bucket, regular hours (billions)
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,
    round(100 * (sum(toFloat64(volume)) / min(sum(toFloat64(volume))) OVER () - 1), 1) AS pct_above_trough
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'
GROUP BY et_time
ORDER BY et_time

2.3 billion shares pass for the opening half hour. 0.77 billion trough reach for 13:30. The biggest bucket na 2.39 billion, and e happen for the closing half hour. That na wia closing auctions and index-tracking flows dey concentrate.

The options tape

Options trade 66.33 million contracts across 11.04 million prints.

QueryOne row for the whole options day: volume, 0DTE, the holiday-shifted week
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-06-29 00:00:00' AND sip_timestamp < '2026-06-30 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-06-29 13:30:00' AND window_start < '2026-06-29 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) = '260629') / 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,
    countIf(sip_timestamp < '2026-06-29 13:30:00') AS premarket_prints,
    reverse(arrayStringConcat(extractAll(reverse(toString(countIf(sip_timestamp < '2026-06-29 13:30:00'))), '[0-9]{1,3}'), ',')) AS premarket_prints_label,
    countIf(sip_timestamp < '2026-06-29 13:30:00'
        AND underlying_symbol NOT IN ('SPX', 'SPXW', 'XSP', 'RUTW', 'VIX', 'VIXW')) AS premarket_non_index_prints,
    arrayStringConcat(arraySort(groupUniqArrayIf(underlying_symbol, sip_timestamp < '2026-06-29 13:30:00')), ', ') AS premarket_underlyings,
    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_label,
    round(top_contract.7, 3) AS top_contract_avg_price,
    round(top_contract.2 - spy_regular_close, 2) AS top_strike_minus_spy_close
FROM global_markets.options_trades
WHERE sip_timestamp >= '2026-06-29 00:00:00' AND sip_timestamp < '2026-06-30 00:00:00'

Calls carry 55.7% of contract volume, and 35.8% of everything wey trade expire that same Monday — the zero-days-to-expiry (0DTE) share. The single contract wey get highest volume for the day na the same-day SPY $741 call: 788,133 contracts at average premium of $0.474, with SPY close land 0.12 dollars below the strike — the most-traded option for the day finish out of the money. SPY trade 12.01 million contracts as underlying; QQQ 7.32 million.

The panel still dey count 40,621 option prints before the 9:30 equity open — every one of dem on cash-settled index root (RUTW, SPX, SPXW, VIX, VIXW, XSP), with 0 stock or ETF option prints for the same window. That one na the rule, e no be accident: index options get extended global-trading-hours sessions, options on stocks and ETFs open with the stock market. The stocks dey trade early — see premarket and after-hours trading — their options no dey.

No contract wey get Friday, July 3 expiration code print all day (0 prints) — market close that Friday — while the Thursday, July 2 expiry trade 10.73 million.

The quote tape: wetin the day cost to trade

Every price for this page dey sit on top quote stream — the National Best Bid and Offer, dem dey re-publish am every time for every listed name. The gap between best bid and best offer, the bid-ask spread, na wetin order go pay to cross.

QueryWetin e cost to cross the spread: NBBO updates and median quoted width, regular hours
The exact SQL behind every number
SELECT
    ticker,
    round(count() / 1e6, 2) AS nbbo_updates_m,
    round(quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, bid_price > 0 AND ask_price >= bid_price), 2) AS median_spread_bps,
    round(quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, bid_price > 0 AND ask_price >= bid_price AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 14:00:00'), 2) AS open_30min_spread_bps,
    round(quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, bid_price > 0 AND ask_price >= bid_price AND sip_timestamp >= '2026-06-29 17:00:00' AND sip_timestamp < '2026-06-29 17:30:00'), 2) AS midday_spread_bps,
    round(quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, bid_price > 0 AND ask_price >= bid_price AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 14:00:00')
        - quantileExactIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, bid_price > 0 AND ask_price >= bid_price AND sip_timestamp >= '2026-06-29 17:00:00' AND sip_timestamp < '2026-06-29 17:30:00'), 2) AS open_minus_midday_bps,
    countIf(NOT (bid_price > 0 AND ask_price >= bid_price)) AS dropped_invalid_quotes
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('SPY', 'QQQ', 'MU', 'WDC')
  AND sip_timestamp >= '2026-06-29 13:30:00' AND sip_timestamp < '2026-06-29 20:00:00'
GROUP BY ticker
ORDER BY ticker

SPY median quoted width na 0.41 basis points of its mid-price, against 0.84 for QQQ, 4.6 for Micron and 8.2 for Western Digital — the widest of the four. One basis point of $10,000 order na one dollar, so if you buy and instantly sell $10,000 of SPY at the quote, e go cost about $0.41; the same round trip for Western Digital go cost $8.2. The trade size no change; na the name change.

All four quoted wider for opening half hour pass for midday control window — SPY 0.41 bps against 0.27, Western Digital 14.33 against 7.55, 6.78 bp opening premium for the widest name. Churn na the other half: 3.98 million NBBO updates on SPY for regular hours, 4.42 million on QQQ.

Rates: the curve barely moved

Treasuries get one quiet Monday. Yields na daily closes, dem change against June 26.

QueryThe Treasury curve, June 29 close vs June 26 (populated maturities only)
The exact SQL behind every number
SELECT
    t.1 AS curve_point,
    round(t.2, 2) AS jun29_yield_pct,
    round((t.2 - t.3) * 100) AS one_day_change_bp
FROM (
    SELECT arrayJoin([
        ('1 month',  toFloat64(mon.yield_1_month),  toFloat64(fri.yield_1_month)),
        ('3 month',  toFloat64(mon.yield_3_month),  toFloat64(fri.yield_3_month)),
        ('1 year',   toFloat64(mon.yield_1_year),   toFloat64(fri.yield_1_year)),
        ('2 year',   toFloat64(mon.yield_2_year),   toFloat64(fri.yield_2_year)),
        ('5 year',   toFloat64(mon.yield_5_year),   toFloat64(fri.yield_5_year)),
        ('10 year',  toFloat64(mon.yield_10_year),  toFloat64(fri.yield_10_year)),
        ('30 year',  toFloat64(mon.yield_30_year),  toFloat64(fri.yield_30_year)),
        ('2s10s spread', toFloat64(mon.yield_10_year - mon.yield_2_year), toFloat64(fri.yield_10_year - fri.yield_2_year))
    ]) AS t
    FROM (SELECT * FROM global_markets.treasury_yields WHERE date = '2026-06-29') AS mon,
         (SELECT * FROM global_markets.treasury_yields WHERE date = '2026-06-26') AS fri
)

The 10-year close for 4.38%, no change for the day (0 bp), while the 3-month bill add 4 bp to reach 3.87%. The 2s10s spread — the 10-year minus the 2-year — close for 0.28 percentage points (-3 bp): still positive, just flatten small small.

The calendar behind the day

QueryJune 29 corporate calendar and information flow, for one row
The exact SQL behind every number
WITH
    (
        SELECT (argMax(d, n), max(n))
        FROM (
            SELECT ex_dividend_date AS d, count() AS n
            FROM global_markets.stocks_dividends
            WHERE ex_dividend_date BETWEEN '2026-06-22' AND '2026-07-02'
            GROUP BY d
        )
    ) AS peak_ex_div,
    (
        SELECT (countIf(form_type = '424B2'), countIf(form_type = '4'), countIf(form_type = '8-K'), count())
        FROM global_markets.stocks_sec_edgar_index
        WHERE filing_date = '2026-06-29'
    ) AS filings,
    (
        SELECT (count(), uniqExact(publisher), countIf(has(tickers, 'NVDA')))
        FROM global_markets.stocks_news
        WHERE toDate(toTimeZone(published_utc, 'America/New_York')) = '2026-06-29'
    ) AS news,
    (
        SELECT 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-06-29'
            )
            WHERE t NOT IN ('NVDA', 'SPCX')
            GROUP BY t
        )
    ) AS runner_up_articles,
    (
        SELECT (any(split_from), any(split_to), count())
        FROM global_markets.stocks_splits
        WHERE ticker = 'HON' AND execution_date = '2026-06-29'
    ) AS hon_split,
    (
        SELECT (
            round(toFloat64(argMaxIf(close, window_start, window_start < '2026-06-27 00:00:00')), 2),
            round(toFloat64(argMaxIf(close, window_start, window_start >= '2026-06-29 00:00:00')), 2)
        )
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'HON'
          AND ((window_start >= '2026-06-26 13:30:00' AND window_start < '2026-06-26 20:00:00')
            OR (window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'))
    ) AS hon_close
SELECT
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-06-29') AS ex_dividend_records_jun29,
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date = '2026-06-29'
        AND ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'GOOGL', 'GOOG', 'META', 'TSLA', 'JPM', 'JNJ',
                       'XOM', 'KO', 'PG', 'V', 'MA', 'HD', 'WMT', 'CVX', 'MRK', 'PEP',
                       'SPY', 'QQQ', 'DIA', 'IWM', 'VTI')) AS household_name_ex_dividends,
    length(['AAPL', 'MSFT', 'NVDA', 'AMZN', 'GOOGL', 'GOOG', 'META', 'TSLA', 'JPM', 'JNJ',
            'XOM', 'KO', 'PG', 'V', 'MA', 'HD', 'WMT', 'CVX', 'MRK', 'PEP',
            'SPY', 'QQQ', 'DIA', 'IWM', 'VTI']) AS household_names_checked,
    concat(monthName(peak_ex_div.1), ' ', toString(toDayOfMonth(peak_ex_div.1))) AS busiest_ex_div_day_of_window,
    peak_ex_div.2 AS busiest_ex_div_day_records,
    (SELECT count() FROM global_markets.stocks_splits WHERE execution_date = '2026-06-29') AS splits_executed,
    (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date = '2026-06-29') AS ipos_listed_jun29,
    (SELECT arrayStringConcat(groupArray(ticker), ', ') FROM (
        SELECT ticker FROM global_markets.stocks_ipos WHERE listing_date = '2026-07-01' ORDER BY ticker
    )) AS jul1_ipo_debuts,
    filings.4 AS sec_filings,
    filings.1 AS prospectus_424b2_filings,
    filings.2 AS insider_form4_filings,
    filings.3 AS filings_8k,
    news.1 AS news_articles,
    news.2 AS news_publishers,
    news.3 AS nvda_articles,
    runner_up_articles AS next_most_covered_articles,
    news.3 - runner_up_articles AS nvda_minus_next_most_covered,
    hon_split.3 AS hon_split_records,
    hon_split.1 AS hon_split_from,
    hon_split.2 AS hon_split_to,
    hon_close.1 AS hon_close_jun26,
    hon_close.2 AS hon_close_jun29

449 dividend records don comot ex-dividend for June 29 — if you wan collect the dividend, you gatz hold the stock before the ex-dividend date — but among 25 household names wey we check, 0 show. The quarter-end wave reach peak for 745 records on July 1. 23 splits don execute and 0 IPOs don list, Wednesday debuts (BSP, ITG, LIME) already dey the calendar.

SEC log 6173 filings wey carry June 29 date: 1473 structured-product pricing supplements (form 424B2) and 1277 insider-trade reports (Form 4) pass 231 8-Ks wey dey make headlines. Our news feed carry 170 articles from 3 publishers; if you comot one ambiguously-tagged reused symbol (wey we drop inside the query), the name wey people cover pass na NVDA for 14 articles against the runner-up 12.

Data notes

Wey data get note, we no just comot am for silent — these four touch headline numbers.

  • The sector baskets na declared method. "Sector" mean the eleven SPDR sector ETFs, market-value-weighted — the same names every session, no be vendor per-ticker classification.
  • Dollar volume na per-minute proxy — close × volume wey dem sum per minute bar, near but no be the same as the sum of print values.
  • Quoted spreads dey exclude invalid quotes (one-sided or crossed NBBO records); the panel dey count wetin e drop (1544 on SPY). Median quoted width na quoting statistic, no be per-trade cost — orders often dey execute inside the quote.
  • One lone print fit contaminate minute bar high or low. QQQ 11:07 ET bar carry $709.58 low while no surrounding bar dip below $715.09 — one print $5.51 under the concurrent market. Every high and low above, we cross-check against adjacent bars; QQQ $705.172 session low pass.
Full data notes
  • Treasury coverage dey thinner than the schema. Four advertised maturities (6-month, 3-, 7- and 20-year) never get populated; the curve show the seven wey dey exist, plus the 2s10s row.
  • One Honeywell "reverse split" wey the tape contradict. The feed carry 1 HON record dated June 29: reverse split wey dey convert 2 old shares into 1 new. HON close $231.3 Friday and $227.71 Monday — no doubling. We no apply am.
  • The news count na one vendor feed, the 3 publishers we carry — no be "all market news".
  • The tick-level receipts — crossed quotes, the phantom-volume correction, the truncated FINRA short-volume file (and why short volume no be short interest) — dey inside the deep dive.

The session, verified

QuerySession check: SPY observed minute-bar span, and the Friday closure for the tape
The exact SQL behind every number
WITH
    (
        SELECT (
            round(toFloat64(minIf(low, formatDateTime(toTimeZone(window_start, 'America/New_York'), '%H:%i') = '11:07')), 2),
            round(toFloat64(minIf(low, formatDateTime(toTimeZone(window_start, 'America/New_York'), '%H:%i') IN ('11:04', '11:05', '11:06', '11:08', '11:09', '11:10'))), 2)
        )
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'QQQ' AND window_start >= '2026-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00'
    ) AS qqq_lone
SELECT
    (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,
    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-06-29 13:30:00' AND window_start < '2026-06-29 20:00:00') AS regular_session_bars,
    qqq_lone.1 AS qqq_1107_lone_low,
    qqq_lone.2 AS qqq_1107_adjacent_bars_low,
    round(qqq_lone.2 - qqq_lone.1, 2) AS qqq_lone_print_below_adjacent
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY' AND window_start >= '2026-06-29 00:00:00' AND window_start < '2026-06-30 00:00:00'

SPY bars run from 04:00 to 19:59 New York time, and e get exactly 390 regular-window bars — one complete session, verified from the tape (the exchange-calendar dataset dey carry only upcoming closures). That Friday, July 3, na full closure — 0 SPY bars print all day, because July 4 fall on Saturday; the four-session week get own recap.

FAQ

How di stock market perform on June 29, 2026?

E day wey growth lead am: QQQ close 2.57% above Friday, SPY 1.62%, DIA 0.81% and IWM 0.45%, with 62.3% of tickers wey trade $1m or more end higher.

Was June 29, 2026 one big day for the Nasdaq?

Big, but no be exceptional: QQQ 2.57% close-over-close move rank 5 of the trailing month 21 sessions by absolute size, against one monthly high of 4.76%.

Which sectors lead on June 29, 2026?

Technology (2.52%) and consumer discretionary (2.37%) lead the eleven SPDR sector baskets; materials come last at -1.82%, one spread of 4.34 percentage points. Utilities, staples, energy and real estate too close lower.

Wetin be the share of options volume on June 29, 2026 wey be 0DTE?

Same-day expiries na 35.8% of the 66.33 million contracts wey dem trade; the busiest single contract, one same-day SPY $741 call (788,133 contracts), finish out of the money.

Why options dey trade before the stock market open?

Only index options dey do am. All 40,621 option prints before 9:30 a.m. ET on June 29 sit on cash-settled index roots (RUTW, SPX, SPXW, VIX, VIXW, XSP), wey list extended global-trading-hours sessions; stock and ETF option prints for that window number 0.

How We Don Do Am

  • Timestamps dey stored for UTC, dem convert am to New York time inside the queries. "Close" na the last regular-session minute bar, no be the auction print; day changes dey compare June 29 with June 26, and the session don verify from the bar span wey dem observe.
  • The trailing-month rank dey use regular-hours close-over-close moves, first session don drop (no prior close inside the window). Option expiries dem re-parse from the OCC ticker (the table own expiry column don break).
  • Every panel, we read am one time, at authoring time, through the gated read-only path. Warehouse state as of July 13, 2026.

Every panel na stored query result — chart, table and SQL dey inside one object. Paste any one of them enter the Strasmore terminal. Next session: June 30.