1
头图

image

前言

  时至今日,WonderTrader已经受到不少朋友的关注,笔者也感到非常荣幸。这样的关注从某种角度来说,也是对笔者的认可,哪怕是批评的声音,也是对笔者的鞭策。之前有一些朋友在研读WonderTrader代码的时候,遇到了一些问题,最主要的就是不清楚整个平台的架构设计,很多细节上理解不透。所以这些朋友已经三番五次跟笔者说,希望笔者写个文章整体介绍一下平台的架构设计。
  其实笔者一开始不是很想写这样的文章。毕竟笔者自问还是下了很多功夫在代码里的,还是希望识货的人多读读源码,而不是看一下架构文章就对WonderTrader口若悬河地指点江山。后来天人交战了一段时间,笔者豁然开朗:既然开源了,何必吝啬多写几篇文章,授人以鱼不如授人以渔。于是乎,就有了这个《WonderTrader架构详解》的系列文章。
  本文是该系列文章的第一篇,主要介绍WonderTrader整体架构和策略实盘环境下的一般流程

核心设计原则

  笔者之前有一篇文章,大致介绍了一下WonderTrader的演变过程。而WonderTrader经过这么多次的迭代和重构,有一套核心的设计原则贯穿始终,这也是WonderTrader经历多次迭代和重构,最终走向成熟而不是分崩离析的核心原因。

1、组件化原则

  在软件工程中,解耦是系统设计的必修课程。耦合太重,各个模块之间的互相依赖太多,会导致代码逻辑复杂难解,从而降低代码的可维护性。所以我们在设计复杂系统的时候,一定要考虑如何合理的解耦。合理解耦以后,得到的就是一个组件化的系统。

  系统组件化,有很多好处

  • 便于团队协作,不同组件的开发可以同步进行,提升开发效率
  • 组件开发更灵活,只要符合组件接口的范式,开发环境可以灵活使用
  • 组件扩展更便捷,对接新的第三方时只需要增量更新,不影响其他组件

  但是系统组件化,也有一些前提

  • 各组件之间通过接口进行访问,没有额外的依赖。所以接口设计的好坏,直接关系到组件化的成功率和效果。
  • 组件化,需要在接口层面进行抽象。而抽象,则难以避免带来性能损失,如果在对性能有极致追求的场景下,组件化一定要谨慎。
  • 对于同一个接口,接口层的抽象,会将符合该接口的不同组件的差异化的点隐藏起来。如果系统一定要用到这些差异化的部分,可能会导致接口设计的复杂化。

  WonderTrader采用的组件化设计,将独立的功能模块全部封装到独立的组件中,用接口连接起来。比较典型的是不同的行情接入模块(Parsers)和不同的交易通道模块(Traders),因为每个模块都要对接各自对应的第三方API,所以采用组件化设计,能有效的将各自不同的逻辑隔离开,让系统只需要关注接口传递的数据即可。此外,执行单元(ExecuteUnit)、风控模块(RiskMonitor)、数据落地模块(DataWriter)和数据读入模块(DataReader)等,都遵循组件化设计的原则。

2、策略最简化原则

  策略最简化原则,从某种角度来说,是一个哲学问题。之所以这么说,是源自于笔者和一位用户的讨论,讨论主要围绕策略的信号接口是怎么实现的来展开的。大致的观点就是这位朋友觉得策略需要确定当前信号到底是要开多、开空、平多或者平空,而笔者却认为策略只需要设置目标部位即可,不需要关注到底是要怎么下达交易指令。
  在上一次重构WonderTrader的时候,笔者花了很长时间来思考一些问题,诸如:

  • 策略关注的最核心的点是什么?
  • 策略是不是一定要知道开平多空?
  • 策略是不是一定要知道不同的接口回调过来的数据结构?
  • 策略是不是一定要自行管理订单?
  • ……

  在经历了反复的思考以后,笔者没有得出任何答案。但是笔者也不是一个拖沓的人,既然没有答案,那么笔者就决定从减法做起。

  • 策略只需要关注信号逻辑,不需要关注如何执行,一切都丢给底层
  • 策略不需要知道开平多空,只需要告诉交易引擎自己的目标部位是什么,一切都丢给底层
  • 策略不需要和任何接口打交道,只和数据打交道,其他的一切都丢给底层
  • 策略不需要管理订单,一切都丢给底层
  • ……

  减法做完以后,笔者也不再纠结这个问题,正如前面提到的,这是一个哲学问题,而大多数哲学问题,都没有答案。但是笔者相信这样的减法,对于每个策略研发人员来说,都是非常友好的。底层会帮助策略把策略逻辑以外的任何事情都搞定,从数据管理到订单执行,包括多空开平,甚至平今对锁等等,底层都会全部搞定。

3、策略一致性原则

  策略的一致性原则,包含多个方面:

  • 策略代码的一致性,即回测和实盘用同样的代码
  • 策略回测和实盘信号的一致性,即实盘中触发的信号,在使用历史数据回测时应当是一致的
  • 同一套策略,不同的交易通道中发出的交易指令,应当是一致的

  策略代码的一致性比较好理解,也比较好实现,只要保证回测框架和实盘框架向策略提供的API是一致的,就可以保证策略可以无缝在回测环境和实盘环境之间切换
  策略信号的一致性,其实是对平台数据处理的一致性的要求。只有实盘中实时处理的数据和历史数据完全一致,才能保证历史回测和实盘信号的一致性。因为实盘环境中,数据的到达有先后,如果处理数据保证策略响应的一致性,确实是比较考验功夫的。笔者在WonderTrader中花了很多精力,来设计一种机制,可以尽可能的保证实盘数据的处理和历史回测数据的一致性,从而保证策略在实盘和回测中信号的一致性
  关于不同的交易通道中,信号和指令的一致性,这个就是WonderTrader的核心机制之一,即1+N的执行架构1+N的执行架构,可以保证一个策略组合的信号在不同的交易通道中都能够一致,从而使得不同的交易通道的策略绩效相差无几。关于1+N执行架构的详细介绍,笔者会在后续的文章中做详细的阐述,这里暂时就不展开了。

