Logo FinLensFinLens Docs

Cài đặt thư viện Python finlens và lấy khoá API

Cài finlens bằng pip trên Python 3.11+, tạo khoá API dạng flk_, đặt biến môi trường FINLENS_API_KEY và chạy truy vấn đầu tiên với client.eod.stock.ohlcv().

Trang này đi từ máy chưa có gì tới lúc bạn cầm trong tay một DataFrame giá cổ phiếu: cài gói, lấy khoá API, chạy truy vấn đầu tiên, và kiểm chứng rằng mình đã cài đúng bản.

Cài đặt

Kiểm tra phiên bản Python

Thư viện yêu cầu Python 3.11 trở lên.

python --version

Đây là ràng buộc kéo theo từ pandas 3.0 — dòng pandas này chỉ phát hành wheel cho Python 3.11 đến 3.14.

Cài từ PyPI

pip install finlens

Lệnh này kéo theo đúng bốn phụ thuộc: pandas (từ 3.0), httpx, packaging và ta-lib. Nếu dùng môi trường ảo, nhớ kích hoạt trước khi cài.

Lấy khoá API

Tạo khoá flk_... bằng một trong hai cách bên dưới: trong extension VS Code (khuyến nghị) hoặc trên finlens.vn.

Đặt khoá vào biến môi trường

# Linux / macOS
export FINLENS_API_KEY="flk_..."
# Windows PowerShell
$env:FINLENS_API_KEY = "flk_..."

Đây là cách được khuyến nghị — nhờ nó mà mã nguồn của bạn không bao giờ chứa khoá.

Chạy truy vấn đầu tiên

import finlens

client = finlens.client()        # đọc FINLENS_API_KEY
df = client.eod.stock.ohlcv("HPG", start="2026-01-01", end="2026-01-05")
print(df)
  symbol       date   open   high    low  close      volume
0    HPG 2026-01-05  23.57  23.70  22.94  23.17  59427911.0

Giá tính bằng nghìn đồng: 23.17 nghĩa là 23.170 VND.

Hai cách tạo khoá API

Mỗi tài khoản chỉ có một khoá API

Khoá là của tài khoản, không phải của thiết bị. Tạo khoá mới — dù ở extension hay trên web — sẽ thu hồi ngay khoá cũ, và mọi nơi đang dùng nó (máy khác, file cấu hình, tác vụ định kỳ) sẽ ngừng hoạt động. Khoá mới chỉ hiển thị đúng một lần; về sau máy chủ chỉ trả lại 12 ký tự đầu qua client.whoami()["key"]["prefix"].

Trong extension VS Code (khuyến nghị)

Hộp thoại Tạo API key mới trong extension FinLens của VS Code, cảnh báo khoá hiện tại sẽ bị thu hồi, với nút Thu hồi và tạo mới

Mở FinLens trên Activity Bar; ở Trang chủ, mục môi trường có nút API key → hộp thoại Tạo API key mới? → Thu hồi và tạo mới.

Cách này được khuyến nghị vì khoá lưu thẳng vào VS Code SecretStorage — không nằm trong file hay trong code, không hiện ở cell notebook nào. Để finlens.client() ở notebook và terminal đọc được khoá này tự động, chạy lệnh FinLens: Ghi API key ra file cấu hình (cho notebook và terminal ngoài): extension ghi khoá vào finlens.toml, và SDK đọc nó ở tầng thứ ba của Ba cách đưa khoá vào client — bạn không phải đặt biến môi trường bằng tay.

Chi tiết extension ở FinLens cho VS Code.

Trên finlens.vn

Cửa sổ Cài đặt tài khoản trên finlens.vn, mục API key dùng cho thư viện Python finlens, với nút Tạo API key mới

Đăng nhập finlens.vn → Cài đặt tài khoản → mục API key → Tạo API key mới. Sao chép khoá flk_... rồi đưa vào FINLENS_API_KEY hoặc finlens.toml như phần cấu hình bên dưới.

ta-lib là phụ thuộc bắt buộc

Từ bản 1.2.0, pip install finlens kéo thêm ta-lib — nó là nền của chỉ báo kỹ thuật. Đây là phụ thuộc bắt buộc, không phải một extra tuỳ chọn: df.finlens.rsi(14) có mặt trên mọi máy cài được finlens, nên bạn không phải học thuộc tính năng nào cần cài thêm gì.

Bạn không cần tự dựng thư viện C của TA-Lib. ta-lib phát hành wheel dựng sẵn cho mọi nền finlens hỗ trợ, và pip chọn đúng cái khớp máy bạn.

