Skip to content
byrnexu edited this page Sep 12, 2023 · 2 revisions

概述

  整个系统的代码已经开发完毕,目前接了现货的XTP和期货的CTP接口,因为所有柜台的仓位管理、盈亏计算、资产管理的算法及订单的状态维护的处理过程都是一样的,所以新接入一个柜台只需要实现一个行情网关和交易网关即可,基于目前设计良好的接口,大部分柜台的行情和交易API接口只需要一两千行代码,两三天时间就可以快速的接入,也就是说如果有需要的话,可以在一个月内接入10个交易柜台。BetterQuant的主要功能和特点包括:

  • 🔥🔥 这是一个设计目标为支持多账户、多策略、多个产品、多托管主机并行的可水平扩展的分布式量化交易系统,支持多产品、多账户、多策略、或者说多个交易员等各个层面的独立核算和风控,简单的说系统提供了十多个维度 (PNL的维度 仓位快照的维度),你可以对每个维度或者任意维度的组合做独立核算风控
     
  • 🔥🔥 你可以通过系统内置pnl监控策略,将任意维度或者维度组合,任意周期的pnl实时走势记录下来,比如说你要记录某个策略下某个资金账号或者某个交易员每分钟的盈亏变动情况,每个产品每分钟的净值曲线数据,只要修改下配置,这些信息就都会被记录下来,所有的这些数据可用于事后风控的分析处理,对于产品而言,收盘拿到结算价就马上能出净值。当然,你如果没有实时记录但是突然想要历史上任意维度或者维度组合的盈亏情况(比如想知道去年一整年某个金工名下某个策略下的某个策略实例每分钟或者每小时的盈亏情况),BetterQuant也可以帮你轻松搞定。通常而言,系统通用而又强大的功能往往会带来整体性能的下降,为了避免这个问题,在那些影响交易性能的点上,BetterQuant采用了大量的元编程和模板表达式技术,使得系统灵活的同时又不失性能。
     
  • 🔥 支持c++和python两种语言编写交易策略,为你贴心设计的策略引擎接口,可以让你方便的进行交易策略的开发,当然策略引擎本身是一个并行任务处理框架,你还可以用来开发非交易策略,比如说一些监控策略,pnl跟踪策略,手拍单策略等等。整个系统几个命令即可完成安装部署。
     
  • 🔥 各种交易柜台的API形式各样,但是目前BetterQuant的设计中只需要API提供了委托回报和查询订单两个接口,系统就可以帮你精确计算和维护产品组合、产品、用户、账户组合、账户、交易帐户、策略组合、策略、策略实例、用户等各个层级的pnl、手续费、仓位以及未完结订单的信息,自动处理系统崩溃后的各种数据和状态的恢复。
     
  • 🔥 系统内单边持仓,策略净头寸管理,策略下单的时候只需要指定多空,交易服务会为你自动选择平仓或者开仓,当前交易账户没有相应头寸,交易服务会自动为你从其他交易账户借取头寸,最大程度的为你降低手续费。
     
  • 🔥 通过算法交易引擎系统为你提供了内置的拆单算法,通过拆单算法的参数,将大型交易订单分解成更小的子订单,以更好地执行交易策略并减少对市场的冲击,当子单的超过一定的时间不成交,系统内部会自动升级该订单的紧急度,根据市场情况调整报单价格,尽可能降低冲击成本的前提下确保订单顺利成交,拆单算法是一个相对复杂的业务逻辑,系统用一个有限状态机轻松而又优雅的解决了这一问题。
     
  • 🔥 分帐户功能,可以在一个账户下开设多个交易账户,每个账户有自己独立的交易参数设置,从而实现类似对每个交易员进行独立核算和考核的需求。
     
  • 🔥🔥 强大的灾备功能,任何子系统崩溃,不会导致最终的数据异常‼️。交易服务崩溃,重启后会重建仓位和PNL信息,交易网关崩溃重启后会自动处理崩溃期间产生的未处理的订单状态变化,风控子系统崩溃后重启,同样会恢复各种风控指标。上述的恢复过程无需撤销任何未完结的订单。
     
  • 🔥 所有子系统,包括行情子系统、策略引擎、交易服务、交易网关、风控子系统都通过无锁共享内存交互❕。成功的消灭常规方案也就是子系统间通过tcp/domainsocket的百微秒级别的延时❕。用共享内存做子系统之间的ipc,使得系统兼具单进程的性能,同时也具备多进程的安全性,即任意系统crash不会导致其他子系统crash。当然虽然 目前子系统之间是通过共享内存交互的,但这并不是一个单机版的交易系统❕,后续会通过web服务提供restful和websocket接口,接受远端报单、回报和其他业务功能。
     
  • 🔥 内置web服务,可以通过web服务的restful接口查询历史行情,也可以通过web服务向指定策略发起人工干预指令‼️。另外web服务还提供了所有的web客户端的restful和websocket接口。
     
  • 🔥 每个子系统有自己独立的PUB_CHANNEL,你可以往自己的PUB_CHANNEL发布TOPIC,比如行情子系统可以发布新合约上线、合约参数的变化情况、风控子系统可以定制自己的风控触发报警,发布到风控子系统的PUB_CHANNEL,每个子系统可以通过系统的统一的格式订阅和发布自己感兴趣的TOPIC‼️
     
  • 🔥 产品组合、产品、用户、账户组合、账户、交易帐户、策略组合、策略、策略实例、用户等各个层级独立的仓位和订单管理功能。你可以快速得到各个层级或者多个层级组合的仓位和订单信息,比如某个策略下某个账户(即策略+账户)的仓位和订单信息。
     
  • 🔥🔥 插件式的风控指标管理🔌,可以根据系统统一的格式撰写动态链接库形式的风控指标,在交易系统运行中你可以启用、禁用或者升级这些风控插件‼️,从而实现风控指标的动态管理,满足一些市场7*24小时交易需要,开放式的api接口使得你可以在风控指标接口里得到你任何想要的数据,通过这些数据结合自己的需求定制灵活多样化的风控指标。目前系统已提供以下风控插件:
