浅谈「玩具型」量化回测框架的构建


(xmnz) #1

这是专栏回归的第一篇文章,也是今后一个阶段新的起点。
本文首发于 ipreacher 的博客 The North,任何形式转载视为同意千字五百元稿费要求。

前言

不管是出于工作需要还是对自身代码能力的要求,回测框架总是量化中绕不过去的一关。尽管现在线上回测平台如雨后春笋般冒出来,各个开源框架也都如火如荼地发展着——但基于定制化和策略安全的考虑,自己手写一个回测框架总是最让人舒心和放心的。所以这一篇,也是记录我最近对回测框架的一些理解。为什么标题中用了“玩具型”这个修饰词——因为我毕竟不是工程出身,对框架的理解很有限,只能说写出来的东西给自己还能勉强用用,如有错谬之处,还请各位同仁同学斧正。

回测框架的两大类别

在实际工作中,我接触过两大类回测框架:一是以 pandas + numpy 为骨架的向量化的小型框架;二是基于事件驱动的完整形态的回测框架。下面我就这两种类别分别叙述。

向量化框架

我的第一个回测框架就是基于 pandas + numpy 的向量化框架,数据用 mongo 落地后通过 pymongo 调用,其主要的思路来自于「干货 | 用pandas轻松搭起量化回测框架」。这篇文章篇幅不长,但讲得很细,涵盖了一些其实不用太关注的点,这里就不一一指出了。在这个逻辑下,最核心的地方,也就是所谓的“策略”,其应该体现为一个函数 f,f 能够将原始的股票价格序列映射为仓位信息,然后将仓位信息转变为持仓市值,再进一步地根据持仓市值去计算各种风险、收益指标。

经常做回测的同学会知道,市面上流行的回测框架几乎都不是基于 pandas + numpy 的,我看到一篇匿名回答写得很好「有没有基于python pandas的回测框架? - 知乎」,作者是这样写的:

没有 因为不需要。 pandas的优势在于向量化操作, 真写成逐行event driven的回测框架谁用谁傻逼,慢得感人。说zipline+dataframe的自己应该没有参数优化过几个策略,因为这个方案的速度比其他方案慢2个量级。向量化的话,你的策略就是一个f: dataframe->vector of position的函数。生成position vector以后 你只需要写一个pnl summary的函数即可。 也就是说你的回测框架只需要一个pnl summary函数就能搞定….当然没有现成的框架 因为自己写100行就结束战斗了

这位作者是位业内高人,一语道破。我写第一个回测框架时,加上 tushare 数据导入和 mongo 落地这两块,包括基础的收益分析和画图在内,一共也就是三百多行的事情。到后期优化后,前后只有两百多行。之前说过,pandas + numpy 的框架一般是用于快速回测的小型框架,并不能够提供全方位的功能。这是由于这类框架,写成 OOP 形式比较困难,而且拓展性较差,还有更主要的一点——如果想要在这个框架上完善各种功能(比如强行做成事件驱动的),那回测速度真的是十分感人。

事件驱动框架

相比之下,事件驱动框架在功能和拓展性方面都完胜向量化框架,在回测速度方面则很难和向量化框架去比较——因为两者的复杂程度不在一个级别。一般来说,一个事件驱动的回测框架回包含这些模块:

  • backtest - 框架主入口,负责轮询事件
  • data - 数据模块,负责读入数据
  • event - 事件模块,负责定义框架的各个基础事件
  • strategy - 策略模块,负责产生交易逻辑
  • execution - 执行模块,负责模拟交易
  • portfolio - 组合模块,负责记录交易所产生的数据,并衍生出风险和收益分析

所谓回测,也就是以上几个模块实现交互、信息共享,最终得到回测结果。各个回测框架中,可能对以上几个模块的处理有所不同,或合并或拆分。当然,这只是最简略的框架,实际情形会比这个复杂很多。关于事件驱动的回测框架,后续将会再做详解。

后续计划

最近就在折腾框架的事情,但受限于毕业论文,并没有充足的时间来做这件事,所以进度不会快。至于后续对事件驱动框架的解读,看大伙反馈再定吧。