Quant工具箱:量化开发之量化交易中台化

回顾上一篇文章,我们设计了事件驱动回测框架,用于验证与优化我们的策略;同时也开发了配套的实时交易系统,保证我们有能力将策略实盘跑起真正的资金来。

但我们要的不仅是能上策略,而是能高效且规范地上策略,服务于团队所有成员,不仅要能用,还要易用。

围绕“易用”这个关键词,我们将分别从 需求分析、解决方案、服务构建,三个方面阐述我们今天的主题:量化交易中台化



一、需求分析

什么是量化交易中台?为什么需要一个易用的量化交易中台呢?

我们就从业务需求上开始说起。对于量化交易而言,上一个稳定的量化策略并不容易,因为要做一个完整的量化交易项目,需要经过一系列复杂的流程。从数据探索性分析开始,到特征工程、模型训练,在到策略上线部署、监控,每个环节都有不少细节。


如果缺少一个合理的管理理论与框架,往往就造成整个研发过程笨重、重复、低效,譬如:

  1. 烟囱式开发,每个团队或成员都可能自己去开发取数模块、调参模块、可视化分析模块等,过程重复,技术也难以在整个公司内沉淀下来
  2. 模型研发缺少标准,多人协作时,难以有效沟通交流
  3. 交付部署困难,缺少统一的策略上线、监控、更新等机制
  4. 研发环节繁多,自动化程度低,难以快速得到业务反馈
  5. 基础资源分散,难以充分利用,如数据资源、计算资源



这个问题也是数据科学领域最头疼的问题,但近些年来,已经有不少头部公司给出了他们的解决方案,数据中台化,量化交易领域也大可借鉴这一思想。

对应的,我们给量化交易中台下一个定义:

量化交易中台是一套完整的量化策略全生命周期管理平台和服务配置体系,通过

  1. 服务编排,打通数据平台与计算调度服务
  2. 知识复用,沉淀特征、算法与策略,沉淀知识
  3. 角色管理,明确策略开发过程中的职责与权限
  4. 流程标准化,实现策略开发、模型交付、实时交易、复盘分析等环节的统一与高度自动化

从而达到量化策略的敏捷交付,沉淀技术、整合资源,提高团队的生产效率。


二、解决方案

目标定下来了,我们就需要策划具体的实施路线。

我们从上文的流程标准化出发,通过这贯穿策略生命周期的4个主要环节(策略开发->模型交付->实时交易->复盘分析),来一步步拆解这个中台。



1. 策略开发

首先就是策略开发,这是一切的开始,和机器学习算法相似,这里要涉及大量的特征工程、策略训练调参、以及效果可视化分析的工作。为了让研究人员能够方便、直接地使用平台进行策略开发,我们需要安装好关键的依赖,减少重复性工作:

  1. 底层算法库:scikit-learn,tensorflow,pyspark等,并配置好对应的后端计算资源,充分利用CPU与GPU集群资源
  2. 统一的数据访问接口:与数据中台交互,快速访问公司底层的数据资源
  3. 标准的策略研究框架:一如前两篇文章提及的向量化回测框架以及事件驱动回测框架,能够整合资源,提供标准的回测、调参、可视化功能
  4. 多租户管理的IDE:前端使用Jupyter作为建模IDE,使用Jupyterhub来支持多租户,使不同团队或项目能拥有独立的开发环境。

这样,基础的研究环境便搭建完毕,只需以anaconda环境为基础,安装团队开发的框架及必要依赖库,就能解放重复开发的生产力,加速研究人员的开发进程。

2. 模型交付

如果说研究环境是生产价值之处,那么模型交付环节,便是沉淀价值之处。一方面我们将模型发布到生产环境提供服务,另一方面,我们也将研究过程中开发的特征、算法、模型等也入库保存,沉淀知识,复用产出。

这里我们使用 git + teamcity + mlflow 来组合出模型的持续交付平台。其中,

  1. git提供版本控制功能,当策略开发完成时,我们将完整的项目代码提交到github远程仓库(策略代码,测试代码,说明文档)
  2. teamcity提供CI/CD功能,在项目代码提交后,首先会触发测试代码,确认项目可执行;然后,便会触发shell脚本,调用mlflow
  3. mlflow提供项目管理与部署功能,留痕策略上线前的重要制品,并支持一键策略部署上线

这里着重介绍mlflow,这是由databricks公司(apache spark创始人建立)于2018年开源的针对机器学习的管理框架,旨在解决机器学习项目中模型难以追踪、复现及部署的难题,提供全生命周期管理。

