Strasmore Research
Market Recap

Market Recap: Q2 2026

2026-07-04

The second quarter of 2026 was the recovery quarter: after a negative first quarter, every major index ETF rose double digits, led by QQQ at 26.5%. The panels below carry the quarter's shape — the monthly staircase, the rates backdrop, the calendar — and its two data caveats, disclosed inline. Every number is a stored query result; expand any panel for the exact SQL.

The quarter on the board

How big was the swing from Q1? This panel computes both quarters' returns in one query — the Q1 reference is recomputed live on the same definitions, not read from anywhere.

QueryQ2 2026 returns for the four index ETFs, with Q1 recomputed live for contrast
The exact SQL behind every number
SELECT ticker,
    round((argMaxIf(toFloat64(close), window_start, toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-06-30') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
         / argMinIf(toFloat64(open), window_start, toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2026-04-01') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) - 1) * 100, 1) AS q2_return_pct,
    round((argMaxIf(toFloat64(close), window_start, toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-03-31') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
         / argMinIf(toFloat64(open), window_start, toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2026-01-01') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) - 1) * 100, 1) AS q1_return_pct,
    round(argMaxIf(toFloat64(close), window_start, toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-06-30') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 2) AS q2_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'QQQ', 'DIA', 'IWM')
  AND window_start >= toDateTime('2026-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
GROUP BY ticker
ORDER BY ticker

QQQ rose 26.5% for the quarter after a -6.9% Q1; SPY 14.1% after -5.2%; IWM 20.2%. Every index that fell in the first quarter more than recovered in the second. The four tell three different stories: the growth index took the deepest Q1 drawdown and posted the biggest recovery; DIA — the price-weighted industrials index — swung from -3.9% to 12.1%; and IWM never really fell at all (0.1% in Q1), so its 20.2% quarter compounded a flat start rather than repairing a drawdown. Recovery and momentum look identical in a quarterly return column; the Q1 column is what tells them apart.

The monthly staircase

QueryQ2 month by month: April, May, June (SPY and QQQ, recomputed identically)
The exact SQL behind every number
SELECT toString(toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York')))) AS period_start, ticker,
    round((argMaxIf(toFloat64(close), window_start, (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199) / argMinIf(toFloat64(open), window_start, (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199) - 1) * 100, 1) AS month_return_pct,
    round(argMaxIf(toFloat64(close), window_start, (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199), 2) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'QQQ')
  AND window_start >= toDateTime('2026-04-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
GROUP BY period_start, ticker
ORDER BY period_start, ticker

The quarter was front-loaded: April did the heavy lifting (SPY 9.9%, QQQ 14.8%), May added more (4.9% and 10.3%), and June gave a little back — SPY -1.2%. The June recap carries the month in detail, including the breadth split beneath it.

The tape's leaders, quarter scale

QueryQ2 regular-hours dollar volume, whole tape (one reused-symbol listing excluded pending entity verification)
The exact SQL behind every number
SELECT ticker,
    round(sum(toFloat64(close) * toFloat64(volume)) / 1e9, 1) AS dollar_bn,
    round(100 * sum(toFloat64(close) * toFloat64(volume)) / max(sum(toFloat64(close) * toFloat64(volume))) OVER (), 1) AS pct_of_leader
FROM global_markets.delayed_stocks_minute_aggs
WHERE window_start >= toDateTime('2026-04-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
  AND (toHour(window_start) * 60 + toMinute(window_start)) BETWEEN 810 AND 1199
  AND ticker NOT IN ('SPCX')
GROUP BY ticker
ORDER BY dollar_bn DESC
LIMIT 8

For the full quarter, MU ($2047.5 billion) edged out SPY ($2032 billion) at the top of the tape — a single stock out-trading the flagship index fund across three months, by 99.2% of the leader's total. Behind them: QQQ ($1658.5 billion), then NVDA at $1591.8 billion — whose June alone is dissected tick by tick here — and TSLA at $1198.8 billion. Note what the list is: regular-hours turnover, not performance — a name can dominate the tape in a falling month. Basis: April 1–June 30 regular hours; one reused-symbol June listing excluded pending entity verification (its receipts).

Rates: the quarter the curve flattened

QueryThe 2s10s spread and the 10-year through Q2, daily
The exact SQL behind every number
SELECT toString(date) AS d,
    round(yield_10_year, 2) AS y10,
    round((yield_10_year - yield_2_year) * 100, 0) AS spread_2s10s_bp
FROM global_markets.treasury_yields
WHERE date >= toDate('2026-04-01') AND date <= toDate('2026-06-30')
  AND isNotNull(yield_10_year) AND isNotNull(yield_2_year)
ORDER BY date

The 2s10s spread came into the quarter at 52 basis points and ended at 30 — a flattening quarter, with the 10-year finishing at 4.44%. The six-month version of this story is in the H1 recap. Mechanically, a flattening means the short end closed distance on the long end; whether that continues is not answerable from this table, and this page doesn't try.

The calendar, quarter scale

QueryQ2's corporate calendar (the June 30 filing-index gap disclosed)
The exact SQL behind every number
SELECT
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date >= toDate('2026-04-01') AND ex_dividend_date <= toDate('2026-06-30')) AS ex_div_events,
    (SELECT count() FROM global_markets.stocks_splits WHERE execution_date >= toDate('2026-04-01') AND execution_date <= toDate('2026-06-30')) AS splits,
    (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date >= toDate('2026-04-01') AND listing_date <= toDate('2026-06-30')) AS ipos,
    (SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date >= toDate('2026-04-01') AND filing_date <= toDate('2026-06-30')) AS q2_filings,
    (SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date = toDate('2026-06-30')) AS filings_jun30

105 companies listed in the quarter, 435 splits executed, and 15402 ex-dividend events paid out. The filing count (235075) carries the disclosed gap: the index for June 30 — the quarter's last day — holds only 31 filings against thousands on neighboring days, so the quarter total is understated until the feed backfills.

The calendar's ramp into quarter-end

QueryListings, splits, and ex-dividend events by month through the quarter
The exact SQL behind every number
SELECT m, ipos, splits, ex_divs FROM (
    SELECT '2026-04' AS m,
        (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date >= toDate('2026-04-01') AND listing_date <= toDate('2026-04-30')) AS ipos,
        (SELECT count() FROM global_markets.stocks_splits WHERE execution_date >= toDate('2026-04-01') AND execution_date <= toDate('2026-04-30')) AS splits,
        (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date >= toDate('2026-04-01') AND ex_dividend_date <= toDate('2026-04-30')) AS ex_divs, 1 AS o
    UNION ALL SELECT '2026-05',
        (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date >= toDate('2026-05-01') AND listing_date <= toDate('2026-05-31')),
        (SELECT count() FROM global_markets.stocks_splits WHERE execution_date >= toDate('2026-05-01') AND execution_date <= toDate('2026-05-31')),
        (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date >= toDate('2026-05-01') AND ex_dividend_date <= toDate('2026-05-31')), 2
    UNION ALL SELECT '2026-06',
        (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date >= toDate('2026-06-01') AND listing_date <= toDate('2026-06-30')),
        (SELECT count() FROM global_markets.stocks_splits WHERE execution_date >= toDate('2026-06-01') AND execution_date <= toDate('2026-06-30')),
        (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date >= toDate('2026-06-01') AND ex_dividend_date <= toDate('2026-06-30')), 3
) ORDER BY o

The corporate calendar tightened as the quarter aged: ex-dividend events climbed every month, from 3947 in April to 6651 in June, and splits rose alongside (129 to 164). Listings held steady across the three months — the wave metaphor belongs to dividends, not IPOs, this quarter.

The session receipt

Query62 sessions in the quarter, verified from the tape, month by month
The exact SQL behind every number
SELECT
    (SELECT uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) FROM global_markets.delayed_stocks_minute_aggs
     WHERE ticker = 'SPY' AND window_start >= toDateTime('2026-04-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')) AS q2_sessions,
    (SELECT uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) FROM global_markets.delayed_stocks_minute_aggs
     WHERE ticker = 'SPY' AND window_start >= toDateTime('2026-04-01 00:00:00') AND window_start < toDateTime('2026-05-01 00:00:00')) AS april_sessions,
    (SELECT uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) FROM global_markets.delayed_stocks_minute_aggs
     WHERE ticker = 'SPY' AND window_start >= toDateTime('2026-05-01 00:00:00') AND window_start < toDateTime('2026-06-01 00:00:00')) AS may_sessions,
    (SELECT uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) FROM global_markets.delayed_stocks_minute_aggs
     WHERE ticker = 'SPY' AND window_start >= toDateTime('2026-06-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')) AS june_sessions

62 sessions, verified from observed bars rather than assumed from the calendar: 21 in April, 20 in May (Memorial Day), 21 in June (Juneteenth). The month-level receipts and closure evidence live in the June recap and the holiday explainer.

Data notes

Full data notes
  • Short interest ends at the June 15 settlement as of generation — the end-of-June print is pending; the June recap carries the full disclosure. This post regenerates when it lands.
  • The June 30 filing-index gap is disclosed inline; the same feed shows a near-empty March 31, so quarter-BOUNDARY filing counts are systematically understated in this vendor index at the moment.
  • Microstructure (tick-level plumbing) is deliberately absent here — the June 29 deep-dive carries a full session's tape anatomy.
  • Volume-leader exclusion: one reused-symbol June listing excluded pending entity verification.

Methodology

  • The period is April 1 – June 30, 2026 — 62 sessions, verified from observed bars. Quarterly returns are first regular-hours open to last regular-hours close within the period; the Q1 contrast is recomputed live on identical definitions.
  • Timestamps stored UTC, filtered with raw UTC bounds; regular hours 13:30–20:00 UTC across the (EDT) quarter. Dollar volume is minute close times minute volume over regular hours.
  • Generation runs through the gated read-only path; the public page never queries live. Warehouse state as of July 4, 2026.

This is the first edition of the standing quarterly recap; Q3's edition will link back here. Month detail: June. The half this quarter completed: H1 2026.