撮合引擎开发:解密黑箱流程

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 笔记

业务流程


前面的几篇文章已经陆续讲到了黑箱内部的一些设计,包括核心的软件结构、数据结构、目录结构等。而从本小节开始,我们将会更加深入,来解密黑箱内部的更多设计和实现细节。

解密黑箱的第一步就是要清楚其内部对数据的处理流程是怎样的。当我们要设计一个新系统的时候,也是一样的,第一步要梳理清楚业务流程和数据流向。对撮合引擎来说,就是要了解:从输入到输出,中间都经过了哪些处理流程

前面的文章已经讲过,本撮合引擎定义了三种输入:开启撮合、处理订单、关闭撮合。后面就分别来看看这三种输入背后的流程。


开启撮合


开启撮合即是开启某个交易标的(交易对)的撮合引擎,未开启撮合的交易标的是无法处理订单的,而已经开启了撮合的交易标的也无法再次开启,不然就会出现同时有两个引擎处理同个交易标的的订单,这是不合理的,同个交易标的的订单只能由一个引擎串行来处理。

为什么不能并行呢?如果同一交易标的的订单可以用多个引擎并行处理的话,那至少会产生几个问题:

  1. **成交价以哪个为准?**理论上,每一时刻只能有一个成交价,那并行之后,就会产生多个成交价,那成交价就难以确定了。
  2. **如何维护统一的委托账本?**理论上,每个交易标的有一本保存了所有委托单的委托账本,那并行之后,如何在多个引擎之间维护这个统一的账本呢?如果用数据库统一维护,那无疑会减低撮合性能;如果分为多个子账本,那就很难保证价格优先、时间优先的原则。

以上这两个问题都不好解决,因此,只能先对所有订单进行定序,然后丢入引擎进行串行处理。

说到定序,自然就需要一个定序队列,因此开启撮合时需要初始化对应交易标的的订单定序队列。初始化好定序队列后,就可以真正启动对应交易标的的引擎了。在 Go 程序中,每个交易标的的引擎是以独立 goroutine 运行的;而在其他语言,比如 Java,则是以独立线程来运行。

引擎启动之后,需要先初始化交易委托账本,用来保存委托单。之后就等待定序队列有订单的时候逐个取出来处理了。

另外,再考虑一个场景,撮合程序重启时会发生什么?对于开启了撮合的交易标的,重启后是否需要恢复呢?需要的话,那如何恢复呢?最简单的方案当然是使用缓存,用 Redis 将开启了撮合的交易标的缓存起来,重启时从 Redis 加载并重新开启这些交易标的即可。

因此,触发开启撮合的场景其实有两个,一是接口的主动调用触发的,二是程序重启后从 Redis 缓存自动加载启动的。

最后,开启撮合的结果是同步返回的,因此,它没有异步的输出。

总结下,开启撮合的内部流程大致如下:


处理订单


开启撮合之后,就可以接收处理订单的输入了。撮合程序接收到处理订单的请求时,第一步需要做一些检查,包括每个参数是否有效、订单是否重复或存在、对应交易标的的引擎是否已经开启等。通过了检查之后,就可以将整个订单缓存到 Redis,接着添加到对应交易标的的定序队列中去,等待对应交易标的的引擎消费它进行撮合处理。这个流程如下图:

当订单成功添加到定序队列中后,接口就可以同步返回成功的响应结果了。后续的处理结果则是通过异步的 MQ 进行输出了。交易标的的引擎接收到订单后,根据不同情况会产生不同的输出结果。

