Vnstock Logo

Chuyển từ vnstock_data 3.x

Cộng đồng

Mục lục

Trang này dành cho người tài trợ đang có mã viết cho vnstock_data 3.x. Thế hệ 5 giữ tên lớp, tên hàm và chữ ký của giao diện hợp nhất (Market, Reference, Fundamental, Macro, Insights, Analytics), nên việc chính là đổi dòng import. Phần còn lại của trang liệt kê những chỗ thế hệ 5 cố ý làm khác, và bạn cần sửa gì ở mỗi chỗ.


1. Một thư viện cho mọi cấp

Thế hệ 5 không có gói vnstock_data. Bản Cộng đồng và bản Mở rộng nay là hai cấp quyền trên cùng thư viện vnstock. Khoá API của bạn quyết định hàm nào chạy được. Không cần vnstock_installer hay vnii để kích hoạt.

Cài đặt

Cài vào một môi trường ảo mới, để mã cũ trên vnstock_data vẫn chạy được trong lúc bạn chuyển:

Shell
python3 -m venv ~/.venv5x
source ~/.venv5x/bin/activate    # Windows: py -m venv "$HOME\.venv5x"; & "$HOME\.venv5x\Scripts\Activate.ps1"
pip install -U --extra-index-url https://vnstocks.com/api/packages vnstock
vnstock register                         # nhập khoá API, đăng ký thiết bị nếu cần
vnstock status                           # kiểm cấp tài trợ và hạn dùng

Thế hệ 5 cần Python 3.10 trở lên.

Đổi dòng import

Python
# vnstock_data 3.x
from vnstock_data import Market, Reference, Fundamental, Macro, Insights, Analytics
from vnstock_data import Quote, Listing, Company, Finance, Trading
from vnstock_data.explorer.vci import Quote as VCIQuote

# Thế hệ 5
from vnstock import Market, Reference, Fundamental, Macro, Insights, Analytics
from vnstock import Quote, Listing, Company, Finance, Trading
from vnstock.explorer.vci import Quote as VCIQuote

import vnstock_data sẽ báo ModuleNotFoundError. Không có gói chuyển tiếp nào giữ tên đó.

Bạn cần sửa gì: thay vnstock_data bằng vnstock ở mọi dòng import. Mã gọi giao diện hợp nhất thường chạy luôn sau bước này.

Lớp kiểu cũ và explorer

  • Các lớp Quote, Listing, Company, Finance, Trading vẫn import được từ vnstock hoặc vnstock.api.
  • vnstock.explorer.<nguồn> vẫn dùng được cho vci, kbs, mas, asean, cafef. Lần import đầu phát DeprecationWarning khuyên chuyển sang Reference, Market, Fundamental.
  • vnstock.explorer.fmarket và from vnstock.explorer.vci import Screener không còn. Một số module explorer khác của bản 3.x cũng không có ở thế hệ 5.

Lớp vnstock.api giữ hành vi cũ: Company, Listing, Trading.foreign_trade(), Trading.prop_trade(), TopStock trả cột thô như các trang thông tin công ty và trạng thái niêm yết của bản Mở rộng mô tả (officer_name, organ_name, sàn HSX…); vnstock.api.Market trả định giá với ngày làm chỉ mục reportDate. Chỉ giao diện hợp nhất đổi sang bộ tên cột chung. Một số cột thô chưa có, ví dụ phần lớn cột của Company(source="VCI").overview(); thư viện bỏ hẳn cột đó chứ không điền giá trị đoán. Lớp vnstock.api sẽ ngừng dần, chưa có ngày. Khi bạn truyền mã ở cả hàm khởi tạo lẫn lời gọi, giá trị truyền sau cùng được dùng.


2. Tham số giờ có tác dụng thật

Bản 3.x nhận một số tham số rồi bỏ qua. Thế hệ 5 làm đúng điều tham số nói.

source=

Ở vnstock_data, ohlcv(..., source="VCI") vẫn trả dữ liệu KBS. Ở thế hệ 5, bạn nhận đúng dữ liệu VCI. Nguồn không phục vụ hàm đó thì báo lỗi, không trả dữ liệu của nguồn khác.

