Wskaźnik High-Low Index: definicja i obliczenia
Wskaźnik High-Low Index stanowi dziesięciodniową średnią kroczącą wskaźnika Record High Percent. Analiza obejmuje wzór na liczbach zaokrąglonych oraz ryzyko błędu małej próby.
Wskaźnik High-Low jako miara szerokości rynku
Wskaźnik High-Low jest miarą szerokości rynku, obliczaną na podstawie dwóch zmiennych. Stanowi on dziesięciodniową prostą średnią kroczącą wskaźnika Record High Percent. Z kolei Record High Percent to liczba nowych 52-tygodniowych maksimów podzielona przez sumę nowych 52-tygodniowych maksimów oraz nowych 52-tygodniowych minimów, pomnożona przez sto. Odczyt powyżej pięćdziesięciu oznacza, że więcej akcji osiąga nowe maksima niż nowe minima, natomiast odczyt poniżej pięćdziesięciu wskazuje na sytuację odwrotną. Wzór jest zatem bardzo zwięzły. Poniżej przedstawiono obliczenia arytmetyczne na zaokrąglonych liczbach oraz błąd wynikający z wielkości próby, który sprawia, że rozstrzygający na pozór odczyt może opierać się na zaledwie kilku spółkach.
Jak obliczyć wskaźnik High-Low Index?
Dwa kroki, z których każdy mieści się w jednym wierszu.
- Oblicz Record High Percent dla pojedynczej sesji: zlicz akcje w swoim uniwersum, które zamknęły się na nowym 52-tygodniowym maksimum, zlicz te, które zamknęły się na nowym 52-tygodniowym minimum, podziel liczbę maksimów przez sumę obu wartości, a następnie pomnóż przez sto.
- Wskaźnik High-Low Index: wyciągnij średnią z ostatnich dziesięciu dziennych odczytów Record High Percent.
Okrągłe liczby czynią to bardziej konkretnym. Na taśmie odnotowano dziewięćdziesiąt nowych maksimów i trzydzieści nowych minimów. Suma maksimów i minimów wynosi sto dwadzieścia, a dziewięćdziesiąt podzielone przez sto dwadzieścia daje zero przecinek siedemdziesiąt pięć, zatem Record High Percent dla tej sesji wynosi siedemdziesiąt pięć. Teraz weźmy dziesięć sesji odczytów: siedemdziesiąt pięć, siedemdziesiąt, sześćdziesiąt pięć, sześćdziesiąt, pięćdziesiąt pięć, pięćdziesiąt, czterdzieści pięć, czterdzieści, trzydzieści pięć oraz trzydzieści. Ich suma wynosi pięćset dwadzieścia pięć, a pięćset dwadzieścia pięć podzielone przez dziesięć daje pięćdziesiąt dwa przecinek pięć. Wskaźnik High-Low Index wynosi pięćdziesiąt dwa przecinek pięć w dniu, w którym sam Record High Percent wyniósł siedemdziesiąt pięć.
Ta różnica to efekt działania średniej kroczącej. Dziesięciodniowa pamięć wygładza szereg, który z dnia na dzień może wahać się od stu do zera, kosztem opóźnienia sygnału. Wskaźnik odpowiada na pytanie, jak kształtowała się szerokość rynku w ciągu ostatnich dwóch tygodni. Nigdy nie odpowiada na pytanie, co wydarzyło się dzisiejszego popołudnia.
Co uznaje się za nowe maksimum 52-tygodniowe?
Akcja osiąga nowe maksimum 52-tygodniowe, gdy jej kurs przewyższa każdą cenę odnotowaną w ciągu poprzednich 52 tygodni. Dostawcy danych stosują różne podejścia: niektórzy porównują maksima i minima wewnątrzsesyjne, inni biorą pod uwagę wyłącznie ceny zamknięcia, co prowadzi do rozbieżnych wyników dla tej samej sesji. Na tej stronie podstawą są wszędzie ceny zamknięcia. Nowe maksima i minima 52-tygodniowe zawiera pełne zestawienie.
Poniższy panel zlicza oba ekstrema dla każdej sesji w ramach stałego koszyka czterdziestu amerykańskich spółek o dużej kapitalizacji w okresie od pierwszego kwietnia do trzydziestego pierwszego lipca 2026 roku. Koszyk tej wielkości pozwala na ręczną weryfikację wyników, co z kolei uwidacznia błąd w formule opisany w dalszej części.
Dokładny kod SQL dla każdej liczby
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_dateW trakcie 77 sesji oba wskaźniki rzadko rosną jednocześnie. W dniu Jul 29, czyli na ostatniej sesji w badanym okresie, 3 z czterdziestu spółek zamknęło się na poziomie maksimum 52-tygodniowego, a 0 na poziomie minimum 52-tygodniowego. W dniu Apr 1, podczas pierwszej sesji, odnotowano 1 maksimów wobec 1 minimów. Pozostałe spółki z koszyka znajdowały się wewnątrz swoich zakresów cenowych i nie zostały uwzględnione w obliczeniach.
Jaki odczyt wskaźnika High-Low Index uznaje się za korzystny?
Poziom 50 stanowi punkt zwrotny, w którym liczba nowych maksimów i minimów pozostaje w równowadze. Tradycyjnie za silny sygnał uznaje się wartość 70, przy której liczba nowych maksimów przewyższa liczbę nowych minimów w stosunku ponad dwa do jednego w ujęciu dziesięciodniowej średniej. Tradycyjnym wskaźnikiem słabości jest poziom 30, będący jego lustrzanym odbiciem. W przedziale między 30 a 70 wskaźnik sugeruje, że skrajne nastroje rynkowe są mieszane, co stanowi stan dominujący przez większość czasu.
Poniższy panel przedstawia surowy dzienny odsetek rekordowych maksimów (Record High Percent) w zestawieniu z jego dziesięciodniową średnią dla tego samego koszyka aktywów. Opóźnienie jest widoczne na wykresie, a nie opisane słownie.
Dokładny kod SQL dla każdej liczby
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_datePrezentowany zakres rozpoczyna się od odsetka rekordowych maksimów na poziomie 100 w dniu Apr 15, przy wartości wskaźnika wynoszącej 52.5. Kończy się on na poziomie 100 w dniu Jul 29, przy wartości wskaźnika 64. Każdy z tych odczytów należy odnosić do poziomów 70 i 30, natomiast dystans między dwiema liniami należy interpretować jako koszt wygładzenia danych: w każdym dniu średnia uwzględnia jeszcze dziewięć poprzednich sesji. Pierwsze dziewięć sesji z danego okresu zostało wykluczonych z panelu, ponieważ obliczenie średniej dziesięciodniowej wymaga dziesięciu dni danych.
Mianownik ignoruje większość rynku
Oto ograniczenie, o którym warto pamiętać. Mianownik wskaźnika Record High Percent to suma nowych maksimów i nowych minimów, i nic więcej. Akcja, której kurs znajduje się w połowie zakresu 52-tygodniowego, nie trafia ani do licznika, ani do mianownika. Indeks nie potrafi odróżnić sesji, w której 900 z 3000 spółek osiągnęło ekstremum, od takiej, w której zrobiło to tylko 9, i w obu przypadkach podaje ten sam dwucyfrowy wynik.
Wyobraźmy sobie giełdę z 6000 spółek podczas spokojnej sierpniowej sesji: 40 akcji ustanawia nowe maksima, 20 nowe minima. Wskaźnik Record High Percent wynosi 40 podzielone przez 60, czyli 66,7, co sugeruje szeroki wzrost. Wynik ten obliczono na podstawie 1% notowanych walorów. Pozostałe 5940 spółek nie miało żadnego wpływu na odczyt.
Koszyk 40 spółek przedstawia to w formie policzalnej. Każda sesja w danym oknie czasowym jest przypisywana do odpowiedniego przedziału w zależności od tego, ile spółek osiągnęło jakiekolwiek ekstremum.
Dokładny kod SQL dla każdej liczby
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_denominatorPodczas 39 sesji w przedziale 1 to 3 names, cały odczyt opierał się na średnio 2 spółkach z 40. Sesje te charakteryzowały się medianą Record High Percent na poziomie 100 i znajdowały się średnio 50 punktów od linii 50. Sesje 10 or more names, w liczbie 1, przy średniej 10 spółek, wykazały medianę 70 i znajdowały się 20 punktów od środka.
Arytmetyka ogranicza zakres możliwych odczytów podczas sesji o niskiej aktywności. Przy trzech spółkach na ekstremach, jedyne możliwe odczyty to 0, 33,3, 66,7 oraz 100. Przy dwóch spółkach możliwe są tylko 0, 50 i 100. Odczyt 66,7 oparty na dwóch maksimach i jednym minimum zawiera ułamek dziesiętny, którego próba statystyczna nie jest w stanie uzasadnić. Rozwiązanie tego problemu jest proste: należy zawsze analizować surowe liczby maksimów i minimów obok indeksu, nigdy nie polegać wyłącznie na samym indeksie.
Szerokość rynku: wskaźnik High-Low a linia wzrostów i spadków
Oba mierniki badają partycypację spółek w ruchu cenowym, lecz robią to w różnych horyzontach czasowych. Linia wzrostów i spadków (advance/decline) zlicza każdy walor, który zakończył sesję wyżej lub niżej względem poprzedniego dnia. Mianownikiem jest tu cały wszechświat akcji, a wskaźnik opisuje sytuację z jednej sesji. Wskaźnik High-Low uwzględnia jedynie spółki znajdujące się w ekstremach 52-tygodniowych. Jego mianownik jest niewielki, a wskaźnik określa położenie cen w odniesieniu do pełnego roku historii. Rynek może wykazywać szerokie wzrosty w ujęciu dziennym, podczas gdy bardzo niewiele spółek znajduje się w pobliżu 52-tygodniowych maksimów.
Poniższy panel wygładza oba mierniki w tym samym okresie dziesięciu sesji dla tego samego koszyka, co pozwala na ich porównanie w jednej skali.
Dokładny kod SQL dla każdej liczby
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_datePara ta otwiera wykres wartościami 52.5 dla wskaźnika High-Low oraz 52.8 dla dziesięciodniowego udziału spółek wzrostowych w dniu Apr 15, a kończy na poziomach 64 oraz 52.5 w dniu Jul 29, w trakcie 68 naniesionych sesji. Udział spółek wzrostowych oscyluje w wąskim przedziale. Mniej więcej połowa koszyka kończy sesję na plusie, a uśrednienie dziesięciu takich odczytów utrzymuje linię w pobliżu środka skali. Wskaźnik High-Low nie posiada takiego punktu odniesienia. Gdy przez dziesięć sesji z rzędu żadna spółka z koszyka nie odnotuje 52-tygodniowego minimum, każdy dzienny odczyt wynosi sto, a średnia również osiąga poziom sto.
Analiza szerokości rynku jest skuteczniejsza, gdy towarzyszą jej mierniki partycypacji. Relatywny wolumen sprawdza, czy dany walor jest dziś przedmiotem nietypowo wysokiego obrotu w stosunku do własnej normy. Największe ruchy cenowe tygodnia wskazują spółki, które faktycznie zmieniły wycenę, a spółki z nietypowym wolumenem w tym tygodniu pokazują, gdzie koncentrował się handel.
FAQ dotyczące wskaźnika High-Low Index
Co oznacza odczyt wskaźnika High-Low Index powyżej 70?
Oznacza to, że w uśrednieniu z ostatnich dziesięciu sesji liczba nowych 52-tygodniowych maksimów przewyższyła liczbę nowych 52-tygodniowych minimów w stosunku lepszym niż dwa do jednego. Jest to konwencjonalny sygnał silnego trendu wzrostowego. Wskaźnik ten nie informuje o liczbie spółek, które osiągnęły poziom ekstremalny; jest to wartość, którą należy sprawdzać równolegle.
Jaka jest różnica między Record High Percent a High-Low Index?
Record High Percent to wartość dla pojedynczej sesji: liczba nowych maksimów podzielona przez sumę nowych maksimów i nowych minimów, pomnożona przez 100. High-Low Index to 10-dniowa prosta średnia krocząca tej wartości. Pierwszy wskaźnik opisuje stan bieżący, drugi natomiast okres ostatnich dwóch tygodni.
Czy High-Low Index może przyjąć wartość 0 lub 100?
Tak. Jeśli przez dziesięć sesji z rzędu żadna spółka w danym uniwersum nie osiągnie nowego 52-tygodniowego minimum, każdy odczyt dzienny wynosi 100, podobnie jak średnia. W sytuacji, gdy żadna spółka nie osiąga ani maksimum, ani minimum, mianownik ułamka wynosi zero, a odczyt dla danej sesji jest niezdefiniowany.
Czy High-Low Index jest tym samym co wskaźnik szerokości rynku typu advance/decline?
Nie. Wskaźnik advance/decline dzieli przez całe uniwersum i opisuje kierunek ruchu w trakcie jednej sesji. High-Low Index dzieli przez niewielką grupę spółek znajdujących się w ekstremach 52-tygodniowych i opisuje pozycję względem cen z całego roku.
Ile spółek zazwyczaj znajduje się w mianowniku High-Low Index?
W przypadku koszyka 40 spółek mierzonego tutaj od kwietnia do lipca 2026 roku, sesje w przedziale 1 to 3 names obejmowały średnio 2 spółek w mianowniku. Liczby dla całych giełd są wyższe w ujęciu bezwzględnym, pozostając jednocześnie niewielkim wycinkiem wszystkich notowanych walorów, dlatego surowe dane powinny być wyświetlane obok wskaźnika.
Każda liczba na tej stronie pochodzi z zapisanego, wersjonowanego zapytania opartego na cenach zamknięcia. Otwórz dowolny panel, aby zapoznać się z kodem SQL, lub zbuduj własną serię danych o szerokości rynku dla wybranego koszyka aktywów w terminalu Strasmore.