一、概述
VectorBT 是一个基于 Python 的开源量化交易库,采用向量化回测方法,通过 NumPy 和 Pandas 加速大规模数据处理,适用于高频策略开发和性能评估。
核心优势
- 极速性能:利用 NumPy 和 Pandas 的向量化运算能力,回测速度比传统方法快 100 倍以上。
- 灵活策略定义:支持基于信号和事件的策略开发,兼容自定义指标和机器学习模型(如 LSTM)。
- 可视化工具:内置 Plotly
- 集成化解决方案:整合数据获取、技术指标计算、策略优化等功能,减少多库整合的复杂度。
功能模块
- 数据获取:支持 雅虎财经
- 策略开发:内置技术指标(如 MACD、RSI),支持自定义指标和批量计算。
- 回测优化:可针对多个参数、资产和时间段进行策略优化,内置 夏普比率
- 风险管理:提供波动率动态仓位管理、交易成本模拟等功能。
应用场景
适用于中高级量化交易者,尤其适合需要快速处理高频数据的场景(如高频交易、机器学习模型验证)。
github地址:https://github.com/polakowo/vectorbt
二、安装
使用虚拟环境安装
conda create --prefix D:\file\conda\envs\vectorbt_env python=3.13.2
conda activate D:\file\conda\envs\vectorbt_env
安装模块vectorbt,akshare
pip install vectorbt akshare
三、实战日K线及MACD金叉/死叉买卖点
MACD(12,26,9)
MACD(12,26,9) 是一组经典参数,用来计算 MACD 指标的三个“窗口长度”:
-
12 —— 快线 EMA 周期
用最近 12 根 K 线(日 K 就是 12 天)做指数移动平均,反应“短期”价格趋势。 -
26 —— 慢线 EMA 周期
用最近 26 根 K 线做指数移动平均,反应“长期”价格趋势。 -
9 —— 信号线(DEA)EMA 周期
把上面两条线之差(MACD 值)再做一次 9 周期的 EMA,得到“信号线”,用来产生金叉/死叉。
一句话总结
-
12 与 26 的差距越大,指标越“迟钝”;差距越小,越“敏感”。
-
9 越小,信号线越紧跟 MACD,金叉死叉出现得越快。
-
寒武纪
这里以寒武纪为例子,分析从2025年的日k线
start.py
import akshare as ak
import vectorbt as vbt
import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio
# ---------------- 1. 拉取日 K ----------------
# 股票代码
symbol = "688256"
# 股票名称
stock_name = "寒武纪"
df = ak.stock_zh_a_hist(
symbol=symbol,
period="daily",
start_date="20250101", # 用足够长的历史
adjust="qfq"
)
df["日期"] = pd.to_datetime(df["日期"])
df = df.set_index("日期").sort_index()
close = df["收盘"]
# ---------------- 2. 计算 MACD & 信号 ----------
macd = vbt.MACD.run(close, fast_window=12, slow_window=26, signal_window=9)
entries = macd.macd_crossed_above(macd.signal)
exits = macd.macd_crossed_below(macd.signal)
# ---------------- 3. 回测 -----------------------
pf = vbt.Portfolio.from_signals(
close,
entries,
exits,
init_cash=100_000,
freq="d"
)
print("=== 每笔交易 ===")
# print(pf.positions.records_readable.head())
# print(pf.positions.records_readable.columns)
# 开仓日期,开仓均价,平仓日期,平仓均价,收益率(该笔交易带来的百分比收益)
cols = ["Entry Timestamp", "Avg Entry Price",
"Exit Timestamp", "Avg Exit Price", "Return"]
print(pf.positions.records_readable[cols])
# ---------------- 4. 画图 -----------------------
buy_idx = entries[entries].index
sell_idx = exits[exits].index
buy_price = close.loc[buy_idx]
sell_price = close.loc[sell_idx]
fig = go.Figure(data=[
go.Candlestick(
x=df.index,
open=df["开盘"],
high=df["最高"],
low=df["最低"],
close=df["收盘"],
name=f"{symbol} 日K",
# k线量柱增加,指定为红色
increasing=dict(line=dict(color="#ff0000"), fillcolor="#ff0000"),
# k线量柱递减,指定为绿色
decreasing=dict(line=dict(color="#40a040"), fillcolor="#40a040")
)
])
fig.add_trace(go.Scatter(
x=buy_idx, y=buy_price * 0.98,
mode="markers",
marker=dict(symbol="triangle-up", size=12, color="red"),
name="买入"
))
fig.add_trace(go.Scatter(
x=sell_idx, y=sell_price * 1.02,
mode="markers",
marker=dict(symbol="triangle-down", size=12, color="green"),
name="卖出"
))
fig.update_layout(
title=f"{symbol} {stock_name} MACD(12,26,9) 信号与回测",
xaxis_rangeslider_visible=False,
height=700
)
# 指定默认浏览器
pio.renderers.default = "browser"
fig.show()
# 保存为html文件
fig.write_html(f"{symbol}_kline_signals.html")
运行python文件,等待43秒左右,会自动打开浏览器,访问html文件。
效果如下:
太大了,看不清,这里再局部放大一点。
可以看到8月1日到8月26日的,K线图。
红色量柱买入,绿色量柱卖出。
终端会输出每笔交易
=== 每笔交易 ===
Entry Timestamp Avg Entry Price Exit Timestamp Avg Exit Price Return
0 2025-04-15 619.88 2025-05-13 678.29 0.094228
1 2025-06-13 604.90 2025-07-08 542.77 -0.102711
2 2025-07-18 582.62 2025-08-26 1344.88 1.308331
参数解释:
Entry Timestamp,开仓日期,真正成交那一刻的日期索引。
Avg Entry Price,开仓均价,如果分批建仓,这里是加权平均价。
Exit Timestamp,平仓日期,最后那一笔平仓的日期。
Avg Exit Price,平仓均价,分批平仓时的加权平均价。
Return,收益率,该笔交易带来的 百分比收益(已考虑杠杆)。
看最后一条信息,2025-07-18日,以582.62元价格买入寒武纪,2025-08-26日,卖出价格1344.88,收益率为130.8%,翻倍了。