一、核心概念与术语:订单薄、买卖盘口、Taker与Maker、限价单与市价单、交易对
各位同学,欢迎来到撮合引擎设计的第一章。
说实话,很多新手一上来就扎进代码里,结果连订单薄长什么样都没搞清楚。我当年刚入行时也犯过这个错——写了一个月撮合逻辑,最后发现连买卖盘口的方向都搞反了。嗯,今天咱们先把这些基础概念掰扯清楚。
1.1 交易对(Trading Pair)
交易对,说白了就是「用什么东西换什么东西」。比如 BTC/USDT,意思就是用 USDT 买 BTC,或者卖掉 BTC 换 USDT。
我个人习惯把交易对拆成三部分看:
- 基础货币(Base Currency):你要买或卖的那个资产,比如 BTC
- 计价货币(Quote Currency):用来标价的资产,比如 USDT
- 价格精度:最小价格变动单位,比如 0.01 USDT
我在项目中遇到过一个问题:某交易所上线了一个新交易对,结果价格精度设成了 0.00000001,导致订单薄里全是小数点后八位的挂单,撮合效率直接崩了。后来我们规定:价格精度不能超过计价货币的流通精度。这是个血的教训。
核心要点:交易对的设计直接影响撮合引擎的吞吐量。精度越高,订单薄越深,但性能开销也越大。
1.2 订单薄(Order Book)
订单薄就是所有未成交订单的集合。你可以把它想象成一个「排队本」——买家排一队,卖家排一队。
为什么叫「薄」?因为早期交易员真的拿个本子记订单,一页一页翻。现在当然都是内存里的数据结构了。
订单薄的核心结构其实很简单:
// 伪代码示意
struct OrderBook {
bids: Vec<Order>, // 买单,按价格从高到低排序
asks: Vec<Order>, // 卖单,按价格从低到高排序
}
你想想看,如果买单和卖单都按价格排好序,撮合就变成了「从队首取订单对比价格」——这效率能不高吗?
我的经验:订单薄在内存里通常用红黑树或跳表实现。别用数组,插入和删除太慢了。我曾经见过一个项目用 ArrayList 存订单薄,结果每秒只能处理 200 笔订单——嗯,后来全重写了。
1.3 买卖盘口(Bid/Ask Spread)
买卖盘口,就是订单薄里最前面的那几档价格。
- 买一(Bid1):当前最高的买入价格
- 卖一(Ask1):当前最低的卖出价格
- 盘口深度:每个价格档位上的挂单数量
盘口差价(Spread) = 卖一价 - 买一价。这个值越小,说明市场流动性越好。
我记得有一次做回测,发现某个交易对的盘口差价长期在 0.5% 以上。这意味着你一买一卖,光差价就亏掉 0.5%。这种交易对,散户根本没法做高频交易。
避坑指南:我曾经在撮合引擎里把盘口数据直接暴露给前端,结果前端每秒拉 10 次,把数据库打爆了。后来加了缓存和限流,才稳住。记住:盘口数据要按需推送,别让客户端轮询。
1.4 Taker 与 Maker
这两个词,我刚开始学的时候总觉得绕。其实一句话就能说清楚:
- Maker:挂单的人,给订单薄「制造」流动性
- Taker:吃单的人,从订单薄「拿走」流动性
举个例子:你在订单薄里挂了一个 100 元买 BTC 的限价单,没人卖,你就成了 Maker。突然有人以 100 元卖给你,那个人就是 Taker。
为什么区分这个?因为交易所通常对 Maker 收更低的手续费,甚至返佣。说白了,交易所需要 Maker 来「养」订单薄,没有 Maker,Taker 就没单可吃。
关键点:在撮合引擎里,Taker 的订单会立即尝试撮合,而 Maker 的订单会进入订单薄等待。这个逻辑决定了撮合流程的入口分支。
1.5 限价单与市价单
这是最基础的两种订单类型,但很多人搞混它们的执行逻辑。
| 订单类型 | 核心逻辑 | 成交价格 | 风险点 |
|---|---|---|---|
| 限价单(Limit Order) | 指定价格,只有达到或优于该价格才成交 | 固定或更好 | 可能无法成交(挂单太久) |
| 市价单(Market Order) | 不指定价格,按当前最优价立即成交 | 随行就市 | 滑点风险(盘口深度不足时) |
我个人习惯这样理解:限价单是「我要这个价,爱卖不卖」;市价单是「我要马上成交,多少钱都行」。
我在项目中遇到过最典型的场景:某个用户下了一笔大额市价买单,结果盘口深度不够,直接吃穿了 5 档价格,成交均价比预期高了 2%。用户投诉说「你们系统有问题」。其实不是系统问题,是市价单的滑点特性——但用户不懂啊。后来我们加了一个「最大滑点保护」参数,市价单可以设置最多接受多少比例的滑点,超过就撤销。
实现建议:在撮合引擎里,市价单的处理逻辑其实比限价单简单——它不需要检查价格,只需要按顺序吃单。但要注意:市价单必须设置数量上限,否则可能把整个订单薄吃光。
1.6 知识体系总览
说了这么多,咱们用一张图把核心概念串起来。下面这张 SVG 图展示了撮合引擎最基础的数据流动关系:
这张图把今天讲的所有概念串起来了。你仔细看:交易对是基础,订单薄是核心数据结构,买卖盘口是订单薄的「快照」,Maker 和 Taker 是两种角色,限价单和市价单是两种操作方式。它们之间是层层递进的关系。
1.7 本章小结
好了,第一章的内容就到这里。咱们今天讲了五个核心概念:
- 交易对:定义交易标的,注意精度设计
- 订单薄:内存中的排序数据结构,核心是快速插入和查询
- 买卖盘口:订单薄的「门面」,直接影响用户体验
- Maker 与 Taker:两种角色,决定了手续费策略和撮合流程
- 限价单与市价单:两种订单类型,执行逻辑完全不同
这些概念是撮合引擎的「砖瓦」。后面咱们讲撮合流程、内存管理、并发控制,全都建立在这些概念之上。所以,如果你现在还有点模糊,建议回头再看一遍——尤其是订单薄的数据结构和 Maker/Taker 的区别,这两个是高频考点。
一句话总结:撮合引擎的本质,就是管理好订单薄,让 Maker 和 Taker 高效地完成限价单和市价单的匹配。其他所有功能,都是围绕这个核心展开的。
公众号:蓝海资料掘金营,微信deep3321