4、订单簿基础:限价单与市价单、订单簿结构、买卖盘口深度

做市的核心,说白了就是跟订单簿打交道。你每天盯着的那个买卖挂单列表,就是订单簿。我刚开始做量化的时候,觉得这东西不就是个价格列表嘛,有啥好研究的?后来在实盘中吃了不少亏,才明白——订单簿的每一层,都藏着市场参与者的真实意图。

今天咱们就把订单簿拆开揉碎了讲。限价单和市价单的区别、订单簿怎么组织、盘口深度怎么看。这些是基本功,但基本功往往最容易被忽视。

4.1 限价单与市价单:两种最基础的订单类型

先说说这两种订单。你想想看,你去菜市场买菜——

  • 市价单:就是「老板,给我来两斤土豆,多少钱都行,马上要!」。你不在乎价格,只在乎成交速度。
  • 限价单:就是「老板,土豆超过3块一斤我就不买了,你啥时候降到3块以下再卖给我」。你在乎价格,愿意等。

在交易系统里,这两种订单的行为完全不同。

市价单(Market Order)

市价单会立即以当前市场上可用的最优价格成交。如果你买,就吃掉卖一;如果卖盘不够,继续吃卖二、卖三……直到你的订单全部成交。

优点:成交速度快,几乎100%成交。
缺点:你无法控制成交价格。尤其在流动性差的时候,滑点可能大得吓人。

我记得有一次做回测,一个市价单在盘口深度只有几百张的合约上,直接打穿了三个价位,滑点损失比预期多了5倍。嗯,从那以后我再也不敢在低流动性品种上无脑用市价单了。

限价单(Limit Order)

限价单指定一个价格,只有市场价格达到或优于这个价格时才会成交。你挂一个买一价,等着别人来卖给你。

优点:你可以精确控制成交价格,甚至能赚到盘口差价。
缺点:可能永远无法成交,或者成交延迟很大。

做市商的核心工作之一,就是不断挂限价单、撤单、再挂。说白了,我们赚的就是限价单提供的流动性溢价。

核心区别一句话总结:市价单买速度,限价单买价格。做市商几乎只用限价单,偶尔用市价单来调整仓位。

4.2 订单簿结构:买卖双方的「战场地图」

订单簿,就是所有未成交限价单的集合。它按价格从高到低排列,分成买盘和卖盘两侧。

咱们来看一个典型的订单簿结构:

卖盘(Ask Side) 价格 数量 累计数量
卖五 100.50 200 1500
卖四 100.40 300 1300
卖三 100.30 400 1000
卖二 100.20 350 600
卖一 100.10 250 250
买一 100.00 300 300
买二 99.90 500 800
买三 99.80 400 1200
买四 99.70 200 1400
买五 99.60 100 1500

这里有几个关键概念:

  • 买一(Bid):当前最高的买入价格,100.00
  • 卖一(Ask):当前最低的卖出价格,100.10
  • 价差(Spread):卖一 - 买一 = 0.10。这是做市商能赚到的理论最大利润
  • 盘口深度:每个价格上的挂单数量

我个人习惯把订单簿看作一个「价格-数量」的二维地图。买盘像一座山,卖盘像另一座山,中间那个山谷就是当前成交价。做市商的工作,就是在山谷两边来回搭桥。

4.3 买卖盘口深度:读懂市场的「呼吸」

盘口深度,说白了就是每个价位上挂了多少钱。它告诉你:如果你想大额交易,市场能承受多大的冲击。

举个例子。假设你想用市价单买入1000股,当前订单簿如下:

  • 卖一:100.10,250股
  • 卖二:100.20,350股
  • 卖三:100.30,400股

你的1000股会这样成交:

  • 先吃掉卖一的250股,成交价100.10
  • 再吃掉卖二的350股,成交价100.20
  • 再吃掉卖三的400股,成交价100.30

总成交金额 = 250×100.10 + 350×100.20 + 400×100.30 = 100,285元
平均成交价 = 100.285元

如果你只看卖一价格100.10,以为只需要100,100元就能买到,那就大错特错了。实际多花了185元。这就是滑点。

避坑指南:我曾经在写策略时,直接用卖一价格乘以数量来计算买入成本。结果回测跑得漂亮,实盘一跑就亏。后来才发现,大单必须考虑盘口深度,用「价格-数量加权平均」来计算真实成交价。