我们知道,处理订单有两种 action下单撤单。撤单的业务逻辑很简单,就是从交易委托账本中查询该订单是否存在,若存在则从委托账本中删除该订单,然后输出撤单成功的撤单结果;若不存在则输出撤单失败的撤单结果。下单的业务逻辑则比较复杂,还要根据不同的订单类型作不同处理。写作此文时的撮合程序版本支持 6 种不同的 type,包括两种限价类型和四种市价类型。下面就来分别讲解不同订单类型的下单在不同条件下会有怎样的结果。

  • limit:普通限价。当委托账本里存在能与该订单匹配成交的委托单时,则可能生成一条或多条成交记录,每条成交记录都将产生异步输出;当委托账本里没有可匹配的委托单时,则将该订单(全部数量或剩余数量)添加到委托账本中,这时不会产生任何输出。
  • limit-ioc:IOC限价-即时成交剩余撤销。当委托账本里存在能与该订单匹配成交的委托单时,则可能生成一条或多条成交记录,每条成交记录都将产生异步输出;当委托账本里没有可匹配的委托单时,则将该订单(全部或剩余数量)进行撤单处理,这时会产生一条撤单成功的输出。
  • market:默认市价-即时成交剩余撤销。和 IOC 限价一样,当委托账本里与该订单相反方向的订单队列里(也称对手方)存在委托单时,则可能生成一条或多条成交记录,每条成交记录都将产生异步输出;当委托账本里对手方没有委托单时,则将该订单(全部或剩余数量)进行撤单处理,这时会产生一条撤单成功的输出。与 IOC 限价不同的在于:IOC 限价订单是由用户指定了委托价格的,而市价则无需指定委托价格,会直接与对手方的头部委托单成交,直到该订单已全部成交或对手方再无委托单为止。
  • market-top5:市价-最优五档即时成交剩余撤销。market 可以与对手方所有价格档位的订单成交,但 market-top5 最多只会和对手方的五个价格档位内的订单成交,超出五档外的订单将不会成交。剩余未成交的都将做撤单处理并产生一条撤单成功的输出。
  • market-top10:市价-最优十档即时成交剩余撤销。最多只会和对手方的十个价格档位内的订单成交。
  • market-opponent:市价-对手方最优价。如果对手方没有订单,则直接对该订单进行撤单处理并产生一条撤单成功的输出;如果对手方有订单,那最多只会成交一档,如果还剩有未成交的量,那将以对手方一档的价格转为限价单并添加到委托账本中,此时不会产生输出。

用图可表示如下:

另外,每个处理订单的请求——不管是下单还是撤单,也都会缓存到 Redis 里,产生变更时还会更新缓存。这样,程序重启后就可以恢复订单了。


关闭撮合


当某个交易标的准备下架、或取消交易、或暂停交易时,都需要关闭引擎。关闭引擎之前,上游服务最好先停止调用处理订单的接口,不然可能会出现一些非预期的错误,虽然程序已经做了容错处理。

关闭引擎时,同样也有些简单的判断,比如判断该交易标的的引擎是否已经开启,未开启的引擎自然无法关闭。

关闭引擎时,如果定序队列中还存在未处理的订单,那应该等这些订单处理完才真正关闭引擎。

最后,也要清除缓存,将该交易标的的所有订单都从缓存中清除。

关闭引擎的结果也是同步返回的,所有也没有异步的输出。

流程图也比较简答:


小结


本小节讲解了撮合黑箱内部的核心业务流程,包括开启撮合、处理订单、关闭撮合三个输入各自的内部逻辑。理解了这些流程之后,下一篇我们开始来讲代码实现。

惯例留几个思考题:如果关闭撮合的同时还有下单的并发请求,是否容易产生问题?如果有,哪里会产生?什么问题?能如何解决?


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
新零售 人工智能 大数据
推三返一互助系统开发|成熟案例|模式分析
他们更重视购物过程体验,希望与品牌商及零售商建立交易关系之上的信任感和亲密感
|
区块链 存储 数据库
量化合约跟单系统开发源码部署|量化交易系统开发(成熟案例)
在去中心化架构下,没有中心化机构的垄断,每个节点都是独立的
|
6月前
|
数据采集 监控 安全
量化交易源码开发丨量化交易系统开发成熟技术/教程方案/策略指南
定你的量化交易系统的需求和目标,包括交易策略、数据来源、风险管理等。
|
机器人 TensorFlow 算法框架/工具
量化交易机器人(币安/OK交易所)系统开发方案策略及源码项目搭建分析
量化交易机器人(币安/OK交易所)系统开发方案策略及源码项目搭建分析
|
消息中间件 缓存 JSON
|
存储 NoSQL 区块链
量化现货合约跟单交易软件系统开发(成熟技术)源码部署
我们需要一个全新的概念来定义业已带来的区块链时代,我们需要一个全新的名词来诠释业已到来的区块链时代
|
数据采集 监控 算法
量化交易阿尔法策略系统开发方案设计
量化交易阿尔法策略系统开发方案设计
|
机器学习/深度学习 存储 人工智能
ChatGPT的各项超能力从哪儿来?万字拆解追溯技术路线图来了!(1)
ChatGPT的各项超能力从哪儿来?万字拆解追溯技术路线图来了!
183 0
|
机器学习/深度学习 存储 自然语言处理
ChatGPT的各项超能力从哪儿来?万字拆解追溯技术路线图来了!(2)
ChatGPT的各项超能力从哪儿来?万字拆解追溯技术路线图来了!
174 0
|
机器学习/深度学习 算法 机器人
分析量化交易机器人开发系统现货合约策略技术
  量化交易的核心是建立交易策略和模型。这些交易策略和模型通常是由金融学、统计学和计算机科学等领域的专家和团队共同开发的,包括基于技术指标的策略、基于基本面分析的策略、基于市场情绪的策略等。
下一篇
无影云桌面