Vnstock Logo

Dữ liệu trong phiên

Thử nghiệm

Mục lục

Bản thử nghiệm, chưa phát hành chính thứ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 đó.

Nguồn của 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 đó:

Shell
vnstock-pipeline stream run <nguồn> <kênh...> --symbols <mã> --seconds 600 --intervals 1m,5m

Luồng xử lý

  1. Kết nối. Phần kết nối vnstock-oapi mở 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.
  2. Bản thô (tuỳ chọn). Khi bật keep_raw hoặc --keep-raw, mỗi thông điệp được ghi nguyên văn vào raw/<nguồn>/<ngày>/stream/.
  3. 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.
  4. 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.
  5. 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ồnCầnGhi chú
dnseAPI Key, SecretMỗi lệnh khớp có giờ khớp và bảng (lô chẵn G1, lô lẻ G4, thoả thuận T1)
tcbsAPI 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ý
ssiAPI Key, Secret (cùng khoá REST)Giờ trong thông điệp tính tới giây
binanceKhô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ố:

Shell
vnstock-pipeline stream channels <nguồn>

Kênh của dnse

KênhNhậ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ôngindex_tick
estimated_market_index.{index}Khôngindex_estimate: chỉ số dự kiến
market_index_influence.{index}.{resolution}Khôngindex_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ôngstatus: 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ênhNhận mãSự kiện
bid, offerCóquote: ba bước giá mua, bán
matchCó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_1mCó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_historyCó, 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
foreignCóforeign_flow
base_priceCóprice_limits
session_statsCóstats: mở cửa, cao, thấp, trung bình trong phiên
indexCó (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ôngput_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_statsCóNhư trên cho phái sinh
derivative_foreignCóforeign_flow của phái sinh
supply_demand_1m, supply_demand_15mCó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ênhNhận mãSự kiện
tradeCótrade (bên chủ động, tổng cộng dồn); price_limits khi trần sàn đổi; auction trong ATO, ATC
quoteCóquote: cổ phiếu HOSE 3 bước, HNX, UPCoM và phái sinh 10 bước
snapshotCóstats trong phiên; quote nếu mã không đăng ký kênh quote; price_limits; auction
statusCóstatus: phiên và trạng thái giao dịch của mã
foreignCóforeign_flow
indexCó (mã chỉ số)index_tick; index_estimate khi có chỉ số dự kiến
ohlcvCó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_lotCó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ênhNhận mãSự kiện
tradeCótrade: từng lệnh khớp
agg_tradeCótrade: lệnh khớp gộp theo lệnh chủ động
block_tradeCó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_tickerCóquote: giá và khối lượng mua bán tốt nhất
depth.{levels}, depth.{levels}.100msCó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.100msCóbook_delta: thay đổi sổ lệnh
avg_priceCóstats: giá trung bình 5 phút
reference_priceCóprice_limits: giá tham chiếu
all_mini_ticker, all_ticker_window.{window}Khôngstats 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ệnhViệ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
--symbolsMã cho các kênh nhận mã; kênh không nhận mã bỏ qua tham số này
--secondsThời lượng phiên. Bỏ trống thì chạy tới khi bấm Ctrl+C
--intervals 1m,5mKhung nến pipeline dựng: 1m, 3m, 5m, 15m, 30m, 1H, 1D (mặc định 1m)
--engine autorust, python hoặc auto (Rust khi có). Hai đường cho cùng kết quả
--keep-rawGiữ 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:

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
controlSố lần kết nối, nối lại, mất kết nối, khoảng bị mất
eventsSố sự kiện theo loại
bars_closedSố nến đã đóng theo khung
decode_errorsSố 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ụ tick và tick_extra của dnse, 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: dnse dùng tick/tick_extra, tcbs dùng history_1m/derivative_match (không có history_1m thì match), ssi dùng trade, binance dùng trade (không có thì agg_trade).
  • 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 = true và được bỏ qua: lịch sử khớp của tcbs, bản ghi cuối của ssi, thông điệp khớp của tcbs lặp lại mà tổng cộng dồn không tăng, lệnh ssi có 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 ssi trong 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 match và derivative_match của tcbs, 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_history của tcbs cù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ì ssi ghi 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 binance chia 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ếuPhạm viKết quả
Nến 1 phút pipeline dựng từ dnse và từ ssi5–6 mã cổ phiếu, phái sinh, hai lần ghiTrù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 dnseCùng phiên27/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 Binance4/4 phút trọnTrù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:

Shell
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,5m

stream 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

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, symbolsThư mục lưu trữ, nguồn, kênh, mã
intervalsKhung nến dựng (mặc định ("1m",))
engine"auto", "rust", "python"
fieldscanonical.FieldSet chọn cột lưu (Sự kiện chuẩn)
keep_rawGiữ bản thô (mặc định theo pipeline.toml)
on_event, on_barHàm nhận danh sách sự kiện, danh sách nến
flush_events, flush_secondsNhịp ghi tệp phần (mặc định 5.000 sự kiện hoặc 5 giây)
compactGộ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ữ:

Python
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:

Shell
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.
  • 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ằng vnstock-oapi auth <nguồn>.
  • Phiên chạy qua nửa đêm, như binance chạ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>).

Bước tiếp theo

Sự kiện chuẩn và bộ cột.