Phiên giao dịch và loại lệnh trên HOSE sau KRX: ATO, ATC, MTL, lô lẻ cho người viết bot
Khoa Pham · · Kiến thức quant
> Tóm tắt nhanh: Từ ngày 05/05/2025, HOSE chuyển sang hệ thống KRX với phiên ATO 09:00–09:15, khớp liên tục đến 14:30 và ATC 14:30–14:45; lệnh thị trường MP được thay bằng MTL. Lệnh ATO/ATC không còn luôn được ưu tiên trước lệnh LO giá trần, giá sàn, sửa giá làm mất ưu tiên thời gian, còn VN30F1M mở cửa sớm hơn cổ phiếu 15 phút.
Một bot giao dịch cổ phiếu không chỉ cần tín hiệu mua bán. Nó còn phải biết lúc này sàn đang ở phiên nào, được dùng loại lệnh gì, có được hủy hay sửa lệnh không, và lệnh chưa khớp sẽ đi đâu khi hết giờ. Nhiều lỗi khi chạy bot thật đến từ những chi tiết này chứ không phải từ chiến lược.
Từ ngày 05/05/2025, Sở Giao dịch Chứng khoán TP.HCM (HOSE) chuyển sang hệ thống giao dịch KRX (Tuổi Trẻ). Khung giờ cơ bản gần như giữ nguyên, nhưng cách xử lý lệnh ATO, ATC, lệnh thị trường, sửa lệnh và lô lẻ đã thay đổi. Bài này tóm tắt các quy tắc đang áp dụng, dựa trên tài liệu hướng dẫn KRX của các công ty chứng khoán (JBSV, 10/2025, DNSE), và nhìn chúng từ góc độ người viết bot.
Cập nhật đến ngày 03/11/2026. Quy định có thể thay đổi, hãy đối chiếu với thông báo của HOSE, HNX và công ty chứng khoán của bạn trước khi chạy tiền thật.
Khớp lệnh định kỳ và khớp lệnh liên tục khác nhau thế nào
Sàn Việt Nam dùng hai cách khớp lệnh:
- Khớp lệnh định kỳ (call auction): lệnh được gom lại trong một khoảng thời gian, rồi hệ thống chọn một mức giá duy nhất để khớp càng nhiều khối lượng càng tốt. Phiên mở cửa (ATO) và đóng cửa (ATC) dùng cách này.
- Khớp lệnh liên tục: mỗi lệnh mới vào được so ngay với sổ lệnh. Nếu có lệnh đối ứng phù hợp thì khớp luôn, theo thứ tự ưu tiên giá trước, thời gian sau.
Với bot, khác biệt quan trọng nhất là: trong phiên định kỳ, bạn chỉ thấy giá dự kiến cho đến khi phiên kết thúc. Trong phiên liên tục, bạn khớp ngay nhưng phải trả chênh lệch giá mua bán (spread).
Lịch giao dịch cổ phiếu trên HOSE
Theo tài liệu so sánh quy định KRX của JBSV, lô chẵn và lô lẻ trên HOSE dùng chung khung giờ sau:
| Thời gian | Phiên | Ghi chú | | --- | --- | --- | | 09:00–09:15 | Khớp lệnh định kỳ mở cửa (ATO) | Không hủy, sửa lệnh trong phiên | | 09:15–11:30 | Khớp lệnh liên tục I | Được hủy, sửa lệnh chưa khớp | | 11:30–13:00 | Nghỉ trưa | | | 13:00–14:30 | Khớp lệnh liên tục II | | | 14:30–14:45 | Khớp lệnh định kỳ đóng cửa (ATC) | Không hủy, sửa lệnh trong phiên | | 09:00–11:30, 13:00–14:45 | Thỏa thuận trong giờ | | | 14:45–15:00 | Thỏa thuận sau giờ | |
Đơn vị giao dịch không đổi: lô chẵn là bội số của 100 cổ phiếu, tối đa 500.000 cổ phiếu mỗi lệnh; lô lẻ từ 1 đến 99 cổ phiếu (JBSV).
Cổ phiếu thuộc diện hạn chế giao dịch thì khác: chúng không khớp liên tục mà khớp theo nhiều đợt định kỳ (PCA), mỗi đợt 15 phút trong khoảng 09:15–11:30 và 13:00–14:30, và không được hủy, sửa lệnh trong 5 phút cuối mỗi đợt (DNSE). Nếu bot của bạn quét cả thị trường, hãy loại hoặc xử lý riêng nhóm mã này.
Các loại lệnh và phiên được dùng
| Loại lệnh | Ý nghĩa | Dùng trên HOSE khi nào | | --- | --- | --- | | LO (lệnh giới hạn) | Mua hoặc bán tại giá chỉ định hoặc tốt hơn | Mọi phiên | | ATO | Chấp nhận giá khớp của phiên mở cửa | Chỉ phiên ATO | | ATC | Chấp nhận giá khớp của phiên đóng cửa | Chỉ phiên ATC | | MTL (thị trường giới hạn) | Khớp ngay với lệnh đối ứng tốt nhất, phần còn lại chuyển thành LO | Phiên liên tục |
Trước KRX, HOSE dùng lệnh thị trường MP. Nay MP được thay bằng MTL. Nếu lệnh MTL không khớp hết, phần còn lại thành lệnh LO ở giá khớp gần nhất cộng 1 bước giá (lệnh mua) hoặc trừ 1 bước giá (lệnh bán) (DNSE). Nghĩa là lệnh "thị trường" có thể nằm lại trên sổ lệnh mà không khớp. Bot cần kiểm tra trạng thái lệnh sau khi gửi, đừng giả định MTL luôn khớp đủ.
Trên HNX, phiên liên tục còn có MAK (khớp một phần, phần còn lại bị hủy) và MOK (khớp toàn bộ hoặc hủy toàn bộ); một số tài liệu gọi theo tên mới là FAK và FOK.
Ba thay đổi của KRX mà bot cần biết
1. ATO, ATC không còn luôn được ưu tiên. Trước đây lệnh ATO/ATC được khớp trước mọi lệnh LO. Nay lệnh ATO/ATC không được ưu tiên trước lệnh LO mua giá trần và lệnh LO bán giá sàn đã nhập vào hệ thống trước đó (JBSV). Trên bảng giá, lệnh ATO/ATC cũng không còn hiện chữ "ATO" hay "ATC" mà hiện tại một mức giá cụ thể. Ví dụ, khi còn dư mua LO, lệnh ATO mua hiển thị ở giá dư mua cao nhất cộng 1 bước giá.
Hệ quả thực tế: khi một mã bị bán tháo và có sẵn nhiều lệnh LO bán giá sàn đặt từ trước, lệnh ATC bán của bạn sẽ xếp sau những lệnh đó. Nếu backtest giả định lệnh ATC luôn khớp ở giá đóng cửa, kết quả sẽ lạc quan hơn thực tế ở đúng những ngày xấu nhất.
2. Được sửa lệnh, nhưng sửa giá làm mất thứ tự ưu tiên. Trong phiên liên tục, bạn được sửa giá hoặc khối lượng của lệnh LO chưa khớp, nhưng không sửa cả hai cùng lúc. Sửa giá hoặc tăng khối lượng làm lệnh mất ưu tiên thời gian, còn giảm khối lượng thì giữ nguyên ưu tiên (JBSV). Lưu ý là một số công ty chứng khoán vẫn xử lý lệnh sửa bằng cách hủy lệnh cũ rồi đặt lệnh mới lên Sở, nên hãy đọc tài liệu API của nơi bạn mở tài khoản.
3. Lệnh ATC chưa khớp không tự bị hủy. Sau khi xác định giá đóng cửa, lệnh ATC hoặc phần còn lại chưa khớp sẽ hết hiệu lực nhưng không tự động bị hủy. DNSE lưu ý rằng sau 14:45, lệnh LO/ATC chưa khớp không được giải tỏa tự động; muốn giao dịch thỏa thuận sau giờ, khách hàng phải yêu cầu giải tỏa rồi đặt lại (DNSE). Với bot, điều này ảnh hưởng đến cách tính sức mua còn lại cuối ngày.
Lô lẻ trên KRX
Trước KRX, lô lẻ trên HOSE chỉ giao dịch trong phiên khớp lệnh liên tục. Nay lô lẻ được đặt lệnh giới hạn liên tục từ 09:00 đến 14:45, tức có thêm phiên ATO và ATC (Tuổi Trẻ). Trong phiên định kỳ, lô lẻ chỉ dùng lệnh có giá cụ thể (LO).
Lô lẻ hữu ích khi bot cần cân lại danh mục nhỏ, ví dụ phải bán 37 cổ phiếu cổ tức. Nhưng sổ lệnh lô lẻ là sổ riêng và thường mỏng hơn nhiều so với lô chẵn, nên giá khớp có thể lệch khá xa giá lô chẵn. Đừng dùng giá lô chẵn để mô phỏng giá khớp lô lẻ trong backtest.
Phái sinh VN30F1M chạy theo lịch khác
Hợp đồng tương lai chỉ số VN30 giao dịch trên HNX, mở cửa sớm hơn cổ phiếu 15 phút (VBSE):
| Thời gian | Phiên | Lệnh được dùng | | --- | --- | --- | | Trước 08:45 | Đặt lệnh trước giờ (được hủy, không được sửa) | ATO, LO | | 08:45–09:00 | ATO (không hủy, sửa) | ATO, LO | | 09:00–11:30 và 13:00–14:30 | Khớp lệnh liên tục | LO, MOK, MAK, MTL | | 14:30–14:45 | ATC (không hủy, sửa) | ATC, LO |
Vì vậy trong 15 phút từ 09:00 đến 09:15, VN30F1M đã khớp liên tục trong khi rổ VN30 vẫn đang trong phiên ATO. Chỉ số VN30 lúc đó chưa phản ánh giá khớp mới của cổ phiếu, nên basis (giá hợp đồng trừ chỉ số) tính trong khoảng này có thể không phản ánh đúng chênh lệch thật. Chiến lược nào dùng basis hoặc so sánh hợp đồng với chỉ số nên bỏ qua hoặc xử lý riêng 15 phút đầu.
Ví dụ: hàm xác định phiên cho bot
Đoạn Python dưới đây trả về phiên hiện tại và các loại lệnh hợp lệ, cho cổ phiếu HOSE (mã không bị hạn chế) và VN30F1M. Nó không xử lý ngày nghỉ lễ hay tạm ngừng giao dịch, bạn cần bổ sung lịch nghỉ của Sở.
from datetime import time
HOSE = [
(time(9, 0), time(9, 15), "ATO", ["ATO", "LO"]),
(time(9, 15), time(11, 30), "LIEN_TUC", ["LO", "MTL"]),
(time(13, 0), time(14, 30), "LIEN_TUC", ["LO", "MTL"]),
(time(14, 30), time(14, 45), "ATC", ["ATC", "LO"]),
]
VN30F = [
(time(8, 45), time(9, 0), "ATO", ["ATO", "LO"]),
(time(9, 0), time(11, 30), "LIEN_TUC", ["LO", "MOK", "MAK", "MTL"]),
(time(13, 0), time(14, 30), "LIEN_TUC", ["LO", "MOK", "MAK", "MTL"]),
(time(14, 30), time(14, 45), "ATC", ["ATC", "LO"]),
]
def phien_hien_tai(t, lich):
for bat_dau, ket_thuc, ten, lenh in lich:
if bat_dau <= t < ket_thuc:
duoc_huy = ten == "LIEN_TUC"
return ten, lenh, duoc_huy
return "NGOAI_GIO", [], False
for t in [time(8, 50), time(9, 5), time(11, 45), time(14, 40)]:
print(t, "| HOSE:", phien_hien_tai(t, HOSE), "| VN30F:", phien_hien_tai(t, VN30F))
Lúc 09:05, kết quả cho thấy cổ phiếu đang ở phiên ATO (không được hủy lệnh) còn VN30F1M đã khớp liên tục. Một bot đặt lệnh cổ phiếu lúc 09:05 rồi định hủy sau 2 phút sẽ bị từ chối. Đặt logic này thành một lớp kiểm tra trước khi gửi lệnh giúp tránh nhiều lỗi khó tái hiện.
Quy định có thể còn thay đổi
Tại họp báo quý III/2026 của Bộ Tài chính ngày 06/10/2026, Ủy ban Chứng khoán Nhà nước cho biết đang nghiên cứu các phương án như giao dịch xuyên trưa, nới biên độ dao động giá và xem xét bỏ một số phiên khớp lệnh định kỳ. Đây chưa phải chính sách đã quyết định và chưa có thời điểm áp dụng (Báo Văn Hóa). Vì vậy, đừng viết cứng giờ giao dịch rải rác trong code. Hãy đặt lịch phiên ở một chỗ duy nhất, như bảng trong ví dụ trên, để sửa nhanh khi quy định đổi.
Câu hỏi thường gặp
Lệnh ATC có chắc chắn khớp không? Không. Lệnh ATC chỉ khớp nếu có đủ lệnh đối ứng tại giá đóng cửa, và sau KRX nó còn xếp sau các lệnh LO giá trần, giá sàn đã đặt trước.
Bot có nên dùng lệnh MTL không? MTL tiện khi cần khớp nhanh, nhưng giá khớp phụ thuộc độ sâu sổ lệnh và phần dư có thể nằm lại. Với mã thanh khoản thấp, lệnh LO có giới hạn giá thường an toàn hơn.
Khi đã nắm phiên và loại lệnh, bước tiếp theo là đưa các ràng buộc này vào backtest để kết quả sát thực 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. Để tính chi phí khớp lệnh cho đúng, xem thêm mô hình slippage trong backtest và market microstructure là gì.