3. 流动性深度度量指标:订单簿斜率、市场深度、成交额冲击成本

聊流动性深度,说白了就是看市场到底能「扛」多大的单子。我刚开始做固收量化那会儿,总觉得流动性就是成交量,后来被市场狠狠教育了一次——有一次我盯着一只活跃券,成交量看着不小,结果一笔5000万的卖单直接把收益率砸穿了5个bp。嗯,从那以后我就明白了,成交量只是表象,深度才是硬道理。

今天咱们把三个核心指标掰开揉碎讲清楚:订单簿斜率市场深度成交额冲击成本。这三个东西,你想想看,其实是从不同角度回答同一个问题:我扔一笔大单进去,市场会怎么反应?

3.1 订单簿斜率:价格对量的敏感度

订单簿斜率,我个人习惯叫它「价格弹性系数」。它衡量的是:在订单簿的某个价位附近,每增加一单位成交量,价格会变动多少。

数学上很简单,就是做线性回归:

# 计算订单簿斜率
def order_book_slope(price_levels, volume_levels):
    """
    price_levels: 价格序列(比如从最优买价到第N档)
    volume_levels: 对应档位的累计成交量
    返回:斜率(正值表示买盘,负值表示卖盘)
    """
    import numpy as np
    # 用最小二乘法拟合
    slope, intercept = np.polyfit(volume_levels, price_levels, 1)
    return slope

斜率绝对值越大,说明价格对量越敏感——说白了就是市场「薄」,一碰就动。我在项目中遇到过一只城投债,它的订单簿斜率是国债期货的10倍以上,那感觉就像在薄冰上走路,稍微大点的单子就能把价格推飞。

实战经验: 斜率在-0.5到0.5之间算正常,超过1就要警惕了。我曾经用这个指标筛掉过一只看似活跃的券——斜率高达2.3,结果第二天做市商直接撤单,流动性瞬间枯竭。

3.2 市场深度:能扛多少量

市场深度更直观——就是订单簿上各档位的累计挂单量。但这里有个坑:只看最优买卖价上的量是不够的。

我一般会看三个深度指标:

  • 最优深度(Depth@1):最优买卖价上的挂单量。这个最常用,但也最容易被操纵。
  • 五档深度(Depth@5):前五档的累计量。能反映更真实的承接能力。
  • 加权深度(WDepth):按价格距离加权,越远的档位权重越低。
def weighted_depth(bids, asks, decay=0.9):
    """
    bids: [(price, volume), ...] 买盘列表,从最优到次优
    asks: [(price, volume), ...] 卖盘列表
    decay: 衰减因子,默认0.9
    返回:加权买盘深度,加权卖盘深度
    """
    w_bid = sum(v * (decay ** i) for i, (p, v) in enumerate(bids))
    w_ask = sum(v * (decay ** i) for i, (p, v) in enumerate(asks))
    return w_bid, w_ask
避坑指南: 我曾经只看最优深度做策略,结果被一个做市商在最优价位挂了1个亿的假单骗了——等我的单子进去,他瞬间撤单,价格直接滑了3个bp。所以现在我都用加权深度,至少能过滤掉一些「钓鱼单」。

3.3 成交额冲击成本:真金白银的代价

这个指标最实在。它回答的是:我要买/卖一定金额,实际成交价格会比当前市价差多少?

计算公式:

冲击成本 = (实际成交均价 - 当前市价) / 当前市价 * 10000  # 单位:bp

但实际计算时,要考虑订单簿的消耗过程。我写过一个模拟函数:

def impact_cost(order_book, target_amount, side='buy'):
    """
    order_book: 订单簿数据,包含价格和量
    target_amount: 目标成交金额(万元)
    side: 'buy' 或 'sell'
    返回:冲击成本(bp),实际成交均价
    """
    remaining = target_amount
    total_cost = 0
    total_volume = 0
    
    levels = order_book['asks'] if side == 'buy' else order_book['bids']
    
    for price, volume in levels:
        trade_volume = min(remaining, volume)
        total_cost += trade_volume * price
        total_volume += trade_volume
        remaining -= trade_volume
        if remaining <= 0:
            break
    
    avg_price = total_cost / total_volume
    mid_price = (order_book['best_ask'] + order_book['best_bid']) / 2
    cost_bp = (avg_price - mid_price) / mid_price * 10000
    
    return abs(cost_bp), avg_price
注意: 这个模型假设订单簿是静态的。实际交易中,你的单子本身会影响后续挂单——这叫「市场反馈效应」。我见过最极端的案例:一笔2亿的买入,冲击成本模型算出来是2bp,实际成交却花了8bp,因为其他交易者看到大单进来,纷纷撤单提价。

3.4 三个指标的关系与综合应用

这三个指标不是孤立的。我习惯把它们放在一起看:

指标 反映什么 典型阈值 我的用法
订单簿斜率 价格对量的敏感度 |斜率| < 0.5 正常 快速筛选「薄券」
市场深度 绝对承接能力 Depth@5 > 5000万 判断能否大额交易
冲击成本 实际交易损耗 < 1bp 优秀 交易成本预算

举个例子:如果一只券的斜率很大(比如1.5),但深度也很大(比如5档有2亿),那冲击成本可能反而可控。反过来,斜率小但深度浅的券,反而更危险——因为一旦突破那层薄薄的挂单,价格会直接跳空。

流动性深度度量指标关系图 流动性深度 订单簿斜率 市场深度 冲击成本 三个指标从不同维度刻画流动性深度 斜率 → 价格敏感度 | 深度 → 绝对容量 | 冲击成本 → 实际交易损耗

最后说一句,这些指标在银行间市场有个特殊之处——因为大部分交易是场外询价,订单簿数据其实不完整。我一般会用「报价请求数据」来近似替代,虽然精度差一些,但趋势是靠谱的。嗯,做量化嘛,很多时候就是在不完美的数据里找相对靠谱的规律。

核心结论: 三个指标要组合使用。单看任何一个都容易踩坑。我个人习惯是:先用斜率筛出「问题券」,再用深度确认「能不能做」,最后用冲击成本算「划不划算」。

公众号:蓝海资料掘金营,微信deep3321