High-Low Index là gì? Độ rộng thị trường
Tìm hiểu High-Low Index, công thức trung bình 10 ngày và ví dụ số tròn, đồng thời nhận diện bẫy cỡ mẫu khi thị trường giao dịch trầm lắng.
Chỉ số High-Low là thước đo độ rộng thị trường, được xây dựng từ hai số liệu. Đây là đường trung bình động đơn giản 10 ngày của Tỷ lệ Đỉnh cao kỷ lục (Record High Percent). Tỷ lệ Đỉnh cao kỷ lục được tính bằng số cổ phiếu lập đỉnh mới trong 52 tuần chia cho tổng số cổ phiếu lập đỉnh mới trong 52 tuần và số cổ phiếu lập đáy mới trong 52 tuần, rồi nhân với 100. Mức trên 50 cho thấy số cổ phiếu ghi nhận đỉnh mới nhiều hơn số cổ phiếu ghi nhận đáy mới. Mức dưới 50 cho thấy điều ngược lại.
Công thức chỉ ngắn như vậy. Phần tiếp theo trình bày phép tính bằng các số tròn và chỉ ra hạn chế về cỡ mẫu, khiến một chỉ số có vẻ dứt khoát lại có thể chỉ dựa trên một nhóm nhỏ cổ phiếu.
Cách tính High-Low Index như thế nào?
Gồm hai bước, mỗi bước có thể trình bày trên một dòng.
- Record High Percent trong một phiên: đếm số cổ phiếu trong phạm vi theo dõi đóng cửa tại mức cao mới trong 52 tuần, đếm số cổ phiếu đóng cửa tại mức thấp mới trong 52 tuần, lấy số mã tăng chia cho tổng số mã ở hai nhóm, rồi nhân với 100.
- High-Low Index: tính bình quân mười giá trị Record High Percent hằng ngày gần nhất.
Các con số tròn giúp minh họa rõ hơn. Thị trường ghi nhận 90 mã lập đỉnh mới và 30 mã lập đáy mới. Tổng số mã lập đỉnh và lập đáy là 120; 90 chia cho 120 bằng 0,75, nên Record High Percent của phiên đó là 75. Tiếp theo, lấy số liệu của mười phiên: 75, 70, 65, 60, 55, 50, 45, 40, 35 và 30. Tổng là 525; 525 chia cho 10 bằng 52,5. High-Low Index ở mức 52,5 trong ngày mà Record High Percent riêng của ngày đó là 75.
Khoảng chênh lệch này là cái giá phải trả khi dùng đường trung bình động. Việc ghi nhận dữ liệu trong mười ngày giúp làm mượt một chuỗi có thể chuyển từ 100 xuống 0 chỉ sau một đêm, nhưng đổi lại chỉ số phản ứng chậm. Chỉ số cho biết độ rộng thị trường đã diễn biến thế nào trong khoảng hai tuần. Nó không cho biết chiều nay đã xảy ra điều gì.
Mức nào được tính là đỉnh mới trong 52 tuần?
Một cổ phiếu lập đỉnh mới trong 52 tuần khi giá của cổ phiếu vượt mọi mức giá được ghi nhận trong 52 tuần trước đó. Các nhà cung cấp dữ liệu không thống nhất về cơ sở tính toán: một số so sánh mức cao và thấp trong phiên, trong khi số khác chỉ so sánh giá đóng cửa. Hai cách này cho ra số liệu khác nhau trong cùng một phiên. Giá đóng cửa là cơ sở được sử dụng xuyên suốt trang này. Các đỉnh và đáy mới trong 52 tuần trình bày chi tiết danh sách này.
Bảng bên dưới đếm cả hai cực trị trong từng phiên đối với một rổ cố định gồm 40 cổ phiếu vốn hóa lớn của Mỹ, trong giai đoạn từ ngày 1 tháng 4 đến ngày 31 tháng 7 năm 2026. Quy mô rổ này giữ cho số lượng đủ nhỏ để có thể kiểm tra thủ công. Nhờ đó, điểm sai trong công thức được nêu rõ ở phần sau.
Câu lệnh SQL chính xác đằng sau mỗi con số
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_dateTrong 77 phiên, hai số liệu này hiếm khi cùng tăng. Vào Jul 29, phiên cuối cùng trong khoảng thời gian, 3 trong số 40 cổ phiếu đóng cửa tại đỉnh 52 tuần và 0 đóng cửa tại đáy 52 tuần. Vào Apr 1, phiên đầu tiên, số cổ phiếu lập đỉnh là 1, còn số cổ phiếu lập đáy là 1. Mọi cổ phiếu khác trong rổ đều nằm đâu đó trong biên độ riêng của mình và không được đưa vào phép tính.
Mức High-Low Index như thế nào được xem là tốt?
Mốc 50 là điểm cân bằng, khi số mức cao và mức thấp tương đương nhau. Mốc mạnh theo quy ước là 70. Tại đây, số mức cao mới vượt số mức thấp mới với tỷ lệ cao hơn two-to-one trong toàn bộ mức trung bình 10 ngày. Mốc yếu theo quy ước là 30, tức hình ảnh đối xứng của mốc 70. Khi chỉ số nằm trong khoảng 30–70, điều đó cho thấy các cực trị của thị trường đang đan xen. Đây cũng là vùng chỉ số thường nằm trong phần lớn thời gian.
Biểu đồ bên dưới thể hiện Record High Percent hằng ngày chưa làm mượt so với mức trung bình 10 ngày của chính chỉ báo này trên cùng một rổ tài sản. Độ trễ được thể hiện trực tiếp trên biểu đồ thay vì mô tả bằng lời.
Câu lệnh SQL chính xác đằng sau mỗi con số
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_dateKhoảng dữ liệu trên biểu đồ bắt đầu với Record High Percent ở mức 100 vào Apr 15, khi chỉ số ở mức 52.5. Khoảng này kết thúc với Record High Percent ở mức 100 vào Jul 29, khi chỉ số ở mức 64. Hãy đối chiếu từng mức với các mốc 70 và 30. Đồng thời, hãy xem khoảng cách giữa hai đường là chi phí của việc làm mượt: trong bất kỳ ngày nào, mức trung bình vẫn bao gồm chín phiên cũ hơn. Chín phiên đầu tiên trong cửa sổ bị loại khỏi biểu đồ, vì mức trung bình 10 ngày cần đủ 10 ngày dữ liệu.
Mẫu số bỏ qua phần lớn thị trường
Đây là hạn chế cần ghi nhớ. Mẫu số của Record High Percent là số mã lập đỉnh mới cộng với số mã lập đáy mới, không bao gồm gì khác. Một cổ phiếu đang nằm giữa biên độ 52 tuần không xuất hiện trong cả tử số lẫn mẫu số. Chỉ số này không thể phân biệt một phiên có 900 trên tổng số 3.000 mã chạm mức cực trị với một phiên chỉ có 9 mã. Cả hai trường hợp đều được thể hiện bằng cùng một con số hai chữ số đầy vẻ chắc chắn.
Hãy hình dung một sàn giao dịch có 6.000 mã trong một phiên tháng Tám trầm lắng: 40 cổ phiếu lập đỉnh mới và 20 cổ phiếu lập đáy mới. Record High Percent bằng 40 chia cho 60, tương đương 66,7, cho thấy một nhịp tăng có vẻ lan tỏa. Nhưng chỉ 1% số mã niêm yết được dùng để tính chỉ số. 5.940 mã còn lại không có quyền biểu quyết.
Rổ 40 mã đưa vấn đề này lên màn hình dưới dạng có thể đếm được. Mỗi phiên trong khoảng thời gian theo dõi được xếp vào một nhóm dựa trên số mã chạm bất kỳ mức cực trị nào.
Câu lệnh SQL chính xác đằng sau mỗi con số
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_denominatorTrong 39 phiên thuộc nhóm 1 to 3 names, toàn bộ kết quả chỉ dựa trên trung bình 2 mã trong tổng số 40 mã. Các phiên đó có Record High Percent trung vị là 100 và cách đường 50 điểm trung vị 50 điểm. Nhóm gồm 10 or more names phiên, trong đó 1 phiên có trung bình 10 mã, có mức trung vị 70 và cách điểm giữa 20 điểm.
Phép tính này giới hạn những gì một phiên thanh khoản thấp có thể thể hiện. Khi có ba mã chạm mức cực trị, các giá trị duy nhất có thể xuất hiện là 0, 33,3, 66,7 và 100. Khi có hai mã, chỉ có thể là 0, 50 hoặc 100. Một mức 66,7 được tạo từ hai mã lập đỉnh mới và một mã lập đáy mới chứa dấu thập phân mà quy mô mẫu không đủ để hỗ trợ. Cách khắc phục rất rõ ràng: hãy đọc số lượng mã lập đỉnh mới và lập đáy mới bên cạnh chỉ số, không bao giờ chỉ nhìn vào chỉ số.
Độ rộng thị trường: High-Low Index và advance/decline
Cả hai thước đo đều trả lời câu hỏi có bao nhiêu cổ phiếu đang tham gia vào xu hướng. Tuy nhiên, chúng sử dụng các khung thời gian khác nhau. Độ rộng advance/decline đếm mọi mã đóng cửa tăng hoặc giảm so với phiên trước. Mẫu số là toàn bộ nhóm cổ phiếu, và chỉ báo mô tả diễn biến trong một ngày. High-Low Index chỉ đếm các mã đang ở mức cực trị trong 52 tuần. Mẫu số nhỏ hơn, và chỉ báo cho biết giá đang nằm ở đâu so với lịch sử cả năm. Thị trường có thể tăng trên diện rộng trong ngày, trong khi rất ít mã ở gần mức cao nhất 52 tuần.
Biểu đồ dưới đây làm mượt cả hai thước đo trong cùng 10 phiên, trên cùng một rổ cổ phiếu, qua đó đưa chúng về cùng một thang đo.
Câu lệnh SQL chính xác đằng sau mỗi con số
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_dateCặp chỉ báo bắt đầu khoảng dữ liệu trên biểu đồ ở mức 52.5 đối với High-Low Index và 52.8 đối với tỷ lệ cổ phiếu tăng trong 10 ngày vào Apr 15. Đến cuối khoảng này, hai mức lần lượt là 64 và 52.5 vào Jul 29, trải trên 68 phiên được biểu diễn. Tỷ lệ cổ phiếu tăng dao động trong một biên độ hẹp. Trong một phiên thông thường, khoảng một nửa số cổ phiếu trong rổ đóng cửa cao hơn. Khi lấy trung bình 10 phiên, đường chỉ báo sẽ nằm gần giữa thang đo. High-Low Index không có điểm neo như vậy. Nếu không có mã nào trong rổ ghi nhận mức thấp nhất 52 tuần trong 10 phiên liên tiếp, mọi giá trị hằng ngày đều là 100 và giá trị trung bình cũng là 100.
Độ rộng thị trường sẽ dễ phân tích hơn khi được đặt cạnh các thước đo mức độ tham gia. Khối lượng tương đối cho biết một mã hôm nay có giao dịch sôi động bất thường so với mức thông thường của chính mã đó hay không. Các cổ phiếu biến động mạnh nhất trong tuần cho thấy những mã thực sự dịch chuyển, còn các cổ phiếu có khối lượng bất thường trong tuần này cho biết dòng giao dịch tập trung ở đâu.
Câu hỏi thường gặp về High-Low Index
Chỉ số High-Low Index trên 70 có ý nghĩa gì?
Điều đó có nghĩa là số cổ phiếu lập đỉnh mới trong 52 tuần cao hơn số cổ phiếu lập đáy mới trong 52 tuần với tỷ lệ trên two-to-one, tính bình quân trong mười phiên gần nhất. Đây là dấu hiệu truyền thống cho thấy thị trường có xung lực mạnh. Chỉ số này không cho biết có bao nhiêu cổ phiếu thực sự chạm mức cực trị. Đây là số liệu cần xem cùng với High-Low Index.
Record High Percent khác High-Low Index như thế nào?
Record High Percent là số liệu của một phiên: số cổ phiếu lập đỉnh mới chia cho tổng số cổ phiếu lập đỉnh mới và lập đáy mới, rồi nhân với 100. High-Low Index là đường trung bình động đơn giản 10 ngày của số liệu đó. Một chỉ số mô tả phiên hôm nay. Chỉ số còn lại mô tả hai tuần gần nhất.
High-Low Index có thể bằng 0 hoặc 100 không?
Có. Nếu không có cổ phiếu nào trong phạm vi theo dõi lập đáy mới trong 52 tuần suốt mười phiên liên tiếp, mọi mức đọc hằng ngày đều bằng 100 và giá trị bình quân cũng bằng 100. Khi không có cổ phiếu nào lập đỉnh mới hoặc đáy mới, phân số có mẫu số bằng 0 và phiên đó không có mức đọc xác định.
High-Low Index có giống độ rộng tăng/giảm (advance/decline breadth) không?
Không. Độ rộng tăng/giảm lấy toàn bộ phạm vi cổ phiếu làm mẫu số và mô tả hướng đi trong một ngày. High-Low Index chỉ tính trên nhóm nhỏ cổ phiếu đang ở các mức cực trị trong 52 tuần. Chỉ số này mô tả vị thế của cổ phiếu so với mặt bằng giá trong một năm.
Mẫu số của High-Low Index thường gồm bao nhiêu cổ phiếu?
Trong rổ 40 cổ phiếu được đo lường tại đây từ tháng 4 đến tháng 7 năm 2026, các phiên thuộc nhóm 1 to 3 names có trung bình 2 cổ phiếu trong mẫu số. Số liệu trên toàn sàn lớn hơn về giá trị tuyệt đối nhưng vẫn chỉ chiếm một phần nhỏ trong tổng số mã niêm yết. Vì vậy, số lượng tuyệt đối cần được hiển thị cạnh chỉ số.
Mọi số liệu đếm trên trang này đều đến từ một truy vấn được lưu trữ và lập phiên bản, sử dụng giá đóng cửa. Mở bất kỳ bảng nào để xem câu lệnh SQL phía sau, hoặc xây dựng lại cùng chuỗi dữ liệu độ rộng trên một rổ cổ phiếu do bạn tự chọn trong terminal Strasmore.