Strasmore Research
Aprendizado Matt ConnorPor Matt Connor · Atualizado 2026-08-08

O que é o High-Low Index? Amplitude do mercado

O High-Low Index é a média de 10 dias do Record High Percent. Veja a fórmula com números arredondados e a armadilha do tamanho da amostra em um mercado calmo.

O High-Low Index é uma medida de amplitude do mercado baseada em duas contagens. Ele corresponde à média móvel simples de 10 dias do Record High Percent. O Record High Percent é calculado dividindo-se o número de novas máximas de 52 semanas pela soma das novas máximas e das novas mínimas de 52 semanas e multiplicando-se o resultado por 100. Uma leitura acima de 50 indica que mais ações estão registrando novas máximas do que novas mínimas. Uma leitura abaixo de 50 indica o contrário. A fórmula é curta. A seguir, mostramos a aritmética com números arredondados e o problema do tamanho da amostra, que permite que uma leitura aparentemente decisiva se baseie em um punhado de ações.

Como calcular o High-Low Index?

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

  1. Record High Percent, 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 o número de máximas pela soma das duas contagens e multiplique por 100.
  2. High-Low Index: calcule a média das últimas 10 leituras diárias de Record High Percent.

Números simples ajudam a visualizar. O mercado 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 Record High Percent 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 High-Low Index marca 52,5 em um dia cujo Record High Percent foi 75.

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

O que é considerado uma nova máxima de 52 semanas?

Uma ação atinge 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 de comparação: alguns usam as máximas e mínimas intradiárias; outros consideram apenas os preços de fechamento. Os dois critérios produzem contagens diferentes para a mesma sessão. Nesta página, os preços de fechamento são usados em todos os casos. Novas máximas e mínimas de 52 semanas apresenta a lista em detalhe.

O painel abaixo contabiliza as duas extremidades 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 suficiente para serem verificadas manualmente. É isso que torna visível mais adiante a falha na fórmula.

QueryNovas máximas e mínimas de 52 semanas por sessão: 40 ações americanas large-cap, 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, foram 1 máximas contra 1 mínimas. Todas as demais ações da cesta ficaram dentro de suas próprias faixas e nunca entraram no cálculo.

Qual é uma boa leitura do High-Low Index?

A linha de 50 é o ponto de equilíbrio, com máximas e mínimas em balanço. O nível convencionalmente forte é 70. Nesse ponto, as novas máximas superaram as novas mínimas em mais de dois para um na média de 10 dias. O nível convencionalmente fraco é 30, o seu oposto. Entre 30 e 70, o índice indica que os extremos do mercado estão mistos. É nessa faixa que ele permanece na maior parte do tempo.

O painel abaixo mostra o Record High Percent diário bruto em comparação com a sua própria média de 10 dias para a mesma cesta. O atraso pode ser visto no gráfico, em vez de ser apenas descrito.

QueryPercentual de máximas históricas e sua média de 10 dias (índice High-Low), 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 Record High Percent de 100 em Apr 15, e o índice está em 52.5. Termina em 100 em Jul 29, com o índice em 64. Compare cada valor com as referências de 70 e 30. Observe também a distância entre as duas linhas como o custo da suavização: em qualquer dia, a média ainda incorpora nove sessões anteriores. As nove primeiras sessões da janela são excluídas do painel, pois uma média de 10 dias precisa de 10 dias.

O denominador ignora a maior parte do mercado

Esta é a limitação que vale reter. O denominador do Record High Percent é a soma de novas máximas e novas mínimas, e nada mais. Uma ação que está no meio do seu intervalo de 52 semanas não entra nem no numerador nem no denominador. O índice não consegue distinguir uma sessão em que 900 dos 3.000 ativos atingiram um extremo de outra em que apenas 9 o fizeram. Nas duas situações, ele mostra o mesmo número de dois dígitos, com aparente precisão.

Imagine uma bolsa com 6.000 ativos numa sessão lenta de agosto: 40 ações atingem novas máximas e 20 atingem novas mínimas. O Record High Percent é 40 dividido por 60, ou 66,7, uma leitura que sugere uma alta ampla. O cálculo foi feito com base em 1% dos ativos listados. Os outros 5.940 não tiveram qualquer participação.