macOS: sàn hệ điều hành nâng lên ở bản 1.2.0

Wheel của finlens nay đòi macOS 13.0 trở lên trên Intel và macOS 14.0 trở lên trên Apple Silicon. Trên máy macOS cũ hơn, pip install finlens báo no matching distribution ngay lúc resolve.

Con số này bám theo wheel của ta-lib. Giữ sàn thấp hơn nghĩa là bạn cài được finlens rồi mới hỏng lúc import — một dòng báo lỗi ngay lúc cài là câu trả lời thật thà hơn.

Sàn Linux và Windows không đổi.

Nếu phần native của TA-Lib không nạp được — thường là sau khi copy một môi trường ảo sang máy khác — mọi lời gọi chỉ báo ném finlens.IndicatorError với mã FL_TA_UNAVAILABLE, và thông báo kèm sẵn lệnh chữa:

pip install --force-reinstall ta-lib

Đây là lỗi của riêng phần chỉ báo. Mọi lời gọi dữ liệu — client.eod.*, client.intraday.*, client.financials.* — vẫn chạy bình thường.

Ba cách đưa khoá vào client

Cấu hình được ghép từ nhiều tầng, ưu tiên từ cao xuống thấp: tham số truyền vào → biến môi trường FINLENS_* → file finlens.toml → mặc định.

import finlens

# 1. Truyền thẳng — tiện khi thử nhanh, đừng commit
client = finlens.client(api_key="flk_...")

# 2. Biến môi trường FINLENS_API_KEY — khuyến nghị
client = finlens.client()

# 3. File cấu hình, khi bạn có nhiều môi trường
client = finlens.client(profile="staging")

File cấu hình được tìm ở ./finlens.toml trước, rồi tới thư mục cấu hình của người dùng (%APPDATA%\finlens\config.toml trên Windows, ~/.config/finlens/config.toml trên Linux và macOS):

[default]
api_key = "flk_..."

[profile.staging]
api_key = "flk_..."

Tên profile cũng đọc được từ biến môi trường FINLENS_PROFILE.

Thư viện không tự đọc file `.env`

Một thư viện tự nạp .env của bạn là một tác dụng phụ bất ngờ: nó đọc một file bạn không hề yêu cầu, và có thể ghi đè biến môi trường bạn đặt có chủ đích. Bản 1.x đã bỏ hẳn hành vi đó. Ai muốn nó thì tự gọi load_dotenv() trong ứng dụng của mình — một dòng, và là lựa chọn của họ.

Giữ khoá API an toàn

Đừng viết thẳng khoá vào mã nguồn rồi đẩy lên Git. Nếu buộc phải đọc khoá trong code, hãy đọc từ môi trường:

import os
import finlens

client = finlens.client(api_key=os.environ["FINLENS_API_KEY"])

Trong notebook dùng chung, finlens.client() không tham số là an toàn nhất: khoá không xuất hiện ở bất kỳ cell nào, nên nó cũng không nằm trong file .ipynb bạn gửi đi.

Nếu dùng file finlens.toml trong thư mục dự án, thêm nó vào .gitignore.

Kiểm tra cài đặt thành công

Bốn dòng dưới đây trả lời bốn câu hỏi khác nhau. Chạy hết chúng trước khi kết luận là "cài xong".

import finlens

finlens.__version__          # '1.1.1' — phải bắt đầu bằng số 1
client = finlens.client()    # khoá có đúng định dạng không (không chạm mạng)
client.status()              # service có sống không
client.whoami()              # khoá có thật sự dùng được không

client.whoami() là lời gọi đầu tiên thật sự đi ra mạng. Nó trả về gói dịch vụ, tình trạng khoá và hạn mức:

client.whoami()["account"]["tier"]        # 'pro'
client.limits()["requests_remaining"]     # 4783
client.limits()["max_symbols_per_request"]

Kiểm `finlens.__version__` chứ đừng tin lệnh cài

Trên Python 3.10 hoặc cũ hơn, pip install finlens không báo lỗi — nó lặng lẽ lùi về một bản 0.1.x cũ, vốn còn nhận Python 3.10. Bản đó có tên hàm khác, tên cột khác và đơn vị khác, nên mọi ví dụ trong bộ tài liệu này sẽ hỏng theo những cách khó đoán.

Nếu finlens.__version__ không bắt đầu bằng 1., hãy nâng Python lên 3.11+ rồi cài lại bằng pip install -U finlens.

