Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor · · Updated 2026-07-26

Sector Scorecard H1 2026: Winners and Losers

All eleven S&P 500 sector ETFs ranked for H1 2026: the winners and losers, the Q1-to-Q2 rotation, breadth inside each sector, and what each costs to trade.

The H1 2026 sector scorecard runs the full spread of outcomes: technology (XLK) finished the six months up 30.8%, communication services (XLC) finished -9.3%, and roughly forty percentage points separated the best sector from the worst. Three of the eleven S&P 500 sector ETFs ended the half in the red, and almost nothing kept its rank from the first quarter to the second, the half was two opposite markets stitched together, and this page scores both. Every number below is a stored query result; expand any panel for the exact SQL.

What a sector ETF is, and how this page scores it

The eleven Select Sector SPDR funds split the S&P 500 into industry buckets, so a single ticker buys, or hedges, one sector view. Each fund holds its sector's index members, weighted by market value, and trades all session like a stock. This page scores each fund four ways: price return (first regular-hours open to last regular-hours close), the quarter split underneath the half number, dollar volume (price times shares traded, the cleanest measure of how much money changed hands), and the bid-ask spread, the gap between the best price to buy at and the best price to sell at, which is what a round trip costs. The index-level ledger for the same six months, rates, options, IPOs, breadth, lives in the H1 2026 market recap.

The scorecard: eleven sectors, half and quarter splits