mlflow在领域抽象方面做得相当出众。它抽象出experiment,意为某个实验项目,可对应单个量化交易策略项目;抽象出run,意为单次实验记录,每个experiment都有多个实验记录,可对应量化交易策略的某个版本;抽象出params/metrics/artifact,分别对应某次实验中的模型参数/性能指标/制品,同样的,也完全可以对应到量化策略中来

  1. params: 量化策略的参数(所有模型参数/开始日期/结束日期/交易标的)
  2. metrics: 策略的样本外回测表现(年化收益/最大回测/夏普比率/年化波动/胜率/胜负比)
  3. artifact: 制品有更大的灵活性,可以存储各式的文件,对于量化开发,我们需要存储:
    1. indicator.csv 存储对于策略的定制化的指标(如换手率/超额收益)
    2. report.ipynb 存储策略的报告文档,集成图、文、表、代码,多角度阐释策略的原理及效果
    3. strategy.pkl 存储可部署的二进制策略文件

其中,strategy.pkl是重要的制品,因为mlflow提供了一键部署功能,可以通过这个pickle文件直接部署成Flask REST服务,能彻底解耦模型环境与业务环境。

3. 实时交易

提及策略的部署,会根据策略形式,分两种上线方式:

  1. 若是集成了信号 + 风控的一体化策略,则我们会提交代码到生产环境,启动一个交易应用进程,订阅行情、进行交易。这也是最常用的策略及对应的部署方式
  2. 若策略仅负责信号生成,并将风控完全交给交易系统处理,则我们会启动1个交易线程 + 1个模型服务线程,模型服务线程提供上文提及的Flask REST服务,交易线程会将收到的行情转发到模型处,并得到对应的信号进行交易。

笔者近来非常喜欢第二种部署方式,原因有3:

  1. 运维方面,解耦模型与交易系统。风控更加客观,但模型本身却比较多变,我们要保证模型更新、迭代时,交易与风控仍然保持运作,避免重启应用,错过重要行情。而当二者解耦时,我们便能实现这样的高可用特性,完美适应电子货币这种7*24小时交易的市场。
  2. 研发发面,研究员只需要关注“何时发出交易信号”,风控、仓位、盈亏管理等交由交易系统处理,能更加专注市场,而纯信号研究的回测也能充分向量化,加速研究的效率。
  3. 实现方面,通过使用RPC模式,使得模型从本地调用切换到远程调用时,业务代码完全无感。

易实现,又能在研发和运维方面提高效率,不失为一个可选的部署方式。同样的想法也适用于拆解交易服务中的OMS,Broker等重型组件,通过微服务来充分解放各模块的开发与扩展。



4. 分析复盘

完成实盘交易,并不是项目的终点,恰恰相反,因为通过复盘,很有可能就触发了新一轮迭代的开始。

复盘,对于量化策略来说至关重要,它能及时验证交易系统及模型是否是正常运作,若不是,则提醒团队停下系统,进行优化。

通常有3个步骤进行复盘:

  1. 抓取交易所的成交明细数据,与本地系统进行比对,确保数据正确无缺漏(交易系统正常)
  2. 再抓取当天的历史数据进行回测复盘,对比实盘订单,观察当天信号是否正常触发(策略无bug)
  3. 最后对成交明细进行逐一分析,确定当日收益情况(策略未失效)

实现方面,需要注意:

  1. 无论是行情数据还是成交数据,都需要增量式抓取,其中,在抓取成交数据时要注意更新数据库中未成交订单的状态更新。
  2. 回测复盘时,也要关注每个信号的触发点的实际订单执行状况:是否成交、成交价格及成交量如何。
  3. 成交情况分析当属复盘中最关键的一环,不仅在于确定收益,更关键的是在策略亏损时,识别出亏损的点、为何亏损,指导策略后续的迭代优化。

在复盘成交明细时,通常要对每一笔交易采用Round Trips方式进行分析,类似于会计中FIFO的记账原则,能细致给出每笔交易的PnL、Carry、持仓时间等。这样我们就能重点观察亏损较大的交易,分析对应的市场行情状态,明确要优化的方向,并回到最初的策略开发工作流中。复盘的思路其实和机器学习中的梯度下降法一样,要往能最大减小loss的方向进行调优。实现方面可以直接使用pyfolio中的round_trips模块,能快速将盈亏分析,并在notebook上图文并茂地展示出来。

复盘是每日的例行公事,属于重复性工作,重复性的工作当交给计算机,从而让人有更多时间进行创造性的工作。在实际的生产过程中,带有重复性志的工作其实非常多,通常的方式是使用crontab进行定时任务调度,但一旦任务变得复杂起来,crontab就非常难以管理。更合理的方式,是使用调度管理框架airflow。

