Strasmore Research
Aprendizado Matt ConnorPor Matt Connor

O que é o Índice High-Low? Amplitude de mercado

O Índice High-Low é a média de 10 dias do Percentual de Máximas Recordes. Veja a fórmula com números redondos e a armadilha do tamanho da amostra.

O Índice High-Low é uma medida de amplitude de mercado calculada a partir de duas contagens: corresponde à média móvel simples de 10 dias do Percentual de Máximas Recordes, e o Percentual de Máximas Recordes é o número de novas máximas de 52 semanas dividido pela soma das novas máximas de 52 semanas e das novas mínimas de 52 semanas, multiplicado por 100. Uma leitura acima de 50 significa que mais ações estão registrando novas máximas do que novas mínimas, enquanto uma leitura abaixo de 50 indica o contrário. A fórmula é curta. A seguir, mostramos a aritmética com números redondos e a falha no tamanho da amostra que permite que uma leitura aparentemente decisiva se apoie em poucas ações.

Como calcular o Índice High-Low?

São duas etapas, ambas cabem em uma linha.

  1. Percentual de Máximas Recordes, para uma única sessão: conte as ações do seu universo que fecharam em uma nova máxima de 52 semanas, conte as que fecharam em uma nova mínima de 52 semanas, divida as máximas pela soma dos dois números e multiplique por 100.
  2. Índice High-Low: calcule a média das últimas 10 leituras diárias do Percentual de Máximas Recordes.

Números redondos tornam o cálculo concreto. Uma sessão registra 90 novas máximas e 30 novas mínimas. Máximas mais mínimas totalizam 120, e 90 dividido por 120 é 0,75. Portanto, o Percentual de Máximas Recordes dessa sessão é 75. Agora considere dez sessões com as seguintes leituras: 75, 70, 65, 60, 55, 50, 45, 40, 35 e 30. A soma é 525, e 525 dividido por 10 é 52,5. O Índice High-Low marca 52,5 em um dia cujo próprio Percentual de Máximas Recordes foi 75.

Essa diferença é o custo da média móvel. Dez dias de histórico suavizam uma série que pode passar de 100 a 0 de um dia para o outro, mas fazem o índice chegar atrasado. O índice mostra como a amplitude se comportou ao longo de duas semanas. Ele nunca mostra o que aconteceu nesta tarde.

O que conta como uma nova máxima de 52 semanas?

Uma ação estabelece uma nova máxima de 52 semanas quando seu preço supera todos os preços registrados nas 52 semanas anteriores. Os provedores de dados divergem quanto à base usada: alguns comparam as máximas e mínimas intradiárias, enquanto outros comparam apenas os preços de fechamento. Os dois métodos produzem contagens diferentes para a mesma sessão. Os preços de fechamento são a base usada em toda esta página. Novas máximas e mínimas de 52 semanas detalha a própria lista.

O painel abaixo conta os dois extremos em cada sessão para uma cesta fixa de 40 ações americanas de grande capitalização, de 1º de abril a 31 de julho de 2026. Uma cesta desse tamanho mantém as contagens pequenas o bastante para serem verificadas manualmente. Isso torna visível mais adiante a falha da fórmula.

QueryNovas máximas e mínimas de 52 semanas por sessão: 40 ações americanas de grande capitalização, abril a julho de 2026
O SQL exato por trás de cada número
WITH daily_close AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(close, window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
                     'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
                     'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
                     'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
      AND window_start >= toDateTime('2025-03-01 00:00:00')
      AND window_start < toDateTime('2026-08-01 05:00:00')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session_date
),
extremes AS (
    SELECT cur.ticker AS ticker,
           cur.session_date AS session_date,
           cur.close_px AS close_px,
           max(hist.close_px) AS high_52w,
           min(hist.close_px) AS low_52w
    FROM daily_close AS cur
    INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
    WHERE cur.session_date >= toDate('2026-04-01')
      AND hist.session_date <= cur.session_date
      AND hist.session_date > cur.session_date - 364
    GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
    SELECT session_date,
           countIf(close_px >= high_52w) AS new_highs,
           countIf(close_px <= low_52w) AS new_lows,
           countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
    FROM extremes
    GROUP BY session_date
    HAVING names_at_extreme > 0
)
SELECT session_date AS date,
       formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
       new_highs,
       new_lows
FROM daily
ORDER BY session_date
Run this yourself

