当前位置: 首页 > news >正文

量化交易系统开发经验分享--回测框架调研

一、前言

       这段时间在集中做一个量化交易系统的开发任务,目前系统的MVP已经完成开发,后续会整理一些经验与成果和大家交流。刚好有一个前期做策略回测这块的调研,下面把调研的成果做一个整理总结先给大家分享一下,请批评指正。

       在介绍本次调研结果之前,我想先说一下目前我对于量化交易和策略回测的理解。首先,我们知道量化交易相比于传统的交易,它最主要的改变在于将交易由人为经验驱动转变为由客观数据驱动,倒不是说人为经验判断一定弱于客观数据,我认为量化真正的意义在于将交易从一门艺术变成了科学,尤其是和计量科学联系在了一起,使得交易的过程可以通过计量科学被理解、共享和优化。

       作为量化交易中的关键一步,策略回测的目的是验证所构建的策略能不能按照预期实现各绩效指标。那从计量的角度证明这个事情,肯定使用的是归纳法,即用数据来证明。这里其实就分出来两种思路,一种是目前应用最多的基于历史数据来证明(通过历史数据进行回测),这种方式最直接也最简单,但是有两个问题,一是对于部分公开市场不活跃的品种数据不足,二是通过一组数据来证明,在统计上缺少说服力,而且策略的鲁棒性不可检验,所以另一种方式是数据模拟的方法,这种方法能够同时检测策略的有效性和鲁棒性,但是在实现上会比第一种复杂一些。这两个思路下分了很多的具体方法,下面分别来介绍。

二、几种策略回测方法及其代表的落地框架比较

2.1. 基于历史数据的回测方法

2.1.1. 向量化回测

       向量化回测是一种基于批量数据处理的回测方法,它利用矩阵运算一次性计算策略在所有时间点的因子、信号和绩效,优点在于速度快,缺点有以下两点,一是忽略了很多市场要素(比如订单簿动态),二是策略的算子无法根据交易情况进行动态调整(比如无法处理动态订单管理等等)。

       代表性的技术框架是VectorBT,这是一个纯向量化回测的框架,从因子、交易信号和绩效指标都由矩阵计算实现,而且各个步骤相互独立计算,在实际应用中可以将这些独立的步骤封装为串行的工作流:

       以VectorBT为代表的向量化回测方法有两个核心的优点,一是简单,忽略了市场结构的因素(如订单簿变化)和各种由于当前交易本身对策略造成的影响(比如动态仓位管理),适合快速验证交易想法本身是否可行;二是快速,向量化计算相比于事件驱动的循环触发,性能有显著的优势。但是其也有明显的局限,一是默认下单即成交,未纳入市场结构的变量,导致只能验证交易想法,无法进一步验证策略在市场内的有效性;二是随着回测数据量的增大,单次矩阵计算对于算力和内存的要求会越来越高(尤其是多维度且大数据量的矩阵计算),如果不做优化会频繁奔溃(内存不足);三是由于因子、信号、仓位、绩效等计算独立且严格串行,所以难以实现前位算子依赖后位算子历史数据的策略(如:网格交易:根据当前持仓成本动态调整买卖档位;因子动态选取策略:在不同的盈亏状态下选择不同的因子执行)。

       VectorBT也尝试解决这些向量化回测的缺陷,对于第一个纳入市场结构因素的问题,VectorBT支持滑点设置,同时滑点变量支持数组输入,因此只要用户能够计算得到与行情数据长度一致的滑点数组,VectorBT是支持动态滑点设置的(是可行的,因为订单簿是市场数据,只要有下单量,理论上就可以计算出每个时间点的滑点);对于第二个内存爆炸的问题,VectorBT一是支持CUDA计算框架(支持cupy的gpu数组);二是基于dask和ray这两个分布式计算库,支持矩阵的分块计算;三是支持内存映射,通过将数据存储在磁盘上,按需加载到内存,避免一次性占用(支持np.memmap作为数组输入);对于第三个算子依赖的问题,如果是后位算子依赖前位算子(比如仓位需要根据交易因子的强弱来动态调整),可以通过自定义处理逻辑,循环的计算后位算子(当然这是以牺牲向量化计算的性能为代价的),VectorBT也支持自定义处理逻辑,但如果是前位算子依赖后位算子的历史数据(比如交易信号需要依据当前持仓动态修正),向量化回测目前没有太好的解决方案,因为这与向量式回测在基本思路上是冲突的(一旦有对后位算子的依赖,必定要每次加载新的后位算子给到前位进行逐行计算,这其实就是事件驱动的逻辑了),所以这里就需要引入事件驱动的回测框架。

