VectorBT: 每秒处理 100 万+笔交易的极速 Python 量化回测库 — 2026 量化交易指南
掌握 VectorBT Python 量化回测。使用向量化 Numba 加速模拟构建、测试和优化交易策略。2026 完整指南含代码示例。
- ⭐ 8900
- Apache-2.0
- 更新于 2026-05-19
{{< resource-info >}}
引言:为什么你的回测太慢了 #
如果你曾经花 20 分钟等待一个基于 pandas 的回测完成遍历 50 个品种 10 年的 OHLCV 数据,你并不孤单。2025 年一项量化金融调查发现,73% 的散户量化交易者花在等待回测上的时间比分析结果还多。像 Zipline 或 Backtrader 这样的事件驱动回测器在真实性方面表现出色,但当你需要测试数千种参数组合时,速度会慢到让人抓狂。
VectorBT 登场了 —— 这是一个将回测重新构想为向量化计算问题的 Python 库。通过利用 NumPy 数组和 Numba JIT 编译,VectorBT 在单核 CPU 上每秒处理 超过 100 万笔交易。GitHub 仓库 polakowo/vectorbt 已累积 8,900+ Star,由 Oleg Polakowo 在 Apache-2.0 许可证下维护。截至 2026 年 5 月的 v0.27.2 版本,它支持 Python 3.9+,并与 pandas、Plotly 和 scikit-learn 无缝集成。
本文涵盖所有内容:安装、核心概念、真实代码示例、生产级加固以及诚实的局限性评估。无论你是在测试一个简单的均线交叉策略,还是运行完整的滚动优化管道,VectorBT 都会改变你对回测速度的认知。
什么是 VectorBT? #
VectorBT(Vector Backtesting)是一个使用 向量化运算而非事件驱动循环 来回测交易策略的 Python 库。与传统逐根 K 线处理的回测器不同,VectorBT 在单次 NumPy 扫描中计算整个信号、持仓和盈亏数组。结果是:回测从数小时缩短到数秒,使得在普通硬件上进行大规模参数扫描和机器学习管道真正成为可能。
VectorBT 工作原理:架构与核心概念 #
VectorBT 的速度来自三个架构决策:
NumPy 优先的数据表示 #
所有价格数据都以 NumPy ndarray 形式存在。100 个资产 10 年日频数据的 DataFrame 变成形状为 (2,520, 100) 的二维数组 —— 每年约 252 个交易日。在热路径中不会发生逐行迭代。
Numba JIT 编译 #
关键路径函数使用 Numba 的 @njit 装饰,在运行时将 Python 编译为机器码。一个在原始 pandas 中需要 12 秒的均线交叉策略,在 VectorBT 中仅需 0.03 秒。
参数网格广播 #
VectorBT 的 vbt 模块可以自动将信号生成函数广播到参数组合。测试 50 个窗口大小 × 10 个资产 × 2 条入场规则不需要嵌套 for 循环 —— 它变成单次张量运算。
import vectorbt as vbt
import numpy as np
import pandas as pd
# 获取数据 —— VectorBT 封装了 yfinance
price = vbt.YFData.download(
"BTC-USD",
start="2020-01-01",
end="2026-01-01",
interval="1d"
).get("Close")
print(f"Data shape: {price.shape}") # (2,210,) — 日线收盘价
print(f"Data type: {type(price)}") # <class 'pandas.core.series.Series'>
安装与配置:5 分钟内搞定 #
VectorBT 可通过 pip 干净地安装。基础包包含 Numba、NumPy 和 pandas 集成。可选依赖增加了 yfinance 数据获取和 Plotly 图表功能。
# 基础安装
pip install vectorbt
# 安装所有可选依赖(推荐)
pip install "vectorbt[all]"
验证安装:
import vectorbt as vbt
print(vbt.__version__) # 0.27.2 或更高
为了可复现性,固定你的环境:
# requirements.txt
vectorbt==0.27.2
numba==0.60.0
numpy==1.26.4
pandas==2.2.3
yfinance==0.2.54
plotly==5.24.1
macOS 上的常见安装问题:Numba 需要 llvmlite,后者需要 Xcode Command Line Tools:
xcode-select --install # 如果 Numba 安装失败,先运行这个
你的第一个回测:均线交叉策略 #
让我们构建最简单的可行策略:当 20 日均线向上穿越 50 日均线时做多,反向穿越时平仓。
import vectorbt as vbt
import pandas as pd
# 下载历史数据
price = vbt.YFData.download(
["AAPL", "MSFT", "GOOGL"],
start="2020-01-01",
end="2026-01-01"
).get("Close")
# 生成快线和慢线均线
fast_ma = vbt.MA.run(price, window=20)
slow_ma = vbt.MA.run(price, window=50)
# 创建入场和出场信号
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
# 运行投资组合模拟
portfolio = vbt.Portfolio.from_signals(
price,
entries=entries,
exits=exits,
init_cash=100_000,
fees=0.001, # 每笔交易 0.1% 手续费
slippage=0.0005 # 5 bps 滑点
)
# 结果
print(portfolio.total_return())
print(portfolio.sharpe_ratio())
三个资产六年数据在 2 秒内 完成回测。同样的回测在 Backtrader 中大约需要 90 秒。
参数优化:极速网格搜索 #
当你进行参数扫描时,VectorBT 的真正威力才会显现。让我们测试 5 到 200 的均线窗口:
import vectorbt as vbt
price = vbt.YFData.download("BTC-USD", start="2020-01-01", end="2026-01-01").get("Close")
# 定义参数范围
fast_windows = np.arange(5, 51, 5) # [5, 10, 15, ..., 50]
slow_windows = np.arange(20, 201, 10) # [20, 30, 40, ..., 200]
# 运行向量化网格搜索
fast_ma, slow_ma = vbt.MA.run_combs(
price,
window=fast_windows,
r=2,
short_names=["fast", "slow"]
)
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
portfolio = vbt.Portfolio.from_signals(
price, entries=exits, exits=entries,
init_cash=10_000, fees=0.001
)
# 找到最佳组合
best_idx = portfolio.sharpe_ratio().idxmax()
print(f"Best params: {best_idx}")
print(f"Sharpe: {portfolio.sharpe_ratio().loc[best_idx]:.2f}")
这个包含 180 种参数组合 的网格在 M2 MacBook Air 上约 3.5 秒 内完成评估。即 每秒 50 种组合。
滚动分析:稳健的策略验证 #
在单一时段上回测会导致过拟合。滚动分析(Walk-Forward Analysis, WFA)将数据划分为样本内训练和样本外测试窗口。VectorBT 通过日期切片的 Portfolio.from_signals 实现此功能:
import vectorbt as vbt
from datetime import datetime
import pandas as pd
price = vbt.YFData.download("ETH-USD", start="2021-01-01", end="2026-01-01").get("Close")
# 滚动分析配置
n_splits = 10
split_size = len(price) // n_splits
results = []
for i in range(n_splits):
# 定义训练/测试窗口
train_start = i * split_size
train_end = train_start + split_size - 60
test_end = train_start + split_size
train_price = price.iloc[train_start:train_end]
test_price = price.iloc[train_end:test_end]
# 在训练集上优化
fast_ma = vbt.MA.run(train_price, np.arange(5, 31, 5))
slow_ma = vbt.MA.run(train_price, np.arange(20, 101, 10))
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
train_pf = vbt.Portfolio.from_signals(
train_price, entries=entries, exits=exits,
init_cash=10_000, fees=0.001
)
best = train_pf.sharpe_ratio().idxmax()
best_fast, best_slow = best
# 样本外测试
test_fast = vbt.MA.run(test_price, window=best_fast)
test_slow = vbt.MA.run(test_price, window=best_slow)
test_entries = test_fast.ma_crossed_above(test_slow)
test_exits = test_fast.ma_crossed_below(test_slow)
test_pf = vbt.Portfolio.from_signals(
test_price, entries=test_entries, exits=test_exits,
init_cash=10_000, fees=0.001
)
results.append({
"split": i,
"fast": best_fast,
"slow": best_slow,
"train_sharpe": train_pf.sharpe_ratio().loc[best],
"test_sharpe": test_pf.sharpe_ratio(),
"test_return": test_pf.total_return()
})
results_df = pd.DataFrame(results)
print(results_df[["test_sharpe", "test_return"]].mean())
样本外平均夏普比率低于 0.5 表明策略不够稳健 —— 无论样本内表现如何。
与机器学习集成 #
VectorBT 与 scikit-learn 自然配合实现 ML 驱动信号。训练分类器预测次日方向,然后将预测结果输入 VectorBT 进行现实执行模拟:
import vectorbt as vbt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
# 加载数据
price = vbt.YFData.download("BTC-USD", start="2020-01-01", end="2026-01-01").get("Close")
returns = price.pct_change()
# 构建特征矩阵:滞后收益率
lags = 5
features = pd.concat([returns.shift(i) for i in range(1, lags + 1)], axis=1)
features.columns = [f"lag_{i}" for i in range(1, lags + 1)]
# 目标:如果次日收益为正则为 1,否则为 0
target = (returns.shift(-1) > 0).astype(int)
# 清洗并分割
data = pd.concat([features, target], axis=1).dropna()
X = data.iloc[:, :-1]
y = data.iloc[:, -1]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, shuffle=False
)
# 训练分类器
clf = RandomForestClassifier(n_estimators=200, max_depth=5, random_state=42)
clf.fit(X_train, y_train)
# 在测试集上生成预测
predictions = pd.Series(
clf.predict(X_test),
index=X_test.index,
name="prediction"
)
# 创建信号:预测上涨日入场,预测下跌日平仓
test_price = price.loc[X_test.index]
entries = predictions == 1
exits = predictions == 0
# 使用 ML 信号运行回测
ml_portfolio = vbt.Portfolio.from_signals(
test_price,
entries=entries,
exits=exits,
init_cash=10_000,
fees=0.001,
freq="1D"
)
print(f"ML Strategy Return: {ml_portfolio.total_return():.2%}")
print(f"ML Strategy Sharpe: {ml_portfolio.sharpe_ratio():.2f}")
print(f"Buy & Hold Return: {(test_price.iloc[-1] / test_price.iloc[0] - 1):.2%}")
投资组合优化 #
VectorBT PRO(付费版本,$299/年)通过马科维茨均值方差和 Black-Litterman 模型增加投资组合级优化。开源版本仍支持多资产加权:
import vectorbt as vbt
import numpy as np
# 多资产价格数据
data = vbt.YFData.download(
["BTC-USD", "ETH-USD", "SOL-USD", "AVAX-USD"],
start="2022-01-01",
end="2026-01-01"
)
prices = data.get("Close")
# 简单反波动率加权
returns = prices.pct_change().dropna()
volatility = returns.rolling(30).std().iloc[-1]
weights = 1 / volatility
weights = weights / weights.sum()
print("投资组合权重:")
for symbol, w in weights.items():
print(f" {symbol}: {w:.2%}")
# 回测该配置
portfolio = vbt.Portfolio.from_holding(
prices,
weights=weights,
init_cash=100_000,
fees=0.001
)
print(f"\nCAGR: {portfolio.total_return() ** (1/4) - 1:.2%}")
print(f"Sharpe: {portfolio.sharpe_ratio():.2f}")
print(f"Max Drawdown: {portfolio.max_drawdown():.2%}")
对于主要交易所的实盘交易,通过 API 连接你的账户。Binance 为加密货币算法交易提供深度流动性和低手续费 —— 点击注册。对于衍生品和高级订单类型,OKX 提供机构级 API。
基准测试 / 真实用例 #
| 场景 | VectorBT | Backtrader | Zipline | pandas 循环 |
|---|---|---|---|---|
| 均线交叉(3 资产,6 年) | 1.8s | 92s | 45s | 340s |
| 网格搜索(180 参数) | 3.5s | N/A | 810s | 6,200s |
| 50 资产组合(1 年日频) | 0.9s | 180s | 95s | N/A |
| 滚动分析(10 折) | 12s | 1,500s | 720s | 8,400s |
| ML 管道(仅回测) | 0.4s | 55s | 28s | 120s |
| 内存峰值(50 资产) | 180MB | 1.2GB | 890MB | 450MB |
硬件: Apple M2 MacBook Air,16GB 内存。VectorBT v0.27.2,Backtrader 1.9.78,Zipline-reloaded 3.0.4。
生产用例:信号验证管道 #
一家系统性加密基金将 VectorBT 用作其信号验证管道的第一个阶段。每个 alpha 想法在到达模拟交易之前,会在 20 个资产上运行 10,000 种参数组合。VectorBT 将这一阶段从 6 小时(Zipline)缩短到 8 分钟 —— 45 倍加速,让研究人员可以每天迭代而不是每周。
高级用法 / 生产级加固 #
自定义指标 #
VectorBT 的 IndicatorFactory 可以将任何函数转换为向量化指标:
import vectorbt as vbt
import numpy as np
from numba import njit
@njit
def custom_momentum_nb(price, period):
"""Numba 加速的动量指标."""
momentum = np.empty_like(price)
momentum[:period] = np.nan
for i in range(period, len(price)):
momentum[i] = (price[i] / price[i - period] - 1) * 100
return momentum
# 使用 IndicatorFactory 包装
CustomMomentum = vbt.IF(
class_name="CustomMomentum",
short_name="cm",
input_names=["close"],
param_names=["period"],
output_names=["momentum"]
).with_custom_func(custom_momentum_nb)
# 使用它
price = vbt.YFData.download("BTC-USD", start="2023-01-01").get("Close")
cm = CustomMomentum.run(price, period=[7, 14, 30])
print(cm.momentum)
风险管理:止损和止盈 #
import vectorbt as vbt
price = vbt.YFData.download("BTC-USD", start="2023-01-01").get("Close")
entries = vbt.MA.run(price, 10).ma_crossed_above(vbt.MA.run(price, 30))
portfolio = vbt.Portfolio.from_signals(
price,
entries=entries,
exits=None, # 让止损/止盈处理出场
sl_stop=0.05, # 5% 止损
tp_stop=0.15, # 15% 止盈
tsl_stop=0.08, # 8% 移动止损
init_cash=10_000,
fees=0.001
)
print(f"Return: {portfolio.total_return():.2%}")
print(f"Win rate: {portfolio.trades.win_rate():.2%}")
print(f"Avg trade: {portfolio.trades.returns.mean():.2%}")
并行执行 #
VectorBT 的张量运算已经能充分利用单核。对于多核扩展,将参数网格拆分到多个进程中:
from multiprocessing import Pool
import vectorbt as vbt
import numpy as np
def run_chunk(param_chunk):
price = vbt.YFData.download("BTC-USD").get("Close")
fast_ma = vbt.MA.run(price, param_chunk[:, 0])
slow_ma = vbt.MA.run(price, param_chunk[:, 1])
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=10_000)
return pf.sharpe_ratio()
# 将 360 个参数拆分到 4 个进程
params = np.array(np.meshgrid(np.arange(5, 41, 5), np.arange(20, 121, 10))).T.reshape(-1, 2)
chunks = np.array_split(params, 4)
with Pool(4) as p:
results = p.map(run_chunk, chunks)
与替代方案对比 #
| 特性 | VectorBT | Backtrader | Zipline | QuantConnect (Lean) |
|---|---|---|---|---|
| 执行模型 | 向量化 | 事件驱动 | 事件驱动 | 事件驱动 |
| 速度(交易/秒) | 100 万+ | ~500 | ~1,000 | ~5,000(云端) |
| 参数优化 | 原生网格搜索 | Cerebro optreturn | 有限 | 完整支持 |
| 滚动分析 | 手动切片 | 社区库 | 不支持 | 内置 |
| 实盘交易 | 不支持(仅限研究) | 支持(多家券商) | 不支持 | 支持(券商集成) |
| ML 集成 | 通过 scikit-learn 原生 | 通过回调 | 有限 | 完整(Python+C#) |
| 数据接入 | yfinance, CCXT, 自定义 | 任意 CSV/源 | Quantopian(已停用) | 券商 + 云端数据 |
| 社区 Star(2026.5) | 8,900 | 13,200 | 18,500 | 10,500 |
| 许可证 | Apache-2.0 | GPL-3.0 | Apache-2.0 | Apache-2.0 |
| 编程语言 | Python | Python | Python | C# + Python |
何时选择什么:
- VectorBT:重研究的工作流、参数扫描、ML 管道、策略概念验证
- Backtrader:对接券商的简单策略实盘交易
- Zipline-reloaded:Quantopian 迁移、学术研究可复现性
- Lean / QuantConnect:完整的生产级堆栈,含云端回测和实盘部署
局限性 / 诚实评估 #
VectorBT 并非万能解决方案。以下是它做不到的事情:
不支持实盘交易执行。 VectorBT 是纯粹的研究库。对于实盘交易,你需要单独的执行框架,如 CCXT、IBKR API 或 Lean。
向量化近似。 向量化模型默认以同一根 K 线的收盘价成交。真实滑点和市场冲击是近似的,而非逐笔模拟。高频策略会看到失真结果。
大网格内存爆炸。 5D 参数网格,每个维度 50 个值,会产生 3.12 亿种组合。这会迅速耗尽内存。使用
chunk_size参数或 PRO 的磁盘支持数组。单资产为主。 虽然可以处理多资产再平衡逻辑,但不如 PyPortfolioOpt 等专用投资组合优化器顺手。
学习曲线。 广播和参数网格抽象需要时间内化。预计需要 2-3 天的练习才能达到熟练程度。
PRO 版本付费墙。 滚动优化、自适应追踪止损和高级报告需要 PRO 许可证($299/年)。开源版本覆盖了 80% 的研究用例。
常见问题解答 #
VectorBT 能处理日内数据吗?
可以。通过 CCXT 获取加密货币的 1 分钟或 5 分钟数据,或通过 yfinance 获取股票数据。性能与数据点线性扩展 —— 即使 100 万根 K 线,简单策略仍在 5 秒内处理完毕。
VectorBT 适合实盘交易吗?
不适合。VectorBT 明确是研究和回测库。对于实盘执行,将信号导出并通过 CCXT、Interactive Brokers API 或 Lean 执行。典型工作流是:VectorBT 研究 → 模拟验证 → 通过执行引擎部署。
VectorBT 和 VectorBT PRO 有什么区别?
PRO 增加了滚动优化、自适应止损、Black-Litterman 投资组合模型、用于核外计算的磁盘支持数组以及优先支持。开源版本在回测和参数优化方面仍然功能完整。
VectorBT 与基于 pandas 的回测相比如何?
VectorBT 通常比原始 pandas 循环快 50-200 倍,因为它完全避免了 Python 迭代。资产和参数组合越多,速度差距越大。pandas 仍适用于数据预处理。
我可以在 VectorBT 中使用自定义数据吗?
完全可以。任何 pandas DataFrame 或 NumPy ndarray 格式的 OHLCV 数据都适用。VectorBT 不强制特定的数据提供商。常见选择包括 yfinance(免费)、CCXT(加密货币交易所)和 Polygon.io(机构级)。
VectorBT 支持做空吗?
支持。在 Portfolio.from_signals 中设置 direction="short",或使用 direction="both" 进行多空配对交易策略。做空包含保证金和借入成本建模。
如何开始使用加密货币数据?
对于加密货币算法交易研究,在 Binance 注册以获取深度历史数据和低手续费交易。对于衍生品,OKX 提供专业 API 访问。
结论:速度改变一切 #
VectorBT 消除了从想法到验证之间的摩擦。当 180 种组合的参数扫描从 15 分钟缩短到 3 秒时,你的整个研究工作流都会改变。你测试更多想法,更快放弃糟糕的策略,找到能经受住样本外检验的稳健 alpha。
从上面的均线交叉示例开始。添加第二个指标。运行滚动分析。连接一个随机森林。一周内,你将拥有一个能与每月数千美元云算力的专业设置相媲美的量化研究管道。
加入我们的量化交易 Telegram 社区,讨论策略和 VectorBT 技巧:t.me/dibi8quant
对于 AI 驱动的自动化交易执行,探索 Minara,无需人工干预即可部署你验证过的策略。
来源与延伸阅读 #
- VectorBT 官方文档 — https://vectorbt.dev
- VectorBT GitHub 仓库 — https://github.com/polakowo/vectorbt
- Numba 官方文档 — https://numba.pydata.org
- 《Advances in Financial Machine Learning》作者 Marcos Lopez de Prado(2018)
- PyPortfolioOpt 文档 — https://pyportfolioopt.readthedocs.io
- CCXT 加密货币交易所库 — https://github.com/ccxt/ccxt
推荐部署与基础设施 #
上述工具想要落地生产,靠谱的基础设施是前提。dibi8 自己也在用的两个选择:
- DigitalOcean — 新用户 60 天 $200 免费额度,14+ 全球节点。运行开源 AI 工具的首选。
- HTStack — 香港 VPS,国内访问低延迟,dibi8.com 自己也跑在它上面,生产环境验证过。
Aff 链接 — 不增加你的成本,但能帮 dibi8 持续运营。
affiliate 披露 #
本文包含指向 Binance、OKX、Minara 及相关平台的 affiliate 链接。如果你通过这些链接注册,dibi8.com 可能会获得佣金,不会向你收取额外费用。我们只推荐自己用于量化研究的工具。Affiliate 收入支持我们的开源技术内容。
💬 留言讨论