Python
from vnstock import Market

eq = Market().equity("ACB")
df = eq.ohlcv(start="2024-01-01", end="2024-03-31", source="kbs")
print(df.attrs["source"])   # 'kbs'

Bạn cần sửa gì: mã nào từng ghi source= mà không để ý kết quả thì nay sẽ nhận số của nguồn đó. Bỏ source= nếu bạn muốn nguồn mặc định.

vnstock.ui.config.set_route() vẫn đổi nguồn mặc định của một hàm, như bản 3.x. Thứ tự chọn nguồn: source= của lời gọi, rồi nguồn đặt bằng set_route(), rồi nguồn mặc định.

Python
from vnstock.ui.config import set_route

set_route("market.equity.trades", "kbs", "quote", "Quote", "intraday")

set_route() chỉ nhận nguồn có sẵn trong thư viện. Lớp nguồn tự viết không còn được nhận; ba đối số cuối giữ cho tương thích và không được dùng. Nguồn lạ, kể cả nguồn của bản cũ như msn, tcbs, dnse, nhận lỗi nêu tên các nguồn dùng được. Tiền mã hoá chỉ nhận source="binance".

length=, limit= và lời gọi trần: đếm theo nến, không theo ngày

Đây là chỗ khác bản 3.x dễ làm sai số liệu nhất, vì mã vẫn chạy mà không báo gì.

  • ohlcv(length=N) với N là số (hoặc chuỗi chữ số như "30") trả N nến của khung đang hỏi. Bản 3.x hiểu là N ngày. Ví dụ length=30 trả 30 nến ngày, còn với interval="1m" thì trả 30 nến một phút, không phải 30 ngày nến phút.
  • length dạng chuỗi kỳ ("10d", "3M", "1Y") vẫn là một khoảng thời gian như bản 3.x.
  • ohlcv() không truyền start, length thì trả 100 nến mới nhất của khung đang hỏi, để lời gọi nhanh. Cần dài hơn thì truyền start hoặc length.
  • ohlcv(start, end, limit=100) trả đúng 100 dòng. Bản 3.x bỏ qua limit. Chỉ có limit=N, không có start, thì nhận N nến mới nhất.

Bạn cần sửa gì: mã nào viết length=N để lấy N ngày thì đổi sang length="Nd" (ví dụ length="30d"), hoặc truyền rõ start và end.

Python
from vnstock import Market

eq = Market().equity("FPT")
eq.ohlcv(length=30)                    # 30 nến ngày mới nhất
eq.ohlcv(length="30d")                 # các nến trong 30 ngày gần nhất, như length=30 của bản 3.x
eq.ohlcv(length=100, interval="1m")    # 100 nến một phút

Lớp kiểu cũ Quote(...).history(length=N) vẫn hiểu N là số ngày, như bản 3.x.

Thiếu định danh thì báo lỗi

Hàm cần mã mà bạn không truyền mã thì nhận InputError, không nhận dữ liệu của một mã tuỳ ý. Ví dụ Reference().fund.nav_report() không có mã quỹ.

Đối số theo vị trí, ngày tháng

  • ohlcv("2026-09-01", "2026-09-30", "1W") chạy được. Bản 3.x chỉ nhận từ khoá.
  • interval nhận thêm d, D, 1d, day, daily, w, week, weekly, M, month, monthly, 60m. Bảng đủ ở Chuyển từ vnstock 4.x.
  • Ngày chỉ nhận YYYY-MM-DD, YYYY-MM (ngày đầu tháng) và YYYY (ngày đầu năm). Bản 3.x nhận cả 01-09-2026 hay 2026/09/01 nhưng có lúc đọc sai ngày; thế hệ 5 báo InputError cho các dạng này.
  • period của báo cáo tài chính nhận thêm Y (năm) và Q (quý). Bản 3.x bỏ qua period="Y" và trả mọi kỳ.

Mã không tồn tại

