教程 / Python3 / Python 量化金融库

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(每个交易日调用)两个函数:

实例

from zipline.api import order, record, symbol


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 模块读取:

实例

import 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 backtrader as bt
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.run() 之前添加分析器
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 做日常研究。框架再成熟,也替代不了你对未来函数、过拟合这些陷阱的警惕。

再次提醒:本教程所有内容仅用于技术学习,不构成任何投资建议。