4.4 订单簿的实时变化:做市商的「心跳」

订单簿不是静止的。每一秒都有新订单进来、撤单、成交。做市商需要实时跟踪这些变化。

常见的订单簿事件有:

  • 新增限价单:有人在某个价位挂单
  • 撤单:有人取消了挂单
  • 成交:限价单被市价单吃掉
  • 修改:有人改了价格或数量(有些交易所支持)

我个人习惯用一个「增量更新」的方式来维护订单簿。每次只处理变化的部分,而不是全量替换。这样效率高得多。

下面是一个简单的订单簿维护代码示例:

class OrderBook:
    def __init__(self):
        self.bids = {}  # 买盘,价格->数量
        self.asks = {}  # 卖盘,价格->数量
        
    def update(self, side, price, quantity):
        """增量更新订单簿"""
        if side == 'bid':
            if quantity == 0:
                # 数量为0表示撤单
                self.bids.pop(price, None)
            else:
                self.bids[price] = quantity
        elif side == 'ask':
            if quantity == 0:
                self.asks.pop(price, None)
            else:
                self.asks[price] = quantity
                
    def get_top_of_book(self):
        """获取最优买卖价"""
        if not self.bids or not self.asks:
            return None
        best_bid = max(self.bids.keys())
        best_ask = min(self.asks.keys())
        return best_bid, best_ask, best_ask - best_bid
    
    def get_depth(self, levels=5):
        """获取指定深度的盘口"""
        sorted_bids = sorted(self.bids.items(), reverse=True)[:levels]
        sorted_asks = sorted(self.asks.items())[:levels]
        return sorted_bids, sorted_asks

这段代码虽然简单,但已经能处理大部分场景了。实盘中,你还需要处理并发、延迟、数据对齐等问题。不过核心逻辑就是这个——维护一个价格到数量的映射。

4.5 盘口深度的可视化:一眼看懂市场结构

光看数字不够直观。我习惯把盘口深度画成图,一眼就能看出市场的「厚度」。

下面是我用SVG画的一个盘口深度示意图:

盘口深度示意图 买五 99.60 买四 99.70 买三 99.80 买二 99.90 买一 100.00 价差 = 0.10 卖一 100.10 卖二 100.20 ← 深度:100股 ← 深度:200股 ← 深度:400股 ← 深度:500股 ← 深度:300股 ← 深度:250股 ← 深度:350股 绿色为买盘,红色为卖盘,宽度代表深度

你看,买盘和卖盘像两座山。买盘越往下越厚(价格越低,愿意买的人越多),卖盘越往上越薄(价格越高,愿意卖的人越少)。这是正常的市场形态。

但有时候你会看到异常形态——比如某个价位突然出现巨量挂单,那可能是有人在「护盘」或者「砸盘」。做市商需要警惕这种异常信号。

注意:盘口深度是动态的。你看到的深度可能在下一秒就消失了(撤单)。做市策略不能完全依赖当前深度来决策,必须考虑「虚假深度」的风险。我曾经见过有人在关键价位挂大单,等价格靠近时瞬间撤单,诱骗其他交易者入场。

4.6 实战中的订单簿应用

说了这么多理论,咱们来点实际的。做市商怎么用订单簿?

  1. 定价:根据买一卖一价差,决定挂单价格。价差越大,挂单可以越宽
  2. 库存管理:通过盘口深度判断市场流动性,决定是否调整仓位
  3. 信号识别:大单吃单、撤单行为,可能预示价格即将变动
  4. 滑点控制:根据深度计算大单的预期滑点,决定是否拆单

我个人习惯在策略启动前,先跑一个「订单簿健康检查」:

  • 价差是否在合理范围内?
  • 买一卖一深度是否足够?
  • 是否有异常的大单?
  • 订单簿更新频率是否正常?

如果这些检查不过,我宁愿不交易,也不冒险进场。做市不是赌博,是概率游戏。订单簿就是你的概率计算器。

核心要点回顾

  • 限价单控制价格,市价单控制速度
  • 订单簿是价格-数量的二维映射
  • 盘口深度决定了大单的滑点成本
  • 实时维护订单簿是做市的基础能力

专注资料整理