Mã sai, ví dụ Market().equity("INVALID").ohlcv(), nhận InputError mã VNSTOCK_INPUT_SYMBOL_UNKNOWN. InputError là lớp con của ValueError, nên except ValueError viết cho bản 3.x vẫn bắt được. Mã có thật nhưng khoảng thời gian không có giao dịch thì nhận bảng rỗng đủ cột.


3. Đầu ra

Ngày ở cột, không ở index

Analytics().valuation(index).pe(), pb(), evaluation() trả ngày ở cột report_date. Bản 3.x đặt ngày vào index tên reportDate.

Python
from vnstock import Analytics

pe = Analytics().valuation("VNINDEX").pe()
pe = pe.set_index("report_date")   # nếu mã cũ dùng df.loc[<ngày>]

Lớp cũ vnstock.api.Market vẫn trả ngày ở index reportDate như bản 3.x.

Kiểu dữ liệu và múi giờ

  • Cột chữ có kiểu string, số có kiểu float64 hoặc kiểu số nguyên cho phép trống.
  • Thời gian có múi giờ. Dữ liệu Việt Nam (cổ phiếu, phái sinh, chứng quyền, quỹ, vĩ mô, định giá, tham chiếu) dùng Asia/Ho_Chi_Minh. Tiền mã hoá, ngoại hối, hàng hoá thế giới dùng UTC.
  • Cột date là nửa đêm theo múi giờ của dữ liệu đó, cùng ngày lịch với bản 3.x.

Ghép một chuỗi vĩ mô với một chuỗi giá không còn lỗi Cannot compare tz-naive and tz-aware, vì hai bên cùng có múi giờ. Mã cũ so cột thời gian với chuỗi ngày trơn thì đọc ví dụ lọc theo ngày.

timezone= của ngoại hối, hàng hoá, chỉ số thế giới

Bản 3.x trả giờ Việt Nam và đổi theo timezone=. Thế hệ 5 luôn trả UTC cho Market().forex(), Market().commodity() và Market().index(s, scope="global"). Truyền timezone="UTC" vẫn chạy; truyền múi giờ khác thì nhận UnsupportedError kèm cách đổi giờ. Đổi sau khi nhận dữ liệu:

Python
from vnstock import Market

df = Market().forex("EURUSD").ohlcv(start="2026-09-01", end="2026-09-30")
df["time"] = df["time"].dt.tz_convert("Asia/Ho_Chi_Minh")

Khung rỗng vẫn đủ cột

Khi khoảng thời gian không có dữ liệu, bạn nhận bảng 0 dòng nhưng đủ cột. Bản 3.x trả bảng không cột nào. df.columns trong mã của bạn không còn biến mất.

Giá lịch sử cổ phiếu lấy từ VCI

Market().equity(s).ohlcv() mặc định lấy từ VCI, bản 3.x lấy từ KBS. Hai nguồn điều chỉnh giá sau sự kiện quyền khác nhau, nên mọi khoảng thời gian có ngày chia cổ tức, tách cổ phiếu đều lệch vài đồng ở các cột giá và khối lượng.

Text
ACB 2024-03-01  KBS  open=16.95  close=16.83  volume=10193800
                VCI  open=16.93  close=16.81  volume=10201609

Muốn số như bản 3.x: ohlcv(..., source="kbs"). Khung tháng của VCI có thêm nến của tháng hiện tại, chưa đóng.


4. Tính năng đã ngừng

Các hàm dưới đây vẫn giữ tên. Gọi thì báo UnsupportedError mã VNSTOCK_FEATURE_REMOVED, kèm phiên bản bắt đầu ngừng và lời gọi thay thế nếu có.

Lời gọiThay bằng
Reference().company(s).news()Không có. Thư viện không còn truy xuất tin tức
Fundamental().equity(s).filing()Không có
Macro().economy().industry_prod(), retail(), population_labor()Không có
Macro().currency().interest_rate()Không có. Các chuỗi lãi suất khác vẫn ở Macro().currency()
Macro().commodity()Giá hàng hoá thế giới: Market().commodity(symbol)
source="mbk", source="fmarket", source="spl"Lỗi nêu nguồn đang phục vụ hàm đó
Macro().gdp(), cpi(), import_export(), fdi(), money_supply(), exchange_rate() (gọi thẳng trên Macro())Macro().economy().gdp(), Macro().currency().exchange_rate()… Đã quá ngày ngừng 31/08/2026 mà bản 3.x báo trước
Reference().derivatives()Reference().futures(symbol), Reference().warrant(symbol). Cùng ngày ngừng 31/08/2026
Reference().company(s).reports(), Company(source="VCI").reports()Không có. Thư viện không truy xuất báo cáo phân tích hay khuyến nghị. Số liệu doanh nghiệp ở Fundamental().equity(s), sự kiện ở Reference().company(s).events()