2.1.2. 事件驱动型回测

       如果说向量化回测适用于快速验证策略想法,那么事件驱动型回测则是验证策略在真实市场上表现的工具,它通过数据回放的方式重现历史行情的发生过程,并驱动策略的运行。事件驱动型回测的主要优势有以下几点:一是所有的算子可以共同独立消费行情,并且可以相互调用历史数据,因此可以实现复杂依赖的交易策略;二是可以通过自定义事件更为方便的实现事件驱动型策略回测(如新闻事件、宏观经济数据发布、财务报表发布等外部冲击);三是可以更为方便的引入订单簿等市场微结构数据,更好的模拟部分成交、滑点等市场特点;四是由于交易逻辑和实盘交易基本一致,在做模拟盘和实盘迁移时更为方便。它的缺点主要有以下几点:一是速度的问题,主要是以下几个方面,首先由于计算是逐行循环驱动,所以速度相对于向量化回测慢一些,在这个问题上,目前比较好的方法是通过向量化的方式支持因子预处理来优化逐行循环的方式,其次是对于参数优化的性能,这个问题大部分框架都实现了并发计算,以及融入了其他优化的寻优算法(主要是遗传算法);二是对于多频率、多行情的消息发布,需要确保精确对齐时间戳。

       代表性的事件驱动型回测技术框架有BackTrader、vnpy和Zipline等。这些框架在策略回测的实现上大同小异,下面介绍一下他们在上述几个待优化点上的解决方案。

       首先是因子的预处理,BackTrader为了提升事件驱动逐行计算的效率,设计了批处理模式(通过设置runonce=True),批处理模式会预先通过向量化计算所有的indicator并储存在数组中,next()方法通过直接索引数组获取值(当然这个模式无法处理有复杂依赖关系的因子),Zipline也有批处理计算的模式来计算因子,和backtrader的区别在于它需要手动的定义make_pipeline方法来计算因子:

       Vnpy并没有因子的预处理功能,所有的因子都是在事件的回调中和其他算子一起计算的,但是也做了一定的优化,即通过其ArrayManager对象来处理行情并缓存因子(ArrayManager实现了很多高性能的共性计算方法,可以供用户直接调用)。

       在参数优化方面,Backtrader和zipline都可以通过多进程并行计算(配置maxcpus参数),vnpy框架不直接支持,需要用户自行实现;其次在寻优算法上面,Backtrader的优化器库backtrader-optimization实现了遗传算法,对于一些多维度,细颗粒度的网格优化能够有比较明显的性能提升,zipline和vnpy也都有各自的寻优算法接口供调用。在时间戳对齐上,Backtrader的每一个引擎都设置了一根主时间轴(默认是添加的第一个数据流),其他的所有数据时间戳都会与其对齐(升频场景引擎能自动处理(向前填充),但是降频的情况需要手动指定降频的方法,比如resample或者replay);vnpy(portfoliostrategy的回测引擎中)也维护了一个主时间轴(dts),会将所有行情数据的时间戳去重纳入,但是未处理混频的问题,会导致数据回放时频率混乱,会造成回测时在高频时间点缺少低频数据输入等问题。

2.2.基于模拟数据的回测方法

       由于单凭历史数据进行回测在统计缺乏说服力,同时无法验证策略在极端情况,或者特定市场冲击下的鲁棒性,因此基于模拟的数据回测方法做了两件事,一是模拟生成多条历史路径,将策略回测的输入从单一数据变成一个分布,以评估策略的统计特性(如收益分布、最大回撤),也为策略的风控举措指定有了更丰富的输入;二是模拟特定的市场冲击,验证策略的鲁棒性。

