Python 量化金融库
Python 量化金融库 本章节介绍量化金融领域常用的 Python 库,并重点演示两个回测框架:zipline 与 Backtrader。 常用量化库总览 按用途划分,量化研究常用的库有这些: 库 用途 安装命令 zi
本章节介绍量化金融领域常用的 Python 库,并重点演示两个回测框架:zipline 与 Backtrader。
常用量化库总览
按用途划分,量化研究常用的库有这些:
| 库 | 用途 | 安装命令 |
|---|---|---|
| zipline | 事件驱动回测框架,Quantopian 公司出品 | conda install -c conda-forge zipline |
| Backtrader | 功能全面的 Python 回测框架,社区活跃 | pip install backtrader |
| QuantLib | 金融工具定价与金融计算(期权、债券等) | pip install QuantLib |
| TA-Lib | 技术指标计算库,内置 150 多个指标 | pip install TA-Lib |
| pyfolio | 投资组合绩效分析,可与回测框架集成生成分析报告 | pip install pyfolio |
| statsmodels | 统计建模:线性回归、时间序列分析等 | pip install statsmodels |
本篇重点是前两个回测框架,其余库在对应主题中按需引入。
zipline
zipline 是一个用于量化金融研究和算法交易的开源框架,由 Quantopian 公司开发,为研究员提供构建、测试和执行量化交易策略的完整工具链。
注意:Quantopian 平台已于 2020 年停止运营,zipline 官方版本停留在 1.3.0,对新版 Python 的兼容性较差。新项目建议优先使用社区维护版 zipline-reloaded,或直接使用下面介绍的 Backtrader。本节内容保留,便于阅读既有资料时理解。
安装
zipline 依赖较多,推荐使用 Anaconda 安装,避免出现依赖冲突:
conda install -c conda-forge zipline
准备数据包
zipline 回测需要特定格式的数据包(bundle),常用 quandl 数据源。
先登录 quandl 官网注册,获得 api key,然后设置环境变量:
# Windows 系统 set QUANDL_API_KEY=你的key # macOS / Linux 系统 export QUANDL_API_KEY=你的key
下载数据包:
zipline ingest -b quandl
查询已下载的数据包:
zipline bundles
输出内容如下所示:
csvdir <no ingestions> quandl 2023-12-09 06:02:03.178299 quandl 2023-12-09 05:59:04.273082 quandl 2023-12-09 05:54:57.277732 quandl 2023-12-09 05:52:15.532504 quandl 2023-12-09 03:32:03.853032 quantopian-quandl <no ingestions>
编写并运行策略
zipline 策略是一个 Python 脚本,核心是 initialize(初始化)和 handle_data(每个交易日调用)两个函数:
实例
def initialize(context):
# 回测开始时执行一次,用于初始化
pass
def handle_data(context, data):
# 每个交易日执行一次:以当前价格买入 10 股苹果股票
order(symbol('AAPL'), 10)
# 记录当日的 AAPL 价格,便于事后分析
record(AAPL=data.current(symbol('AAPL'), 'price'))
order(symbol('AAPL'), 10) 表示在每个交易日以当前价格购买 10 股苹果公司股票。
record(...) 则把当日的股价记录下来,回测结束后可以画出价格曲线。
使用 zipline run 命令执行回测:
zipline run -f my_strategy.py --start 2016-1-1 --end 2018-1-1 -o buyapple_out.pickle --no-benchmark
输出内容如下所示:
Simulated 503 trading days first open: 2016-01-04 14:30:00+00:00 last close: 2017-12-29 21:00:00+00:00
| 命令参数 | 说明 |
|---|---|
| -f my_strategy.py | 指定策略文件 |
| --start / --end | 指定回测的起始和结束日期 |
| -o buyapple_out.pickle | 指定输出文件,回测的交易记录和绩效数据保存在其中 |
| --no-benchmark | 不设置业绩比较基准 |
读取回测结果
回测结果是一个 pickle 文件,用标准库 pickle 模块读取:
实例
# 指定 pickle 文件路径
pickle_file_path = 'buyapple_out.pickle'
# 以二进制只读方式打开并反序列化
with open(pickle_file_path, 'rb') as file:
buyapple_out_data = pickle.load(file)
# 打印读取的数据,包含每日的交易与绩效明细
print(buyapple_out_data)
输出内容是一个按日索引的 DataFrame,包含每日盈亏(pnl)、持仓市值、杠杆率等字段:
period_open period_close short_value pnl long_exposure ... max_leverage excess_return treasury_period_return trading_days period_label
2016-01-04 21:00:00+00:00 2016-01-04 14:31:00+00:00 2016-01-04 21:00:00+00:00 0.0 0.00000 0.0 ... 0.000000 0.0 0.0 1 2016-01
Backtrader
Backtrader 是目前社区最活跃的 Python 回测框架之一,纯 Python 实现、安装简单、文档齐全,支持股票、期货、加密货币等多市场回测。
安装如下:
pip install backtrader
核心概念
Backtrader 的架构围绕几个核心对象展开:
| 对象 | 角色 |
|---|---|
| Cerebro | 回测引擎的"大脑",负责加载数据、策略并驱动整个回测流程 |
| Data Feed | 数据源,把 pandas DataFrame 等格式的行情数据喂给引擎 |
| Strategy | 策略类,引擎逐根 K 线调用它的 next() 方法,在这里写交易逻辑 |
| Indicator | 指标(如 SMA、CrossOver),声明后引擎自动完成计算和对齐 |
| Broker | 模拟券商,管理资金、订单撮合和手续费 |
| Analyzer | 分析器,自动统计收益、回撤、交易次数等绩效数据 |
实例:双均线策略回测
用 Backtrader 重做上一篇的双均线策略:10 日均线上穿 30 日均线买入,下穿卖出:
实例
import yfinance as yf
# 策略类:继承 bt.Strategy
class SmaCross(bt.Strategy):
# 策略参数,可通过 params 外部调整,避免硬编码
params = dict(fast=10, slow=30)
def __init__(self):
# 短期与长期简单移动平均线
self.fast_ma = bt.ind.SMA(period=self.p.fast)
self.slow_ma = bt.ind.SMA(period=self.p.slow)
# 交叉指标:金叉时大于 0,死叉时小于 0
self.crossover = bt.ind.CrossOver(self.fast_ma, self.slow_ma)
def next(self):
# 无持仓且出现金叉 -> 买入 10 股
if not self.position and self.crossover > 0:
self.buy(size=10)
# 有持仓且出现死叉 -> 全部卖出
elif self.position and self.crossover < 0:
self.close()
# 用 yfinance 获取数据,转成 Backtrader 数据源
data = yf.download("600519.SS", start="2021-01-01", end="2023-12-31",
auto_adjust=False, progress=False, multi_level_index=False)
feed = bt.feeds.PandasData(dataname=data)
# 组装回测引擎
cerebro = bt.Cerebro()
cerebro.adddata(feed) # 添加数据
cerebro.addstrategy(SmaCross) # 添加策略
cerebro.broker.setcash(100000.0) # 初始资金 10 万元
cerebro.broker.setcommission(commission=0.0003) # 手续费万三
print("初始市值: %.2f" % cerebro.broker.getvalue())
cerebro.run() # 运行回测
print("最终市值: %.2f" % cerebro.broker.getvalue())
输出结果如下所示:
初始市值: 100000.00 最终市值: 100434.33
策略三年间小幅盈利 434 元。对比一下上一篇手写的向量化回测,Backtrader 帮我们处理了撮合时点、手续费、资金占用等细节,这正是框架的价值。
注意:本例每笔买入 10 股,按茅台约 1800 元的股价占用资金约 1.8 万元,10 万元初始资金足够。如果改成一次买入 100 股(约 18 万元),订单会因资金不足被引擎直接拒绝。另外 A 股实盘最小交易单位是 1 手(100 股),本例为演示方便未按手数取整。
Backtrader 还内置了丰富的分析器,一行代码即可输出完整的绩效报告:
实例
cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=bt.TimeFrame.Days) # 夏普比率
cerebro.addanalyzer(bt.analyzers.DrawDown) # 回撤分析
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) # 交易统计
# 运行后从结果中提取分析器输出
result = cerebro.run()
print("夏普比率:", result[0].analyzers.sharperatio.get_analysis()["sharperatio"])
print("最大回撤: %.2f%%" % result[0].analyzers.drawdown.get_analysis().max.drawdown)
# 还可以绘制交互式回测图表(弹窗展示资金曲线与交易点)
# cerebro.plot()
输出结果如下所示(本例仓位很轻,仅 10 股,回撤和夏普数值仅作演示):
夏普比率: -0.01632125043146268 最大回撤: 3.78%
如何选择回测框架
| 框架 | 优势 | 适合场景 |
|---|---|---|
| 手写 pandas 回测 | 完全透明,理解原理的最佳途径 | 学习阶段、快速验证简单想法 |
| Backtrader | 安装简单、文档全、社区活跃 | 个人研究者的主力回测框架 |
| zipline | 工程化程度高,与 Quantopian 研究体系一脉相承 | 阅读存量资料;新项目建议用 zipline-reloaded |
| VectorBT | 向量化计算,批量参数优化速度极快 | 大规模参数扫描、策略筛选 |
建议:从手写回测入门,理解原理后切换到 Backtrader 做日常研究。框架再成熟,也替代不了你对未来函数、过拟合这些陷阱的警惕。
再次提醒:本教程所有内容仅用于技术学习,不构成任何投资建议。