3、回测平台搭建:使用Python搭建简易回测框架、Backtrader库入门、Zipline库简介
做量化交易,回测平台就是你的实验室。没有它,策略就是空中楼阁。
我刚开始做量化那会儿,踩过不少坑。最惨的一次,用Excel手动回测了一个看起来稳赚的策略,结果实盘第一天就亏了5%。后来才发现,我漏算了滑点和手续费。嗯,从那以后,我再也不敢用手工回测了。
这一章,咱们就聊聊怎么搭建回测平台。我会从最基础的Python框架讲起,再带你入门Backtrader,最后简单介绍Zipline。说白了,就是让你知道:回测到底是怎么跑的,以及用什么工具跑最顺手。
核心观点:回测框架的核心就三件事——数据输入、策略逻辑、绩效输出。搞懂这三样,任何框架你都能快速上手。
3.1 用Python搭建简易回测框架
别一上来就上大框架。我建议你先自己写一个简单的回测引擎。为什么?因为只有亲手写过,你才能真正理解回测的底层逻辑。
一个最简回测框架,其实就三个部分:
- 数据模块:加载历史K线数据
- 策略模块:定义买卖信号
- 执行模块:模拟交易并计算收益
来看个例子。这是我早期项目里用过的简化版代码:
import pandas as pd
import numpy as np
class SimpleBacktest:
def __init__(self, data, initial_cash=100000):
self.data = data
self.cash = initial_cash
self.position = 0
self.equity_curve = []
def run(self, strategy_func):
for i in range(len(self.data)):
price = self.data['close'].iloc[i]
signal = strategy_func(self.data.iloc[:i+1])
if signal == 1 and self.cash > 0:
# 全仓买入
self.position = self.cash / price
self.cash = 0
elif signal == -1 and self.position > 0:
# 全仓卖出
self.cash = self.position * price
self.position = 0
equity = self.cash + self.position * price
self.equity_curve.append(equity)
return pd.Series(self.equity_curve)
# 一个简单的均线策略
def ma_strategy(data):
if len(data) < 20:
return 0
ma5 = data['close'].tail(5).mean()
ma20 = data['close'].tail(20).mean()
if ma5 > ma20:
return 1 # 买入
elif ma5 < ma20:
return -1 # 卖出
return 0
# 使用示例
data = pd.DataFrame({'close': [100, 102, 101, 105, 108, 107, 110]})
bt = SimpleBacktest(data)
result = bt.run(ma_strategy)
print(result)
你看,核心逻辑就这么几行。遍历每一天的价格,根据策略信号决定买卖,最后算总资产。我在项目中遇到过一个问题:这个框架没有考虑交易成本。实盘时你会发现,手续费和滑点能吃掉你大部分利润。
我的经验:写简易框架时,一定要预留交易成本的接口。哪怕先设成0,也比后面改代码强。我吃过这个亏,改起来真的很痛苦。
3.2 Backtrader库入门
简易框架写完了,你可能会想:有没有现成的、功能更全的库?有,Backtrader就是我最常用的一个。
Backtrader是Python生态里最流行的回测框架之一。它最大的优点是:设计优雅,扩展性强。你想想看,一个框架能让你用几行代码就完成数据加载、策略编写、绩效分析,是不是很爽?
先看个完整的例子:
import backtrader as bt
# 1. 定义策略
class MyStrategy(bt.Strategy):
def __init__(self):
self.sma = bt.indicators.SimpleMovingAverage(
self.data.close, period=15)
def next(self):
if self.data.close[0] > self.sma[0]:
self.buy(size=100)
elif self.data.close[0] < self.sma[0]:
self.sell(size=100)
# 2. 加载数据
data = bt.feeds.YahooFinanceData(
dataname='AAPL',
fromdate=datetime(2020, 1, 1),
todate=datetime(2023, 12, 31))
# 3. 运行回测
cerebro = bt.Cerebro()
cerebro.addstrategy(MyStrategy)
cerebro.adddata(data)
cerebro.broker.setcash(100000.0)
cerebro.broker.setcommission(commission=0.001)
print('初始资金: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('最终资金: %.2f' % cerebro.broker.getvalue())
这段代码做了三件事:
- 定义策略:在
next()方法里写买卖逻辑 - 加载数据:支持Yahoo、CSV等多种数据源
- 配置回测:设置初始资金、手续费
我个人习惯用Backtrader做策略原型验证。为什么?因为它内置了50多种技术指标,你根本不用自己算。而且它的订单执行引擎很真实,会模拟市价单、限价单、滑点等细节。
注意:Backtrader的next()方法每次只处理一根K线。如果你需要用到多根K线的数据,记得用self.datas[0].close.get(size=5)这种方式获取历史数据。我曾经在这里卡了整整一个下午。
Backtrader还有一个很实用的功能——分析器。你可以轻松得到夏普比率、最大回撤、年化收益等指标:
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
results = cerebro.run()
strat = results[0]
print('夏普比率:', strat.analyzers.sharpe.get_analysis())
print('最大回撤:', strat.analyzers.drawdown.get_analysis())
你看,几行代码就把绩效分析搞定了。这就是框架的价值。
3.3 Zipline库简介
说完Backtrader,咱们再聊聊Zipline。这个库你可能听说过,它是Quantopian公司开发的,曾经是业界标杆。
Zipline和Backtrader最大的区别在于:Zipline更偏向事件驱动,而且和Alphalens、Pyfolio等库深度集成。如果你做因子分析,Zipline会是更好的选择。
来看个Zipline的简单例子:
from zipline.api import order_target, record, symbol
from zipline import run_algorithm
import pandas as pd
def initialize(context):
context.asset = symbol('AAPL')
def handle_data(context, data):
# 获取过去30天的平均价格
price_history = data.history(
context.asset, 'price', 30, '1d')
avg_price = price_history.mean()
current_price = data.current(
context.asset, 'price')
if current_price > avg_price:
order_target(context.asset, 100)
else:
order_target(context.asset, 0)
# 运行回测
start = pd.Timestamp('2020-01-01', tz='UTC')
end = pd.Timestamp('2023-12-31', tz='UTC')
results = run_algorithm(
start=start,
end=end,
initialize=initialize,
handle_data=handle_data,
capital_base=100000,
data_frequency='daily',
bundle='yahoo'
)
Zipline的handle_data函数每天被调用一次,你可以在里面写策略逻辑。它的data.history方法可以获取历史数据,data.current获取当前数据。
不过我得提醒你:Zipline的安装比较麻烦。它依赖很多底层库,在Windows上尤其容易出问题。我建议你在Linux或Mac上使用,或者直接用Docker镜像。
我的建议:如果你是新手,先从Backtrader入手。它安装简单,文档齐全,社区活跃。等你把Backtrader玩熟了,再考虑Zipline。毕竟,工具是拿来用的,不是拿来折腾的。
3.4 三个框架的对比
说了这么多,你可能有点晕。到底该选哪个?我整理了一个表格,方便你对比:
| 特性 | 简易框架 | Backtrader | Zipline |
|---|---|---|---|
| 上手难度 | 低 | 中 | 高 |
| 安装难度 | 无 | 低 | 高 |
| 内置指标 | 无 | 50+ | 20+ |
| 订单类型 | 仅市价单 | 市价/限价/止损 | 市价/限价 |
| 绩效分析 | 需自己写 | 内置分析器 | 需配合Pyfolio |
| 适合场景 | 学习原理 | 策略原型验证 | 因子研究 |
你想想看,如果你只是想验证一个简单的均线策略,用Backtrader就够了。但如果你在做多因子模型,需要和Alphalens配合做因子IC分析,那Zipline会更合适。
下面这张图展示了三个框架的核心流程对比,帮你理清思路:
这张图很直观。简易框架就是一条直线,你自己控制每一步。Backtrader和Zipline则提供了更完整的生命周期管理。
避坑指南:不管你用哪个框架,一定要做过拟合检测。我见过太多人在回测里跑出漂亮曲线,实盘却一塌糊涂。记住:回测的目的是发现策略的缺陷,而不是证明它有多完美。
好了,关于回测平台搭建就聊这么多。你可能会问:学了这些够用吗?说实话,够你应付大部分场景了。剩下的,就是在实战中慢慢积累经验了。
公众号:蓝海资料掘金营,微信deep3321