Bước giá và biên độ dao động: cổ phiếu HOSE, HNX, UPCoM và phái sinh VN30F1M

· · Kiến thức quant

Bước giá và biên độ dao động: cổ phiếu HOSE, HNX, UPCoM và phái sinh VN30F1M

> Tóm tắt nhanh: Bước giá cổ phiếu HOSE là 10 đồng với giá dưới 10.000 đồng, 50 đồng từ 10.000 đến 49.950 đồng và 100 đồng từ 50.000 đồng, còn HNX, UPCoM là 100 đồng. Biên độ thông thường là ±7% trên HOSE, ±10% trên HNX, ±15% trên UPCoM; hợp đồng tương lai VN30 có bước giá 0,1 điểm, tương đương 10.000 đồng mỗi hợp đồng, và biên độ ±7%.

Bước giá (tick size) là khoảng chênh nhỏ nhất giữa hai mức giá được phép đặt lệnh. Biên độ dao động là khoảng giá tối đa mà một chứng khoán được phép đi trong ngày so với giá tham chiếu, giới hạn bởi giá trần và giá sàn. Hai quy định này nghe như chi tiết kỹ thuật, nhưng chúng quyết định chi phí tối thiểu mỗi lần giao dịch, mức trượt giá và cả việc lệnh của bạn có được Sở chấp nhận hay không.

Bài này tóm tắt bước giá và biên độ đang áp dụng cho cổ phiếu trên HOSE, HNX, UPCoM và cho hợp đồng tương lai VN30, kèm đoạn Python để tính giá trần, giá sàn và làm tròn giá đặt lệnh.

Cập nhật đến ngày 03/11/2026. Khi chuyển sang hệ thống KRX từ tháng 5/2025, bước giá, lô giao dịch và biên độ được giữ như trước (JBSV, 10/2025). Hãy kiểm tra lại với thông báo của Sở trước khi dùng cho tiền thật.

Bước giá cổ phiếu trên ba sàn

Với giao dịch khớp lệnh, bước giá như sau (DNSE, JBSV):

| Sàn | Loại chứng khoán | Mức giá | Bước giá | | --- | --- | --- | --- | | HOSE | Cổ phiếu, chứng chỉ quỹ đóng | Dưới 10.000 đồng | 10 đồng | | HOSE | Cổ phiếu, chứng chỉ quỹ đóng | 10.000 đến 49.950 đồng | 50 đồng | | HOSE | Cổ phiếu, chứng chỉ quỹ đóng | Từ 50.000 đồng | 100 đồng | | HOSE | ETF, chứng quyền có bảo đảm | Mọi mức giá | 10 đồng | | HNX, UPCoM | Cổ phiếu | Mọi mức giá | 100 đồng |

Giao dịch thỏa thuận dùng bước giá 1 đồng. Lô chẵn là bội số của 100 cổ phiếu, lô lẻ từ 1 đến 99 cổ phiếu.

Điểm cần để ý là bước giá của HOSE thay đổi theo vùng giá. Một cổ phiếu giá 9.990 đồng đặt được ở 9.980 hay 10.000, nhưng khi vượt 10.000 đồng thì chỉ đặt được 10.000, 10.050, 10.100. Nếu bot tính giá đặt lệnh bằng cách cộng một số đồng cố định vào giá hiện tại, lệnh sẽ bị từ chối khi giá đi qua các ngưỡng 10.000 và 50.000.

Bước giá tương đối: chi phí ẩn của mỗi lệnh

Thứ quan trọng với người giao dịch không phải bước giá tính bằng đồng mà là bước giá tính theo phần trăm giá. Chênh lệch giá mua bán (spread) không thể nhỏ hơn một bước giá, nên muốn khớp ngay, bạn phải trả ít nhất một bước giá cho mỗi vòng mua bán.

| Giá cổ phiếu (HOSE) | Bước giá | Bước giá / giá | | --- | --- | --- | | 9.990 đồng | 10 đồng | 0,10% | | 10.000 đồng | 50 đồng | 0,50% | | 25.000 đồng | 50 đồng | 0,20% | | 49.950 đồng | 50 đồng | 0,10% | | 50.000 đồng | 100 đồng | 0,20% | | 120.000 đồng | 100 đồng | 0,08% |

