Что такое индекс High-Low и как он работает
Индекс High-Low представляет собой десятидневное среднее значение процента новых максимумов. Узнайте формулу расчета на простых числах и риски использования малых выборок.
Индекс High-Low — это показатель рыночной широты, основанный на двух значениях: 10-дневном простом скользящем среднем процента новых максимумов (Record High Percent). Процент новых максимумов — это количество новых 52-недельных максимумов, деленное на сумму новых 52-недельных максимумов и новых 52-недельных минимумов, умноженное на 100. Значение выше 50 означает, что количество акций, обновивших максимумы, превышает количество акций, обновивших минимумы; значение ниже 50 указывает на обратное. Формула предельно проста. Ниже приведен расчет в округленных числах и описание изъяна выборки, из-за которого убедительно выглядящий показатель может опираться лишь на горстку акций.
Как рассчитывается индекс High-Low?
Два шага, каждый из которых умещается в одну строку.
- Процент новых максимумов (Record High Percent) для одной сессии: подсчитайте количество акций в вашей выборке, закрывшихся на новом 52-недельном максимуме, и количество акций, закрывшихся на новом 52-недельном минимуме. Разделите число максимумов на сумму этих двух значений, затем умножьте на 100.
- Индекс High-Low: усредните последние 10 ежедневных значений процента новых максимумов.
Округленные числа делают расчет наглядным. На ленте зафиксировано 90 новых максимумов и 30 новых минимумов. Сумма максимумов и минимумов равна 120; 90, деленное на 120, дает 0,75, значит, процент новых максимумов за эту сессию равен 75. Теперь возьмем десять сессий: 75, 70, 65, 60, 55, 50, 45, 40, 35 и 30. Их сумма составляет 525, а 525, деленное на 10, дает 52,5. Индекс High-Low равен 52,5 в день, когда процент новых максимумов составил 75.
Этот разрыв — результат работы скользящего среднего. Десятидневная «память» сглаживает ряд, который может за ночь измениться от 100 до 0, ценой запоздалой реакции. Индекс показывает, какой была широта рынка в течение двух недель. Он не отвечает на вопрос, что произошло сегодня днем.
Что считается новым 52-недельным максимумом?
Акция достигает нового 52-недельного максимума, когда ее цена превышает любую цену, зафиксированную за предыдущие 52 недели. Поставщики данных расходятся в методологии: одни сравнивают внутридневные максимумы и минимумы, другие — только цены закрытия, что дает разные результаты для одной и той же сессии. На этой странице везде используются цены закрытия. Новые 52-недельные максимумы и минимумы содержит сам список.
В приведенной ниже панели подсчитаны оба экстремума для фиксированной корзины из 40 крупных американских компаний за период с 1 апреля по 31 июля 2026 года. Такой размер корзины позволяет легко проверить расчеты вручную, что позже сделает очевидным изъян в формуле.
Точный SQL-код для каждого числа
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За 77 сессий эти два показателя редко растут одновременно. Jul 29, в последнюю сессию периода, 3 из 40 бумаг закрылись на 52-недельном максимуме, а 0 — на 52-недельном минимуме. Apr 1, в первую сессию, соотношение составило 1 максимумов к 1 минимумам. Все остальные бумаги в корзине остались внутри своего диапазона и не попали в расчет.
Какое значение индекса High-Low считается хорошим?
Отметка 50 является точкой равновесия между максимумами и минимумами. Общепринятым индикатором силы является уровень 70, где новые максимумы превышают новые минимумы более чем в два раза в среднем за 10 дней. Общепринятый индикатор слабости — зеркальная отметка 30. В диапазоне от 30 до 70 индекс указывает на смешанные рыночные экстремумы, где он и находится большую часть времени.
На графике ниже представлен необработанный ежедневный процент новых максимумов в сравнении с его 10-дневным средним для той же корзины. Лаг (задержка) виден на графике, а не описан словами.
Точный SQL-код для каждого числа
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Отображаемый диапазон начинается с процента новых максимумов 100 на Apr 15, при значении индекса 52.5. Он заканчивается на 100 на Jul 29, индекс 64. Сравнивайте каждое значение с отметками 70 и 30, а расстояние между двумя линиями воспринимайте как цену сглаживания: в любой день среднее значение все еще учитывает девять предыдущих сессий. Первые девять сессий периода исключены из панели, так как для 10-дневного среднего нужно 10 дней.
Знаменатель игнорирует большую часть рынка
Вот ограничение, которое важно учитывать. Знаменатель процента новых максимумов — это новые максимумы плюс новые минимумы, и ничего больше. Акция, находящаяся в середине своего 52-недельного диапазона, не попадает ни в числитель, ни в знаменатель. Индекс не может отличить сессию, где 900 из 3000 бумаг достигли экстремума, от той, где это сделали 9 бумаг, и в обоих случаях выдает уверенное двузначное число.
Представьте биржу с 6000 бумаг в спокойную августовскую сессию: 40 акций обновили максимумы, 20 — минимумы. Процент новых максимумов равен 40, деленным на 60, то есть 66,7, что выглядит как широкий рост. Это значение вычислено на основе 1% листингов. Остальные 5940 бумаг не участвовали в голосовании.
Корзина из 40 бумаг наглядно демонстрирует это. Каждая сессия в периоде распределена по корзинам в зависимости от того, сколько бумаг достигли какого-либо экстремума.
Точный SQL-код для каждого числа
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В 39 сессиях в корзине 1 to 3 names весь показатель основывался в среднем на 2 бумагах из 40. Медианный процент новых максимумов в этих сессиях составил 100, а отклонение от отметки 50 — 50 пунктов. В 10 or more names сессиях, 1 из которых пришлись на среднее значение 10 бумаг, медианное значение составило 70, а отклонение от центра — 20 пунктов.
Арифметика ограничивает возможности «тонкой» сессии. Если экстремума достигли три бумаги, возможные значения — только 0, 33,3, 66,7 и 100. Если две бумаги — только 0, 50 и 100. Значение 66,7, полученное на основе двух максимумов и одного минимума, содержит десятичную дробь, которую выборка не может обосновать. Правильная привычка: всегда смотрите на необработанные данные о количестве максимумов и минимумов рядом с индексом, а не только на сам индекс.
Рыночная широта: индекс High-Low против линии «рост/падение»
Оба показателя оценивают участие акций. Они делают это на разных временных горизонтах. Широта по линии «рост/падение» (advance/decline) учитывает каждую бумагу, которая закрылась выше или ниже вчерашнего дня. Ее знаменатель — вся совокупность акций, и она описывает один день. Индекс High-Low учитывает только бумаги на 52-недельном экстремуме. Его знаменатель мал, и он описывает положение цен относительно годовой истории. Лента может быть широко растущей в течение дня, в то время как лишь немногие бумаги находятся вблизи 52-недельного максимума.
На панели ниже оба показателя сглажены за те же 10 сессий по той же корзине, что позволяет привести их к одной шкале.
Точный SQL-код для каждого числа
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Пара начинает отображаемый диапазон с 52.5 для индекса High-Low и 52.8 для 10-дневной доли растущих акций на Apr 15, и заканчивает на 64 и 52.5 на Jul 29, за 68 сессий. Доля растущих акций находится в узком диапазоне. Примерно половина корзины закрывается ростом в обычную сессию, и усреднение десяти таких дней оставляет линию около середины шкалы. У индекса High-Low нет такого якоря. Когда ни одна бумага в корзине не обновляет 52-недельный минимум в течение десяти сессий подряд, каждое ежедневное значение равно 100, и среднее значение также равно 100.
Широту рынка лучше оценивать вместе с показателями участия. Относительный объем показывает, торгуется ли бумага сегодня необычно активно по сравнению с собственной нормой. Крупнейшие ценовые движения недели показывает, какие бумаги действительно совершили значительное движение, а акции с необычным объемом на этой неделе — где сосредоточились торги.
Часто задаваемые вопросы об индексе High-Low
Что означает значение индекса High-Low выше 70?
Это означает, что новые 52-недельные максимумы превысили новые 52-недельные минимумы более чем в два раза в среднем за последние десять сессий. Это общепринятый индикатор сильного рынка. Он ничего не говорит о том, сколько именно акций достигли экстремума, поэтому это число нужно проверять параллельно.
В чем разница между процентом новых максимумов и индексом High-Low?
Процент новых максимумов — это показатель за одну сессию: новые максимумы, деленные на сумму новых максимумов и новых минимумов, умноженные на 100. Индекс High-Low — это 10-дневное простое скользящее среднее этого показателя. Один описывает сегодняшний день. Другой описывает последние две недели.
Может ли индекс High-Low быть равен 0 или 100?
Да. Если ни одна акция в выборке не обновляет 52-недельный минимум в течение десяти сессий подряд, каждое ежедневное значение равно 100, как и среднее. Когда ни одна акция не обновляет ни максимум, ни минимум, знаменатель дроби равен нулю, и для этой сессии значение индекса не определено.
Является ли индекс High-Low тем же самым, что и широта по линии «рост/падение»?
Нет. Широта «рост/падение» использует в знаменателе всю совокупность акций и описывает направление одного дня. Индекс High-Low использует в знаменателе небольшую группу акций на 52-недельных экстремумах и описывает положение относительно цен за год.
Сколько акций обычно входит в знаменатель индекса High-Low?
В корзине из 40 бумаг, измеренной здесь с апреля по июль 2026 года, сессии в корзине 1 to 3 names имели в среднем 2 бумаг в знаменателе. В масштабах всей биржи абсолютные значения выше, но они все равно остаются лишь малой частью всех листингов, поэтому необработанные данные должны быть на экране рядом с индексом.
Каждый подсчет на этой странице является сохраненным версионированным запросом по ценам закрытия. Откройте любую панель, чтобы прочитать SQL-код, лежащий в ее основе, или создайте ту же серию широты рынка на собственной корзине в терминале Strasmore.