2. 市场微观结构:订单簿与价格形成

高频交易的核心战场是订单簿(Order Book)——一个记录所有未成交买卖指令的实时电子列表。理解订单簿的结构与动态变化,是量化策略设计的基础。本章将拆解订单簿的组成要素、订单类型、价差与深度,并展示其动态演化过程。

2.1 订单簿基本结构

订单簿由买盘(Bid Side)和卖盘(Ask Side)两部分组成。每一侧按价格优先、时间优先原则排序。下表展示了典型订单簿的快照结构:

方向 价格(元) 数量(手) 累计数量 订单编号
卖盘 10.05 200 800 #A005
卖盘 10.04 300 600 #A003
卖盘 10.03 100 300 #A001
买盘 10.02 150 500 #B002
买盘 10.01 200 350 #B004
买盘 10.00 150 150 #B001

关键概念:

  • 最优买价(Best Bid):当前最高买入价格,本例为 10.02 元。
  • 最优卖价(Best Ask):当前最低卖出价格,本例为 10.03 元。
  • 买卖价差(Bid-Ask Spread):最优卖价与最优买价之差,即 10.03 - 10.02 = 0.01 元。
  • 市场深度(Market Depth):各价位上的挂单数量总和,反映市场承接大额订单的能力。
订单簿结构示意图 卖盘(Ask Side) 价格 10.05 数量 200 价格 10.04 数量 300 价格 10.03 数量 100 ← 最优卖价 买盘(Bid Side) 价格 10.02 数量 150 ← 最优买价 价格 10.01 数量 200 价格 10.00 数量 150 价差 = 0.01 市场深度 买盘深度 = 150+200+150 = 500手 | 卖盘深度 = 100+300+200 = 600手 新卖单进入 新买单进入

2.2 限价订单与市价订单

高频交易中,订单类型决定了策略的执行逻辑与成本。两种核心订单类型对比如下:

特性 限价订单(Limit Order) 市价订单(Market Order)
执行价格 指定价格或更优 当前最优可用价格
成交确定性 低(可能不成交) 高(立即成交)
交易成本 提供流动性,通常获返佣 消耗流动性,支付价差成本
对订单簿影响 增加深度,缩小价差 减少深度,可能扩大价差
典型用途 做市、挂单等待 追单、止损、大额拆单
高频交易视角: 限价订单是“流动性提供者”,市价订单是“流动性消耗者”。在交易所的收费结构中,提供流动性通常享有费率折扣或返佣,而消耗流动性则需支付较高手续费。策略设计时需权衡成交概率与成本。

2.3 买卖价差与市场深度

买卖价差是衡量市场流动性的核心指标。价差越小,交易成本越低,市场越活跃。价差由以下因素决定:

  • 波动性:波动越大,做市商风险越高,价差扩大。
  • 成交量:成交活跃的股票价差通常较小。
  • 信息不对称:知情交易风险高时,价差扩大以补偿做市商。

市场深度则反映订单簿的“厚度”。深度越大,大额订单对价格的冲击越小。深度通常用深度图(Depth Chart)可视化,横轴为价格,纵轴为累计挂单量。

市场深度曲线示意图 价格 累计数量 买盘深度 卖盘深度 最优买价 最优卖价 价差

2.4 订单簿动态变化

订单簿并非静态快照,而是随事件驱动持续更新。高频策略需要实时处理以下四类事件:

  1. 新订单进入:限价单加入队列,市价单立即撮合。
  2. 订单撤销:未成交的限价单被取消,深度减少。
  3. 订单成交:买卖双方匹配,订单从簿中移除。
  4. 订单修改:修改价格或数量,相当于先撤单再下新单。
实战案例: 假设当前最优买价为 10.02,最优卖价为 10.03。一笔市价买入 200 手的订单进入后,会立即吃掉 10.03 价位的 100 手,然后继续吃掉 10.04 价位的 100 手。订单簿更新后,最优卖价变为 10.04,价差从 0.01 扩大至 0.02。高频策略需在毫秒级感知这种变化并调整后续报价。

2.5 订单簿数据在 Python 中的表示

在实际高频系统中,订单簿通常以字典嵌套列表或Pandas DataFrame的形式存储。以下是一个简化的 Python 实现示例:

# 订单簿数据结构示例
order_book = {
    'bids': [  # 买盘,按价格降序排列
        {'price': 10.02, 'size': 150, 'order_id': 'B002'},
        {'price': 10.01, 'size': 200, 'order_id': 'B004'},
        {'price': 10.00, 'size': 150, 'order_id': 'B001'}
    ],
    'asks': [  # 卖盘,按价格升序排列
        {'price': 10.03, 'size': 100, 'order_id': 'A001'},
        {'price': 10.04, 'size': 300, 'order_id': 'A003'},
        {'price': 10.05, 'size': 200, 'order_id': 'A005'}
    ]
}

# 计算买卖价差
best_bid = order_book['bids'][0]['price']
best_ask = order_book['asks'][0]['price']
spread = best_ask - best_bid
print(f"最优买价: {best_bid}, 最优卖价: {best_ask}, 价差: {spread}")

# 计算市场深度(前3档)
bid_depth = sum(item['size'] for item in order_book['bids'][:3])
ask_depth = sum(item['size'] for item in order_book['asks'][:3])
print(f"买盘深度: {bid_depth}, 卖盘深度: {ask_depth}")
性能注意: 高频场景下,订单簿更新频率可达每秒数千次。使用纯 Python 列表进行插入/删除操作会带来较大延迟。生产环境中通常使用 collections.deque、sortedcontainers 库或 C++ 扩展来优化订单簿的维护效率。

2.6 订单簿动态变化可视化

下图展示了订单簿在收到一笔市价买单后的典型变化过程:

订单簿动态变化:市价买单冲击 变化前 卖盘 10.05 200手 10.04 300手 10.03 100手 ← 最优卖价 买盘 10.02 150手 ← 最优买价 10.01 200手 → 市价买入200手 变化后 卖盘 10.05 200手 10.04 200手 ← 新最优卖价 10.03 0手(已成交) 买盘 10.02 150手 ← 最优买价不变 10.01 200手 价差从 0.01 扩大至 0.02,最优卖价上移一档