A cesta de 40 ativos coloca isso no ecrã de forma quantificável. Cada sessão da janela é classificada numa faixa conforme o número de ativos que registou qualquer extremo.

QueryComo o denominador fica estreito: 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 da faixa 1 to 3 names, a leitura baseou-se numa média de 2 ativos entre 40. Essas sessões apresentaram um Record High Percent mediano de 100 e ficaram, em mediana, a 50 pontos da linha dos 50. As 10 or more names sessões, 1 delas com uma média de 10 ativos, apresentaram uma mediana de 70 e ficaram a 20 pontos do centro.

A aritmética limita até o que uma sessão com poucos ativos pode mostrar. Com três ativos num extremo, as únicas leituras possíveis são 0, 33,3, 66,7 e 100. Com dois ativos, são 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 esse problema é simples: leia as contagens brutas de máximas e mínimas ao lado do índice, nunca o índice isoladamente.

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

As duas medidas avaliam quantas ações estão a participar. Mas fazem isso em horizontes diferentes. A amplitude de avanço/queda contabiliza todos os ativos que fecharam em alta ou em baixa face ao dia anterior. O denominador é todo o universo de ações, e a medida descreve um dia. O índice High-Low contabiliza apenas os ativos que atingiram um extremo de 52 semanas. O denominador é menor, e a medida mostra onde as cotações estão em relação a um ano completo de histórico. O mercado pode subir de forma ampla no dia, enquanto muito poucas ações se aproximam de uma máxima de 52 semanas.

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

QueryDuas medidas de breadth, mesma cesta: índice High-Low de 10 dias vs. participação de ações em alta de 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 par inicia o intervalo representado em 52.5 para o índice High-Low e em 52.8 para a parcela de ações em alta em 10 dias, em Apr 15, e termina em 64 e 52.5, em Jul 29, ao longo de 68 sessões representadas. A parcela de ações em alta permanece numa faixa estreita. Numa sessão normal, aproximadamente metade da cesta fecha em alta. A média de dez sessões mantém a linha próxima do centro da escala. O índice High-Low não tem esse ponto de referência. Quando nenhuma ação da cesta regista uma mínima de 52 semanas durante dez sessões consecutivas, todas as leituras diárias são 100, e a média também permanece em 100.

A amplitude de mercado é mais informativa quando analisada ao lado de medidas de participação. Volume relativo indica se uma ação está a ser negociada hoje com um volume invulgarmente elevado face ao seu padrão. As maiores altas e baixas da semana mostra quais ações efetivamente se movimentaram, e ações com volume invulgar nesta semana mostra para onde foi o volume negociado.

Perguntas frequentes sobre o High-Low Index

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

Isso significa que os novos máximos de 52 semanas superaram os novos mínimos de 52 semanas por uma margem superior a two-to-one na média das últimas dez sessões. Esse é o indicador convencional de força do mercado. A leitura não informa quantas ações atingiram um extremo. Esse é o número que deve ser analisado em conjunto.

Qual é a diferença entre Record High Percent e o High-Low Index?

Record High Percent é o valor de uma única sessão: novos máximos divididos pela soma de novos máximos e novos mínimos, multiplicados por 100. O High-Low Index é a média móvel simples de dez dias desse indicador. Um descreve o dia de hoje. O outro descreve as últimas duas semanas.

O High-Low Index pode ser 0 ou 100?

Sim. Se nenhuma ação do universo atingir um novo mínimo de 52 semanas durante dez sessões consecutivas, todas as leituras diárias serão 100, assim como a média. Quando nenhuma ação atingir um novo máximo ou mínimo, a fração terá denominador zero e a sessão não terá uma leitura definida.

O High-Low Index é igual à amplitude de alta/baixa?

Não. A amplitude de alta/baixa usa todo o universo como denominador e descreve a direção de um único dia. O High-Low Index usa como denominador o pequeno grupo de ações que está em extremos de 52 semanas e descreve a posição em relação a um ano de preços.

Quantas ações normalmente entram no denominador do High-Low Index?

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


Todas as contagens desta página vêm de uma query armazenada e versionada sobre preços de fechamento. Abra qualquer painel para consultar o SQL correspondente ou reconstrua a mesma série de amplitude com uma cesta própria no terminal Strasmore.

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