核心架构介绍

  前面提到的设计原则,相对比较抽象。下面笔者将结合示意图,分别介绍WonderTrader回测框架实盘框架以及策略在实盘中的基本流程。读者可以从下面的架构设计中和前面提到的设计原则互相参考,应该可以得到一些印证。

1、回测框架

回测框架架构图
  上图是WonderTrader回测框架的架构图。从上图我们可以看出来,回测框架还是比较简洁的。整个回测框架的核心在于4个仿真器和一个历史数据回放器。而4个仿真器,分别对应3种不同类型的策略,以及执行单元。
  而策略部分,除了C++策略可以直接和回测引擎交互以外,多语言策略(现在只实现了python)则需要通过C接口的粘合层跟回测引擎进行交互,同时还需要提供一个多语言子框架提供多语言环境下的API和底层交互接口(python下为wtpy)
  执行单元,是实盘中执行器的核心逻辑模块,用于执行交易指令和管理订单的。因为执行单元只能C++开发,所以不再提供C接口粘合层。Exec仿真器,则通过定时设置目标仓位,触发执行单元的核心逻辑,并对执行单元发出的交易指令进行模拟撮合,从而达到回测执行单元,分析执行逻辑的表现的目的
  历史数据回放器,通过从数据引擎加载历史数据,并根据历史数据按数据周期进行回放,触发策略的重算,从而驱动策略逻辑,并在仿真器Mocker中进行仿真撮合,进而达到回测的目的。从上图可以看出,历史数据回放器,可以从WT数据文件系统CSV文件以及数据库(目前只对接了Mysql)加载历史数据。

2、实盘框架

实盘框架架构图
  WonderTrader实盘框架相比回测框架就要复杂很多。除了策略实现和回测框架是一致的(前文提到的策略一致性原则),底层核心为了对接实盘中不同的功能模块,所以就有了很大的不同。
  策略引擎,也是一个策略组合,接收到数据组件广播的实时数据以后,触发策略重算,从而生成信号,并经由策略引擎轧平汇总以后,丢给执行器执行,而执行器调用不同的执行单元的执行逻辑以后,最终通过Trades交易通道模块,向交易柜台下达交易指令,从而完成一轮信号的生产执行的循环。目前策略引擎针对不同类型的策略实现上有一些区别,所以分成了3种策略引擎。
  需要注意的是,数据组件其实是作为一个独立的伺服在运行的。目的也比较明确,就是要实现读写分离,并且可以同时向多个组合盘实例提供数据服务。数据组件通过调用DataWriter模块接口进行数据的落地,数据存储支持WT文件系统以及数据库两种模式。而策略则通过策略引擎调用数据管理器,通过DataReader从数据存储中读取文件到内存中,得到数据管理器中返回的数据切片。
  还有一个相对独立的模块,就是风控模块RiskMonitor。风控模块主要针对组合盘(策略引擎)的虚拟资金进行风控,目前内置的风控模块支持的指标主要包括最大日内回撤最大多日回撤等风险指标进行控制。

3、策略基本流程

CTA实盘基本流程图
  上图是WonderTrader中CTA策略在实盘环境中的基本流程。

  • 首先Parser从行情源接入行情数据,并解析成WonderTrader自己的tick数据
  • tick数据先传递给CTATicker(数据同步器)进行时间戳的同步控制
  • 每一笔tick,都会触发策略的on_tick回调
  • tick数据的时间戳确定了上一个分钟的结束,就会判断是否有K线刚好闭合
  • 如果K线已经闭合,则触发策略的on_bar回调
  • 如果策略订阅的全部K线都闭合了,则触发策略的on_schedule回调进行重算
  • 策略重算过程中,调整了目标仓位,最终汇总到策略引擎中进行汇总处理
  • 头寸汇总以后,分发给各个执行器进行执行
  • 执行器调用底层执行单元的逻辑发出下单指令
  • 最后下单指令通过交易通道Traders最终下达交易柜台

  WonderTrader一共有三种不同的策略引擎,以用于不同应用场景的策略。除了HFT策略,策略直接对接交易通道Trader以外,另外两种策略的基本流程都和上面介绍的CTA基本流程是一致的。

结束语

  由于篇幅有限,本文的介绍就到此结束了。相信通过本文的介绍,各位读者对于WonderTrader的整体架构已经有了一个初步的认知了。如果有读者愿意更进一步的了解WonderTrader,希望这篇文章可以帮助到各位。下一周,笔者将围绕数据处理,来介绍WonderTrader的数据处理机制,望各位读者届时多多捧场。

  WonderTrader旨在给各位量化从业人员提供更好的轮子,将技术相关的东西都封装在平台中,力求给策略研发带来更好的策略开发体验。

最后再安利一下WonderTrader

WonderTradergithub地址:https://github.com/wondertrad...

WonderTrader官网地址:https://wondertrader.github.io

wtpygithub地址:https://github.com/wondertrad...


市场有风险,投资需谨慎。以上陈述仅作为对于历史事件的回顾,不代表对未来的观点,同时不作为任何投资建议。


WonderTrader
31 声望23 粉丝