Strasmore Research
Edukasi Matt ConnorOleh Matt Connor

Apa Itu High-Low Index? Market Breadth

High-Low Index adalah rata-rata 10 hari Record High Percent. Pelajari rumus dengan angka bulat dan jebakan ukuran sampel saat pasar sepi.

Indeks High-Low adalah ukuran market breadth yang dibangun dari dua hitungan: indeks ini merupakan simple moving average 10 hari dari Record High Percent, sedangkan Record High Percent adalah jumlah new 52-week highs dibagi jumlah new 52-week highs dan new 52-week lows, lalu dikalikan 100. Angka di atas 50 berarti lebih banyak saham mencetak new highs daripada new lows, sedangkan angka di bawah 50 berarti sebaliknya. Rumusnya sesingkat itu. Bagian berikut menguraikan perhitungannya dengan angka bulat serta kelemahan ukuran sampel yang memungkinkan angka yang tampak tegas bertumpu pada segelintir saham.

Bagaimana cara menghitung Indeks High-Low?

Dua langkah, dan keduanya dapat ditulis dalam satu baris.

  1. Record High Percent untuk satu sesi: hitung saham dalam universe yang ditutup pada new 52-week high, hitung saham yang ditutup pada new 52-week low, bagi jumlah highs dengan jumlah keduanya, lalu kalikan 100.
  2. Indeks High-Low: ambil rata-rata 10 angka Record High Percent harian terakhir.

Angka bulat membuatnya lebih konkret. Dalam satu sesi, tercatat 90 new highs dan 30 new lows. Jumlah highs dan lows adalah 120, dan 90 dibagi 120 sama dengan 0,75, sehingga Record High Percent untuk sesi tersebut adalah 75. Selanjutnya, ambil 10 angka dari 10 sesi: 75, 70, 65, 60, 55, 50, 45, 40, 35, dan 30. Jumlahnya 525, dan 525 dibagi 10 sama dengan 52,5. Indeks High-Low berada di 52,5 pada hari ketika Record High Percent hari itu sendiri adalah 75.

Selisih tersebut merupakan konsekuensi dari moving average. Memori 10 hari menghaluskan rangkaian yang dapat bergerak dari 100 ke 0 dalam semalam, tetapi konsekuensinya adalah sinyal datang terlambat. Indeks ini menunjukkan kondisi breadth selama sekitar dua minggu. Indeks ini tidak pernah menunjukkan apa yang terjadi sore ini.

Apa yang dianggap sebagai new 52-week high?

Saham mencetak new 52-week high ketika harganya melampaui semua harga yang tercatat dalam 52 minggu sebelumnya. Data provider berbeda dalam menentukan basisnya: sebagian membandingkan intraday highs dan lows, sementara yang lain hanya membandingkan closing prices. Keduanya menghasilkan jumlah yang berbeda untuk sesi yang sama. Closing prices menjadi basis di seluruh halaman ini. New 52-week highs dan lows menguraikan daftar tersebut.

Panel di bawah menghitung kedua ekstrem tersebut pada setiap sesi untuk basket tetap yang terdiri atas 40 saham large-cap AS, dari 1 April hingga 31 Juli 2026. Ukuran basket ini membuat hitungannya cukup kecil untuk diperiksa secara manual. Hal itu yang nantinya membuat kelemahan rumus terlihat.

QueryNew 52-week highs dan lows setiap sesi: 40 saham large-cap AS, April hingga Juli 2026
SQL tepat di balik setiap angka
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

Dalam 77 sesi, kedua hitungan tersebut jarang meningkat secara bersamaan. Pada Jul 29, yaitu sesi terakhir dalam periode tersebut, 3 dari 40 saham ditutup pada 52-week high dan 0 ditutup pada 52-week low. Pada Apr 1, yaitu sesi pertama, perbandingannya adalah 1 highs dan 1 lows. Semua saham lain dalam basket berada di dalam kisaran masing-masing dan tidak masuk ke dalam perhitungan.

Berapa angka Indeks High-Low yang baik?

