七天打造一套量化交易系统:Day3-回测系统的选择、搭建及改造
前期回顾
为了选择一个好的量化回测库,需要考虑许多方面。比如每个项目的成熟度、维护程度、教程文档是否完善、执行速度、功能性、灵活性等等。
Backtesting.py、VectorBT、Backtrader、Zipline、PyAlgotrade、PyBacktest 这些都是支持 Python 语言的量化回测库,我也都进行过测试使用。
VectorBT 对于以惊人的速度执行数千次迭代特别有用,Backtesting.py 是一个非常直观和成熟的库。这两个项目都在积极维护,并拥有一个蓬勃发展的用户社区,不断提供反馈,创建内容和教程。这也是我试用起来比较顺手的两个项目,借鉴之后自己搭建了更加适合自己的 miniQuant 量化回测系统。接下来对这三个系统进行逐一分享。
VectorBT
VectorBT 是回测量化策略最快的库,但是它的语法不太直观,并且基于向量的方法使得实现具有递归特征的策略变得具有挑战性。
VectorBT 优势
1、最快的可用库
2、优秀的文档
3、活跃社区
4、提供了大量的指南和教程
5、与TA Lib和Pandas TA的集成
VectorBT 缺点
1、新功能仅适用于专业版
2、观点化和不太直观的语法
3、量化策略实现难度大
// 基于 VectorBT 库实现的双均线策略回测代码示例
import vectorbt as vbt
price = data = get_data(ticker='AAPL',from_date='2020-01-01',to_date='2022-11-30')['Close']
fast_ma = vbt.MA.run(price, 12)
slow_ma = vbt.MA.run(price, 24)
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,freq='1D')
pf.stats()
pf.plot()
VectorBT 回测绩效结果
VectorBT 回测交易记录
VectorBT 回测绩效绘图
Backtesting.py
Backtesting.py 是基于事件驱动结构实现的回测系统,事件驱动更适用于实盘中,一笔行情过来驱动一个或多个策略模块运行。但以事件驱动的方式进行回测,运行时间就会长很多。
Backtesting.py 优势
1、直观且易于上手
2、优秀的文档
3、活跃社区
4、提供了大量的指南和教程
5、事件驱动结构允许递归功能
6、与TA Lib和Pandas TA的集成
Backtesting.py 缺点
1、与基于向量的回溯器相比,执行速度较慢
2、无法测试投资组合或多资产策略
// 基于 Backtesting.py 库实现的双均线策略回测代码示例
import backtesting as bt
from backtesting import Strategy, Backtest
from backtesting.lib import crossover
import pandas as pd
def MovingAverage(closes:pd.Series, n:int) -> pd.Series:
return pd.Series(closes).rolling(n).mean()
class SmaCross(Strategy):
sma_fast = 12
sma_slow = 24
def init(self):
self.sma1 = self.I(MovingAverage, self.data.Close, self.sma_fast)
self.sma2 = self.I(MovingAverage, self.data.Close, self.sma_slow)
def next(self):
if not self.position and crossover(self.sma1, self.sma2):
self.buy()
elif self.position and crossover(self.sma2, self.sma1):
self.position.close()
data = get_data(ticker='AAPL',from_date='2020-01-01',to_date='2022-11-30')
bt = Backtest(data, SmaCross, cash=10_000, commission=0,exclusive_orders=True)
stats = bt.run()
print(stats)
print(stats._trades)
bt.plot()
Backtesting.py 回测绩效结果
Backtesting.py 回测交易记录
Backtesting.py 回测绩效绘图
自研 miniQuant
前面提到 VectorBT 在量化回测中运行快,但是语法不易理解,编写策略的难度大;Backtesting.py 虽然易于上手,但其基于事件驱动运行比较慢。那有没有一个回测系统能够集这两个库的优点于一身,同时摒弃掉各自的缺点呢?目前还没有找到,那索性就自己造个轮子。
自研 miniQuant 实现思路也很简单,参考了 Backtesting.py 的架构,将回测中的事件驱动方式改成了循环模式,行情数据回放一遍的功夫,回测结果就出来了,运行效率大大提高。
自研的 miniQuant 可扩展性更强,各个模块独立开来,策略模块可以无缝接入实盘接口,同时也保留了用于实盘的事件驱动方式。
// 商品期货日内交易策略-HANS123 回测代码示例
from Strategy import Hans123
from DataFactory import DataFactory
from DrawChat import DrawChat
if __name__ == "__main__":
# 策略参数,可扩展
arg = {
'data_path': './data/RBL8.csv', # 行情数据路径
'initial_equity': 10000, # 初始权益
'commission': 2, # 手续费
'price_tick': 10, # 期货合约最小变动单位,股票基金等标的无需该参数默认填1
'stop_surplus': 50, # 止盈点数
'stop_loss': -40, # 止损点数
'retrace_line': 5, # 止盈后回撤反弹退出点数
'start_minute': '31', # 开始交易分钟数
}
hans123 = Hans123(arg=arg)
hans123.run()
# 获取策略运行分析结果
anslysis_summary, daily_summary = hans123.anslysis()
print("========回测结果=========")
print(anslysis_summary)
print("========每日汇总=========")
print(daily_summary)
details = hans123.get_trade_details()
# 获取策略回测交易详情,平仓分析
details_df, close_anslysis = hans123.get_trade_details_df()
print("========逐笔交易=========")
print(details_df)
# 画图模块
chat = DrawChat()
chat.draw_fund_treand(arg['initial_equity'], 10, details, title)
miniQuant 回测结果及交易记录
miniQuant 回测资金走势
miniQuant 绘制买卖点
从上面可以看到该策略交易了1382笔,如果把这些买卖点绘制在一张图上肯定画不下,所以提供了按单个交易日为单位绘制买卖点的方式,方便进行回测分析。
# 画指定日期交易情况的买卖点
details = hans123.get_trade_details('2021-06-09')
# 获取指定日期的行情数据
kline = hans123.get_kline_datas('2021-06-09')
chat.draw_buy_sell_in_kline(kline, details)
这里的图就不放了,在上一篇文章中展示过买卖点的截图。【七天打造一套量化交易系统:Day2-量化交易策略基本模型及要点】