Ao longo de 77 sessões, as duas contagens raramente sobem juntas. Em Jul 29, a última sessão da janela, 3 das 40 ações fecharam em uma máxima de 52 semanas e 0 fecharam em uma mínima de 52 semanas. Em Apr 1, a primeira sessão, a divisão foi de 1 máximas contra 1 mínimas. Todas as demais ações da cesta permaneceram dentro de suas próprias faixas e nunca entraram no cálculo.

Qual é uma boa leitura do Índice High-Low?

A linha de 50 é o ponto de equilíbrio, com máximas e mínimas em equilíbrio. O marcador convencional de força é 70, quando as novas máximas superaram as novas mínimas por mais de two-to-one na média de 10 dias. O marcador convencional de fraqueza é 30, o seu oposto. Entre 30 e 70, o índice indica que os extremos do mercado estão misturados. É nessa faixa que ele permanece na maior parte do tempo.

O painel abaixo mostra o Percentual de Máximas Recordes diário bruto contra a própria média de 10 dias, para a mesma cesta. A defasagem aparece no gráfico, em vez de ser apenas descrita.

QueryPercentual de máximas históricas e sua média de 10 dias (High-Low Index), cesta de 40 ações
O SQL exato por trás de cada número
WITH daily_close AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(close, window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
                     'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
                     'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
                     'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
      AND window_start >= toDateTime('2025-03-01 00:00:00')
      AND window_start < toDateTime('2026-08-01 05:00:00')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session_date
),
extremes AS (
    SELECT cur.ticker AS ticker,
           cur.session_date AS session_date,
           cur.close_px AS close_px,
           max(hist.close_px) AS high_52w,
           min(hist.close_px) AS low_52w
    FROM daily_close AS cur
    INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
    WHERE cur.session_date >= toDate('2026-04-01')
      AND hist.session_date <= cur.session_date
      AND hist.session_date > cur.session_date - 364
    GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
    SELECT session_date,
           countIf(close_px >= high_52w) AS new_highs,
           countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
    FROM extremes
    GROUP BY session_date
    HAVING names_at_extreme > 0
),
rhp AS (
    SELECT session_date,
           round(100 * new_highs / names_at_extreme, 1) AS record_high_pct
    FROM daily
),
smoothed AS (
    SELECT session_date,
           record_high_pct,
           round(avg(record_high_pct) OVER (ORDER BY session_date
                                            ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS high_low_index_pct,
           count() OVER (ORDER BY session_date
                         ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) AS sessions_in_window
    FROM rhp
)
SELECT session_date AS date,
       formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
       record_high_pct,
       high_low_index_pct
FROM smoothed
WHERE sessions_in_window = 10
ORDER BY session_date
Run this yourself

O intervalo exibido começa com um Percentual de Máximas Recordes de 100 em Apr 15, enquanto o índice estava em 52.5. Ele termina em 100 em Jul 29, com o índice em 64. Compare cada leitura com os marcadores de 70 e 30. Observe também a distância entre as duas linhas como o preço da suavização: em qualquer dia, a média ainda incorpora nove sessões anteriores. As primeiras nove sessões da janela foram excluídas do painel, pois uma média de 10 dias exige 10 dias.

O denominador ignora a maior parte do mercado

Esta é a limitação que vale lembrar. O denominador do Percentual de Máximas Recordes é formado pelas novas máximas mais as novas mínimas, e nada além disso. Uma ação que está no meio da sua faixa de 52 semanas não entra nem no numerador nem no denominador. O índice não consegue distinguir uma sessão em que 900 de 3.000 ações atingiram um extremo de outra em que apenas 9 o fizeram. Ele registra ambas com o mesmo número de dois dígitos, transmitindo a mesma aparência de convicção.

Imagine uma bolsa com 6.000 ações em uma sessão fraca de agosto: 40 ações estabelecem novas máximas e 20 estabelecem novas mínimas. O Percentual de Máximas Recordes é 40 dividido por 60, ou 66,7, uma leitura que parece indicar uma alta ampla. Mas o cálculo usou apenas 1% das ações listadas. As outras 5.940 ações não tiveram participação.

A cesta de 40 ações coloca uma versão contável desse problema na tela. Cada sessão da janela é classificada em um grupo conforme o número de ações que registrou qualquer extremo.

QueryComo o denominador fica menor: sessões agrupadas pelo número de ações em extremos de 52 semanas
O SQL exato por trás de cada número
WITH daily_close AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(close, window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
                     'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
                     'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
                     'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
      AND window_start >= toDateTime('2025-03-01 00:00:00')
      AND window_start < toDateTime('2026-08-01 05:00:00')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session_date
),
extremes AS (
    SELECT cur.ticker AS ticker,
           cur.session_date AS session_date,
           cur.close_px AS close_px,
           max(hist.close_px) AS high_52w,
           min(hist.close_px) AS low_52w
    FROM daily_close AS cur
    INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
    WHERE cur.session_date >= toDate('2026-04-01')
      AND hist.session_date <= cur.session_date
      AND hist.session_date > cur.session_date - 364
    GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
    SELECT session_date,
           countIf(close_px >= high_52w) AS new_highs,
           countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
    FROM extremes
    GROUP BY session_date
    HAVING names_at_extreme > 0
)
SELECT multiIf(names_at_extreme <= 3, '1 to 3 names',
               names_at_extreme <= 9, '4 to 9 names',
               '10 or more names') AS sample_size_bucket,
       count() AS readings,
       round(avg(names_at_extreme), 1) AS avg_names_in_denominator,
       round(quantileDeterministic(0.5)(100 * new_highs / names_at_extreme,
                                        cityHash64(session_date)), 1) AS median_record_high_pct,
       round(quantileDeterministic(0.5)(abs(100 * new_highs / names_at_extreme - 50),
                                        cityHash64(session_date)), 1) AS median_distance_from_50
FROM daily
GROUP BY sample_size_bucket
ORDER BY avg_names_in_denominator
Run this yourself

Nas 39 sessões do grupo 1 to 3 names, toda a leitura se baseou em uma média de 2 ações entre 40. Nessas sessões, o Percentual de Máximas Recordes mediano foi 100, e a leitura ficou a uma distância mediana de 50 pontos da linha de 50. As 10 or more names sessões do outro grupo, 1 delas com uma média de 10 ações, apresentaram uma mediana de 70 e ficaram a 20 pontos do meio da escala.

A aritmética limita até mesmo as leituras que uma sessão com poucos participantes pode produzir. Com três ações em um extremo, as únicas leituras possíveis são 0, 33,3, 66,7 e 100. Com duas ações, apenas 0, 50 e 100. Uma leitura de 66,7 baseada em duas máximas e uma mínima contém uma casa decimal que a amostra não sustenta. A prática que corrige o problema é simples: leia as contagens brutas de máximas e mínimas ao lado do índice. Nunca analise o índice isoladamente.

Amplitude de mercado: Índice High-Low versus avanço/queda

As duas medidas perguntam quantas ações estão participando. Mas analisam horizontes diferentes. A amplitude de avanço/queda conta todas as ações que terminaram em alta ou em baixa em relação ao dia anterior. Seu denominador é todo o universo, e a medida descreve um único dia. O Índice High-Low conta apenas as ações que estão em um extremo de 52 semanas. Seu denominador é pequeno, e a medida descreve onde os preços estão em relação a um ano inteiro de histórico. O mercado pode subir de forma ampla no dia enquanto pouquíssimas ações estão próximas de uma máxima de 52 semanas.

O painel abaixo suaviza as duas medidas ao longo das mesmas 10 sessões e usa a mesma cesta, colocando-as na mesma escala.

QueryDuas medidas de breadth, mesma cesta: High-Low Index de 10 dias vs. proporção de altas em 10 dias
O SQL exato por trás de cada número
WITH daily_close AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
           argMax(close, window_start) AS close_px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
                     'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
                     'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
                     'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
      AND window_start >= toDateTime('2025-03-01 00:00:00')
      AND window_start < toDateTime('2026-08-01 05:00:00')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session_date
),
extremes AS (
    SELECT cur.ticker AS ticker,
           cur.session_date AS session_date,
           cur.close_px AS close_px,
           max(hist.close_px) AS high_52w,
           min(hist.close_px) AS low_52w
    FROM daily_close AS cur
    INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
    WHERE cur.session_date >= toDate('2026-04-01')
      AND hist.session_date <= cur.session_date
      AND hist.session_date > cur.session_date - 364
    GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
    SELECT session_date,
           countIf(close_px >= high_52w) AS new_highs,
           countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
    FROM extremes
    GROUP BY session_date
    HAVING names_at_extreme > 0
),
prior AS (
    SELECT ticker,
           session_date,
           close_px,
           lagInFrame(close_px, 1) OVER (PARTITION BY ticker ORDER BY session_date
                                         ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
    FROM daily_close
),
breadth AS (
    SELECT session_date,
           round(100 * countIf(close_px > prev_close) / count(), 1) AS advancing_pct
    FROM prior
    WHERE session_date >= toDate('2026-04-01')
      AND prev_close > 0
    GROUP BY session_date
    HAVING count() >= 20
),
combined AS (
    SELECT d.session_date AS session_date,
           round(100 * d.new_highs / d.names_at_extreme, 1) AS record_high_pct,
           b.advancing_pct AS advancing_pct
    FROM daily AS d
    INNER JOIN breadth AS b ON d.session_date = b.session_date
),
smoothed AS (
    SELECT session_date,
           round(avg(record_high_pct) OVER (ORDER BY session_date
                                            ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS high_low_index_pct,
           round(avg(advancing_pct) OVER (ORDER BY session_date
                                          ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS advancing_pct_10d,
           count() OVER (ORDER BY session_date
                         ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) AS sessions_in_window
    FROM combined
)
SELECT session_date AS date,
       formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
       high_low_index_pct,
       advancing_pct_10d
FROM smoothed
WHERE sessions_in_window = 10
ORDER BY session_date
Run this yourself

O intervalo exibido começa em 52.5 para o Índice High-Low e em 52.8 para a participação de ações em alta na média de 10 dias, em Apr 15. Termina em 64 e 52.5 em Jul 29, ao longo de 68 sessões exibidas. A participação de ações em alta permanece em uma faixa estreita. Em uma sessão normal, cerca de metade da cesta fecha em alta. A média de dez dessas sessões mantém a linha próxima ao meio da escala. O Índice High-Low não tem esse ponto de ancoragem. Quando nenhuma ação da cesta registra uma mínima de 52 semanas durante dez sessões seguidas, cada leitura diária é 100, e a média também fica em 100.

A amplitude de mercado é mais informativa quando acompanhada de medidas de participação. Volume relativo mostra se uma ação está negociando hoje com volume excepcionalmente alto em relação ao seu próprio padrão. As maiores altas e baixas da semana mostra quais ações efetivamente se movimentaram, e ações com volume incomum nesta semana mostra para onde foi o volume negociado.

Perguntas frequentes sobre o Índice High-Low

O que significa uma leitura do Índice High-Low acima de 70?

Significa que as novas máximas de 52 semanas superaram as novas mínimas de 52 semanas por mais de two-to-one na média das últimas dez sessões. Esse é o marcador convencional de um mercado forte. A leitura não informa quantas ações atingiram algum extremo. Essa é a quantidade que deve ser verificada ao lado do índice.

Qual é a diferença entre o Percentual de Máximas Recordes e o Índice High-Low?

O Percentual de Máximas Recordes é a medida de uma única sessão: novas máximas divididas por novas máximas mais novas mínimas, multiplicado por 100. O Índice High-Low é a média móvel simples de 10 dias dessa medida. Uma descreve o dia atual. A outra descreve as duas últimas semanas.

O Índice High-Low pode ser 0 ou 100?

Sim. Se nenhuma ação do universo estabelecer uma nova mínima de 52 semanas durante dez sessões consecutivas, cada leitura diária será 100, assim como a média. Quando nenhuma ação estabelece uma nova máxima ou uma nova mínima, a fração tem denominador igual a zero e não há leitura definida para essa sessão.

O Índice High-Low é igual à amplitude de avanço/queda?

Não. A amplitude de avanço/queda divide pelo universo inteiro e descreve a direção de um único dia. O Índice High-Low divide pelo pequeno grupo de ações que estão em extremos de 52 semanas e descreve a posição dos preços em relação ao histórico de um ano.

Quantas ações normalmente estão no denominador do Índice High-Low?

Na cesta de 40 ações medida aqui entre abril e julho de 2026, as sessões do grupo 1 to 3 names tiveram, em média, 2 ações no denominador. As contagens de toda a bolsa são maiores em termos absolutos, mas continuam representando uma pequena parcela de todas as ações listadas. Por isso, as contagens brutas devem aparecer na tela ao lado do índice.


Toda contagem desta página vem de uma consulta armazenada e versionada baseada em preços de fechamento. Abra qualquer painel para consultar o SQL por trás dele ou reconstrua a mesma série de amplitude usando uma cesta própria no terminal Strasmore.

#market breadth#52-week highs#indicators#record high percent