Strasmore Research
Market Recap

Resumo do mercado primeiro semestre de 2026

Matt ConnorBy Matt Connor Updated 2026-07-23

O primeiro semestre de 2026 foi composto por dois mercados distintos: um primeiro trimestre em que todos os principais ETFs de índices caíram ou ficaram estagnados, e um segundo trimestre que recuperou esses resultados. O SPY fechou o semestre com alta de 8.8%; o QQQ subiu 18.7%; e o 21.3% do IWM foi o melhor primeiro semestre registrado pelo ETF de small-caps em nosso histórico — o detalhamento está abaixo, recalculado contra todos os anos anteriores em uma única consulta. O mercado de taxas apresentou seu próprio cenário: o 2s10s spread achatou de 72 pontos de base para 30 ao longo do semestre, sem nunca inverter. Esta página é o balanço completo do período — o placar, o ranking histórico, a progressão mensal, a curva de juros completa por vencimento, os onze setores, a evolução mensal do mercado de opções e os principais ativos individuais do semestre. Cada número aqui é o resultado de uma consulta armazenada; expanda qualquer painel para ver o SQL.

O desempenho do semestre

QueryH1 2026: retornos do semestre, Q1 e Q2 para os quatro ETFs de índice — calculados em uma única consulta
O SQL exato por trás de cada número
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(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 h1_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

A divisão em dois trimestres define o formato do semestre: SPY -5.2% seguido de 14.1%; QQQ -6.9% seguido de 26.5%. O IWM foi o líder silencioso do semestre em 21.3% — as small caps superaram todos os índices de large-caps ao longo dos seis meses. Os detalhes trimestrais estão no resumo do Q2. Uma nota sobre a aritmética dos semestres: o 8.8% do SPY para os seis meses é muito inferior ao seu Q2 isolado, já que o semestre combina um drawdown e uma recuperação — o efeito composto de -5.2% e 14.1% resulta no valor indicado na tabela, e qualquer manchete sobre o "retorno do primeiro semestre" esconde esse movimento de ida e volta.

O primeiro semestre contra todos os outros primeiros semestres

Um 8.8% é incomum? Os painéis abaixo recalculam o MESMO retorno do primeiro semestre — da abertura à fechamento do horário regular, de janeiro a junho — para cada ano de histórico em minutos, em uma consulta por par de ETF com aritmética idêntica para cada ano, e então classificam este semestre em relação aos demais. A data mais antiga do histórico em minutos está verificada na metodologia abaixo; o primeiro primeiro semestre completo em arquivo é o indicado pelos recibos.

QueryCada primeiro semestre no tape: SPY e QQQ, recalculados identicamente por ano (contagem de sessões anual exibida)
O SQL exato por trás de cada número
SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS y,
       ticker,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions,
       round((argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100, 1) AS h1_return_pct
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'QQQ')
  AND window_start >= toDateTime('2003-01-01 00:00:00')
  AND window_start < toDateTime('2026-07-01 00:00:00')
  AND toMonth(toTimeZone(window_start, 'America/New_York')) <= 6
  AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY y, ticker
HAVING sessions >= 100
ORDER BY y ASC, ticker ASC
QueryRanking: este semestre contra todos os anteriores (SPY e QQQ; rank 1 = melhor; autoexcluído)
O SQL exato por trás de cada número
SELECT ticker,
       round(anyIf(ret, y = 2026), 1) AS h1_2026_pct,
       arrayCount(x -> x > anyIf(ret, y = 2026), groupArrayIf(ret, y != 2026)) + 1 AS rank_best,
       count() AS halves_compared,
       min(y) AS first_year,
       anyIf(sessions, y = 2026) AS sessions_2026
FROM (
    SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS y,
           ticker,
           uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions,
           (argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100 AS ret
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ')
      AND window_start >= toDateTime('2003-01-01 00:00:00')
      AND window_start < toDateTime('2026-07-01 00:00:00')
      AND toMonth(toTimeZone(window_start, 'America/New_York')) <= 6
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY y, ticker
    HAVING sessions >= 100
)
GROUP BY ticker
ORDER BY ticker ASC

O 8.8% do SPY ocupa a posição de 6 de 23 primeiros semestres desde 2004 (rank 1 = melhor) — o terço superior, mas não é um recorde. O 18.7% do QQQ ocupa a posição de 3 de 16 semestres comparáveis — a série do QQQ é mais curta — o fundo operou sob um ticker diferente por um período de anos — e qualquer ano com menos de cem sessões no primeiro semestre para um ticker é excluído por uma trava de contagem de sessões mostrada na tabela, portanto as exclusões são visíveis em vez de silenciosas.

QueryCada primeiro semestre no tape: DIA e IWM, mesma aritmética
O SQL exato por trás de cada número
SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS y,
       ticker,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions,
       round((argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100, 1) AS h1_return_pct
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('DIA', 'IWM')
  AND window_start >= toDateTime('2003-01-01 00:00:00')
  AND window_start < toDateTime('2026-07-01 00:00:00')
  AND toMonth(toTimeZone(window_start, 'America/New_York')) <= 6
  AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY y, ticker
HAVING sessions >= 100
ORDER BY y ASC, ticker ASC
QueryRanking: DIA e IWM contra todos os primeiros semestres anteriores (rank 1 = melhor; autoexcluído)
O SQL exato por trás de cada número
SELECT ticker,
       round(anyIf(ret, y = 2026), 1) AS h1_2026_pct,
       arrayCount(x -> x > anyIf(ret, y = 2026), groupArrayIf(ret, y != 2026)) + 1 AS rank_best,
       count() AS halves_compared,
       min(y) AS first_year,
       anyIf(sessions, y = 2026) AS sessions_2026
FROM (
    SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS y,
           ticker,
           uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions,
           (argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100 AS ret
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('DIA', 'IWM')
      AND window_start >= toDateTime('2003-01-01 00:00:00')
      AND window_start < toDateTime('2026-07-01 00:00:00')
      AND toMonth(toTimeZone(window_start, 'America/New_York')) <= 6
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY y, ticker
    HAVING sessions >= 100
)
GROUP BY ticker
ORDER BY ticker ASC

A linha de small-caps é o destaque do semestre: o IWM ocupa a posição de 1 de 23 primeiros semestres desde 2004 — o melhor registrado para o fundo, à frente de todos os semestres de recuperação na tabela. O 8.4% do DIA ocupa a posição de 4 de 23. A base, explicada de forma direta: abertura ao fechamento do horário regular dentro de cada primeiro semestre do calendário, aritmética idêntica para cada ano, limite superior fixado no fim deste período para que o conjunto de comparação não cresça silenciosamente quando anos posteriores forem processados.

Mês a mês

QueryO semestre, mês a mês (SPY e QQQ, recalculados identicamente em uma única consulta)
O SQL exato por trás de cada número
SELECT toString(toStartOfMonth(toDate(toTimeZone(window_start, 'America/New_York')))) AS period_start, 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,
    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), 2) AS month_close
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'QQQ')
  AND window_start >= toDateTime('2026-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')
GROUP BY period_start, ticker
ORDER BY period_start, ticker

O movimento foi de alta moderada, seguida de quedas, uma alta acentuada, mais altas e uma queda leve: abril foi o ponto de inflexão do semestre (SPY 9.9%, QQQ 14.8% — o melhor mês do QQQ no semestre), e junho encerrou o período com estabilidade em -1.2% para o SPY. O resumo de junho, com a amplitude de mercado detalhada por trás desse número estável, está aqui. Analisando a tabela mês a mês: o ano começou praticamente estável (SPY 0.9% em janeiro), caiu durante fevereiro (-0.5%) e março (-4.2%), depois abril reverteu a tendência em um único mês, maio estendeu o rali (4.9%) e junho desacelerou. Três dos seis meses foram negativos — uma contagem de meses equilibrada para um semestre que terminou com saldo positivo sólido, o que é o padrão comum para semestres de ações e vale lembrar quando um único mês parece um veredito definitivo.

Taxas: a curva completa, vencimento por vencimento

A curva do Treasury apresentou um twist, não um deslocamento paralelo. O trecho curto — os vencimentos que acompanham mais de perto a política monetária — quase não se moveu; o de dois anos subiu dois terços de um ponto percentual; o de trinta anos mal teve alteração. O painel apresenta a curva completa, comparando o início do semestre com o final.

QuerySete vencimentos: yield no início do semestre vs. no fim, e a variação
O SQL exato por trás de cada número
SELECT maturity, start_pct, end_pct, round((end_pct - start_pct) * 100, 0) AS change_bp FROM (
    SELECT '1-month' AS maturity, (SELECT round(argMin(yield_1_month, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_1_month)) AS start_pct, (SELECT round(argMax(yield_1_month, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_1_month)) AS end_pct, 1 AS o
    UNION ALL SELECT '3-month', (SELECT round(argMin(yield_3_month, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_3_month)), (SELECT round(argMax(yield_3_month, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_3_month)), 2
    UNION ALL SELECT '1-year', (SELECT round(argMin(yield_1_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_1_year)), (SELECT round(argMax(yield_1_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_1_year)), 3
    UNION ALL SELECT '2-year', (SELECT round(argMin(yield_2_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_2_year)), (SELECT round(argMax(yield_2_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_2_year)), 4
    UNION ALL SELECT '5-year', (SELECT round(argMin(yield_5_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_5_year)), (SELECT round(argMax(yield_5_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_5_year)), 5
    UNION ALL SELECT '10-year', (SELECT round(argMin(yield_10_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_10_year)), (SELECT round(argMax(yield_10_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_10_year)), 6
    UNION ALL SELECT '30-year', (SELECT round(argMin(yield_30_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_30_year)), (SELECT round(argMax(yield_30_year, date), 2) FROM global_markets.treasury_yields WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30') AND isNotNull(yield_30_year)), 7
) ORDER BY o

Ao ler a coluna de variação de cima para baixo, o twist é evidente: o de um mês moveu-se -2 pontos base em seis meses, enquanto o de dois anos subiu 67 e o de 30 anos apenas 5. Um deslocamento paralelo move todos os vencimentos juntos; este semestre moveu o meio da curva e manteve as duas pontas estáveis — as taxas curtas ancoradas próximas à política e as taxas longas com pouca marcação a mercado.

O impacto na inclinação

QueryResultados da inclinação: início, fim, mínimo — o spread nunca inverteu este semestre
O SQL exato por trás de cada número
SELECT
    round((argMin(yield_10_year - yield_2_year, date)) * 100, 0) AS start_bp,
    round((argMax(yield_10_year - yield_2_year, date)) * 100, 0) AS end_bp,
    round(min((yield_10_year - yield_2_year)) * 100, 0) AS min_bp,
    count() AS prints
FROM global_markets.treasury_yields
WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30')
  AND isNotNull(yield_10_year) AND isNotNull(yield_2_year)

O curto prazo subindo mais rápido que o longo prazo é o que define um achatamento: o spread 2s10s caiu de 72 para 30 pontos de base ao longo dos dados de 124 — e seu menor valor no semestre foi 27, portanto a curva achatou sem chegar a inverter. Se um achatamento da curva "significa" algo sobre o que virá a seguir é uma previsão, e esta tabela não faz previsões.

QueryO spread 2s10s, cada registro do semestre
O SQL exato por trás de cada número
SELECT toString(date) AS d, round((yield_10_year - yield_2_year) * 100, 0) AS spread_2s10s_bp
FROM global_markets.treasury_yields
WHERE date >= toDate('2026-01-01') AND date <= toDate('2026-06-30')
  AND isNotNull(yield_10_year) AND isNotNull(yield_2_year)
ORDER BY date

A série diária mostra que o achatamento não foi um evento isolado, mas um processo gradual — 124 dados em queda ao longo do semestre, com o spread iniciando o ano em 72 pontos de base e terminando em 30.

Setores: a dispersão que o índice ocultou

Quais partes do mercado realmente geraram os ganhos do semestre? Os onze ETFs de setores da SPDR, divididos entre o primeiro e o segundo trimestre, em uma única análise.

QueryOs onze ETFs de setor: retorno H1 2026, divisão Q1 e Q2, e volume em dólar no H1
O SQL exato por trás de cada número
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

A dispersão é o ponto central: o setor de tecnologia (XLK) fechou o semestre com alta de 30.8% — com um 42% segundo trimestre — enquanto o de serviços de comunicação (XLC) fechou com -9.3%, um spread de aproximadamente quarenta pontos percentuais entre o melhor e o pior setor em seis meses. Investir no "mercado" significava estar exposto a ambos os extremos. O setor de energia (XLE) é o exemplo de cautela sobre períodos longos: o XLE mostra um semestre saudável de 18.8% — construído a partir de um 36.9% primeiro trimestre seguido por um -11% segundo. Foi o setor de grande capitalização mais forte do mercado no trimestre em que os índices caíram, e um dos mais fracos no trimestre em que recuperaram. O setor financeiro (XLF) seguiu o caminho inverso: -9.9% no primeiro trimestre, depois 7.7% no segundo. Um único número para o primeiro semestre suaviza essas oscilações; a divisão trimestral oferece a visão real.

O custo para negociar cada setor

Tabelas de retorno são comuns; cotações em tempo real não são. Este painel mede o spread bid-ask mediano de cada ETF setorial ao longo de uma sessão representativa completa — 123 sessões no semestre, sendo a de 29 de junho a medida utilizada aqui, conforme indicado — a partir de cada atualização do NBBO naquele dia.

QueryMedian quoted spread por ETF de setor, uma sessão representativa (29 de junho de 2026), regular hours
O SQL exato por trás de cada número
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

Todas as onze cotações apresentam alguns pontos de base ou menos — a mais barata em 0.62 bps (XLV) e a mais larga em 2.23 bps (XLRE) — o que define o sentido prático de "ETFs setoriais são líquidos": o custo para assumir qualquer posição setorial é medido em centésimos de percentual. Para comparação com ações individuais, o análise detalhada de 29 de junho mostra o spread de um papel de baixa liquidez em centenas de vezes esses níveis, na mesma sessão.

Amplitude no semestre

A amplitude em escala semestral apresenta duas nuances aqui. A visão macro: o SPY registrou 64 sessões de alta contra 59 de baixa ao longo dos 123 do semestre — quase uma probabilidade de cinquenta por cento de dias de alta sob um período solidamente positivo, o que caracteriza uma subida gradual no gráfico diário. A visão detalhada — considerando cada ticker — ocorre na escala mensal: a divisão entre altas e baixas de junho está em o resumo de junho (mais tickers caíram do que subiram lá), e a contagem do limite trimestral está em o resumo do Q2. Um escaneamento de avanços de todo o mercado em um único período de seis meses excede o limite de consulta que esta página gera; esse limite é informado aqui em vez de ser reduzido silenciosamente.

QuerySessões do SPY em alta vs. baixa ao longo do semestre, um resumo rápido
O SQL exato por trás de cada número
SELECT countIf(day_ret > 0) AS up_sessions,
       countIf(day_ret < 0) AS down_sessions,
       countIf(day_ret = 0) AS flat_sessions,
       count() AS sessions_total
FROM (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           round((argMax(toFloat64(close), window_start) / argMin(toFloat64(open), window_start) - 1) * 100, 2) AS day_ret
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= toDateTime('2026-01-01 00:00:00')
      AND window_start < toDateTime('2026-07-01 00:00:00')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
)

O fluxo de opções, mês a mês

O que um registro de apenas meio ano pode mostrar: a evolução do próprio fluxo de opções. Cada painel abaixo é um scan completo de um mês — volume total de contratos e a fatia negociada no dia do vencimento (0DTE). O resumo dos dados: o volume subiu de 1316.1 milhões de contratos em janeiro para 1477.9 milhões em junho — o mês mais movimentado do semestre — e a participação de vencimento no mesmo dia subiu de 26.5% em janeiro para 34.3% em junho, o maior índice do período. Um terço do volume de opções de junho foi negociado em contratos que venciam no mesmo dia.

QueryJaneiro: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-01-01 00:00:00')
  AND window_start < toDateTime('2026-02-01 00:00:00')
QueryFevereiro: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-02-01 00:00:00')
  AND window_start < toDateTime('2026-03-01 00:00:00')
QueryMarço: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-03-01 00:00:00')
  AND window_start < toDateTime('2026-04-01 00:00:00')
QueryAbril: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-04-01 00:00:00')
  AND window_start < toDateTime('2026-05-01 00:00:00')
QueryMaio: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-05-01 00:00:00')
  AND window_start < toDateTime('2026-06-01 00:00:00')
QueryJunho: volume total de contratos de options e share de vencimento no mesmo dia (uma varredura)
O SQL exato por trás de cada número
SELECT round(sum(toFloat64(volume)) / 1e6, 1) AS contracts_mm,
       round(100.0 * sumIf(toFloat64(volume), toDateOrNull(concat('20', substring(ticker, length(ticker) - 14, 6))) = toDate(toTimeZone(window_start, 'America/New_York'))) / sum(toFloat64(volume)), 1) AS zero_dte_pct,
       uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS sessions
FROM global_markets.options_minute_aggs
WHERE window_start >= toDateTime('2026-06-01 00:00:00')
  AND window_start < toDateTime('2026-07-01 00:00:00')

O custo para negociar, amostrado mensalmente

QuerySPY median quoted spread em uma sessão de amostra rotulada por mês (segundas quartas-feiras), cada atualização NBBO
O SQL exato por trás de cada número
SELECT toDate(toTimeZone(sip_timestamp, 'America/New_York')) AS session,
       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), 3) 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 = 'SPY'
  AND ((sip_timestamp >= toDateTime64('2026-01-14 14:30:00', 9) AND sip_timestamp < toDateTime64('2026-01-14 21:00:00', 9))
    OR (sip_timestamp >= toDateTime64('2026-02-11 14:30:00', 9) AND sip_timestamp < toDateTime64('2026-02-11 21:00:00', 9))
    OR (sip_timestamp >= toDateTime64('2026-03-11 13:30:00', 9) AND sip_timestamp < toDateTime64('2026-03-11 20:00:00', 9))
    OR (sip_timestamp >= toDateTime64('2026-04-15 13:30:00', 9) AND sip_timestamp < toDateTime64('2026-04-15 20:00:00', 9))
    OR (sip_timestamp >= toDateTime64('2026-05-13 13:30:00', 9) AND sip_timestamp < toDateTime64('2026-05-13 20:00:00', 9))
    OR (sip_timestamp >= toDateTime64('2026-06-10 13:30:00', 9) AND sip_timestamp < toDateTime64('2026-06-10 20:00:00', 9)))
GROUP BY session
ORDER BY session ASC

O spread mediano cotado do SPY na segunda quarta-feira de cada mês: 0.145 bps na amostra de janeiro, 0.144 na de fevereiro, aproximadamente o dobro desse valor durante as amostras da primavera, e 0.409 bps na amostra de junho — o maior dos seis meses. Observação sobre o basis: estas são sessões de amostra rotuladas individualmente (a segunda quarta-feira de cada mês), não medianas de todo o mês — um escaneamento de todo o tape de seis meses excede o orçamento de consulta desta página. As datas das amostras estão no painel, e cotações inválidas são contabilizadas lá, em vez de serem descartadas silenciosamente.

Os nomes de destaque do semestre

Notabilidade medida, não editorial: a lista abaixo apresenta o topo do ranking de volume financeiro do trimestre, recalculado aqui para que esta página apresente seus próprios dados, e cada nome que teve análise detalhada possui um link para ela.

QueryVolume em dólar no Q2 em regular hours, tape total (um símbolo reutilizado excluído aguardando verificação)
O SQL exato por trás de cada número
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

MU negociou mais que o SPY durante o segundo trimestre ($2047.5 bilhões contra $2032 bilhões) — o mesmo dado que o resumo do Q2 apresenta. Para as seis ações individuais nesse grupo de líderes, o semestre:

QueryRetornos do semestre e Q2 do grupo de líderes mais volume em dólar no semestre — uma consulta filtrada por ticker
O SQL exato por trás de cada número
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, (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', 'NVDA', 'TSLA', 'SNDK', 'AMD', 'INTC')
  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

O setor de memória e semicondutores dominou o semestre: SNDK rendeu 830.1% em seis meses, MU 290% — sua análise detalhada de junho está disponível aqui — e INTC 269.3%. NVDA, o maior volume do grupo com $3287.9 bilhões de turnover semestral, rendeu 5.2% — um dígito enquanto as ações de memória multiplicaram; sua análise detalhada de junho detalha essa divergência sessão por sessão. TSLA é a única ação em queda no grupo, com -8.2%. A mega-listagem de junho negocia sob um ticker reaproveitado e está excluída das varreduras de líderes até a verificação da entidade — seu primeiro mês possui um post com dados detalhados. Base: o SET de líderes é escolhido pelo volume financeiro em horário regular do Q2 (a varredura acima); as colunas de retorno referem-se ao semestre, do primeiro fechamento ao último fechamento em horário regular.

A onda de IPOs do semestre, mês a mês

QueryNovos listings por mês ao longo do semestre
O SQL exato por trás de cada número
SELECT toString(toStartOfMonth(listing_date)) AS m, count() AS listings
FROM global_markets.stocks_ipos
WHERE listing_date >= toDate('2026-01-01') AND listing_date <= toDate('2026-06-30')
GROUP BY m
ORDER BY m

A onda de listagens foi concentrada no início e irregular: fevereiro foi o mês mais movimentado do semestre, com 47 listagens, enquanto março foi o mais calmo, com 17 — a famosa mega-listagem de junho ocorreu em um mês de volume comum (35 listagens).

O calendário do semestre

QueryCalendário corporativo do H1 2026 (todos os três gaps de fechamento de mês do índice divulgados)
O SQL exato por trás de cada número
SELECT
    (SELECT count() FROM global_markets.stocks_dividends WHERE ex_dividend_date >= toDate('2026-01-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-01-01') AND execution_date <= toDate('2026-06-30')) AS splits,
    (SELECT count() FROM global_markets.stocks_ipos WHERE listing_date >= toDate('2026-01-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-01-01') AND filing_date <= toDate('2026-06-30')) AS h1_filings,
    (SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date = toDate('2026-03-31')) AS filings_mar31,
    (SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date = toDate('2026-04-30')) AS filings_apr30,
    (SELECT uniqExact(accession_number) FROM global_markets.stocks_sec_edgar_index WHERE filing_date = toDate('2026-06-30')) AS filings_jun30

205 empresas abriram capital no semestre — uma onda de listagens cujo maior debut em junho possui seu próprio post detalhado por recibo — além de 830 splits e 28356 eventos ex-dividend. Para fins de comparação, isso representa mais de uma nova listagem por sessão de negociação ao longo do semestre. O total de registros apresenta uma tripla divulgação: o índice da SEC está quase vazio em cada fechamento de mês do semestre cujo último dia do calendário foi um dia útil (55 registros indexados em 31 de março, 34 em 30 de abril, e 31 em 30 de junho, contra milhares em dias adjacentes), portanto, a contagem de registros do semestre está subestimada até que o feed seja atualizado — a lacuna de fechamento de mês possui sua própria nota diagnóstica.

O resumo da sessão

Query123 sessões no semestre, verificadas no tape
O SQL exato por trás de cada número
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-01-01 00:00:00') AND window_start < toDateTime('2026-07-01 00:00:00')) AS h1_sessions

Notas de dados

Notas completas de dados
  • O short interest termina no fechamento de 15 de junho conforme a geração (o print de fim de junho está pendente — detalhes completos no resumo de junho; este post é atualizado quando os dados chegarem).
  • Três dias de fechamento de mês de 2026 no índice estão quase vazios (31 de março, 30 de abril, 30 de junho — todos os fechamentos de mês do semestre cujo último dia do calendário foi um dia útil); os dados são divulgados junto com as contagens, conforme detalhado em nota sobre a lacuna de fechamento de mês. Os fechamentos de meses do ano anterior possuem milhares de registros, portanto, trata-se de uma lacuna no feed, não de um feriado de registro.
  • O leaderboard em escala de metade do ano é limitado: um escaneamento de seis meses de todo o mercado excede o orçamento de consulta que esta página gera, portanto, o conjunto de nomes notáveis é escolhido pelo escaneamento de líder em escala trimestral mostrado no texto, e os retornos do semestre são calculados para esse conjunto fixo — a base é declarada onde é utilizada. Os resumos do Q2 e junho contêm as tabelas completas de líderes em suas respectivas escalas.
  • A amplitude de todo o mercado em escala de metade do ano também é limitada — a divisão por granularidade diária é exibida; as contagens por ticker estão disponíveis em escala mensal e trimestral, linkadas na seção de amplitude.
  • A série histórica do QQQ é mais curta que a do SPY: o fundo operou sob um símbolo raiz diferente durante alguns anos; o limite de contagem de sessões exclui esses anos visivelmente (as contagens de sessões por ano estão na tabela).
  • Os seis painéis de opções são escaneamentos mensais de toda a fita e a amostra de tendência de spread utiliza uma sessão rotulada por mês — ambos rodam no caminho de processamento em lote; as bases das amostras são declaradas no texto.
  • A microestrutura está detalhada no análise profunda de 29 de junho.

Metodologia

  • O período compreende de 1º de janeiro a 30 de junho de 2026 — 123 sessões, verificadas a partir de barras observadas. Os retornos consideram o intervalo entre a abertura e o fechamento do horário regular de cada janela, todos calculados nas mesmas consultas exibidas.
  • Comparações históricas são recalculadas em tempo real contra o histórico completo de minutos no momento da geração — nunca são lidas de valores armazenados. Verificação de profundidade: a data da primeira barra de minuto na visualização atrasada utilizada aqui coincide com a da tabela base (setembro de 2003), conferida durante a elaboração; portanto, o primeiro semestre completo disponível é o de 2004. Cada consulta de histórico define seu limite superior no fim deste período (o conjunto de comparação não cresce quando anos posteriores são ingeridos) e aplica uma trava de sessões mínimas com contagens anuais exibidas.
  • Os timestamps são armazenados em UTC com limites brutos em UTC. Blocos de histórico plurianuais filtram o horário regular pelo relógio de parede do Eastern Time (9:30–15:59, convertido por linha — a única convenção segura contra o horário de verão ao longo das décadas); blocos de janela única em intervalos apenas em EDT utilizam a banda bruta de UTC equivalente. Ambas as convenções estão declaradas aqui.
  • A geração ocorre via caminho de leitura restrito; a página pública nunca consulta dados ao vivo. Estado do warehouse em 5 de julho de 2026.

Esta é a primeira edição do recap semestral recorrente; a edição do ano completo será publicada em janeiro. Detalhes do trimestre: Q2 2026. Os dados macroeconômicos contra os quais o semestre é comparado estão em o cenário macro.