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):各价位上的挂单数量总和,反映市场承接大额订单的能力。
2.2 限价订单与市价订单
高频交易中,订单类型决定了策略的执行逻辑与成本。两种核心订单类型对比如下:
| 特性 | 限价订单(Limit Order) | 市价订单(Market Order) |
|---|---|---|
| 执行价格 | 指定价格或更优 | 当前最优可用价格 |
| 成交确定性 | 低(可能不成交) | 高(立即成交) |
| 交易成本 | 提供流动性,通常获返佣 | 消耗流动性,支付价差成本 |
| 对订单簿影响 | 增加深度,缩小价差 | 减少深度,可能扩大价差 |
| 典型用途 | 做市、挂单等待 | 追单、止损、大额拆单 |
高频交易视角: 限价订单是“流动性提供者”,市价订单是“流动性消耗者”。在交易所的收费结构中,提供流动性通常享有费率折扣或返佣,而消耗流动性则需支付较高手续费。策略设计时需权衡成交概率与成本。
2.3 买卖价差与市场深度
买卖价差是衡量市场流动性的核心指标。价差越小,交易成本越低,市场越活跃。价差由以下因素决定:
- 波动性:波动越大,做市商风险越高,价差扩大。
- 成交量:成交活跃的股票价差通常较小。
- 信息不对称:知情交易风险高时,价差扩大以补偿做市商。
市场深度则反映订单簿的“厚度”。深度越大,大额订单对价格的冲击越小。深度通常用深度图(Depth Chart)可视化,横轴为价格,纵轴为累计挂单量。
2.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 订单簿动态变化可视化
下图展示了订单簿在收到一笔市价买单后的典型变化过程: