3、市场微观结构:订单簿与市场深度、买卖价差与流动性、交易成本分析、滑点与冲击成本
各位同学,今天我们来聊聊市场微观结构。这玩意儿,说白了就是市场的「毛细血管」。你策略再牛,算法再快,如果看不懂订单簿,不理解买卖价差,那你的盈利很可能就被这些「隐形杀手」吃掉了。我个人习惯,在搭建任何套利系统之前,第一件事就是先把市场的底裤扒干净——也就是把微观结构摸透。
3.1 订单簿与市场深度
订单簿是什么?就是交易所里所有挂单的集合。买一、买二、卖一、卖二……这些数据实时跳动,构成了市场的骨架。我见过不少新手,只看最新成交价,不看订单簿,结果一梭子进去,直接打穿了好几档价位。
市场深度,就是订单簿上各个价位的挂单量。深度越好,你吃单的冲击就越小。举个例子:
# 模拟一个简单的订单簿结构
order_book = {
'bids': [ # 买单,价格从高到低
(100.10, 500), # 买一:价格100.10,挂单500股
(100.05, 1200), # 买二
(100.00, 3000), # 买三
],
'asks': [ # 卖单,价格从低到高
(100.15, 400), # 卖一
(100.20, 1500), # 卖二
(100.25, 2500), # 卖三
]
}
def get_market_depth(order_book, side='bid', levels=3):
"""计算指定方向的市场深度"""
if side == 'bid':
return sum([qty for price, qty in order_book['bids'][:levels]])
else:
return sum([qty for price, qty in order_book['asks'][:levels]])
print(f"买三档深度: {get_market_depth(order_book, 'bid')} 股")
print(f"卖三档深度: {get_market_depth(order_book, 'ask')} 股")
你看,买一只有500股,卖一只有400股。如果你要买入1000股,直接吃卖一,只能吃到400股,剩下的600股就得吃卖二甚至卖三。价格自然就上去了。这就是深度不足带来的问题。
3.2 买卖价差与流动性
买卖价差,就是卖一价减去买一价。这个数字越小,说明流动性越好。为什么?因为买卖双方愿意挨得很近,市场撮合效率高。
我在项目中遇到过一种情况:某个小币种,买卖价差经常达到0.5%甚至1%。你想想看,套利空间本来就只有0.2%,结果一进场,光价差就吃掉你0.5%,这还玩个屁?
流动性,其实可以从几个维度看:
- 价差宽度: 越小越好,通常小于0.01%算极好
- 挂单量: 买卖一档的挂单量越大,流动性越好
- 订单簿斜率: 价格变动时,挂单量变化是否平滑
这里我给大家一个简单的流动性评分公式,我自己经常用:
def liquidity_score(order_book):
"""简单的流动性评分,越高越好"""
bid1_price, bid1_qty = order_book['bids'][0]
ask1_price, ask1_qty = order_book['asks'][0]
spread = (ask1_price - bid1_price) / bid1_price
depth = bid1_qty + ask1_qty
# 价差越小越好,深度越大越好
score = depth / (spread * 10000 + 1)
return round(score, 2)
print(f"流动性评分: {liquidity_score(order_book)}")
3.3 交易成本分析
交易成本不只是手续费。很多人只盯着交易所的万二、万一,其实隐性成本才是大头。我把它拆成三块:
| 成本类型 | 说明 | 典型范围 |
|---|---|---|
| 显性成本 | 手续费、印花税、过户费 | 0.01% - 0.1% |
| 隐性成本 | 买卖价差、滑点、冲击成本 | 0.02% - 0.5% |
| 机会成本 | 未成交导致的收益损失 | 难以量化 |
显性成本好算,交易所明码标价。隐性成本才是坑。我曾经做过一个回测,策略年化收益20%,结果加上隐性成本后,只剩8%。嗯,那感觉就像辛辛苦苦搬砖,结果发现老板扣了大部分工资。
计算总交易成本时,我建议这样:
def total_trade_cost(price, qty, fee_rate=0.0002, spread=0.0001):
"""计算一次交易的总成本"""
fee = price * qty * fee_rate # 手续费
spread_cost = price * qty * spread # 价差成本
total = fee + spread_cost
return {
'fee': round(fee, 2),
'spread_cost': round(spread_cost, 2),
'total': round(total, 2),
'cost_rate': round(total / (price * qty) * 100, 4)
}
cost = total_trade_cost(100.0, 1000)
print(f"总成本: {cost['total']} 元, 成本率: {cost['cost_rate']}%")
3.4 滑点与冲击成本
滑点,就是你下单时的预期成交价和实际成交价之间的差值。冲击成本,是你的订单对市场价格造成的影响。两者其实是一体两面。
为什么会滑点?说白了,就是你的订单太大,或者市场流动性不够。你下单的瞬间,价格已经变了。我记得有一次做跨期套利,我算好了价差,一键下单,结果滑点直接吃掉了整个套利空间。从那以后,我再也不敢不看订单簿就盲目下单了。
冲击成本的计算,我常用这个模型:
def impact_cost(order_book, trade_qty, side='buy'):
"""计算买入或卖出的冲击成本"""
if side == 'buy':
levels = order_book['asks']
else:
levels = order_book['bids']
remaining = trade_qty
total_cost = 0
weighted_price = 0
for price, qty in levels:
if remaining <= 0:
break
fill_qty = min(remaining, qty)
total_cost += fill_qty * price
weighted_price = total_cost / (trade_qty - remaining + fill_qty)
remaining -= fill_qty
if remaining > 0:
print("警告:订单簿深度不足,无法完全成交")
return None
# 冲击成本 = 加权成交价 - 最优价
if side == 'buy':
best_price = order_book['asks'][0][0]
else:
best_price = order_book['bids'][0][0]
impact = (weighted_price - best_price) / best_price * 100
return round(impact, 4)
impact = impact_cost(order_book, 1000, 'buy')
print(f"买入1000股的冲击成本: {impact}%")
你看,买入1000股,冲击成本可能只有0.05%。但如果买入10000股呢?冲击成本可能飙升到0.5%以上。这就是为什么大资金做套利,必须拆单、用算法交易。
好了,这一章的内容就到这里。市场微观结构,说白了就是让你看清市场的「底牌」。订单簿、价差、流动性、滑点——这些不是枯燥的理论,而是你每天交易时都要面对的「战场地形」。下一章,我们会聊聊如何把这些微观结构数据,真正用到套利策略的构建中去。