QueryThe eleven sector ETFs: H1 2026 return, Q1 and Q2 split, and H1 dollar volume
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-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 h1_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)
         / 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(sumIf(toFloat64(close) * toFloat64(volume), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) / 1e9, 1) AS h1_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 >= toDateTime('2026-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
GROUP BY ticker
ORDER BY ticker
Run this yourself

Read the half column first: technology led at 30.8%, with industrials at 19% and energy at 18.8% behind it, while three sectors finished negative, communication services at -9.3%, consumer discretionary at -2.3%, and financials at -2.2%. Eight of eleven positive is respectable breadth for a half that opened with falling indexes.

The quarter columns hold the real story. Q1's leaders were energy (36.9%), materials (9.8%), utilities (7%), and staples (5.5%), one commodity trade plus the classic defensives, while technology (-8.7%), financials (-9.9%), and discretionary (-9.3%) fell alongside the broad market. Q2 inverted the table: technology returned 42%, industrials 13.3%, and health care 7.8%, while energy (-11%), communication services (-3.7%), and utilities (-1%) finished the quarter in the red. Energy's round trip, 36.9% then -11%, and financials' mirror image, -9.9% then 7.7%, are the two cleanest illustrations of what a single half-year number hides.

The rotation, month by month

Three tickers carry the whole rotation story, so this panel tracks them at month grain: XLE (Q1's leader), XLK (Q2's), and XLF (the mirror trade).

QueryXLE, XLF, and XLK by month: the H1 2026 rotation at month grain
The exact SQL behind every number
SELECT toString(toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York')))) AS month, ticker,
    round((argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
         / argMinIf(toFloat64(open), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) - 1) * 100, 1) AS month_return_pct
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('XLE', 'XLF', 'XLK')
  AND window_start >= toDateTime('2026-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
GROUP BY month, ticker
ORDER BY month, ticker
Run this yourself

XLE rose in each of the first three months, 14.1% in January, 11.6% in February, 6% in March, a decelerating staircase, then went three straight months without a gain (-0.2%, -4.7%, -6.8%). XLK ran the mirror image: negative in January, February, and March, then 18.9% in April and 19.1% in May, back-to-back months that built nearly the entire sector-leading half. April is the handoff: the leadership flip sits in a single column of this table. XLF's two positive months were April and June, at 4.7% and 4.7%. The releases the half traded against, inflation prints, payrolls, the Treasury curve, are collected in the macro picture entering H2 2026.

Breadth inside each sector

A sector fund's return says nothing about how many of its members participated. The warehouse carries no sector-classification column, so this panel measures within-sector breadth with a fixed, fully disclosed basket: five household large-cap names per sector, fifty-five in total, every one listed in the SQL. It is a sample of famous names, not the funds' actual holdings, the basket's limits are spelled out in the data notes.

QueryFive-name baskets per sector: members up vs down, median, best and worst, H1 2026
The exact SQL behind every number
SELECT sector,
       count() AS members,
       countIf(ret_pct > 0) AS members_up,
       countIf(ret_pct <= 0) AS members_down,
       round(quantileDeterministic(0.5)(ret_pct, cityHash64(ticker)), 1) AS median_member_pct,
       argMax(ticker, (ret_pct, ticker)) AS best_member,
       round(max(ret_pct), 1) AS best_member_pct,
       argMin(ticker, (ret_pct, ticker)) AS worst_member,
       round(min(ret_pct), 1) AS worst_member_pct
FROM (
    SELECT ticker,
           multiIf(ticker IN ('AAPL','MSFT','NVDA','AVGO','ORCL'), 'technology (XLK)',
                   ticker IN ('META','GOOGL','NFLX','DIS','TMUS'), 'communication services (XLC)',
                   ticker IN ('XOM','CVX','COP','EOG','SLB'), 'energy (XLE)',
                   ticker IN ('JPM','BAC','WFC','GS','MS'), 'financials (XLF)',
                   ticker IN ('GE','CAT','RTX','UNP','UPS'), 'industrials (XLI)',
                   ticker IN ('LLY','UNH','JNJ','ABBV','MRK'), 'health care (XLV)',
                   ticker IN ('AMZN','TSLA','HD','MCD','NKE'), 'consumer discretionary (XLY)',
                   ticker IN ('PG','COST','WMT','KO','PEP'), 'consumer staples (XLP)',
                   ticker IN ('NEE','SO','DUK','CEG','AEP'), 'utilities (XLU)',
                   ticker IN ('PLD','AMT','EQIX','WELL','SPG'), 'real estate (XLRE)',
                   'materials (XLB)') AS sector,
           (argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
            / argMinIf(toFloat64(open), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) - 1) * 100 AS ret_pct
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL','MSFT','NVDA','AVGO','ORCL','META','GOOGL','NFLX','DIS','TMUS','XOM','CVX','COP','EOG','SLB','JPM','BAC','WFC','GS','MS','GE','CAT','RTX','UNP','UPS','LLY','UNH','JNJ','ABBV','MRK','AMZN','TSLA','HD','MCD','NKE','PG','COST','WMT','KO','PEP','NEE','SO','DUK','CEG','AEP','PLD','AMT','EQIX','WELL','SPG','LIN','SHW','APD','FCX','ECL')
      AND window_start >= toDateTime('2026-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
    GROUP BY ticker
)
GROUP BY sector
ORDER BY median_member_pct DESC, sector
Run this yourself

Two rows earn the most attention. Health care: all 5 of its five basket names rose, with a median of 21.7%, while XLV, the fund, gained 2.5% on the half. A fund's return is weighted by market value; a basket median weights every member equally, health care is the widest case of the basket beating the fund. Technology is the same gap in reverse, and, measured end to end, the widest of all: the fund gained 30.8% while its five biggest household names split 3 up and 2 down with a median of 5.2%, and ORCL printed -25.7%. The sector's headline gain did not come from its classic megacaps, where it did come from is the next panel. Elsewhere in the table: CAT's 84.3% is the best print among all fifty-five names, and communication services is the weakest room in the building, 1 of five up, a -15.2% median, with NFLX at -24.2%.

The memory-semis trade inside technology

QueryEight heavily traded chip and memory names: H1 return, quarter split, H1 dollar volume
The exact SQL behind every number
SELECT ticker,
    round((argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
         / argMinIf(toFloat64(open), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) - 1) * 100, 1) AS h1_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, (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, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
         / argMinIf(toFloat64(open), window_start, window_start >= toDateTime('2026-04-01 00:00:00') 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(sumIf(toFloat64(close) * toFloat64(volume), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) / 1e9, 1) AS h1_dollar_bn
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('MU', 'SNDK', 'NVDA', 'AMD', 'INTC', 'AVGO', 'QCOM', 'TXN')
  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 h1_return_pct DESC, ticker
Run this yourself

Take technology apart and the half's defining single-name trade appears. SNDK returned 830.1% in six months, MU 290%, INTC 269.3%, and AMD 165.3%, while NVDA, the biggest single-name tape in the set at $3287.9 billion of half-year turnover, returned 5.2%, with AVGO at 6.9% and QCOM at 6.3%. The complex split in two: the memory-and-foundry names multiplied while the established AI-accelerator names went sideways. The Q2 column carries the timing: MU's 229.9%, INTC's 210%, and AMD's 179.8% landed in the same quarter XLK printed its 42%, the sector fund's rally and the memory repricing are the same three months of tape. MU's June is dissected tick by tick here, and NVDA's June deep-dive tracks the divergence session by session.

Where the trading dollars went

QuerySector ETF dollar volume, Q1 vs Q2 2026: every fund traded less in the recovery quarter
The exact SQL behind every number
SELECT ticker,
    round(sumIf(toFloat64(close) * toFloat64(volume), 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) / 1e9, 1) AS q1_dollar_bn,
    round(sumIf(toFloat64(close) * toFloat64(volume), 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) / 1e9, 1) AS q2_dollar_bn,
    round((sumIf(toFloat64(close) * toFloat64(volume), 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)
         / sumIf(toFloat64(close) * toFloat64(volume), 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) - 1) * 100, 0) AS q2_vs_q1_pct
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('XLB', 'XLC', 'XLE', 'XLF', 'XLI', 'XLK', 'XLP', 'XLRE', 'XLU', 'XLV', 'XLY')
  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 q2_vs_q1_pct DESC, ticker
Run this yourself

Dollar volume moved in one direction: every one of the eleven sector funds traded fewer dollars in the second quarter than in the first. The top row of the table is the smallest decline, XLK at -23%, from $161.2 billion to $124.8 billion, and the bottom is real estate at -45%. The sector wrappers were busiest in the quarter the indexes fell, and activity in them thinned as the recovery ran. Two scale notes from the panels above: XLE was the half's most-traded sector fund at $316.2 billion, and MU alone turned over $2862.1 billion, roughly ten times the XLK fund's $286 billion. Sector products were the scoreboard; single names were where the H1 game was played.

What it costs to trade each sector

Return tables are everywhere; quote tapes are not. This panel measures each fund's median quoted bid-ask spread, the cost of a round trip, across one full labeled session, June 29, 2026, from every NBBO update printed that day.

QueryMedian quoted spread by sector ETF, one representative session (June 29, 2026), regular hours
The exact SQL behind every number
SELECT ticker,
    round(quantileDeterministicIf(0.5)((toFloat64(ask_price) - toFloat64(bid_price)) / ((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, toUInt64(toUnixTimestamp64Micro(sip_timestamp)), bid_price > 0 AND ask_price >= bid_price), 2) AS med_spread_bps,
    round(count() / 1e6, 2) AS quote_updates_m,
    countIf(NOT (bid_price > 0 AND ask_price > 0 AND ask_price >= bid_price)) AS invalid_dropped
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('XLB', 'XLC', 'XLE', 'XLF', 'XLI', 'XLK', 'XLP', 'XLRE', 'XLU', 'XLV', 'XLY')
  AND sip_timestamp >= toDateTime64('2026-06-29 13:30:00', 9) AND sip_timestamp < toDateTime64('2026-06-29 20:00:00', 9)
GROUP BY ticker
ORDER BY med_spread_bps, ticker
Run this yourself

The cheapest fund to trade that session was XLV at a median of 0.62 basis points; the widest was XLRE at 2.23. One basis point is a hundredth of a percent, so the entire table sits at hundredths of a percent per round trip, the practical meaning of "sector ETFs are liquid." Quote-update counts vary almost tenfold across the table, and the medians still cluster within a couple of basis points of each other. For contrast, the June 29 microstructure deep-dive works the same session's SPY quote tape, which runs tighter still than any fund in this table.

FAQ

Which sector performed best in H1 2026?

Technology. XLK returned 30.8% for the half, all of it in the second quarter (42% in Q2 after -8.7% in Q1). Communication services (XLC) was the worst at -9.3%.

Did the same sectors lead in Q1 and Q2 2026?

No, the two quarters were near-opposites. Energy led Q1 at 36.9% and finished Q2 at -11%; technology printed -8.7% in Q1 and led Q2 at 42%. Utilities and staples led early and faded late.

How much does it cost to trade a sector SPDR ETF?

On the measured June 29, 2026 session, median quoted spreads ran from 0.62 basis points (XLV) to 2.23 (XLRE), hundredths of a percent per round trip, far tighter than a typical single stock.

Why does a sector ETF's return differ from its members' returns?

The funds weight holdings by market value, so a few giant members dominate the print, while a basket median treats every member equally. In H1 2026 the gap was widest in health care: a five-name basket median of 21.7% against XLV's 2.5%.

What are the eleven sector ETFs?

XLB (materials), XLC (communication services), XLE (energy), XLF (financials), XLI (industrials), XLK (technology), XLP (consumer staples), XLRE (real estate), XLU (utilities), XLV (health care), and XLY (consumer discretionary). Together they partition the S&P 500.

Data notes

Full data notes
  • The breadth baskets are fixed editorial samples of five household large-caps per sector, not fund holdings, and carry no weights. Candidates were screened against the half's split calendar, minute bars are unadjusted, and a mid-period split poisons an open-to-close return, and two otherwise obvious names were replaced on that screen. Every figure on this page is a price return; dividends are not included.
  • Basket medians use deterministic quantiles, and best/worst members are tie-broken by ticker, so regeneration cannot reorder ties.
  • The spread panel measures one labeled session (June 29, 2026), not the whole half; a six-month whole-quote-tape scan across eleven tickers exceeds the query budget this page generates under. Invalid quotes (crossed or one-sided) are counted in the panel, not silently dropped.
  • The scorecard panel is the same query the H1 recap carries, so the two pages cannot disagree on a sector number.

Methodology

  • The window is January 1 – June 30, 2026. Returns are first regular-hours open to last regular-hours close within each window, computed inside the queries shown. Regular hours are filtered on the Eastern wall clock (9:30–15:59, converted per row), DST-safe across the half's EST and EDT months.
  • Quarter boundaries are applied on the Eastern trading date: Q1 ends March 31, Q2 begins April 1.
  • Dollar volume sums price times shares over regular hours in the same queries.
  • Generation runs through the gated read-only path; the public page never queries live. Warehouse state as of July 12, 2026.

The half's full ledger, indexes, rates, the options tape, is in the H1 2026 market recap. To slice a sector differently, every panel's SQL runs as-is on the Strasmore terminal.