airflow是airbnb公司于2015年开源出来的项目,如今已跻身为apache顶级项目,其实用性不言而喻:

  1. 灵活易用。airlfow最大的特点就是其使用Python脚本作为调度任务的配置文件,让调度任务的灵活性大大增加,使得airflow几乎能和其他所有系统配合使用。例如,airflow使用DAG有向无环图定义任务依赖关系,复盘任务就是一个dag文件,文件中写明了3个任务,数据抓取 >> 回测 >> 复盘分析,任务将按照预定时间、在依赖任务执行成功后执行。
  2. 高伸缩性的架构,极易扩展。airflow可外接celery编排多个工作节点,在未来,我们的模型可能需要实时离线训练,这会有频繁调度及大计算量的需求,而airflow+celery 就能很好地解决这个场景需求。
  3. 漂亮的UI设计。不得不承认,人是视觉动物,友善的界面确实能极大提高使用体验。

另外,除了每日的复盘分析,我们也会需要实时对策略表现有一个监控,例如净值、最近300笔订单的执行情况等。这部分我们可以直接采用开源的BI工具metabase,推荐的原因也很类似,漂亮的UI + 灵活易用。

如此一来,我们就明确了各个环节的主要流程及对应的服务后,接下来就该来编排这些服务,让工作流真正流转起来。



三、服务构建

服务构建方面,我们遵循微服务的原则,服务之间以轻量级RESTful协议交互,降低耦合性,同时保证每个服务的高伸缩、高可用。我们使用docker进行服务编排,并将服务分隔成前、中、后3层。后台整合数据与计算资源,中台专注于策略研发,前台则是直面业务,管理交易与日常任务运行。

一图胜千言:


每个服务的功能我们都已经明确了,现在关键任务是梳理服务之间的关联。其中,最关键的是以下两组联系:

  1. 服务入口Jupyterhub,需要对接好底层mongodb存储的时序数据库以及spark的集群计算资源,充分利用后台资源;
  2. mlflow teamcity metabase trader airflow等服务都以postgres为数据库后端、存储元数据,保证迁移时重要数据不丢失;

通过docker的容器支持,我们能快速的在云端拉起整个服务,从0到1只需十来分钟。之后设置好防火墙与端口转发,就可以在本地机器上随时享用这个7*24小时不间断的量化中台服务了。

四、总结

1. 分析

至此,对比最初的需求,总结一下我们做的工作

  1. 我们通过docker编排起了一整套服务,打通数据计算后台、研究中台以及管理前台
  2. 通过git+mlflow实现知识沉淀与复用
  3. 研究员只需要(权限上也只能)使用jupyter环境,便能参与生产,确保研究员的专注度。模型交付、复盘等均已自动化,可由IT负责运维。剩下的则是由基金经理来决定上线与否。
  4. 开发流程上,我们提供了统一的环境与框架支持;交付流程上,teamcity的持续交付很好地解决了整个流程反馈慢的问题,确保“谁开发谁维护”的可行性;实时交易流程上,我们使用RESTful方式对接交易系统与模型;复盘流程上,airflow + pyfolio + metabase的定时调度确保了高度自动化

当然,亦是有不尽人意的地方存在

  1. 服务尚不完美,距离产品化还有距离。最简单的例子,作为核心后端postgresql必须要高可用,整个服务才能稳定。同样的,rabbitmq、teamcity、celery、spark等集群也很类似,为了更好的扩展与维护服务,要深入各个服务的技术栈,掌握其中细节。这样,即使未来服务种类增加、压力增重时,我们的服务依然保持可靠、有效。
  2. 速度一直是在交易领域不能不提的话题。很遗憾,我们使用大量跨进程、甚至跨节点的访问,使得系统已经不适合超高频的交易领域。同时,为了快速开发,我们几乎都是采用纯Python的技术栈,选择即是取舍,毕竟对于小公司、小团队而言,真的是很难有时间、也有能力去cover类似C++这样复杂的技术栈。也要牢记:过早的优化是万恶之源。

其实还有一个点,是在技术之外的,那就是人。文章不涉及,不代表不重要。事实上,人才是价值产生的源泉。找到更多志同道合、有能力、有执行力的同事,才能真正地让整套服务产生规模化效应,为公司、为团队带来更多利润。(p.s. 团队管理该算是最大也最难的技术了)

2. 下一步

总算,我们建立起了整套量化交易的服务中台,可用、能用、也易用。交易系统开发的工作该告一段落了,可以让它在实际的生产服务中逐步迭代 。下一步,我们将从Developer视角切换到Analyst视角,开始将重心移到研究策略上。毕竟只有真正研发出有效稳定的策略,以上所有的基础设施才算产生了价值。策略该如何研发,细节上要注意什么,我们就到下篇文章来一起探讨吧


编辑于 2019-12-10

文章被以下专栏收录

    面向quant的工具集,服务于 1. 量化开发(中台化的交易系统平台) 2. 量化研究(面向机器学习的投研方案) 3. 实盘交易(基于电子货币的实盘心得)