Level 50 merupakan titik tengah, ketika highs dan lows seimbang. Penanda kuat yang umum digunakan adalah 70. Pada level tersebut, jumlah new highs telah melampaui new lows dengan rasio lebih dari two-to-one dalam rata-rata 10 hari penuh. Penanda lemah yang umum digunakan adalah 30, sebagai kebalikannya. Di antara 30 dan 70, indeks menunjukkan bahwa ekstrem pasar masih beragam. Di kisaran inilah indeks biasanya berada.

Panel di bawah menampilkan Record High Percent harian mentah dan rata-rata 10 harinya untuk basket yang sama. Lag terlihat pada chart, bukan hanya dijelaskan.

QueryRecord High Percent dan rata-rata 10 harinya (High-Low Index), keranjang 40 saham
SQL tepat di balik setiap angka
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

Kisaran yang ditampilkan dibuka pada Record High Percent sebesar 100 pada Apr 15, dengan indeks di 52.5. Kisaran tersebut ditutup pada 100 pada Jul 29, dengan indeks di 64. Bandingkan masing-masing dengan penanda 70 dan 30. Jarak antara kedua garis menunjukkan biaya penghalusan: pada hari tertentu, rata-rata masih membawa sembilan sesi yang lebih lama. Sembilan sesi pertama dalam periode tersebut tidak ditampilkan karena rata-rata 10 hari membutuhkan 10 hari data.

Denominator mengabaikan sebagian besar pasar

Inilah keterbatasan yang perlu diingat. Denominator Record High Percent adalah new highs ditambah new lows, dan tidak mencakup yang lain. Saham yang berada di tengah kisaran 52 minggunya tidak masuk numerator maupun denominator. Indeks ini tidak dapat membedakan sesi ketika 900 dari 3.000 saham mencapai ekstrem dari sesi ketika hanya 9 saham yang mencapainya. Keduanya akan menghasilkan angka dua digit yang sama dan tampak meyakinkan.

Bayangkan bursa dengan 6.000 saham pada sesi Agustus yang sepi: 40 saham mencetak new highs dan 20 mencetak new lows. Record High Percent adalah 40 dibagi 60, atau 66,7, yang terlihat seperti kenaikan pasar yang luas. Namun perhitungannya hanya menggunakan 1% dari seluruh saham yang tercatat. Sebanyak 5.940 saham lainnya tidak ikut menentukan angka tersebut.

Basket yang terdiri atas 40 saham menunjukkan versi yang dapat dihitung dari masalah itu. Setiap sesi dalam periode tersebut dikelompokkan berdasarkan jumlah saham yang mencetak ekstrem apa pun.

QuerySeberapa kecil denominator: sesi dikelompokkan berdasarkan jumlah saham pada ekstrem 52-week
SQL tepat di balik setiap angka
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

Dalam 39 sesi pada bucket 1 to 3 names, seluruh angka tersebut bertumpu pada rata-rata 2 saham dari 40 saham. Sesi-sesi tersebut memiliki median Record High Percent sebesar 100 dan berada sejauh median 50 poin dari level 50. Sebanyak 10 or more names sesi, dengan 1 di antaranya memiliki rata-rata 10 saham, memiliki median 70 dan berada sejauh 20 poin dari titik tengah.

Perhitungan ini membatasi angka yang dapat dicetak oleh sesi dengan partisipasi tipis. Dengan tiga saham pada ekstrem, angka yang mungkin hanya 0, 33,3, 66,7, dan 100. Dengan dua saham, angka yang mungkin hanya 0, 50, dan 100. Angka 66,7 yang dibangun dari dua highs dan satu low memuat satu angka desimal yang tidak didukung oleh ukuran sampelnya. Kebiasaan yang dapat mengatasi masalah ini sederhana: baca jumlah highs dan lows mentah di samping indeks, dan jangan membaca indeks sendirian.

Market breadth: Indeks High-Low vs advance/decline

Kedua ukuran ini menilai berapa banyak saham yang berpartisipasi. Namun, keduanya menggunakan horizon yang berbeda. Breadth advance/decline menghitung setiap saham yang ditutup naik atau turun dibandingkan hari sebelumnya. Denominator-nya adalah seluruh universe, dan ukuran ini menggambarkan satu hari. Indeks High-Low hanya menghitung saham yang berada pada ekstrem 52 minggu. Denominator-nya kecil, dan indeks ini menunjukkan posisi harga terhadap riwayat satu tahun penuh. Pasar dapat naik secara luas pada hari tertentu, sementara hanya sedikit saham yang berada dekat dengan 52-week high.

