Dữ liệu trong phiên
Mục lục
Trang này viết cho vnstock_pipeline v6.0.0rc1, bản thử nghiệm. Tên hàm, tham số và cột dữ liệu có thể còn đổi trước ngày phát hành; khi cài, ghi rõ số phiên bản như ở trang Cài đặt. Bản đang phát hành chính thức là v3.1.1, xem tài liệu bản đó.
Chọn nguồn bạn có khoá, mã trên trang sẽ điền theo. Chưa chọn thì mã giữ chỗ trống <nguồn>. Nguồn xếp theo bảng chữ cái, không phải khuyến nghị.
Trong giờ giao dịch, pipeline nhận thông điệp liên tục từ nguồn, giải mã về sự kiện chuẩn, dựng nến từ khớp lệnh và ghi tệp Parquet theo nguồn, theo ngày. Một lệnh làm đủ các bước đó:
vnstock-pipeline stream run <nguồn> <kênh...> --symbols <mã> --seconds 600 --intervals 1m,5mLuồng xử lý
- Kết nối. Phần kết nối
vnstock-oapimở kết nối tới cổng stream chính thức của nguồn bằng khoá của bạn, rồi đăng ký các kênh bạn chọn. Kênh chưa khai sẵn, kênh lệnh, vị thế, tài khoản đều bị từ chối trước khi gửi đăng ký. Mất kết nối thì phần kết nối tự nối lại với thời gian chờ tăng dần và đánh dấu khoảng bị mất. - Bản thô (tuỳ chọn). Khi bật
keep_rawhoặc--keep-raw, mỗi thông điệp được ghi nguyên văn vàoraw/<nguồn>/<ngày>/stream/. - Giải mã. Thông điệp được giải mã về sự kiện chuẩn: lệnh khớp, bảng giá, chỉ số, khối ngoại… (Sự kiện chuẩn và bộ cột). Phần giải mã chạy trong lõi Rust.
- Dựng nến. Lệnh khớp ở bảng chính được gom thành nến theo các khung bạn chọn. Nến của chính nguồn (nếu có kênh nến) được ghi riêng, giữ nhãn nguồn phát.
- Ghi tệp. Cứ vài giây hoặc vài nghìn sự kiện, pipeline ghi một tệp phần cho mỗi loại sự kiện. Khi phiên kết thúc, các tệp phần trong ngày được gộp thành một tệp.
Phiên dừng khi hết --seconds, khi bạn bấm Ctrl+C, hoặc khi phần kết nối hết lượt nối lại. Phiên nào dừng cũng đóng nốt
nến đang mở, ghi phần còn lại và gộp tệp.
Nguồn hỗ trợ
| Nguồn | Cần | Ghi chú |
|---|---|---|
dnse | API Key, Secret | Mỗi lệnh khớp có giờ khớp và bảng (lô chẵn G1, lô lẻ G4, thoả thuận T1) |
tcbs | API Key, Smart OTP mỗi phiên 24 giờ | Bảng giá, khớp lệnh, phái sinh, thoả thuận, cung cầu chủ động. Kênh history_1m và match_history có giờ khớp; match, bảng giá, phái sinh mang giờ nhận. Ngoài giờ giao dịch nguồn không gửi gì, kể cả khi vừa đăng ký |
ssi | API Key, Secret (cùng khoá REST) | Giờ trong thông điệp tính tới giây |
binance | Không cần khoá | Cổng dữ liệu thị trường công khai, thị trường giao ngay. Mã cặp viết liền: BTCUSDT |
Liệt kê kênh của một nguồn ngay trên máy, kèm mẫu tham số:
vnstock-pipeline stream channels <nguồn>Kênh của dnse
| Kênh | Nhận mã | Sự kiện |
|---|---|---|
tick.{board} | Có | trade: giá, khối lượng, tổng cộng dồn |
tick_extra.{board} | Có | trade kèm bên chủ động và giá trung bình |
top_price.{board} | Có | quote: các bước giá mua, bán |
expected_price.{board} | Có | auction: giá khớp dự kiến ở phiên định kỳ |
security_definition.{board} | Có | price_limits: trần, sàn, tham chiếu, trạng thái mã |
market_index.{index} | Không | index_tick |
estimated_market_index.{index} | Không | index_estimate: chỉ số dự kiến |
market_index_influence.{index}.{resolution} | Không | index_contribution: mức đóng góp của từng mã |
foreign.{board} | Có | foreign_flow: khối ngoại mua, bán, room |
ohlc.{resolution} | Có | bar đang hình thành |
ohlc_closed.{resolution} | Có | bar đã đóng |
session.{product_group}.{board} | Không | status: chuyển phiên |
{board}: G1 lô chẵn, G4 lô lẻ, T1 thoả thuận. {resolution}: 1, 3, 5, 15, 30, 1H, 1D, 1W. Tên chỉ
số theo nguồn: VN30, VNINDEX, HNX, UPCOM (pipeline lưu thành HNXINDEX, UPCOMINDEX). Hợp đồng tương lai dùng
mã KRX, ví dụ 41I1GB000.
Kênh của tcbs
| Kênh | Nhận mã | Sự kiện |
|---|---|---|
bid, offer | Có | quote: ba bước giá mua, bán |
match | Có | trade: giá, khối lượng, tổng khối lượng, tổng giá trị, giờ nhận. Thông điệp lặp lại hoặc không làm tổng tăng mang replay = true |
history_1m | Có | trade: từng lệnh khớp cổ phiếu, có giờ khớp và bên chủ động; tổng ngày và mua, bán chủ động cộng dồn ở cột chi tiết. Tên kênh theo nguồn là lịch sử giá 1 phút |
match_history | Có, một mã | trade: từng lệnh có giờ. Khi đăng ký, nguồn có thể gửi lại các lệnh đã khớp trong ngày; các lệnh này mang replay = true |
foreign | Có | foreign_flow |
base_price | Có | price_limits |
session_stats | Có | stats: mở cửa, cao, thấp, trung bình trong phiên |
index | Có (số chỉ số) | index_tick. Mã là số của nguồn: 1 VNINDEX, 2 VN30, 3 HNXINDEX, 4 HNX30, 5 UPCOMINDEX, 11 VN100. Số chưa định danh được lưu với mã TCBS_<số> |
put_through.{floor} | Không | put_through_offer (chào mua, bán) và trade thoả thuận đã khớp. {floor}: 1 HOSE, 2 HNX, 3 UPCoM |
derivative_match, derivative_bid, derivative_offer, derivative_stats | Có | Như trên cho phái sinh |
derivative_foreign | Có | foreign_flow của phái sinh |
supply_demand_1m, supply_demand_15m | Có | flow: mua, bán chủ động theo khung 1 phút, 15 phút, kèm cộng dồn |
Kênh match_history chỉ nhận một mã mỗi phiên. Đăng ký nhiều mã thì phần kết nối báo lỗi ngay.
Kênh của ssi
| Kênh | Nhận mã | Sự kiện |
|---|---|---|
trade | Có | trade (bên chủ động, tổng cộng dồn); price_limits khi trần sàn đổi; auction trong ATO, ATC |
quote | Có | quote: cổ phiếu HOSE 3 bước, HNX, UPCoM và phái sinh 10 bước |
snapshot | Có | stats trong phiên; quote nếu mã không đăng ký kênh quote; price_limits; auction |
status | Có | status: phiên và trạng thái giao dịch của mã |
foreign | Có | foreign_flow |
index | Có (mã chỉ số) | index_tick; index_estimate khi có chỉ số dự kiến |
ohlcv | Có | bar khung tick: mỗi lần khớp (cổ phiếu, phái sinh) hoặc mỗi lần chỉ số cập nhật (chỉ số HOSE) |
odd_lot | Có | trade, quote, stats trên bảng lô lẻ; chỉ mã HOSE (nguồn không phát lô lẻ của mã HNX) |
Kênh index nhận VN30, VNINDEX, HNXINDEX, HNX30, UPCOMINDEX…, không phân biệt hoa thường. Đăng ký ALL để
nhận mọi mã của một kênh.
Kênh của binance
| Kênh | Nhận mã | Sự kiện |
|---|---|---|
trade | Có | trade: từng lệnh khớp |
agg_trade | Có | trade: lệnh khớp gộp theo lệnh chủ động |
block_trade | Có | trade trên bảng thoả thuận |
kline.{interval} | Có | bar theo giờ UTC; final = true khi nến đóng |
mini_ticker, ticker, ticker_window.{window} | Có | stats 24 giờ trượt, hoặc cửa sổ 1h, 4h, 1d |
book_ticker | Có | quote: giá và khối lượng mua bán tốt nhất |
depth.{levels}, depth.{levels}.100ms | Có | quote: sổ lệnh 5, 10 hoặc 20 mức, mỗi giây hoặc mỗi 100 ms |
diff_depth, diff_depth.100ms | Có | book_delta: thay đổi sổ lệnh |
avg_price | Có | stats: giá trung bình 5 phút |
reference_price | Có | price_limits: giá tham chiếu |
all_mini_ticker, all_ticker_window.{window} | Không | stats của mọi cặp, một mảng mỗi giây |
{interval} của nến: 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.
Lệnh stream
| Lệnh | Việc |
|---|---|
stream channels <nguồn> | Liệt kê kênh, tham số, kênh nào nhận mã |
stream run <nguồn> <kênh…> [--symbols] [--seconds] [--intervals] [--engine] [--keep-raw] | Nối, giải mã, dựng nến, ghi vào thư mục lưu trữ |
stream record <nguồn> <kênh…> --seconds N -o tệp.jsonl [--symbols] | Chỉ ghi thông điệp ra tệp, không giải mã |
stream replay tệp.jsonl [--source] [--intervals] [--engine] | Chạy một tệp đã ghi qua đúng luồng của phiên, vào thư mục lưu trữ |
| Tham số | Ý nghĩa |
|---|---|
--symbols | Mã cho các kênh nhận mã; kênh không nhận mã bỏ qua tham số này |
--seconds | Thời lượng phiên. Bỏ trống thì chạy tới khi bấm Ctrl+C |
--intervals 1m,5m | Khung nến pipeline dựng: 1m, 3m, 5m, 15m, 30m, 1H, 1D (mặc định 1m) |
--engine auto | rust, python hoặc auto (Rust khi có). Hai đường cho cùng kết quả |
--keep-raw | Giữ nguyên văn thông điệp dưới raw/ |
Kết thúc, stream run in tóm tắt phiên dạng JSON:
{
"source": "<nguồn>", "date": "2026-11-04", "engine": "rust",
"started_at": "2026-11-04T10:08:43+07:00", "ended_at": "2026-11-04T10:10:13+07:00",
"frames": 19789,
"control": {"connected": 1},
"events": {"trade": 954, "quote": 8559, "stats": 586, "bar": 950, "index_tick": 29},
"bars_closed": {"1m": 9},
"decode_errors": {},
"parts": 102,
"quality": {"1m": {"trades": 864, "duplicates": 0, "off_board": 0, "late": 0, "replayed": 68, "gaps": []}}
}| Khoá | Nghĩa |
|---|---|
control | Số lần kết nối, nối lại, mất kết nối, khoảng bị mất |
events | Số sự kiện theo loại |
bars_closed | Số nến đã đóng theo khung |
decode_errors | Số thông điệp không giải mã được, theo mã lỗi |
quality.<khung> | Bộ dựng nến thấy gì: trades (lệnh dùng), duplicates (lệnh trùng, đã bỏ), off_board (lô lẻ, thoả thuận, không dựng nến), late (lệnh tới muộn sau khi nến đã đóng), replayed (lệnh nguồn gửi lại, đã bỏ), gaps (khối lượng hụt so với tổng cộng dồn của nguồn) |
Nến dựng từ khớp lệnh
- Chỉ bảng chính. Nến chỉ gom lệnh lô chẵn, như nến của sàn và của nguồn. Lô lẻ và thoả thuận vẫn được lưu ở
stream_trades, nhưng không vào nến. - Không đếm hai lần.
- Khi hai kênh cùng mang một lệnh, ví dụ
tickvàtick_extracủadnse, pipeline dùng tổng khối lượng cộng dồn của nguồn để bỏ bản trùng. - Mỗi nguồn có một nhóm kênh dựng nến:
dnsedùngtick/tick_extra,tcbsdùnghistory_1m/derivative_match(không cóhistory_1mthìmatch),ssidùngtrade,binancedùngtrade(không có thìagg_trade).
- Khi hai kênh cùng mang một lệnh, ví dụ
- Lệnh gửi lại không vào nến. Lệnh nguồn gửi lại khi vừa đăng ký mang
replay = truevà được bỏ qua: lịch sử khớp củatcbs, bản ghi cuối củassi, thông điệp khớp củatcbslặp lại mà tổng cộng dồn không tăng, lệnhssicó tổng cộng dồn đã thấy, và nói chung lệnh cũ hơn 60 giây lúc nhận. - Lệnh đến lệch thứ tự. Lệnh
ssitrong cùng một giây có thể đến không theo thứ tự khớp. Lệnh có tổng nhỏ hơn bản trước vẫn được tính; giá mở và giá đóng của nến theo thứ tự tổng cộng dồn, không theo thứ tự đến. - Khối lượng theo tổng cộng dồn ở nguồn dạng ảnh chụp. Với kênh
matchvàderivative_matchcủatcbs, một thông điệp khớp là ảnh chụp của mã và có thể gộp nhiều lệnh. Vì vậy khối lượng nến lấy bằng phần tăng của tổng cộng dồn, không cộng khối lượng từng thông điệp. Nhờ vậy nến không hụt khi nguồn gộp lệnh. - Giá trị nến tính bằng đồng.
- Cổ phiếu: giá × 1.000 × khối lượng.
- Hợp đồng tương lai chỉ số VN30, VN100: 100.000 đồng mỗi điểm.
- Phái sinh khác chưa có hệ số, nên giá trị để trống, không ghi số đoán.
- Với nguồn dạng ảnh chụp, giá trị lấy theo phần tăng của tổng giá trị cộng dồn khi tổng đó khớp với giá.
- Mỗi mã một phiên cho mỗi nguồn. Hai phiên cùng nguồn cùng có một mã, ví dụ phiên bảng giá và phiên
match_historycủatcbscùng có FPT, ghi vào một thư mục gốc sẽ cho hai bộ nến của mã đó. - Giờ.
- Nến cổ phiếu, chỉ số, phái sinh chia theo giờ Việt Nam; nến ngày bắt đầu 00:00 giờ Việt Nam.
- Nến đóng 2 giây sau khi hết khung (
close_delay), vìssighi giờ tới giây và thông điệp đến chậm tới khoảng một giây. Phát lại tệp dùng cùng độ trễ, nên cho cùng nến như phiên trực tiếp. - Nến
binancechia theo UTC như nến của chính Binance. Giá và giá trị tính theo tài sản định giá (ví dụ USDT), khối lượng theo tài sản gốc.
Kiểm thử nội bộ ngày 04/11/2026 trong giờ giao dịch so ba cặp nến, kết quả như sau:
| Cặp đối chiếu | Phạm vi | Kết quả |
|---|---|---|
Nến 1 phút pipeline dựng từ dnse và từ ssi | 5–6 mã cổ phiếu, phái sinh, hai lần ghi | Trùng giá mở, cao, thấp, đóng, khối lượng và giá trị ở 74/74 phút trọn |
Nến tự dựng và nến ohlc_closed của dnse | Cùng phiên | 27/28 nến trùng, phút còn lại nến của nguồn ít hơn 100 cổ phiếu |
Nến 1 phút tự dựng từ binance và nến kline_1m của Binance | 4/4 phút trọn | Trùng tuyệt đối |
Đây là quan sát tại thời điểm kiểm, không phải cam kết về dữ liệu của nguồn.
Ghi lại và chạy lại
Khi cần đối chiếu hay thử cách xử lý khác mà không mở lại phiên, hãy ghi thông điệp ra tệp rồi chạy lại:
vnstock-pipeline stream record <nguồn> <kênh...> --symbols <mã> --seconds 600 -o ~/phien/<nguồn>-0930.jsonl
vnstock-pipeline stream replay ~/phien/<nguồn>-0930.jsonl --intervals 1m,5mstream replay không nối tới nguồn, nhưng cần giấy phép như stream run, vì giải mã và dựng nến là phần được cấp
phép. Tệp đi qua đúng luồng của phiên trực tiếp: giải mã, dựng nến với
cùng quy tắc của nguồn, ghi vào ngày của thông điệp đầu tiên. Tệp ghi bằng --keep-raw cũng chạy lại được.
Dùng trong Python
from vnstock_pipeline import Session, Store
def on_bar(bars): # nến 1m, 5m vừa cập nhật hoặc vừa đóng
for bar in bars:
if bar["final"]:
print(bar["symbol"], bar["interval"], bar["close"], bar["volume"])
session = Session(
Store(), "<nguồn>",
["<kênh 1>", "<kênh 2>"], # tên kênh: vnstock-pipeline stream channels <nguồn>
["<mã>"],
intervals=("1m", "5m"),
on_bar=on_bar, # on_event=... nhận mọi sự kiện đã giải mã
)
stats = session.run(seconds=600) # chặn tới khi hết giờ hoặc Ctrl+C
print(stats.to_dict())Tham số của Session | Ý nghĩa |
|---|---|
store, source, channels, symbols | Thư mục lưu trữ, nguồn, kênh, mã |
intervals | Khung nến dựng (mặc định ("1m",)) |
engine | "auto", "rust", "python" |
fields | canonical.FieldSet chọn cột lưu (Sự kiện chuẩn) |
keep_raw | Giữ bản thô (mặc định theo pipeline.toml) |
on_event, on_bar | Hàm nhận danh sách sự kiện, danh sách nến |
flush_events, flush_seconds | Nhịp ghi tệp phần (mặc định 5.000 sự kiện hoặc 5 giây) |
compact | Gộp tệp phần khi phiên kết thúc (mặc định True) |
Trong mã bất đồng bộ, dùng await session.arun(seconds=...) và session.stop().
Chạy lại tệp đã ghi, hoặc chỉ giải mã, dựng nến mà không ghi vào thư mục lưu trữ:
from vnstock_pipeline import replay_events, replay_bars
from vnstock_pipeline.stream import replay_into_store
events, errors = replay_events("ssi-0930.jsonl") # danh sách sự kiện chuẩn, lỗi kèm số dòng
bars, quality = replay_bars("ssi-0930.jsonl", "1m") # nến đã đóng và báo cáo của bộ dựng nến
replay_into_store(Store(), "ssi-0930.jsonl", intervals=("1m",))Chạy nhiều nguồn cùng lúc
Mỗi nguồn chạy một tiến trình, cùng ghi vào một thư mục gốc:
vnstock-pipeline stream run <nguồn 1> <kênh...> --symbols FPT,HPG &
vnstock-pipeline stream run <nguồn 2> <kênh...> --symbols FPT,HPG,VN30 &
vnstock-pipeline stream run <nguồn 3> <kênh...> --symbols BTCUSDT,ETHUSDT &Tệp của mỗi nguồn nằm ở thư mục source=<nguồn> riêng, còn mục lục được cập nhật dưới khoá chung. Đọc gộp nhiều nguồn
bằng Store().read("stream_trades", date="2026-11-04"), rồi lọc theo cột source.
Lưu ý khi chạy
- Mỗi nguồn có giới hạn số kết nối và số mã mỗi kết nối riêng.
- Với
binance, khi số luồng vượt giới hạn của một kết nối, phần kết nối tự mở thêm kết nối. Phần kết nối cũng tự nối lại trước mốc nguồn đóng kết nối định kỳ. - Với các nguồn khác, đăng ký vượt giới hạn thì nguồn từ chối và phiên báo lỗi.
- Với
- Phiên của nguồn mở bằng OTP hết hạn thì phần kết nối báo
OtpRequiredError; mở lại bằngvnstock-oapi auth <nguồn>. - Phiên chạy qua nửa đêm, như
binancechạy cả đêm, tự sang thư mục của ngày mới và gộp tệp của ngày cũ. - Dữ liệu trong phiên dùng cho nghiên cứu của bạn. Lưu trữ, hiển thị hay chia sẻ dữ liệu theo điều khoản của từng nguồn
(
vnstock-oapi terms <nguồn>).
