3. 订单簿微观结构:限价单与市价单、订单簿的构建与更新、盘口深度分析
做市的核心,说白了就是跟订单簿打交道。你每天盯着的那个买卖盘口,背后是一套精密的微观结构在运转。我刚开始做量化的时候,觉得订单簿不就是一堆价格和数量嘛,有什么好研究的?直到有一次,我在一个流动性极差的币对上做市,盘口薄得像纸一样,一个市价单过来直接把我打穿——嗯,从那以后我再也不敢小看订单簿的微观结构了。
3.1 限价单与市价单:两种订单的灵魂差异
先聊聊最基础的两种订单类型。你想想看,交易所里所有的交易行为,归根结底就两种:限价单和市价单。
- 限价单(Limit Order):你指定一个价格,挂在那里等别人来吃。比如我挂一个买价100.5,那只有卖价≤100.5的时候才会成交。限价单提供流动性,但存在未成交风险。
- 市价单(Market Order):你不指定价格,直接按当前最优价成交。比如我下个市价买单,系统会立刻吃掉卖一、卖二、卖三……直到买够数量。市价单消耗流动性,但成交速度快,代价是滑点。
我个人习惯把限价单比作「钓鱼」——你放好饵,等鱼上钩。市价单则是「撒网」——不管价格,先把货捞上来再说。做市商的核心工作,就是不断挂限价单提供流动性,同时用市价单来对冲风险。
关键认知:限价单是「被动单」,市价单是「主动单」。做市商赚的就是限价单的买卖价差,但必须时刻提防被市价单「吃掉」。
3.2 订单簿的构建与更新:从零开始搭一个盘口
订单簿长什么样?说白了就是一个价格-数量的映射表。买单从高到低排列,卖单从低到高排列。中间那个空隙,就是价差。
我当年在搭建自己的做市系统时,第一步就是写一个订单簿的数据结构。这里给你看一个简化版的Python实现:
class OrderBook:
def __init__(self):
self.bids = {} # 买单:价格 -> 数量
self.asks = {} # 卖单:价格 -> 数量
self.bid_sorted = [] # 按价格降序排列
self.ask_sorted = [] # 按价格升序排列
def update(self, side, price, quantity):
"""更新订单簿,side: 'buy' 或 'sell'"""
if side == 'buy':
if quantity == 0:
self.bids.pop(price, None)
else:
self.bids[price] = quantity
self.bid_sorted = sorted(self.bids.items(), reverse=True)
else:
if quantity == 0:
self.asks.pop(price, None)
else:
self.asks[price] = quantity
self.ask_sorted = sorted(self.asks.items())
def get_top_of_book(self):
"""获取最优买卖价"""
best_bid = self.bid_sorted[0][0] if self.bid_sorted else None
best_ask = self.ask_sorted[0][0] if self.ask_sorted else None
return best_bid, best_ask
def get_spread(self):
"""计算当前价差"""
bid, ask = self.get_top_of_book()
if bid and ask:
return ask - bid
return None
这个代码虽然简单,但已经能跑通核心逻辑了。实际生产中,订单簿的更新频率极高——每秒几百次甚至上千次。我建议你用红黑树或者跳表来维护排序,而不是像我上面那样每次重新排序,否则性能会崩。
避坑指南:我曾经在实盘中使用Python的dict+排序来处理订单簿,结果在高频场景下延迟飙到几十毫秒。后来改用sortedcontainers库的SortedDict,延迟降到了微秒级。记住:订单簿更新是IO密集型+计算密集型的混合体,优化要双管齐下。
3.3 盘口深度分析:看透买卖力量的博弈
盘口深度,就是订单簿上各个价位的挂单量分布。它能告诉你:市场在哪个价位有支撑,哪个价位有阻力。
我常用的几个深度指标:
| 指标 | 计算公式 | 含义 |
|---|---|---|
| 买盘总量 | ∑(买单量 × 价格) | 当前买方总资金量 |
| 卖盘总量 | ∑(卖单量 × 价格) | 当前卖方总筹码量 |
| 深度比 | 买盘总量 / 卖盘总量 | >1 表示买方强势,<1 表示卖方强势 |
| 价差宽度 | 卖一价 - 买一价 | 流动性越好,价差越小 |
| 深度斜率 | 相邻价位挂单量的变化率 | 斜率陡峭说明该价位有强支撑/阻力 |
举个例子。假设当前盘口是这样的:
卖五: 101.0 200股
卖四: 100.8 150股
卖三: 100.6 100股
卖二: 100.4 80股
卖一: 100.2 50股
-------------------
买一: 100.0 60股
买二: 99.8 90股
买三: 99.6 120股
买四: 99.4 180股
买五: 99.2 250股
你看,买盘在99.2到99.6这个区间挂单量明显增加,说明这里有较强的支撑。卖盘在100.6到101.0区间挂单量也在增加,说明上方有阻力。我个人习惯用深度斜率来量化这个现象——斜率绝对值越大,该价位的「墙」越厚。
注意:盘口深度是动态变化的。大资金经常会挂「幽灵单」——挂上去又撤掉,制造虚假深度。我曾经在ETH上吃过这个亏,看到买一挂了500个ETH以为支撑很强,结果市价单打过去瞬间撤单,直接滑了0.3%。所以,做深度分析时一定要结合挂单存活时间和撤单率来过滤虚假信号。
3.4 知识体系总览
下面这张图是我自己梳理的订单簿微观结构知识框架,帮你把零散的点串起来:
从这张图你能看到,订单类型、订单簿构建、深度分析这三块是互相支撑的。你只有理解了限价单和市价单的博弈逻辑,才能设计出合理的订单簿数据结构;只有把订单簿更新得又快又准,深度分析才有意义;而深度分析的结果,最终会反馈到你的报价价差优化上。
嗯,这一章的内容就到这里。记住:订单簿是你的战场,每一笔挂单都是你的士兵。读懂它,你才能打好做市这场仗。