client.status() không cần khoá hợp lệ — nó vẫn trả lời khi khoá sai hoặc đã hết hạn, nên đây là cách phân biệt "service đang có vấn đề" với "khoá của tôi có vấn đề".

Tạo client không chạm mạng

finlens.client() chỉ kiểm định dạng khoá tại chỗ; việc xác thực thật xảy ra ở lời gọi dữ liệu đầu tiên. Nhờ vậy đặt nó ở cell đầu notebook hay trong __init__ của một lớp không bao giờ hỏng vì một trục trặc mạng.

Muốn phát hiện khoá sai ngay lúc khởi động ứng dụng thì gọi connect() — nó chủ động chạy handshake:

client = finlens.client()
client.connect()             # ném lỗi ngay tại đây nếu khoá hỏng

Đóng client đúng cách

Client giữ một pool kết nối và một event loop chạy nền. Cả hai được đóng tự động lúc thoát interpreter, nên phần lớn script không phải làm gì. Khi muốn giải phóng sớm, dùng context manager:

import finlens

with finlens.client() as client:
    df = client.eod.stock.ohlcv(["HPG", "VCB"], start="2026-01-01")

# Đã đóng, không cần gọi client.close()

Bản bất đồng bộ bắt buộc dùng async with (hoặc await client.connect() trước lời gọi đầu tiên), vì engine phải được tạo trên chính event loop của bạn:

import finlens

async def main():
    async with finlens.AsyncClient() as client:
        df = await client.eod.stock.ohlcv("HPG")

Tuỳ chỉnh client

Mọi tham số đều bỏ trống được, và mỗi cái đều có biến môi trường tương ứng.

Tham sốBiến môi trườngÝ nghĩa
api_keyFINLENS_API_KEYKhoá API
timeoutFINLENS_TIMEOUTThời gian chờ tối đa của một request HTTP, tính bằng giây
deadlineFINLENS_DEADLINENgân sách thời gian cho cả lời gọi, kể cả các lần thử lại
max_concurrencyFINLENS_MAX_CONCURRENCYSố request song song tối đa
max_retriesFINLENS_MAX_RETRIESSố lần thử lại tối đa cho mỗi request
profileFINLENS_PROFILEProfile trong finlens.toml
ca_bundleFINLENS_CA_BUNDLEĐường dẫn tới CA bundle của tổ chức bạn

max_concurrency bị kẹp xuống theo giới hạn của gói dịch vụ sau lần handshake đầu tiên: sự thật của server thắng phỏng đoán của client.

deadline tồn tại vì một lý do rất cụ thể — không có nó, 50 mã × 3 lần thử × backoff có thể treo hàng chục phút trong một cell notebook.

Khi có gì đó không chạy

Triệu chứngNguyên nhân thường gặpCách xử lý
ConfigurationError: Thiếu API keyChưa đặt FINLENS_API_KEY, hoặc đã đặt nhưng chưa mở lại terminalTruyền finlens.client(api_key=...) để kiểm chứng nhanh
ConfigurationError: API key chứa khoảng trắngSao chép khoá từ email hoặc terminal bị ngắt dòngDán lại khoá, bỏ mọi khoảng trắng
InvalidApiKeyErrorKhoá sai hoặc đã bị thu hồiTạo khoá mới trong tài khoản
ApiKeyExpiredError / AccountExpiredErrorKhoá hoặc gói dịch vụ hết hạnKiểm client.whoami()["account"]["expires_at"]
TlsVerificationErrorMáy nằm sau proxy kiểm tra TLS hoặc phần mềm diệt virusTrỏ tới CA bundle của tổ chức: finlens.client(ca_bundle="/đường/dẫn/ca.pem") hoặc đặt FINLENS_CA_BUNDLE
IndicatorError mã FL_TA_UNAVAILABLEPhần native của TA-Lib không nạp đượcpip install --force-reinstall ta-lib
no matching distribution trên macOSBản 1.2.0 nâng sàn lên macOS 13.0 (Intel) và 14.0 (Apple Silicon)Nâng macOS, hoặc ghim finlens==1.1.0
AttributeError ở client.eod.marketĐang làm theo tài liệu 0.1.xNamespace chỉ số nay tên là client.eod.index
KeyError: 'Date'Đang làm theo tài liệu 0.1.xTên cột nay viết thường: date