名称 插件名称 插件功能
risk-plugin-trd-symbol-list 黑白名单 设置任意维度维度组合的交易黑白名单,比如产品层面、账户层面
risk-plugin-pnl-monitor pnl监控插件 监控任意维度维度组合的pnl,超过就禁止买入或者开仓
risk-plugin-close-tday-stg 平今仓控制 中金所、大商所、郑商所可根据OrderStg决定是否可平今
risk-plugin-self-trade-ctrl 自成交控制 防止任意维度维度组合自成交的风控插件
risk-plugin-flow-ctrl-plus 流控插件 控制任意维度维度组合的流控的目标

  系统启动的时候会自动加载这些插件,你也可以根据系统统一的规范编写自定义风控插件。  

  • 🔥🔥🔥 系统有一个风控模组的概念,每个风控模组就像一个容器,你可以放入上面提到的你想要的风控插件,每个风控模组也可以根据配置决定当前模组是按照什么粒度进行并行的风控处理,比如说账户粒度,那么不同的账号或者比账号更小粒度的交易账户风控处理可以同时进行。然后我们可以根据配置组合任意多个风控模组,这样不同的风控请求就会被最适合的模组里最快的执行,从而实现整个风控子系统在任意维度的并发处理,而且所有的这些并发处理是无锁的,为了确保性能,风控条目产生的中间状态都保存在共享内存中(和内存不一样,即使程序crash,共享内存中的中间状态不会丢失),你也可以通过配置选择阻塞或者非阻塞的异步任务处理方式,根据不同的需求通过配置动态生成你想要的风控子系统是BetterQuant的一个巨大创新。

  下面的例子配置了4个风控模组:

  第一个是全局风控,对于那些逻辑简单且需要所有维度的风控都在这里执行,第二个是acctId维度的风控,不同账户的风控都在这里可以并发执行,第三个是更细粒度的acctId和trdAcctId维度的风控,不同交易账户级别的风控在这里可以并发执行,第四个是stgId维度的风控,不同策略层面的各种风控可以在这里并发执行。每个模组需要启用什么样的风控插件只需要将插件拷贝到该风控模组配置中的riskCtrlpluginPath目录即可,每个风控模组的配置tdSrvTaskDispatcherParam中的taskSpecificThreadPoolSize=4用于指定并行风控的线程池的大小。

 riskCtrlModuleComb:
   -   
     step: "global"
     fieldGroupUsedToGenHash: ""
     tdSrvTaskDispatcherParam: moduleName=TDSrvTaskDispatcherParam;taskRandAssignedThreadPoolSize=0;taskSpecificThreadPoolSize=4;preCreateTaskSpecificThreadPool=1
     riskCtrlpluginPath: ./plugin/global
     tdSrvRiskSegmentSize: 10485760 # 10mb
   -   
     step: "acctId"
     fieldGroupUsedToGenHash: "acctId"
     tdSrvTaskDispatcherParam: moduleName=TDSrvTaskDispatcherParam;taskRandAssignedThreadPoolSize=0;taskSpecificThreadPoolSize=4;preCreateTaskSpecificThreadPool=1
     riskCtrlpluginPath: ./plugin/acctId
     tdSrvRiskSegmentSize: 10485760 # 10mb
   -   
     step: "acctId-trdAcctId"
     fieldGroupUsedToGenHash: "acctId&trdAcctId"
     tdSrvTaskDispatcherParam: moduleName=TDSrvTaskDispatcherParam;taskRandAssignedThreadPoolSize=0;taskSpecificThreadPoolSize=4;preCreateTaskSpecificThreadPool=1
     riskCtrlpluginPath: ./plugin/acctId-trdAcctId
     tdSrvRiskSegmentSize: 10485760 # 10mb
   -   
     step: "stgId"
     fieldGroupUsedToGenHash: "stgId"
     tdSrvTaskDispatcherParam: moduleName=TDSrvTaskDispatcherParam;taskRandAssignedThreadPoolSize=0;taskSpecificThreadPoolSize=4;preCreateTaskSpecificThreadPool=1
     riskCtrlpluginPath: ./plugin/stgId
     tdSrvRiskSegmentSize: 10485760 # 10mb

 

  • 🔥🔥 强大的事前事中风控模块,你可以根据表达式自定义风控指标,比如通过acctId=10000&marketCode=SZSE&symbolCode=00002&side=Bid限制每秒SZSE市场00002买入数量、特定时间间隔内的买入数量、买入金额、买入笔数,单笔买入数量买入金额等等各种风控指标。表达式acctId=&marketCode=SZSE&symbolCode=可控制每个账号在SZSE市场每个品种的下单数量、下单金额、下单笔数等风控指标。
     
  • 🔥🔥 强大的pnl实时监控功能‼️,你可以在任何子系统(比如策略端)实时订阅并监控产品、账户、策略组合、策略、策略实例、用户、市场、标的、多头头寸、空头头寸等每个维度的已实现盈亏、未实现盈亏(浮动盈亏)、手续费使用情况,或者说任意维度组合的已实现盈亏、未实现盈亏(浮动盈亏)、手续费使用情况‼️
     
  • 🔥 配置好费率表之后,系统就可以实时精准的帮你计算成交过程中产生的手续费,这些体现在每一笔订单的回报中。系统兼容各种按笔或者按成交金额计算手续费的情况,同时也能够准确处理平今仓产生的手续费情况。
     
  • 🔥 系统外状态码动态维护功能,由于交易系统可能会接入多个交易所/交易柜台,每个外部交易服务都有自己特定的状态码,策略执行过程中也会收到未知的外部状态,系统在收到这些外部状态之后会自动收录,你可以在运行期间将其映射到指定的内部状态码,由此策略端就能够正确的处理新的状态码的业务逻辑。整个过程无需重启任何子系统❕。
     
  • 🔥 每一个策略包含一个策略实例集合,每个策略实例有自己的运行参数,策略实例集合由一个线程池管理,参数可以在运行期间修改,策略实例的回调函数会响应这个修改,你可以在回调函数里实现相应的逻辑。另外也可以在运行中增加或者禁用策略实例❕。这一点对于一些7*24小时交易的市场尤为重要。
     
  • 🔥 小于10微秒的 tick to order 报单性能。
     
  • 🔥 历史行请的保存和回放,可以按照设定从时序数据库里提取历史行情按照一定的倍速回放,比如100倍或者0.01倍的速度回放保存在时序数据库里的历史行情。
     
  • 🔥 模拟成交,可以设定一个模拟单最终状态为挂单、全成、部成或者废单等,部成的情况你可以指定成交的笔数以及每一笔的成交比例,结合上面的历史行情回放可以实现简单的回测功能。