Cổ phiếu có luôn lấp gap không? Dữ liệu
Cổ phiếu có luôn lấp gap không? Không trong mọi khung thời gian cố định. Xem tỷ lệ lấp trong cùng phiên, 5, 20 và 60 phiên, kèm SQL phía sau.
Cổ phiếu có phải lúc nào cũng lấp gap không? Không trong bất kỳ khung thời gian nào đủ ngắn để giao dịch. Nhận định này chủ yếu tồn tại vì không ai xác định rõ khung thời gian.
Gap là khoảng cách giữa giá mở cửa hôm nay và giá đóng cửa phiên chính hôm qua. Fill là thời điểm giá giao dịch quay trở lại qua mức đóng cửa trước đó. Toàn bộ lập luận phụ thuộc vào việc người đọc sẵn sàng chờ bao lâu để gap được lấp.
Gap là gì và khi nào được xem là đã lấp gap
Gap được đo bằng cách so sánh giá mở cửa với giá đóng cửa phiên trước. Phiên hôm qua kết thúc ở một mức giá, còn hôm nay mở cửa ở một mức giá khác. Phần chênh lệch đó là gap. Gap không phải là khoảng cách từ mức cao nhất hoặc thấp nhất trong phiên hôm qua. Đây là một mục tiêu khác và dễ đạt hơn nhiều. Việc đánh tráo hai khái niệm này khiến một “gap” có thể âm thầm được lấp trước giờ nghỉ trưa trong một phiên giao dịch bình thường. Gap nhỏ xuất hiện trong gần như mọi phiên. Giao dịch ở các múi giờ khác, thay đổi thành phần chỉ số, tin tức riêng lẻ của từng cổ phiếu và các điều chỉnh vào ngày giao dịch không hưởng quyền đều có thể làm thay đổi mức giá hợp lý trong khi thị trường Mỹ đóng cửa. Vì sao cổ phiếu tạo gap qua đêm trình bày nguồn gốc của quá trình định giá lại qua đêm này.
Một gap được xem là đã lấp tại thời điểm đầu tiên cổ phiếu giao dịch trở lại qua mức giá đóng cửa của phiên trước. Tuy nhiên, định nghĩa này chưa đầy đủ nếu không gắn với một thời hạn cụ thể. Trong một khoảng thời gian không giới hạn, một cổ phiếu có thanh khoản cao gần như chắc chắn sẽ chạm qua bất kỳ mức giá nào mà độc giả nêu ra. Khi đó, nhận định “gap luôn được lấp” trở thành một mệnh đề không thể kiểm chứng, chứ không phải một sự thật. Mỗi con số dưới đây đều đi kèm một khung thời gian cụ thể.
Phân tích trên toàn bài sử dụng cùng một mẫu gồm tám cổ phiếu vốn hóa lớn của Mỹ. Mẫu này bao gồm các ngày xuất hiện gap từ tháng 1 năm 2021 đến tháng 2 năm 2026. Việc lấp gap được kiểm tra dựa trên mức cao nhất và thấp nhất trong các nến một phút của phiên giao dịch thông thường. Các gap dưới 0,25% bị loại vì chỉ phản ánh sai số làm tròn.
Các gap của cổ phiếu có luôn được lấp đầy trong cùng ngày không?
Hãy bắt đầu với quy mô. Phân nhóm mọi gap theo mức độ lớn, sau đó xem liệu giá đóng cửa phiên trước có được chạm lại trước khi phiên đó kết thúc hay không.
Câu lệnh SQL chính xác đằng sau mỗi con số
WITH sessions AS
(
SELECT
ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMin(toFloat64(open), window_start) AS session_open,
argMax(toFloat64(close), window_start) AS session_close,
toFloat64(max(high)) AS session_high,
toFloat64(min(low)) AS session_low
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
AND window_start >= '2021-01-01'
AND window_start < '2026-07-01'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
GROUP BY ticker, d
),
gapped AS
(
SELECT
d,
session_open,
session_high,
session_low,
lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prior_close
FROM sessions
),
measured AS
(
SELECT
abs(100 * (session_open / prior_close - 1)) AS gap_pct,
toUInt8(if(session_open > prior_close,
session_low <= prior_close,
session_high >= prior_close)) AS filled_same_session
FROM gapped
WHERE prior_close > 0
AND d <= toDate('2026-02-28')
AND abs(100 * (session_open / prior_close - 1)) >= 0.25
)
SELECT
multiIf(gap_pct < 0.5, '0.25 to 0.5%',
gap_pct < 1, '0.5 to 1%',
gap_pct < 2, '1 to 2%',
gap_pct < 4, '2 to 4%',
'4% or more') AS gap_bucket,
count() AS gap_days,
round(100 * avg(filled_same_session), 1) AS same_session_fill_pct
FROM measured
GROUP BY gap_bucket
ORDER BY min(gap_pct) ASCCác gap nhỏ nhất trong mẫu, từ 0,25% đến 0,5%, được lấp đầy trong cùng phiên với tỷ lệ 74.6% qua 2381 lần xuất hiện. Các gap từ 4% trở lên được lấp đầy trong cùng phiên với tỷ lệ 14.8%. Độ dốc đi xuống của biểu đồ là điểm cốt lõi: gap càng nhỏ thì cổ phiếu càng thường quay lại vượt qua vùng gap trong ngày. Nói cách khác, gap nhỏ thường chỉ là nhiễu và nhiễu có xu hướng đảo chiều.
Mất bao lâu để gap được lấp đầy?
Kéo dài thời hạn quan sát thì tỷ lệ lấp đầy chỉ có thể tăng. Khoảng thời gian dài hơn sẽ bổ sung các trường hợp được lấp đầy và không loại bỏ trường hợp nào. Vấn đề là bao nhiêu phần trong tổng số đó xảy ra quá muộn để còn hữu ích.
Câu lệnh SQL chính xác đằng sau mỗi con số
WITH sessions AS
(
SELECT
ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMin(toFloat64(open), window_start) AS session_open,
argMax(toFloat64(close), window_start) AS session_close,
toFloat64(max(high)) AS session_high,
toFloat64(min(low)) AS session_low
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
AND window_start >= '2021-01-01'
AND window_start < '2026-07-01'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
GROUP BY ticker, d
),
paths AS
(
SELECT
d,
session_open,
session_high,
session_low,
lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prior_close,
min(session_low) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) AS low_5,
max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) AS high_5,
min(session_low) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS low_20,
max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS high_20,
min(session_low) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 59 FOLLOWING) AS low_60,
max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 59 FOLLOWING) AS high_60
FROM sessions
),
gaps AS
(
SELECT
session_open > prior_close AS gap_up,
prior_close,
session_low,
session_high,
low_5,
high_5,
low_20,
high_20,
low_60,
high_60
FROM paths
WHERE prior_close > 0
AND d <= toDate('2026-02-28')
AND abs(100 * (session_open / prior_close - 1)) >= 1
),
flags AS
(
SELECT arrayJoin([
(1, '1 session', toUInt8(if(gap_up, session_low <= prior_close, session_high >= prior_close))),
(2, '5 sessions', toUInt8(if(gap_up, low_5 <= prior_close, high_5 >= prior_close))),
(3, '20 sessions', toUInt8(if(gap_up, low_20 <= prior_close, high_20 >= prior_close))),
(4, '60 sessions', toUInt8(if(gap_up, low_60 <= prior_close, high_60 >= prior_close)))
]) AS f
FROM gaps
)
SELECT
tupleElement(f, 2) AS horizon,
count() AS gaps_measured,
round(100 * avg(tupleElement(f, 3)), 1) AS filled_pct
FROM flags
GROUP BY horizon
ORDER BY min(tupleElement(f, 1)) ASCTrong số các gap từ 1% trở lên ở 2191, có 34% được lấp đầy ngay trong cùng phiên và 88.7% được lấp đầy trong vòng 60 sessions. Con số thứ hai thường được trích dẫn, nhưng không nêu rõ khung thời gian. Sáu mươi phiên tương đương khoảng ba tháng giao dịch, là thời gian nắm giữ dài đối với một vị thế dựa trên một biến động lệch giá chỉ kéo dài một ngày. Một gap được lấp đầy vào ngày thứ 47, sau khi cổ phiếu trước đó đã đi xa theo hướng ngược lại, vẫn được tính là đã lấp đầy trong thống kê đó.
Khoảng trống do nhiễu và khoảng trống do thông tin là hai nhóm khác nhau
Khoảng trống giá trong một phiên yên ắng với thanh khoản thông thường chỉ là một điều chỉnh giá nhỏ. Khoảng trống xuất hiện sau tin lợi nhuận hoặc đề nghị thâu tóm phản ánh sự thay đổi trong định giá doanh nghiệp, và không còn mức giá cũ để quay về. Thanh khoản giúp phân biệt hai trường hợp này khá hiệu quả: khi toàn thị trường muốn giao dịch quanh một mức giá mới, số lượng prints thường cao hơn nhiều lần so với turnover thông thường.
Câu lệnh SQL chính xác đằng sau mỗi con số
WITH sessions AS
(
SELECT
ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
argMin(toFloat64(open), window_start) AS session_open,
argMax(toFloat64(close), window_start) AS session_close,
toFloat64(max(high)) AS session_high,
toFloat64(min(low)) AS session_low,
sum(toFloat64(volume)) AS session_volume
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
AND window_start >= '2021-01-01'
AND window_start < '2026-07-01'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
GROUP BY ticker, d
),
paths AS
(
SELECT
d,
session_open,
session_high,
session_low,
session_volume,
lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prior_close,
avg(session_volume) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN 21 PRECEDING AND 2 PRECEDING) AS normal_volume,
min(session_low) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS low_20,
max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS high_20
FROM sessions
),
measured AS
(
SELECT
session_volume / normal_volume AS volume_ratio,
toUInt8(if(session_open > prior_close, session_low <= prior_close, session_high >= prior_close)) AS filled_same_session,
toUInt8(if(session_open > prior_close, low_20 <= prior_close, high_20 >= prior_close)) AS filled_20_sessions
FROM paths
WHERE prior_close > 0
AND normal_volume > 0
AND d >= toDate('2021-03-01')
AND d <= toDate('2026-02-28')
AND abs(100 * (session_open / prior_close - 1)) >= 1
)
SELECT
multiIf(volume_ratio < 1.5, 'Under 1.5x normal',
volume_ratio < 3, '1.5x to 3x normal',
'3x or more') AS volume_regime,
count() AS gap_days,
round(100 * avg(filled_same_session), 1) AS same_session_fill_pct,
round(100 * avg(filled_20_sessions), 1) AS within_20_sessions_fill_pct
FROM measured
WHERE isFinite(volume_ratio)
GROUP BY volume_regime
ORDER BY min(volume_ratio) ASCCác khoảng trống từ 1% trở lên, với volume thấp hơn 1,5 lần turnover thông thường của cổ phiếu, được lấp đầy trong cùng phiên với tỷ lệ 35.9%. Các khoảng trống có cùng quy mô nhưng volume từ ba lần turnover thông thường trở lên được lấp đầy trong cùng phiên với tỷ lệ 15.3%, và được lấp đầy trong vòng 20 phiên với tỷ lệ 45.8%, xét trên 59 số trường hợp. Nhóm có volume cao là nơi tập trung các khoảng trống sau tin lợi nhuận và các khoảng trống do thương vụ. Gộp hai nhóm thành một con số trung bình sẽ không mô tả chính xác nhóm nào.
Vì sao những phút đầu phiên làm sai lệch thống kê gap
Một giao dịch khớp lệnh được ghi nhận lúc 9:31 sáng thường thiếu độ tin cậy. Giá mở cửa hình thành qua một phiên đấu giá, tức một lần khớp lệnh theo lô duy nhất, thiết lập cùng một mức giá cho mọi lệnh được xếp hàng qua đêm. Bài giải thích về đấu giá mở cửa của chúng tôi trình bày cơ chế này. Trong những phút sau lần khớp đó, spread được chào thường ở mức rộng nhất trong ngày. Chỉ một giao dịch nhỏ cũng có thể tạo ra mức cao hoặc thấp mà thực tế không có khối lượng đáng kể nào được giao dịch tại đó. Bài Spread mở rộng khi mở cửa giải thích vì sao báo giá tại thời điểm này lại mỏng như vậy.
Biểu đồ dưới đây cho thấy đặc điểm trên dữ liệu giao dịch của chính rổ tài sản: biên độ cao-thấp trung bình trong một phút, tính theo điểm cơ bản (một điểm cơ bản bằng một phần một trăm phần trăm), được phân theo các khung giờ mười lăm phút trong năm 2025.
Câu lệnh SQL chính xác đằng sau mỗi con số
SELECT
formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 15 MINUTE), '%H:%i') AS et_time,
round(10000 * avg(toFloat64(high) / toFloat64(low) - 1), 1) AS avg_range_bps,
round(avg(toFloat64(volume)) / 1000, 1) AS avg_volume_k
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
AND window_start >= '2025-01-01'
AND window_start < '2026-01-01'
AND toFloat64(low) > 0
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
GROUP BY et_time
ORDER BY et_time ASCKhung giờ mở cửa có biên độ trung bình 24.4 điểm cơ bản mỗi phút, so với 6.9 điểm cơ bản trong khung 12:30, với khối lượng 303.9 nghìn cổ phiếu mỗi phút so với 69.6 nghìn. Một giao dịch khớp lệnh được ghi nhận trong khung giờ đầu tiên đó dựa trên những mức giá kém tin cậy nhất trong ngày. Các số liệu trong cùng phiên nêu trên có bao gồm những phút này, nên bị đẩy cao hơn đôi chút. Lưu ý này áp dụng cho mọi thống kê về giao dịch khớp lệnh trong cùng ngày, bao gồm cả thống kê này.
Cần kiểm tra gì trước khi coi một gap là cơ hội giao dịch
- Khung thời gian. Tỷ lệ lấp gap không gắn với thời hạn cụ thể thì không phải là một thống kê có ý nghĩa.
- Phạm vi mẫu. Cần biết gap do tin tức có được tách khỏi gap trong những phiên yên ắng hay không, và tiêu chí phân loại được xác định như thế nào.
- Cách đo lường. Cần biết việc lấp gap có được kiểm định dựa trên biên độ giao dịch thực tế hay không, và những phút đầu phiên có được tính vào hay không.
- Các mã còn tồn tại. Cần biết mẫu có chỉ gồm những cổ phiếu vẫn còn giao dịch hôm nay hay không. Cách chọn mẫu này âm thầm loại bỏ những gap chưa bao giờ được lấp.
Cách diễn đạt chính xác hơn hẹp hơn nhiều so với khẩu hiệu. Các gap nhỏ trong điều kiện thanh khoản thông thường thường nhanh chóng quay về mức cũ. Các gap lớn đi kèm khối lượng cao là sự định giá lại và thường duy trì trong nhiều tháng. Để theo dõi trực tiếp những mã đang xuất hiện gap, trang các cổ phiếu tăng giảm mạnh nhất tuần này cập nhật diễn biến của tuần hiện tại. Trang thị trường phục hồi sau các cú sập như thế nào áp dụng cùng nguyên tắc về khung thời gian đối với mức giảm của chỉ số.
Câu hỏi thường gặp
Cổ phiếu có phải lúc nào cũng lấp gap không?
Không. Trong mẫu dữ liệu này, 88.7% số gap từ 1% trở lên quay lại giao dịch qua mức đóng cửa phiên trước trong vòng 60 sessions. Điều đó có nghĩa là một tỷ lệ đáng kể vẫn chưa được lấp sau khoảng ba tháng giao dịch. Mệnh đề “lúc nào cũng lấp” chỉ đúng khi không đặt giới hạn thời gian, và khi đó không còn có thể kiểm chứng.
Mất bao lâu để một gap được lấp?
Tùy loại gap. Trong dữ liệu này, 34% số gap từ 1% trở lên được lấp ngay trong cùng phiên. Các gap còn lại được lấp trong những tuần và tháng tiếp theo. Gap nhỏ chủ yếu được lấp trong ngày. Gap đi kèm thanh khoản lớn mất nhiều thời gian nhất.
Common gap khác breakaway gap như thế nào?
Thuật ngữ trên biểu đồ phân loại gap theo bối cảnh. Common gap xuất hiện trong một ngày giao dịch thông thường, với khối lượng thông thường và không có tin tức cụ thể. Breakaway gap xuất hiện cùng khối lượng lớn và thông tin mới, thường khi giá thoát khỏi một vùng giá mà cổ phiếu đã duy trì trong một thời gian. Phân tách theo khối lượng ở panel phía trên là cách đo lường cụ thể cho cùng sự khác biệt này.
Vì sao thống kê gap fill giữa các nguồn lại khác nhau nhiều như vậy?
Có bốn lựa chọn khiến con số thay đổi đáng kể: khoảng thời gian đo việc lấp gap, nhóm cổ phiếu được chọn, giai đoạn dữ liệu và cách xác định gap dựa trên giá đóng cửa phiên trước hay dựa trên mức cao và thấp của phiên trước. Một tỷ lệ gap fill không nêu rõ cả bốn yếu tố này thì không thể so sánh với tỷ lệ khác.
Cách đo lường các con số này
Các phiên được xây dựng từ dữ liệu bar một phút trong giờ giao dịch chính thức theo giờ New York. Giá mở cửa là giá mở cửa của bar đầu tiên trong phiên chính thức. Giá đóng cửa là giá đóng cửa của bar cuối cùng. Mức cao và thấp trong ngày là các cực trị của những bar này. Mỗi gap được đo so với giá đóng cửa của phiên trước của cùng ticker.
Các khoảng thời gian 5, 20 và 60 phiên đều bao gồm chính ngày xuất hiện gap. Ngày xuất hiện gap dừng ở cuối tháng 2/2026, trong khi dữ liệu giao dịch được cập nhật đến tháng 6/2026. Vì vậy, mọi gap trong panel thời gian đều có ít nhất 60 phiên tiếp theo để theo dõi. Không gap nào bị ghi nhận là chưa được lấp chỉ vì thiếu dữ liệu.
Khối lượng thông thường trong panel thứ ba là khối lượng trung bình trong phiên chính thức của 20 phiên kết thúc trước ngày thứ hai liền trước ngày xuất hiện gap. Cách tính này loại ngày xuất hiện gap và ngày liền trước đó khỏi mức chuẩn của chính chúng.
Nhóm mẫu gồm tám cổ phiếu vốn hóa lớn có thanh khoản cao. Các cổ phiếu thanh khoản thấp hơn xuất hiện gap thường xuyên hơn và có đặc điểm gap fill khác nhau. Vì vậy, không thể áp dụng các tỷ lệ này cho nhóm vốn hóa nhỏ nếu chưa chạy lại cùng phép kiểm định trên nhóm đó.
Mỗi panel trong bài đều có phần SQL chính xác ngay bên dưới. Để chạy cùng phép kiểm định trên một ticker bạn theo dõi, hãy đặt câu hỏi bằng tiếng Anh tự nhiên trên terminal Strasmore.