第二章:市场微观结构——订单簿与撮合机制、买卖价差与市场深度、交易成本分析
大家好,我是老李。在量化交易这行摸爬滚打了十来年,我越来越觉得,搞懂市场微观结构,就像厨师必须了解火候一样重要。你策略再牛,模型再炫,如果不懂订单是怎么成交的、成本是怎么产生的,那盈利很可能只是纸面富贵。
这一章,我们就来扒开K线图的外衣,看看市场最底层的运作逻辑。说白了,就是搞清楚你下的单子,到底是怎么变成成交记录的。
2.1 订单簿与撮合机制:市场的“心跳”
订单簿,你可以把它想象成一个实时更新的“买卖意愿清单”。买家和卖家都在上面挂单,等着对方来成交。
订单簿的核心要素:
- 买盘(Bid): 所有想买的人,出的最高价是多少,要买多少量。
- 卖盘(Ask): 所有想卖的人,要的最低价是多少,要卖多少量。
- 最优报价: 买一(最高买价)和卖一(最低卖价)。这两者之间的差距,就是后面要讲的买卖价差。
撮合机制:价格优先、时间优先
交易所的撮合引擎,就像一个铁面无私的裁判。规则很简单:
- 价格优先: 买单出价高的优先成交,卖单出价低的优先成交。
- 时间优先: 价格相同的情况下,先挂单的先成交。
举个例子。假设当前订单簿是这样的:
| 方向 | 价格 | 数量 |
|---|---|---|
| 卖一 | 10.02 | 100 |
| 卖二 | 10.01 | 200 |
| —— | —— | —— |
| 买一 | 10.00 | 150 |
| 买二 | 9.99 | 300 |
这时候,如果你下了一个市价买单(买入200股),会发生什么?
嗯,这里要注意。你的买单会直接跟卖一成交。但卖一只有100股,不够。剩下的100股,就会继续跟卖二(10.01元)成交。最终,你以10.00元成交了100股,以10.01元成交了100股。这就是市价单的“吃单”过程。
关键点: 市价单追求的是“立即成交”,但成交价格不确定。限价单追求的是“指定价格”,但可能无法成交。
我个人习惯,在做高频策略时,会尽量使用限价单,避免被“滑点”吃掉利润。但在做趋势跟踪时,市价单的确定性更重要。
2.2 买卖价差与市场深度:流动性的“温度计”
买卖价差(Bid-Ask Spread): 就是卖一价减去买一价。它直接反映了市场的交易成本。
- 价差小: 说明市场流动性好,买卖双方都活跃,交易成本低。比如大盘蓝筹股。
- 价差大: 说明市场流动性差,交易冷清,你进去交易容易被“宰”。比如一些小盘股或流动性差的期货合约。
市场深度(Market Depth): 指的是在某个价格附近,有多少挂单量。深度越厚,说明市场越能“扛住”大单的冲击。
举个例子,同样是买卖价差都是0.01元,但一个市场在买一和卖一后面各有10万手的挂单,另一个市场只有100手。你觉得哪个市场更健康?显然是前者。因为即使你下个几万手的单子,价格也不会剧烈波动。
避坑指南: 我曾经在交易一个流动性很差的品种时,看到价差很小,以为成本很低。结果一进去,发现深度极差,我的单子直接把价格打穿了,成交均价远高于预期。所以,价差和深度要结合起来看,缺一不可。
2.3 交易成本分析:滑点、佣金、冲击成本
很多新手只看佣金,觉得万分之一很低。其实,真正的成本大头,往往是滑点和冲击成本。
1. 佣金(Commission): 这是交易所和券商收的固定费用。现在竞争激烈,佣金已经很低了,通常不是主要矛盾。
2. 滑点(Slippage): 你下单时的预期价格,和实际成交价格之间的差异。
- 原因: 网络延迟、市场波动、订单簿深度不足。
- 例子: 你看到买一价是10.00元,下了市价买单。但就在你下单的瞬间,价格跳到了10.01元,你最终以10.01元成交。这0.01元就是滑点。
3. 冲击成本(Market Impact Cost): 你的大单子进场,对市场价格造成的“冲击”。
- 原因: 你的买单吃掉了卖一、卖二、卖三...导致价格不断上涨。你的卖单则相反。
- 例子: 你想买入100万股。订单簿上卖一到卖五总共只有50万股。你的单子会吃掉所有卖单,并推动价格不断上涨。最终,你的平均成交价远高于最初的卖一价。这部分额外的成本,就是冲击成本。
你想想看,对于大资金来说,冲击成本才是真正的“隐形杀手”。
重要提醒: 在回测中,如果不考虑滑点和冲击成本,你的策略夏普比率可能看起来很漂亮。但实盘一跑,你会发现收益大打折扣,甚至亏损。我建议,回测时至少加上一个最小变动价位的滑点,比如0.01元。对于大单,还需要根据订单簿深度模型,动态估算冲击成本。
下面我用一个简单的Python代码,演示如何估算市价单的冲击成本。这只是一个基础模型,实际生产中要复杂得多。
def estimate_market_impact(order_book, order_quantity):
"""
估算市价买单的冲击成本
order_book: 订单簿,格式为 [(price, volume), ...] 按价格升序排列
order_quantity: 买入数量
"""
total_cost = 0
remaining = order_quantity
for price, volume in order_book:
if remaining <= 0:
break
trade_volume = min(volume, remaining)
total_cost += trade_volume * price
remaining -= trade_volume
if remaining > 0:
print("警告:订单簿深度不足,无法完全成交!")
return None
avg_price = total_cost / order_quantity
# 假设初始最优卖价是 order_book[0][0]
initial_ask = order_book[0][0]
impact_cost = (avg_price - initial_ask) / initial_ask * 10000 # 以基点表示
return impact_cost
# 示例用法
book = [(10.00, 100), (10.01, 200), (10.02, 300)]
quantity = 250
impact = estimate_market_impact(book, quantity)
print(f"冲击成本: {impact:.2f} 基点")
这段代码的逻辑很简单:模拟市价单逐层吃掉卖单,计算平均成交价,再与初始卖价比较。你会发现,买的量越大,冲击成本越高。
好了,这一章的内容就到这里。市场微观结构是量化交易的基石,理解它,你才能更好地设计交易算法、控制风险。下一章,我们会深入探讨如何利用这些微观结构数据,构建更聪明的交易策略。