专栏首页IT进修之路交易所撮合交易【一】

交易所撮合交易【一】

前言

        最近一直在研究股票(币币)交易所撮合引擎,从一个连撮合概念都不太清晰我逐步摸索渐渐的有了一些自己的理解和概念。所以打算写一个撮合引擎,希望集众人智慧做出一个不错的引擎。

撮合规则

        本次主要是实现,限价和市价交易;

        撮合规则:                 (一)买价大于等于卖价,可以成交,先挂单为价格定制者,即为成交价;                 (二)相同价格,以时间早的先成交。                 (三)市价最先成交,以对手价为成交价。

撮合架构与技术定性

架构与技术定性的因素:                 1、撮合的本质是一个单一线性过程,没有办法并发的。(如果有请大神指点...)                 2、以单一订单为撮合逻辑(吃完一个单,再从订单薄拿出下一个订单吃),评率太高,耗时长。                 3、数据库撮合,不考虑,只考虑内存撮合。                 4、撮合的时候:只需要拿出最优,不需要排序。                 5、撮合结果:不需要关心和谁交易。结合“第二点”让每一个price level是可以在逻辑上独立的。降低频率。

框架与技术选择:                 线程框架选择:“伦敦外汇交易所LMAX开源的Disruptor框架”,性能这些就在多做阐述了。                 内存框架选择:开始考虑的是redis,最终决定用Hazelcast主要原因是简单,快,集群方便。                 数据库的选择:因为项目基本上是数据流开发,根据业内对数据流支持毕竟友好的方面考虑选择mongodb                 吃单的时候,以并行流计算的方式获得最优匹配。                 撮合完成后用Flink或规则引擎完成k线数据盘口深度数据生成。(还在考虑中)

部分技术的实现

因为之前一些朋友是以订单薄为撮合薄的,我也实现了下,下面是一些重要细节的代码:

//获取匹配的订单薄数据
IMap<Long, Order> outMap = hzInstance.getMap(HzltUtil.getMatchKey(coinTeam, isBuy));
/**
 * -★
 * -使用Java 8 Stream API中的并行流来计算最优
 * -能快速的拿到撮合对象,不用排序取值,降低性能消耗
 */
Order outOrder = outMap.values().parallelStream().min(HzltUtil::compareOrder).get();

//这种方式最难的,就是整理盘口深度数据了

    /**
     * -★
	 * -获取行情深度
	 * 
	 * @param coinTeam 交易队
	 * @param isBuy    是否是买
	 * @return List<Depth>
	 */
	public List<Depth> getMarketDepth(String coinTeam, Boolean isBuy) {
		List<Depth> depths = new ArrayList<Depth>();
		IMap<Long, Order> map = hzInstance.getMap(HzltUtil.getMatchKey(coinTeam, isBuy));
		if (map.size() > 0) {
			/**
			 * -这个流:主要是安价格分组和统计,使用并行流快速归集。
			 */ 
			List<Depth> list = map.entrySet().parallelStream().map(mo -> mo.getValue())
					.collect(Collectors.groupingBy(Order::getPrice)).entrySet().parallelStream()
					.map(ml -> new Depth(ml.getKey().toString(),
							ml.getValue().stream().map(o -> o.getUnFinishNumber()).reduce(BigDecimal.ZERO, BigDecimal::add)
									.toString(),
							"0", 1, coinTeam, isBuy))
					.sorted((d1, d2) -> HzltUtil.compareTo(d1, d2)).collect(Collectors.toList());
			/**
			 * -这个流:主要是盘口的累计计算,因涉及排序选择串行流
			 */
			list.stream().reduce(new Depth("0", "0", "0", 1, coinTeam, isBuy), (one, two) -> {
				one.setTotal((new BigDecimal(one.getTotal()).add(new BigDecimal(two.getNumber()))).toString());
				depths.add(new Depth(two.getPrice(), two.getNumber(), one.getTotal(), two.getPlatform(),
						two.getCoinTeam(), two.getIsBuy()));
				return one;
			});
		} else {
			Depth depth = new Depth("0", "0", "0", 1, coinTeam, isBuy);
			depths.add(depth);
		}
		return depths;
	}

这种方式撮合记录非常多,对订单的修改也很频繁,对数据库的压力很大,而且计算的量级也会很庞大,所以抛弃...

未解决的问题

问题一: 当市价把对手盘吃空,是以最后成交价挂单,还是直接撤销?如果是挂单,是变成限价挂单吗? 问题二:市价买入后,撮合到最后,剩下的钱连最小单位都买不了,怎么处理呢?直接撤销么?有撤销记录吗?

问题三:我看过有的朋友把买卖盘分成2个撮合队列,那么同时来买卖市价,是两个以上次成交价对吃吗,还是各自吃对手盘呢?

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 敲了这么久的代码,@Transactional你真会用了吗

    首先请大家看一下下面的代码,大家觉得有问题吗?代码的期望是子事务遇到异常进行回滚,而父事务不受其影响,在外部调用addParent()后,大家觉这段代码能做到吗...

    IT大咖说
  • 微服务架构,如何做分布式,通用缓存机制?

    在分布式系统中,特别是最近很火的微服务架构下,有没有或者能不能总结出一个业务静态数据的通用缓存处理机制或方案,这篇文章将结合一些实际的研发经验,尝试理清其中存在...

    搜云库技术团队
  • MySQL 性能优化之骨灰级,高阶神技 !

    MySQL调优对于很多程序员而言,都是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰。

    掌上编程
  • 手把手使用SonarQube分析、改善项目代码质量

    SonarQube是一个开源的代码质量管理系统,可用来快速定位代码中的Bug、漏洞以及不优雅的代码。它支持几乎所有的常见编程语言,例如Java、JavaScri...

    用户4172423
  • 带你学习最简单的分页插件PageHelper

    PageHelper是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库, 例如mysql、 oracle、mariaDB、 DB2、...

    框架师
  • Python 数据库迁移工具 Alembic

    Alembic 是一款轻量型的数据库迁移工具,它与 SQLAlchemy 一起共同为 Python 提供数据库管理与迁移支持。

    keinYe
  • 美团Java研发三面(3年经验):MySQL+Spring源码+分布式+算法+线程

    虽然自己记性不太好,但还是记录了一下,热乎乎的面经啊,也有一些问题没能记住。三面技术面经如下:

    IT大咖说
  • MySQL 性能优化之骨灰级,高阶神技 !

    MySQL调优对于很多程序员而言,都是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰。

    用户4143945
  • 笔记 | 大型网站的特点与设计宗旨

    假设服务器宕机了,用户就无法访问 我们就必须保证网站稳定的向用户提供7*24小时不间断的服务 哪怕有服务器节点宕机了,依然用备用集确保服务正常访问

    阿凯
  • 基于RabbitMQ消息队列的分布式事务解决方案 - MQ分布式消息中间件实战

    一款分布式消息中间件,基于erlang语言开发, 具备语言级别的高并发处理能力。和Spring框架是同一家公司。 支持持久化、高可用

    JavaEdge

扫码关注云+社区

领取腾讯云代金券