Panel di bawah menghaluskan kedua ukuran tersebut selama 10 sesi yang sama, pada basket yang sama, sehingga keduanya berada pada skala yang sama.

QueryDua ukuran breadth, keranjang yang sama: High-Low Index 10 hari vs porsi saham yang naik 10 hari
SQL tepat di balik setiap angka
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

Kedua ukuran tersebut membuka kisaran yang ditampilkan pada 52.5 untuk Indeks High-Low dan 52.8 untuk advancing share 10 hari pada Apr 15. Keduanya berakhir pada 64 dan 52.5 pada Jul 29, selama 68 sesi yang ditampilkan. Advancing share berada dalam kisaran yang sempit. Pada sesi normal, sekitar setengah saham dalam basket ditutup lebih tinggi. Rata-rata 10 sesi membuat garisnya tetap dekat dengan titik tengah skala. Indeks High-Low tidak memiliki titik acuan seperti itu. Jika tidak ada saham dalam basket yang mencetak 52-week low selama 10 sesi berturut-turut, setiap angka harian adalah 100 dan rata-ratanya juga 100.

Breadth lebih mudah dibaca jika dilengkapi ukuran partisipasi. Relative volume menunjukkan apakah suatu saham diperdagangkan dengan volume yang jauh lebih tinggi hari ini dibandingkan normalnya. Saham dengan pergerakan terbesar minggu ini menunjukkan saham mana yang benar-benar bergerak, sedangkan saham dengan volume tidak biasa minggu ini menunjukkan ke mana aktivitas trading mengalir.

FAQ Indeks High-Low

Apa arti angka Indeks High-Low di atas 70?

Artinya, jumlah new 52-week highs melampaui jumlah new 52-week lows dengan rasio lebih dari two-to-one dalam rata-rata 10 sesi terakhir. Ini merupakan penanda umum untuk tape yang kuat. Angka tersebut tidak menunjukkan berapa banyak saham yang mencapai ekstrem. Jumlah itu harus diperiksa secara terpisah.

Apa perbedaan antara Record High Percent dan Indeks High-Low?

Record High Percent adalah angka untuk satu sesi: new highs dibagi new highs ditambah new lows, lalu dikalikan 100. Indeks High-Low adalah simple moving average 10 hari dari angka tersebut. Yang pertama menggambarkan hari ini. Yang kedua menggambarkan dua minggu terakhir.

Bisakah Indeks High-Low berada di 0 atau 100?

Bisa. Jika tidak ada saham dalam universe yang mencetak new 52-week low selama 10 sesi berturut-turut, setiap angka harian adalah 100 dan rata-ratanya juga 100. Jika tidak ada saham yang mencetak high maupun low, pecahannya memiliki denominator nol dan sesi tersebut tidak memiliki angka yang terdefinisi.

Apakah Indeks High-Low sama dengan breadth advance/decline?

Tidak. Breadth advance/decline membagi jumlah saham dengan seluruh universe dan menggambarkan arah pergerakan dalam satu hari. Indeks High-Low membagi jumlah saham dengan kelompok kecil yang berada pada ekstrem 52 minggu dan menggambarkan posisinya terhadap harga selama satu tahun.

Biasanya berapa banyak saham yang masuk denominator Indeks High-Low?

Pada basket 40 saham yang diukur di sini dari April hingga Juli 2026, sesi dalam bucket 1 to 3 names memiliki rata-rata 2 saham dalam denominator. Jumlah di seluruh bursa lebih besar secara absolut, tetapi tetap hanya sebagian kecil dari seluruh saham yang tercatat. Karena itu, jumlah highs dan lows mentah harus ditampilkan di samping indeks.


Setiap hitungan di halaman ini berasal dari stored query berversi yang menggunakan closing prices. Buka panel mana pun untuk membaca SQL di baliknya, atau bangun kembali rangkaian breadth yang sama menggunakan basket pilihan Anda di terminal Strasmore.

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