Ba phần không còn tên:

  • Insights().screener (bộ lọc cổ phiếu): AttributeError.
  • vnstock.CommodityPrice (giá hàng hoá trong nước): ImportError.
  • Reference().company(s).article_detail().

vnstock.api.Macro không còn trả dữ liệu. Các chỉ số vĩ mô còn lại gọi qua Macro().economy(), Macro().currency().

Báo cáo tài chính không mất gì: vẫn có vci, kbs, mas.

Quỹ mở đổi nguồn

Dữ liệu quỹ lấy từ CafeF (mặc định) và DigiInvest, dành cho cấp tài trợ từ Bronze. Có tên mới holdings, industry_allocation, asset_allocation. Tên cũ (top_holding, industry_holding, asset_holding, nav_report…) vẫn trả dữ liệu với bộ cột cũ, kèm FutureWarning, tới hết ngày 06/04/2027. fund_id số của bản cũ không còn nghĩa: dùng mã quỹ. Chi tiết ở Dữ liệu quỹ mở.


5. Thời hạn của các tên cũ

Tên cũDùng thayCòn chạy tới
Market().pe(), pb(), evaluation()Analytics().valuation(index).pe()…31/12/2026, có FutureWarning
vnstock.api.MarketAnalytics().valuation(index)31/12/2026, có FutureWarning
vnstock.api.TopStockInsights().ranking31/12/2026, có FutureWarning
Tên cũ của nhóm quỹ mởXem trang quỹ mở06/04/2027, có FutureWarning
Lớp Quote, Listing, Company, Finance, TradingMarket, Reference, FundamentalChưa công bố ngày; nhóm này sẽ ngừng dần

Sau ngày ghi trong bảng, tên cũ báo lỗi thay vì trả dữ liệu. Các hàm Macro() gọi thẳng và Reference().derivatives() đã qua ngày ngừng nên nay báo lỗi, xem mục 4.


6. Lỗi

Mọi ngoại lệ kế thừa VnstockError và mang code, kind, action, message_vi, message_en. Năm tên lỗi nguồn của bản 3.x vẫn import được từ gốc gói và từ vnstock.core.exceptions:

TênThế hệ 5
DataSourceBlockedErrorLớp cha, nay là lớp con của NetworkError
AccessDeniedErrorNguồn từ chối, HTTP 403, mã VNSTOCK_SOURCE_BLOCKED
RateLimitedErrorNguồn báo gọi quá nhanh, HTTP 429, mã VNSTOCK_SOURCE_RATE_LIMITED
ChallengeRequiredErrorNguồn từ chối truy cập tự động, mã VNSTOCK_SOURCE_CHALLENGE. Thư viện dừng, không thử lại
CircuitOpenErrorGiữ để mã cũ chạy; hiện không nơi nào báo lỗi này

Mọi mệnh đề except viết cho bản 3.x vẫn bắt được đúng những gì nó bắt trước đây. except NetworkError nay bắt thêm năm lớp trên. InputError là lớp con của cả VnstockError lẫn ValueError, nên except ValueError vẫn bắt được lỗi mã sai và tham số sai.

Thế hệ 5 không có cơ chế tạm ngừng gọi một nguồn sau nhiều lần lỗi. circuit_status() trả {} và reset_circuit() trả 0. Mã nào dựa vào cơ chế đó để tự giãn nhịp gọi thì cần tự thêm thời gian chờ.

Lỗi cấp quyền:

  • Hàm chưa mở cho cấp của bạn: EntitlementError, mã VNSTOCK_TIER_ROUTE.
  • Nguồn chưa mở cho cấp của bạn: EntitlementError, mã VNSTOCK_TIER_SOURCE.