2.2.1. 基于计量模型的模拟回测(以蒙特卡洛模拟为例)

       蒙特卡洛模拟通过随机抽样和大量重复实验获得策略的统计特性,由于其需要大量的计算,一般通过向量化的回测框架来实现(比如:VectorBT),具体步骤包括:

  1. 生成随机路径:通过随机过程(如几何布朗运动)模拟价格序列。
  2. 向量化回测:对每条路径运行策略,批量计算绩效指标。
  3. 统计分析:汇总所有模拟结果(如计算夏普比率的分布)。

VectorBT可以通过矩阵运算和并行化高效实现蒙特卡洛模拟:

2.2.2. 基于代理的模拟回测

       基于代理的建模根据一组规则模拟代理人(例如个人交易者或机构)的互动,从而复制金融市场的复杂动态,这些模型生成了模拟认为的数据。相比于基于计量方法的模拟,基于代理的模拟能进一步模拟突发事件以及不同市场风格对于策略的影响。

       ABIDES(Agent-Based Interactive Discrete Event Simulation)是JP Morgen开源的基于代理的模拟框架,它通过定义不同的市场参与者(基础的包括背景代理:市场一般参与者,负责模拟市场的流动性、策略代理:负责模拟待回测策略的交易、事件代理:负责模拟极端事件的发生)以及参与者的交易目的来产生仿真交易信息(包括形成订单簿、价格等)。框架默认背景代理是通过一个明确的交易策略(框架叫价值信念)加一定的噪声引入不确定性,同时框架允许设置大量不同的背景代理(比如100个机构投资者(比如采用均值回归策略)代理,50个散户代理(追涨杀跌)的代理,10个做市代理(保持市场流动性稳定)等)以刻画不同的市场风格。

       目前我刚开始研究这个框架,还没有跑过完整的回测,但是我能想到的问题有这么几个:第一基于代理模拟的市场成交要如何与历史数据做关联(这个问题计量的模拟方法可以通过设置随机种子实现);第二,这个框架的本质是同时运行大量的不同策略以实现交互,如何解决计算性能的问题。这部分我会再研究。

  • 总结

       基于这些回测框架,我觉得可以把回测这个场景再做一个细分,如果用户只想快速验证某个交易想法(其实主要是因子层面),那完全没有必要用事件驱动这种重框架,而一旦用户希望把一个策略运行到实盘,那他必须要更深入的考虑市场实际成交等因素,这个时候事件驱动的回测框架是明显优于向量化回测的。在这两个回测方式的基础上,为了进一步检验策略的统计显著性以及鲁棒性,需要引入数据模拟的回测方式,其中计量方式的重点检测策略的统计显著性,而代理的方式重点检测极端情况对于策略的影响。

相关文章:

  • JavaScript 循环语句全解析:选择最适合的遍历方式
  • 代码随想录训练营第二十一天 |589.N叉数的前序遍历 590.N叉树的后序遍历
  • LeetCode 215题解 | 数组中的第K个最大元素
  • Spring Boot 中的重试机制
  • 基于.Net Core开发的GraphQL开源项目
  • istio in action之服务网格和istio组件
  • Spring Boot 集成 Flink CDC 实现 MySQL 到 Kafka 实时同步
  • Linux 常用命令集合
  • 从InfluxDB到StarRocks:Grab实现Spark监控平台10倍性能提升
  • COT思维链:SequentialChain 方法有哪些参数;优化后的提示词
  • 【C语言】(9)—指针3
  • VSCode1.101.0便携版|中英文|编辑器|安装教程
  • 一个.Net开源的关系管理系统
  • 汇编学习——iOS开发对arm64汇编的初步了解
  • go 通过汇编学习atomic原子操作原理
  • AI面经总结-试读
  • C# 方法(方法重载)
  • 【MySQL】表空间结构 - 从何为表空间到段页详解
  • 服务器mysql连接我碰到的错误
  • Git的核心作用详解
  • 北京航空航天大学首个海外创新研究院落户巴西
  • 中国恒大:清盘人向香港高等法院申请撤回股份转让
  • 退休10年后,70岁成都高新区管委会原巡视员王晋成被查
  • 库尔德工人党决定自行解散
  • 欧阳娜娜携家人回江西探亲,受聘为江西吉安文化旅游大使
  • 湖南湘西州副州长刘冬生主动交代问题,接受审查调查