TA-Lib và pandas-ta: Từ chỉ báo kỹ thuật đến Feature Engineering trong Quant Trading
TA-Lib và pandas-ta
Phần 1. TA-Lib và pandas-ta không chỉ để “vẽ RSI, MACD”
Khi làm phân tích chứng khoán bằng Python, dữ liệu ban đầu thường chỉ gồm Open, High, Low, Close và Volume. Đây là dữ liệu gốc của thị trường, nhưng nếu muốn xây hệ thống sàng lọc, backtest hay mô hình Machine Learning thì thường cần biến chúng thành những đặc trưng có ý nghĩa hơn. Đây chính là vai trò của TA-Lib và pandas-ta.
Ví dụ, từ chuỗi giá đóng cửa của một cổ phiếu, có thể tính RSI để đo trạng thái momentum, ROC để đo tốc độ thay đổi của giá, Moving Average để mô tả xu hướng. Từ High, Low và Close có thể tính ATR để đo biến động. Từ giá và volume có thể xây OBV hoặc các feature về dòng tiền. Như vậy, dữ liệu ban đầu chỉ có vài cột nhưng sau quá trình feature engineering có thể trở thành một dataset chứa hàng chục biến mô tả nhiều trạng thái khác nhau của cổ phiếu.

TA-Lib thường được dùng như một “engine tính indicator”. Cách sử dụng khá trực tiếp: đưa dữ liệu vào một hàm rồi nhận kết quả đầu ra. Ví dụ:
import talib
df["RSI_14"] = talib.RSI(df["close"], timeperiod=14)
df["ATR_14"] = talib.ATR(
df["high"],
df["low"],
df["close"],
timeperiod=14
)
df["SMA_20"] = talib.SMA(
df["close"],
timeperiod=20
)Cách tiếp cận của pandas-ta lại khá gần với tư duy làm việc bằng DataFrame. Khi đang nghiên cứu dữ liệu trong Jupyter Notebook hoặc Google Colab, có thể tính nhiều indicator và gắn trực tiếp chúng vào dataset. Vì vậy pandas-ta thường tạo cảm giác thuận tiện hơn trong quá trình khám phá dữ liệu và thử nghiệm feature.
Nhưng điểm đáng chú ý nhất không nằm ở việc thư viện nào có nhiều indicator hơn. Trong Quant Trading, RSI hay MACD không nhất thiết phải được sử dụng theo cách truyền thống như “RSI dưới 30 thì mua” hay “MACD cắt lên thì mua”. Chúng có thể đơn giản chỉ là biến đầu vào của một mô hình.
Giả sử tại một phiên giao dịch, cổ phiếu có RSI = 67, ROC20 = +8%, ATR/Close = 2,5%, Volume Z-score = 2,1 và Relative Strength so với VN-Index = +5%. Thay vì dùng từng indicator riêng để đưa ra Buy/Sell, Quant có thể xem toàn bộ chúng như một vector mô tả trạng thái hiện tại của cổ phiếu.
Từ đó có thể đặt những bài toán thú vị hơn: những cổ phiếu có tổ hợp feature tương tự đang thuộc cùng một nhóm hành vi nào? Breakout nào có xác suất thành công cao hơn? Phiên nào đang xuất hiện anomaly về giá và volume? Những feature nào thực sự có predictive information?
Đó là lúc TA-Lib và pandas-ta chuyển từ công cụ phân tích kỹ thuật thành công cụ xây dựng dữ liệu cho Quant Research.
Phần 2. Điểm quan trọng không phải có bao nhiêu indicator, mà là mỗi feature đang bổ sung thông tin gì
Một sai lầm phổ biến khi mới tiếp cận TA-Lib hoặc pandas-ta là thấy thư viện có rất nhiều indicator rồi đưa tất cả vào model. Một dataset rất dễ xuất hiện RSI, Stochastic, Williams %R, CCI, ROC, Momentum, MACD, SMA20, EMA20, SMA50 và hàng chục biến khác.
Nhìn bề ngoài, model có rất nhiều feature. Nhưng về mặt thông tin, chưa chắc model đang nhận được nhiều thứ mới.
Giả sử một cổ phiếu tăng rất mạnh trong 20 phiên. RSI có thể tăng, ROC tăng, Momentum dương, MACD dương, Stochastic tiến gần vùng cao và giá nằm trên MA20. Sáu indicator khác nhau cùng chuyển sang trạng thái bullish, nhưng nguyên nhân gốc vẫn chủ yếu là giá vừa tăng mạnh.
Đây là vấn đề feature redundancy.
Một model nhận RSI, Stochastic, ROC và Momentum có thể tưởng như đang có bốn nguồn thông tin. Nhưng thực tế chúng có thể chỉ là bốn phép biến đổi khác nhau của cùng một chuỗi giá.
Vì vậy một feature set tốt thường không bắt đầu bằng câu hỏi “thêm indicator nào nữa?”, mà bằng câu hỏi:
Model đang thiếu chiều thông tin nào?
Ví dụ có thể chia dữ liệu thành một số nhóm logic. Trend mô tả hướng đi của thị trường; Momentum đo tốc độ thay đổi; Volatility cho biết mức độ rủi ro; Volume phản ánh mức độ tham gia của dòng tiền; Relative Strength cho biết cổ phiếu mạnh hay yếu hơn VN-Index; Beta mô tả mức độ nhạy với thị trường.
Một dataset khá đơn giản có thể chỉ cần:
Return20
ROC20
ATR_pct
Volume_Zscore
RS20_vs_VNIndex
Beta60Sáu feature này đôi khi hữu ích hơn việc đưa 30 indicator kỹ thuật tương quan rất cao vào cùng một model.
Ví dụ Volume Z-score có thể tự xây:
mean_volume = df["volume"].rolling(20).mean()
std_volume = df["volume"].rolling(20).std()
df["Volume_Z"] = (
df["volume"] - mean_volume
) / std_volumeRelative Strength với VN-Index cũng không cần một indicator phức tạp:
stock_return = df["close"].pct_change(20)
index_return = vnindex["close"].pct_change(20)
df["RS20"] = stock_return - index_returnATR có thể lấy từ TA-Lib rồi chuẩn hóa theo giá:
df["ATR14"] = talib.ATR(
df["high"],
df["low"],
df["close"],
14
)
df["ATR_pct"] = df["ATR14"] / df["close"]Việc chia ATR cho giá rất quan trọng nếu muốn so sánh nhiều cổ phiếu. ATR bằng 2.000 đồng có ý nghĩa hoàn toàn khác giữa cổ phiếu giá 20.000 và cổ phiếu giá 150.000. Sau khi chuẩn hóa thành tỷ lệ, feature trở nên dễ so sánh hơn.
Đây chính là tư duy: không chỉ tính indicator, mà phải biến indicator thành dữ liệu có thể so sánh và có ý nghĩa đối với bài toán đang giải quyết.
Nếu mục tiêu là Clustering cổ phiếu, các feature còn cần được standardize trước khi đưa vào K-Means. Return có thể nằm quanh vài phần trăm, Beta quanh 0–2, RSI từ 0–100 còn volume có thể hàng triệu cổ phiếu. Nếu đưa trực tiếp vào model, những biến có scale lớn có thể chi phối khoảng cách giữa các quan sát.
Khi đó pipeline thường có dạng:
OHLCV
↓
TA-Lib / pandas-ta
↓
Custom Quant Features
↓
StandardScaler
↓
K-Means / Decision Tree / Random Forest / Isolation ForestTA-Lib và pandas-ta chỉ nằm ở một đoạn trong cả quá trình. Chất lượng model cuối cùng phụ thuộc nhiều hơn vào cách xây feature và cách thiết kế bài toán.
Phần 3. TA-Lib hay pandas-ta chỉ là công cụ; Quant edge nằm ở cách sử dụng dữ liệu
Nếu mục tiêu chỉ là tính một vài indicator quen thuộc như RSI, MACD, ATR hay ADX, TA-Lib là một lựa chọn rất tự nhiên. Cách gọi hàm rõ ràng, dễ kiểm soát và phù hợp với pipeline đã xác định trước indicator nào cần sử dụng.
Nếu đang trong giai đoạn research, liên tục thử nghiệm nhiều feature trên DataFrame, cách tiếp cận của pandas-ta thường thuận tiện hơn. Có thể nhanh chóng thêm indicator, kiểm tra correlation, loại feature, thử lại model rồi tiếp tục nghiên cứu.
Nhưng với Quant Trading, lựa chọn giữa hai thư viện thực ra không phải vấn đề quan trọng nhất.
Một model không trở nên tốt hơn chỉ vì indicator được tính bằng TA-Lib thay vì pandas-ta. Và cũng không trở nên tốt hơn vì dataset có 100 indicator thay vì 10.
Điểm quyết định nằm ở việc các feature đó có cung cấp information mới hay không.
Ví dụ một nghiên cứu breakout có thể bắt đầu bằng năm feature rất đơn giản: Return20 đo momentum, Volume Z-score phát hiện thanh khoản bất thường, ATR_pct đo volatility, RS20 đo sức mạnh so với VN-Index và khoảng cách tới MA20 đo mức độ kéo giãn khỏi trend.
Sau đó có thể tạo target:
1 = sau breakout 10 phiên giá tiếp tục tăng > 5%
0 = breakout thất bạiLúc này TA-Lib chỉ chịu trách nhiệm tạo một vài feature. Phần thực sự có giá trị nằm ở việc kiểm tra xem những feature nào giúp phân biệt hai nhóm breakout.
Có thể chạy Decision Tree và phát hiện rằng Volume Z-score đóng vai trò quan trọng. Có thể chạy Random Forest và thấy Relative Strength có information mạnh hơn RSI. Có thể chạy Clustering và phát hiện các breakout tự chia thành những nhóm hành vi khác nhau. Hoặc dùng Isolation Forest để phát hiện những phiên có tổ hợp giá, volume và volatility bất thường.
Đây là khác biệt giữa Technical Analysis bằng Python và Quant Research bằng Python.
Technical Analysis thường hỏi: RSI đang bao nhiêu?
Quant Research sẽ hỏi:
Khi RSI ở mức này, Relative Strength đang tăng, volume bất thường và volatility ở trạng thái như hiện tại, phân phối lợi nhuận 20 phiên tiếp theo trong lịch sử trông như thế nào?
Một vấn đề nữa phải đặc biệt cẩn thận là look-ahead bias. Indicator luôn cần một khoảng dữ liệu quá khứ để tính toán. SMA50 không thể có giá trị thực sự ở phiên thứ 10. RSI14 cũng cần đủ dữ liệu trước khi ổn định. Nếu xử lý missing value sai, backfill dữ liệu hoặc vô tình sử dụng thông tin của phiên tương lai, model có thể có kết quả backtest rất đẹp nhưng hoàn toàn không thể giao dịch thật.
Tương tự, nếu tạo feature bằng giá đóng cửa ngày hôm nay nhưng giả định chiến lược cũng mua được tại chính giá đóng cửa đó, cần xem lại thời điểm thông tin thực sự available. Trong Quant, timestamp và data leakage đôi khi quan trọng hơn lựa chọn thuật toán.
Vì vậy một quy trình hợp lý thường là:
Dữ liệu sạch → feature có logic → loại redundancy → kiểm tra leakage → train model → out-of-sample test → tính transaction cost → đánh giá stability.
TA-Lib và pandas-ta giúp xử lý rất tốt phần đầu của chuỗi này. Chúng giúp biến OHLCV thành một không gian feature phong phú hơn. Nhưng chúng không tự tạo ra Alpha.