Không có tuỳ chọn tắt xác thực TLS, và đó là chủ ý: tắt nó để sửa một lỗi cấu hình là đổi một phút phiền phức lấy một lỗ hổng vĩnh viễn — trong khi chính khoá API của bạn đi qua đúng kết nối đó.

Danh sách đầy đủ các lớp ngoại lệ và mã lỗi FL_* nằm ở Xử lý lỗi.

Tiếp theo

Khi báo lỗi, gửi kèm kết quả của finlens.build_info() — phần lớn thư viện được biên dịch, nên số phiên bản một mình không đủ để dựng lại đúng bản build bạn đang chạy.

>>> finlens.build_info()
{'version': '1.1.1', 'commit': 'a1b2c3d', 'built_at': '...', 'cython': '3.2.9',
 'python': '3.12', 'platform': 'windows-amd64'}

Đã có khoá, giờ làm gì

Xem 17 notebook ví dụ thực chiến — chạy trên dữ liệu thật, đi từ lời gọi API đầu tiên tới dashboard thị trường, screener định giá, screener tín hiệu kỹ thuật và backtest tránh look-ahead.

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

Cài đặt thư viện Python finlens bằng lệnh nào?

Cài từ PyPI bằng `pip install finlens`. Thư viện yêu cầu Python từ 3.11 trở lên, kiểm bằng `python --version` trước khi cài — ràng buộc này kéo theo từ pandas 3.0, dòng pandas chỉ phát hành wheel cho Python 3.11 đến 3.14. Lệnh cài thêm bốn phụ thuộc: `pandas`, `httpx`, `packaging` và `ta-lib` — `ta-lib` là bắt buộc chứ không phải extra. Nếu dùng môi trường ảo thì kích hoạt trước khi cài. Cài xong, kiểm `finlens.__version__` — nó phải bắt đầu bằng `1.`.

Khoá API của FinLens lấy ở đâu và có dạng như thế nào?

Đăng nhập finlens.vn, vào Cài đặt tài khoản, mở mục API Key rồi bấm Tạo API Key. Khoá của bản 1.x có tiền tố `flk_`. Khoá chỉ hiển thị đúng một lần sau khi tạo nên phải sao chép và cất giữ ngay; làm mất thì tạo khoá mới. Về sau máy chủ chỉ trả lại 12 ký tự đầu của khoá, đọc bằng `client.whoami()["key"]["prefix"]`, chứ không bao giờ trả lại khoá đầy đủ.

Nên lưu khoá API thế nào cho an toàn khi viết code Python?

Đừng viết thẳng khoá vào mã nguồn rồi đẩy lên Git. Với thư viện Python finlens, cách được khuyến nghị là đặt khoá vào biến môi trường `FINLENS_API_KEY` rồi gọi `finlens.client()` không tham số — khoá không xuất hiện ở cell nào nên cũng không nằm trong file `.ipynb` bạn gửi đi. Trên Linux và macOS dùng `export FINLENS_API_KEY="flk_..."`, trên Windows PowerShell dùng `$env:FINLENS_API_KEY = "flk_..."`. Nếu dùng file `finlens.toml` trong thư mục dự án thì thêm nó vào `.gitignore`.

Làm sao kiểm tra đã cài đúng bản và khoá API còn dùng được?

Chạy bốn dòng của thư viện Python finlens, mỗi dòng trả lời một câu hỏi khác nhau: `finlens.__version__` phải bắt đầu bằng `1.`; `finlens.client()` kiểm định dạng khoá tại chỗ mà không chạm mạng; `client.status()` cho biết dịch vụ có sống không và trả lời được cả khi khoá sai hoặc hết hạn; `client.whoami()` là lời gọi thật đầu tiên, trả về gói dịch vụ, tình trạng khoá và hạn mức. Hạn mức còn lại đọc bằng `client.limits()["requests_remaining"]`.

Vì sao pip lại cài về một bản finlens 0.1.x cũ?

Vì máy đang chạy Python 3.10 hoặc cũ hơn. Bản 1.x khai `requires-python >= 3.11`, nên trên Python cũ `pip install finlens` không báo lỗi mà lặng lẽ lùi về một bản 0.1.x — bản đó có tên hàm khác, tên cột khác và đơn vị khác, nên mọi ví dụ trong bộ tài liệu này sẽ hỏng theo những cách khó đoán. Kiểm bằng `finlens.__version__`; nếu nó không bắt đầu bằng `1.` thì nâng Python lên 3.11+ rồi chạy `pip install -U finlens`.

Cập nhật lần cuối

Nội dung trang