2. 买卖价差(Bid-Ask Spread):四个核心指标的计算与Python实现

买卖价差,说白了就是市场流动性的「体温计」。我做了这么多年量化,每次看一个品种能不能做,第一件事就是看它的价差结构。今天咱们就把绝对价差、相对价差、有效价差、实现价差这四个指标彻底讲透。

2.1 先搞懂买卖价差是什么

你想想看,你去菜市场买苹果,小贩喊价5块,你出价4块5。这中间的5毛钱,就是价差。金融市场里也一样——买方愿意出的最高价(Bid)和卖方愿意收的最低价(Ask),中间的差值就是买卖价差。

价差越小,说明市场越活跃,流动性越好。我见过一些垃圾币,价差能到5%以上,那基本就是有价无市的状态。

核心公式:
绝对价差 = Ask价格 - Bid价格

2.2 绝对价差(Absolute Spread)

这是最直观的指标。直接拿卖一价减买一价就行。

def absolute_spread(ask_price, bid_price):
    """
    计算绝对价差
    :param ask_price: 卖一价
    :param bid_price: 买一价
    :return: 绝对价差值
    """
    return ask_price - bid_price

# 举个栗子
ask = 100.50  # 卖方报价
bid = 100.30  # 买方报价
spread = absolute_spread(ask, bid)
print(f"绝对价差: {spread:.2f}")  # 输出: 0.20

嗯,这里要注意:绝对价差有个问题——它不比较价格水平。比如茅台500块一股,价差0.2元;某垃圾股5块一股,价差0.1元。你能说垃圾股流动性更好吗?显然不能。这就引出了相对价差。

2.3 相对价差(Relative Spread)

相对价差把价格水平考虑进去了。我习惯用中间价做分母,这样更稳定。

我的经验: 在跨品种比较流动性时,一定要用相对价差。绝对价差只适合同一个品种不同时间段的对比。
def relative_spread(ask_price, bid_price):
    """
    计算相对价差(百分比形式)
    """
    mid_price = (ask_price + bid_price) / 2
    spread = (ask_price - bid_price) / mid_price * 100
    return spread

# 对比两个品种
stock_a = relative_spread(100.50, 100.30)  # 约0.2%
stock_b = relative_spread(5.10, 5.00)      # 约1.98%
print(f"茅台相对价差: {stock_a:.2f}%")
print(f"垃圾股相对价差: {stock_b:.2f}%")

看到了吧?茅台虽然绝对价差大,但相对价差反而小。这才是真实流动性的体现。

2.4 有效价差(Effective Spread)

这个指标有意思了。它衡量的是「实际成交价格」和「中间价」的偏离程度。我当年做高频策略时,最关注的就是这个指标。

为什么会这样?因为很多时候你看到的报价和实际成交价不一样。比如你看到买一价100.30,但你的大单子可能把价格打到了100.35才成交完。

def effective_spread(trade_price, bid_price, ask_price):
    """
    计算有效价差
    :param trade_price: 实际成交价格
    :param bid_price: 买一价
    :param ask_price: 卖一价
    :return: 有效价差(以中间价的百分比表示)
    """
    mid_price = (ask_price + bid_price) / 2
    # 买方发起的交易用正号,卖方发起的用负号
    # 这里简化处理,假设是买方发起
    effective = 2 * (trade_price - mid_price) / mid_price * 100
    return effective

# 场景:你以100.40的价格买入
trade = 100.40
bid = 100.30
ask = 100.50
eff = effective_spread(trade, bid, ask)
print(f"有效价差: {eff:.2f}%")  # 输出正值,说明买方支付了溢价
避坑指南: 我曾经在回测时直接用绝对价差代替有效价差,结果策略表现虚高。实际交易中,大单的冲击成本会让有效价差远大于报价价差。千万别偷懒!

2.5 实现价差(Realized Spread)

实现价差是有效价差的「升级版」。它考虑了交易后的价格变化。说白了,就是看你这笔交易做完后,市场有没有「反噬」你。

我习惯用5秒后的价格来做计算。太短了噪声大,太长了又混入其他信息。

def realized_spread(trade_price, future_mid_price, bid_price, ask_price):
    """
    计算实现价差
    :param trade_price: 成交价
    :param future_mid_price: 交易后一段时间(如5秒)的中间价
    :param bid_price: 交易时的买一价
    :param ask_price: 交易时的卖一价
    :return: 实现价差
    """
    mid_price = (bid_price + ask_price) / 2
    # 买方发起:成交价 - 未来中间价
    realized = 2 * (trade_price - future_mid_price) / mid_price * 100
    return realized

# 假设你买入后,中间价从100.40跌到了100.35
trade = 100.40
future_mid = 100.35
bid = 100.30
ask = 100.50
real = realized_spread(trade, future_mid, bid, ask)
print(f"实现价差: {real:.2f}%")  # 正值说明你买在了相对高点

2.6 四个指标的关系与实战选择

指标 衡量什么 适用场景
绝对价差 报价层面的直接成本 日内高频、单一品种
相对价差 标准化后的交易成本 跨品种比较、组合管理
有效价差 实际成交的隐性成本 订单执行质量评估
实现价差 包含市场冲击的总成本 大单交易、策略回测

我个人习惯这样用:做日内策略看绝对价差和有效价差;做组合管理看相对价差;做大单交易必须看实现价差。缺一个都不行。

2.7 知识体系总览

下面这张图把四个指标的关系和计算逻辑串起来了,建议保存下来对照着看。

买卖价差核心指标体系 买卖价差 绝对价差 Ask - Bid 相对价差 (Ask-Bid)/Mid × 100% 有效价差 2×(Trade-Mid)/Mid 实现价差 2×(Trade-FutureMid)/Mid 实战选择建议 日内高频 → 绝对+有效 | 组合管理 → 相对 | 大单交易 → 实现

最后说一句:这四个指标不是孤立的。我一般会先算绝对价差看个大概,再用相对价差做横向对比,然后通过有效价差评估执行质量,最后用实现价差检验策略的鲁棒性。一套组合拳下来,流动性好不好,心里就有数了。

小技巧: 如果你用的是高频数据,建议把四个指标都算成滚动窗口(比如1分钟窗口),这样能捕捉到流动性的动态变化。我习惯用pandas的rolling函数来做,效率很高。
专注资料整理