Thông báo hiện hai ngôn ngữ, tiếng Việt trước. Chọn một ngôn ngữ bằng vnstock settings language vi (hoặc en), hay VNSTOCK_LANG=en cho một lần chạy. Xem thêm ở Đăng nhập và dòng lệnh.


7. Nguồn mặc định và tên mới

Giao diện hợp nhất lấy nguồn mặc định theo bảng nguồn của bản 3.x, kể cả những chỗ sau:

  • Market().etf(s), Market().bond(s): giá lịch sử và khớp lệnh lấy từ KBS.
  • Nến trong phiên (1m tới 1H) của chỉ số, hợp đồng tương lai, chứng quyền lấy từ VCI; nến ngày vẫn lấy từ KBS.
  • Market().quote([...]), odd_lot([...]), put_through([...]) lấy từ KBS. odd_lot() và put_through() trả đúng các mã trong danh sách symbols_list bạn truyền vào.
  • Reference().index.members(), Reference().index(s).members(), Reference().index.list_by_group() lấy từ KBS; VNINDEX, HNXINDEX, UPCOMINDEX được đọc là cả sàn HOSE, HNX, UPCOM.

Ngoài cách đếm length ở mục 2, thế hệ 5 cố ý khác bản 3.x ở các điểm về nguồn và quy ước dữ liệu:

  • Market().equity(s).ohlcv() lấy từ VCI, xem mục 3.
  • Market().equity(s).trades() (hay intraday()) lấy từ VCI (bản 3.x lấy từ VND). Mặc định trả 100 dòng mỗi lần gọi (thay vì 1.000 dòng ở bản cũ) để tránh quá tải nguồn; VCI giới hạn tối đa 1.000 dòng/lần gọi và hỗ trợ phân trang qua tham số last_id. Nhãn mua bán và tổng khối lượng có thể khác; truyền source="vnd" nếu cần số như cũ.
  • Company(source="KBS").overview() đổi nhãn free_float_percentage thành charter_capital_vnd (vốn điều lệ theo đồng, ví dụ 70.862.404.140.000) và free_float thành par_value_vnd (mệnh giá cổ phiếu 10.000đ), phản ánh đúng bản chất dữ liệu thay vì nhãn sai của bản 3.x.
  • Cột match_type trong khớp lệnh (trades()/intraday()): nguồn KBS trả nhãn chữ thường buy, sell, ato, atc như bản gốc vnstock_data (nguồn VCI trả Buy, Sell, ATO, ATC).
  • Reference().fund.list() và Market().fund(s).history() chuẩn hóa mã quỹ CafeF SSISCA đồng nhất (nguồn CafeF ghi SSI-SCA).
  • Reference().equity.list_by_industry() viết hoa cột symbol (ví dụ A+ FUND).

Các tên có trong tài liệu bản Mở rộng đều dùng được:

  • Macro().global_macro (tên khác: Macro().world): bond_yield(market="VN", tenor="10Y") cho lợi suất trái phiếu, fed_rate() cho lãi suất của Cục Dự trữ Liên bang Mỹ, index(symbol="DXY") cho chỉ số DXY hoặc DJI. Cửa sổ mặc định 1 năm là 365 ngày bao gồm cả 2 đầu ngày (120 phiên).
  • Reference().company(s).overview() trả cùng kết quả với .info(). Bảng có thêm cột short_name (tên viết tắt); với source="kbs" có num_employees (số nhân viên).
  • Reference().index("VN30").info() trả thông tin một chỉ số từ danh mục chỉ số có sẵn trong thư viện; .description() trả đoạn mô tả.
  • Market().index(s, scope="global") đọc chỉ số thế giới từ Dukascopy như bản 3.x, thời gian theo UTC.

Danh sách nguồn mặc định của từng hàm ở Nguồn dữ liệu.

Dữ liệu truy xuất qua thư viện đến từ nguồn bên thứ ba và chỉ để tham khảo. Hãy tự kiểm tra trước khi dùng cho quyết định của mình.