Một cổ phiếu giá 10.000 đồng có bước giá tương đối gấp 5 lần một cổ phiếu giá 9.990 đồng, dù hai mức giá gần như bằng nhau. Với chiến lược giao dịch nhiều lần mỗi ngày, khác biệt này có thể lớn hơn cả lợi thế của tín hiệu. Khi backtest cổ phiếu Việt Nam, hãy mô hình chi phí trượt giá theo bước giá của từng mã, thay vì dùng một tỷ lệ phần trăm cố định cho mọi mã.

Biên độ dao động cổ phiếu

Biên độ trong ngày giao dịch thông thường là ±7% trên HOSE, ±10% trên HNX và ±15% trên UPCoM, so với giá tham chiếu (DSC). Giá tham chiếu thường là giá đóng cửa của phiên liền trước, trừ một số trường hợp đặc biệt do Sở quy định như ngày giao dịch không hưởng quyền.

Với cổ phiếu ngày đầu niêm yết hoặc giao dịch trở lại sau khi bị tạm ngừng từ 25 phiên liên tiếp trở lên, biên độ rộng hơn: ±20% trên HOSE, ±30% trên HNX và ±40% trên UPCoM (JBSV, DSC).

Giá trần và giá sàn phải là mức giá hợp lệ theo bước giá, nên chúng được làm tròn. Tài liệu của DNSE có ví dụ một cổ phiếu HOSE giá tham chiếu 39.000 đồng, giá trần 41.700 đồng và giá sàn 36.300 đồng (DNSE). Tính thô thì 39.000 × 1,07 = 41.730 và 39.000 × 0,93 = 36.270. Cả hai được làm tròn vào phía trong biên độ theo bước 50 đồng, nên biên độ thực tế hơi hẹp hơn 7%.

Hợp đồng tương lai VN30: bước giá 0,1 điểm, biên độ ±7%

Hợp đồng tương lai chỉ số VN30 (VN30F1M và các kỳ hạn khác) có quy định riêng (VBSE):

| Thông số | Giá trị | | --- | --- | | Hệ số nhân | 100.000 đồng mỗi điểm | | Bước giá | 0,1 điểm chỉ số | | Biên độ dao động | ±7% | | Đơn vị giao dịch | 1 hợp đồng | | Giá tham chiếu | Giá thanh toán cuối ngày của phiên liền trước (ngày đầu tiên dùng giá lý thuyết) |

Một bước giá 0,1 điểm tương đương 0,1 × 100.000 = 10.000 đồng cho một hợp đồng. Với hợp đồng ở mức 1.900 điểm, bước giá tương đối chỉ khoảng 0,005%, nhỏ hơn rất nhiều so với cổ phiếu. Đây là một lý do phái sinh VN30 phù hợp với chiến lược giao dịch trong ngày hơn cổ phiếu cơ sở.

Lưu ý giá tham chiếu của phái sinh là giá thanh toán cuối ngày chứ không phải giá khớp cuối cùng. Nếu bạn tự tính giá trần, giá sàn của VN30F1M từ dữ liệu nến, hãy dùng đúng cột giá thanh toán, nếu không sẽ lệch.

Ví dụ Python: làm tròn giá và tính trần, sàn

Đoạn code dưới đây cài đặt bảng bước giá HOSE, làm tròn giá đặt lệnh về mức hợp lệ, và tính giá trần, giá sàn theo cách làm tròn vào trong biên độ như ví dụ của DNSE.

import math

def buoc_gia_hose(gia):
    """Bước giá cổ phiếu HOSE (đồng), khớp lệnh."""
    if gia < 10_000:
        return 10
    if gia < 50_000:
        return 50
    return 100

def lam_tron_xuong(gia):
    b = buoc_gia_hose(gia)
    return math.floor(gia / b) * b

def lam_tron_len(gia):
    b = buoc_gia_hose(gia)
    return math.ceil(gia / b) * b

def tran_san_hose(tham_chieu, bien_do=0.07):
    tran = lam_tron_xuong(tham_chieu * (1 + bien_do))
    san = lam_tron_len(tham_chieu * (1 - bien_do))
    return tran, san

def tran_san_vn30f(tham_chieu, bien_do=0.07, buoc=0.1):
    tran = math.floor(round(tham_chieu * (1 + bien_do) / buoc, 6)) * buoc
    san = math.ceil(round(tham_chieu * (1 - bien_do) / buoc, 6)) * buoc
    return round(tran, 1), round(san, 1)

