portfolio_bt cung cấp bộ công cụ backtest danh mục dạng vector hóa, tập trung cho các chiến lược crypto futures nhưng có thể áp dụng cho mọi tập dữ liệu giá dạng bảng. Thư viện nhận vào dataframe vị thế (df_pos) và dataframe giá đóng cửa (df_close), tự căn chỉnh thời gian, tính phí giao dịch dựa trên turnover và xuất ra các metric hiệu suất cũng như biểu đồ phân tích.
- Xử lý được universe lớn nhờ toàn bộ phép toán đều vector hóa trên
pandas/numpy - Hai chế độ phân bổ vốn
full_equalvàpartial_equalphục vụ chiến lược equal-weight toàn tập hoặc top-N - Tính toán phí chuẩn hóa theo turnover để mô phỏng chi phí vào/ra vị thế futures
- Tự động resample lợi nhuận về daily, thống kê thanh khoản giao dịch, drawdown, fitness, margin …
- Cung cấp tập phương thức
plot_*để trực quan hóa PnL, exposure, đóng góp từng symbol và turnover
portfolio_bt/
├── __init__.py # Alias: PortfolioVectorizeBT → BacktestInformation (v1)
├── backtest.py # Bản triển khai gốc của BacktestInformation
├── backtest_v2.py # Phiên bản refactor với caching và helper tách riêng
├── requirements.txt # Dependencies tối thiểu để chạy notebook/plot
└── README.md
- API chính được export qua
portfolio_bt.PortfolioVectorizeBT - Align vị thế và giá, đảm bảo index thời gian chuẩn
datetime - Tính weight theo chế độ
strategy_type(full_equalhoặcpartial_equal) - Tính gross return, turnover, fee từng symbol, net return và cumulative PnL
- Tổng hợp metric và trade stats ngay khi khởi tạo; hỗ trợ
print_metrics()vàprint_allocation_summary() - Bộ hàm
plot_*để vẽ PnL, exposure, bảng metric năm, đóng góp symbol và heatmap turnover
- Giữ nguyên chữ ký hàm, do đó có thể swap trực tiếp với bản v1
- Refactor lại pipeline: tách bước chuẩn bị dữ liệu, tính toán và resample rõ ràng hơn
- Thêm caching metric/drawdown để giảm tính toán lặp lại trong notebook
- Sử dụng hằng số đặt tên rõ ràng (
DAYS_PER_YEAR,BASIS_POINTS_MULTIPLIER...) - Phù hợp cho các workflow cần đọc metric nhiều lần hoặc kết hợp nhiều plot
BacktestInformation.metrics (hoặc get_metrics() với bản v2) cung cấp các khóa chính:
total_profit_perc: Tổng lợi nhuận tính theo % trên toàn khoảng backtestannual_return_perc: Lợi nhuận thường niên hoá dựa trên 365 ngàysharpe: Sharpe ratio sử dụng daily returndaily_turnover_perc: Turnover trung bình theo ngàyfitness: Thước đo fitness (Sharpe * sqrt(|return|/turnover)) với ngưỡng turnover tối thiểu 12.5%max_drawdown_perc: Max drawdown theo %calmar: Calmar ratiohit_rate_perc: Tỷ lệ ngày có lợi nhuận dươngmargin_bps: Tổng lợi nhuận quy đổi sang basis points trên vốn sử dụng trung bìnhavg_profit_per_win_trade_perc/avg_loss_per_loss_trade_perc: Lợi nhuận/lỗ trung bình mỗi tradenum_trades: (thuộc tính riêng, không nằm trong dict) số giao dịch được suy ra từ thay đổi vị thế
Ngoài ra class còn lưu trữ weight_df, turnover_by_symbol, cum_pnl, các thước đo exposure trung bình (avg_long_exposure, avg_short_exposure, …) để tái sử dụng.
plot_pnl(): Đường PnL tích luỹ sau phíplot_exposure(): Biểu đồ long/short/net exposure theo thời gianplot_yearly_metrics_table(): Bảng metric theo từng năm (Sharpe, MDD, Turnover, Return, Fitness)plot_symbol_contributions(): Cột đóng góp % của từng symbol; tự động giới hạn top/bottom khi universe lớnplot_yearly_symbol_contributions(): Cột đóng góp từng năm, bố trí dạng lướiplot_symbol_turnover_table(): Heatmap turnover theo symbol/thời gian với tuỳ chọn tần suất và top-N
Các module lõi chỉ phụ thuộc vào:
pandasnumpymatplotlibseaborn
File requirements.txt vẫn giữ một số thư viện hỗ trợ môi trường notebook/SSH trong project lớn, nhưng không bắt buộc nếu bạn chỉ dùng các class backtest.
import numpy as np
import pandas as pd
from portfolio_bt.backtest import BacktestInformation
# Giả lập dữ liệu 3 symbol với bar 15 phút
index = pd.date_range("2024-01-01", periods=96, freq="15T")
symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT"]
# Vị thế chuẩn hoá [-1, 0, 1]
positions = pd.DataFrame(
np.random.choice([-1, 0, 1], size=(len(index), len(symbols))),
index=index, columns=symbols
)
# Giá đóng cửa giả lập
prices = pd.DataFrame(
20000 + np.cumsum(np.random.randn(len(index), len(symbols)), axis=0),
index=index, columns=symbols
)
bt = BacktestInformation(
df_pos=positions,
df_close=prices,
fee_rate=0.0005,
strategy_type="partial_equal",
allocation_fraction=0.5,
target_active=2,
)
bt.print_metrics()
bt.plot_pnl()Để dùng bản refactor, chỉ cần đổi import:
from portfolio_bt.backtest_v2 import BacktestInformation # API tương tự- Thư viện không bao gồm tầng lấy dữ liệu. Bạn cần chuẩn bị
df_posvàdf_close(vx: truy vấn từ database riêng hoặc file csv). - Các phương thức plot sử dụng
matplotlibvàseaborn; ensure môi trường notebook hoặc backend phù hợp. - Khi tái sử dụng trong packages khác, có thể import qua
portfolio_bt.PortfolioVectorizeBT(trỏ vềbacktest.BacktestInformation).
Framework được tối ưu để cắm vào pipeline backtest nội bộ, nhưng vẫn đủ nhẹ để nhúng vào notebook khám phá chiến lược.