1. 订单簿不平衡指标构建

任务目标

基于限价订单簿中买卖盘口的挂单量,构建订单簿不平衡指标(Order Book Imbalance, OBI),并验证该指标对短期价格变动是否具有预测能力。本案例使用Python实现,核心交付物为一个可独立运行的脚本,输出指标序列及对应的短期价格变动方向,用于后续分析。

环境与依赖

需要Python 3.8+环境,依赖库仅需pandas和numpy。若需可视化可额外安装matplotlib(本案例不强制)。

核心实现

订单簿不平衡指标定义为:OBI = (BidVolume - AskVolume) / (BidVolume + AskVolume),其中BidVolume为买一档挂单量,AskVolume为卖一档挂单量。OBI取值范围为[-1, 1],正值表示买方挂单强势,负值表示卖方挂单强势。短期价格变动定义为未来N笔成交(或固定时间窗口)内的价格变化方向。

以下代码实现了OBI计算、短期价格变动标记,以及一个简单的方向准确率评估函数。输入数据为模拟的订单簿快照序列(含买一/卖一价量),实际使用时替换为真实数据源即可。

import pandas as pd
import numpy as np

def compute_obi(bid_vol, ask_vol):
    """计算订单簿不平衡指标"""
    denom = bid_vol + ask_vol
    return np.where(denom == 0, 0, (bid_vol - ask_vol) / denom)

def label_short_term_move(mid_prices, horizon=5):
    """标记未来horizon笔的短期价格方向: 1涨, -1跌, 0平"""
    moves = []
    for i in range(len(mid_prices) - horizon):
        future = mid_prices[i + horizon]
        current = mid_prices[i]
        if future > current:
            moves.append(1)
        elif future < current:
            moves.append(-1)
        else:
            moves.append(0)
    # 末尾不足horizon的部分填充NaN
    moves.extend([np.nan] * horizon)
    return np.array(moves)

def evaluate_obi_predictive_power(obi_series, move_series):
    """评估OBI方向与短期价格变动的吻合度(忽略平盘与NaN)"""
    valid = ~np.isnan(move_series) & (move_series != 0)
    if valid.sum() == 0:
        return 0.0, 0
    # OBI符号与价格变动方向一致的比例
    correct = np.sign(obi_series[valid]) == move_series[valid]
    accuracy = correct.mean()
    return accuracy, int(valid.sum())

# ========== 最小可复现示例 ==========
if __name__ == "__main__":
    # 模拟10笔订单簿快照(实际使用时替换为真实数据)
    np.random.seed(42)
    n = 100
    bid_price = 100 + np.cumsum(np.random.randn(n) * 0.01)
    ask_price = bid_price + 0.02  # 固定价差
    bid_vol = np.random.randint(10, 100, n).astype(float)
    ask_vol = np.random.randint(10, 100, n).astype(float)

    # 计算OBI
    obi = compute_obi(bid_vol, ask_vol)

    # 计算中间价及短期变动
    mid_price = (bid_price + ask_price) / 2
    moves = label_short_term_move(mid_price, horizon=5)

    # 评估预测能力
    acc, sample_count = evaluate_obi_predictive_power(obi, moves)
    print(f"有效样本数: {sample_count}")
    print(f"OBI方向准确率: {acc:.2%}")

    # 输出前5行数据预览
    df = pd.DataFrame({
        "bid_vol": bid_vol[:5],
        "ask_vol": ask_vol[:5],
        "obi": obi[:5],
        "mid_price": mid_price[:5],
        "future_move": moves[:5]
    })
    print("\n前5行数据预览:")
    print(df)

运行与验证

运行方式:将上述代码保存为obi_analysis.py,在终端执行python obi_analysis.py。

验证方法:程序会输出有效样本数和OBI方向准确率。由于使用随机模拟数据,准确率会接近50%(无预测能力),这属于正常现象——本案例的目的是提供完整的指标构建与评估框架。若接入真实订单簿数据,准确率显著高于55%即可认为OBI对短期价格变动有预测作用。

通过条件:脚本无报错运行完毕,输出有效样本数大于0,且准确率数值在0~1之间。将bid_vol/ask_vol替换为真实盘口数据后,即可得到有实际意义的OBI序列与评估结果。

常见问题

  • 数据频率问题:订单簿快照通常为毫秒级,而价格变动需要设定合理的时间窗口(如50ms、100ms),本案例使用固定笔数(horizon=5)作为简化,实际使用时建议改为时间窗口。
  • 多档深度:本案例仅用一档盘口,若需更稳健的指标,可将OBI扩展为多档加权形式,例如按距离加权各档位挂单量。