for tc in [39_000, 9_500, 48_000]:
    tran, san = tran_san_hose(tc)
    print(f"Tham chiếu {tc:>6}: trần {tran:>6}, sàn {san:>6}, "
          f"biên độ thực tế +{tran/tc-1:.2%} / {san/tc-1:.2%}")

print("VN30F tham chiếu 1900.0:", tran_san_vn30f(1900.0))
print("VN30F tham chiếu 1873.4:", tran_san_vn30f(1873.4))

Kết quả:

Tham chiếu  39000: trần  41700, sàn  36300, biên độ thực tế +6.92% / -6.92%
Tham chiếu   9500: trần  10150, sàn   8840, biên độ thực tế +6.84% / -6.95%
Tham chiếu  48000: trần  51300, sàn  44650, biên độ thực tế +6.88% / -6.98%
VN30F tham chiếu 1900.0: (2033.0, 1767.0)
VN30F tham chiếu 1873.4: (2004.5, 1742.3)

Dòng đầu khớp với ví dụ của DNSE. Dòng thứ hai cho thấy giá trần có thể nằm ở vùng bước giá khác với giá tham chiếu: tham chiếu 9.500 đồng (bước 10 đồng) nhưng trần 10.150 đồng (bước 50 đồng).

Đoạn code này để hiểu cơ chế và để kiểm tra dữ liệu. Khi chạy bot thật, hãy lấy giá trần, giá sàn do Sở công bố qua bảng giá hoặc API của công ty chứng khoán, vì có những trường hợp đặc biệt (điều chỉnh giá tham chiếu khi chia cổ tức, cổ phiếu mới niêm yết) mà công thức đơn giản không bao hết. Với phái sinh, cách làm tròn ở trên là giả định của chúng tôi, hãy đối chiếu với giá trần, sàn thực tế.

Biên độ ảnh hưởng đến backtest thế nào

Biên độ tạo ra hai tình huống mà backtest đơn giản hay bỏ qua:

  1. Không bán được khi giá nằm sàn. Khi một cổ phiếu giảm sàn với dư bán lớn, lệnh bán của bạn chỉ khớp nếu có người mua. Backtest dùng giá đóng cửa sẽ giả định bạn thoát được ở giá sàn, trong khi thực tế lệnh có thể không khớp và bạn phải giữ qua phiên sau, có khi giảm tiếp.
  2. Không mua được khi giá nằm trần. Tương tự, tín hiệu mua vào cổ phiếu tăng trần thường không khớp, nên lợi nhuận "đuổi trần" trong backtest dễ bị phóng đại.

Một cách xử lý đơn giản: trong backtest, đánh dấu những phiên mà giá đóng cửa bằng giá sàn (hoặc trần) và coi lệnh bán (hoặc mua) trong phiên đó là không khớp. Cách này còn thô vì một phần lệnh vẫn có thể khớp, nhưng nó tốt hơn giả định khớp đủ. Bạn có thể đọc thêm về các giả định khớp lệnh trong bài mô hình slippage trong backtest.

Với phái sinh, biên độ ±7% hiếm khi bị chạm trong phiên bình thường, nhưng khi chạm thì tình huống tương tự xảy ra với lệnh cắt lỗ. Chiến lược có đòn bẩy nên tính đến khả năng không đóng được vị thế trong ngày biến động cực mạnh.

Câu hỏi thường gặp

Vì sao lệnh của tôi bị từ chối dù giá nằm trong biên độ? Thường do giá không phải bội số của bước giá, ví dụ đặt 25.020 đồng cho cổ phiếu HOSE ở vùng bước 50 đồng.

Bước giá của chứng chỉ quỹ ETF trên HOSE là bao nhiêu? 10 đồng cho mọi mức giá, khác với cổ phiếu.

Biên độ có sắp thay đổi không? Ngày 06/10/2026, Ủy ban Chứng khoán Nhà nước cho biết đang nghiên cứu phương án nới biên độ, nhưng chưa quyết định và chưa có thời điểm áp dụng (Báo Văn Hóa). Hãy để biên độ là tham số trong code thay vì viết cứng.

Khi đã đưa bước giá và biên độ vào mô hình chi phí, kết quả backtest sẽ sát với giao dịch thật hơn. Bạn có thể dựng chiến lược, backtest và chạy paper trading trên nền tảng QuantVN. Nếu bạn giao dịch phái sinh, đọc thêm hướng dẫn chứng khoán phái sinh Việt Nam.