1. 订单簿不平衡与短期价格方向预测

任务目标

基于订单簿中买一至买五档与卖一至卖五档的挂单量,计算订单簿不平衡度(Order Book Imbalance, OBI),并构建一个简单的逻辑回归模型,预测未来3秒价格方向(上涨/下跌)。本案例使用合成订单簿数据演示完整流程,不依赖外部数据源。

实现思路

订单簿不平衡度定义为:OBI = (BidVolume - AskVolume) / (BidVolume + AskVolume),其中 BidVolume 为买盘五档挂单总量,AskVolume 为卖盘五档挂单总量。OBI 取值范围为 [-1, 1],正值表示买方力量占优,负值表示卖方力量占优。我们使用过去 N 个时间片的 OBI 序列作为特征,预测未来 3 秒的价格方向。

完整代码

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# ========== 1. 合成订单簿数据 ==========
np.random.seed(42)
n_samples = 2000
n_levels = 5  # 盘口档位数

def generate_order_book_sample():
    """生成一个时间片的订单簿快照"""
    mid_price = 100.0
    # 买盘五档:价格递减,量随机
    bid_prices = mid_price - np.arange(1, n_levels+1) * 0.01
    bid_volumes = np.random.randint(50, 500, size=n_levels).astype(float)
    # 卖盘五档:价格递增,量随机
    ask_prices = mid_price + np.arange(1, n_levels+1) * 0.01
    ask_volumes = np.random.randint(50, 500, size=n_levels).astype(float)
    return bid_volumes, ask_volumes

# 生成连续时间片数据
bid_volumes_history = []
ask_volumes_history = []
for _ in range(n_samples + 10):  # 多生成10个用于构造标签
    bid_v, ask_v = generate_order_book_sample()
    bid_volumes_history.append(bid_v)
    ask_volumes_history.append(ask_v)

# ========== 2. 构造特征与标签 ==========
def compute_obi(bid_v, ask_v):
    """计算单个时间片的OBI"""
    total_bid = np.sum(bid_v)
    total_ask = np.sum(ask_v)
    return (total_bid - total_ask) / (total_bid + total_ask)

# 使用过去5个时间片的OBI作为特征
window_size = 5
X = []
y = []

for i in range(window_size, n_samples):
    # 特征:过去5个时间片的OBI
    obi_seq = []
    for j in range(i - window_size, i):
        obi = compute_obi(bid_volumes_history[j], ask_volumes_history[j])
        obi_seq.append(obi)
    X.append(obi_seq)
    
    # 标签:未来3秒价格方向(用中间价变化判断)
    # 用当前时间片与3个时间片后的中间价比较
    current_mid = (bid_volumes_history[i][0] * 0 + 100.0)  # 简化:中间价固定为100
    # 实际中价格会随盘口变化,这里用合成方式生成方向
    # 以当前OBI的正负为基础,加上随机噪声生成标签
    current_obi = compute_obi(bid_volumes_history[i], ask_volumes_history[i])
    # 若OBI > 0.1 则大概率上涨,< -0.1 则大概率下跌,中间随机
    if current_obi > 0.1:
        prob_up = 0.7
    elif current_obi < -0.1:
        prob_up = 0.3
    else:
        prob_up = 0.5
    label = 1 if np.random.rand() < prob_up else 0  # 1=上涨, 0=下跌
    y.append(label)

X = np.array(X)
y = np.array(y)

# ========== 3. 训练与评估 ==========
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = LogisticRegression()
model.fit(X_train, y_train)

y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

# 输出模型系数,观察OBI与价格方向的关系
print(f"测试集准确率: {accuracy:.4f}")
print(f"模型系数: {model.coef_[0]}")
print(f"截距: {model.intercept_[0]}")

# ========== 4. 单样本预测示例 ==========
# 取最后一个样本进行预测
sample_obi = X[-1].reshape(1, -1)
pred_prob = model.predict_proba(sample_obi)[0]
print(f"\n样本OBI序列: {X[-1]}")
print(f"预测上涨概率: {pred_prob[1]:.4f}, 预测下跌概率: {pred_prob[0]:.4f}")
print(f"预测方向: {'上涨' if model.predict(sample_obi)[0] == 1 else '下跌'}")

运行方式

需要安装 numpy 和 scikit-learn。直接运行脚本即可:

pip install numpy scikit-learn
python order_book_imbalance.py

验证方法

程序输出以下内容即表示运行成功:

  • 测试集准确率:模型在测试集上的预测准确率,通常在 0.5~0.7 之间(因合成数据含随机噪声,准确率会随运行波动)。
  • 模型系数:若系数为正,说明 OBI 越高越倾向于预测上涨,符合逻辑。
  • 单样本预测:展示最后一个样本的 OBI 序列及预测概率。

判定标准:程序无报错且输出上述三项内容,即完成案例闭环。若要验证模型有效性,可观察系数符号是否与预期一致(正系数表示 OBI 与上涨概率正相关)。

关键说明

本案例使用合成数据演示完整建模流程,核心逻辑(OBI 计算 → 特征构造 → 模型训练 → 预测)可直接替换为真实订单簿数据流。真实场景中,中间价需从盘口价格计算,标签需使用未来 3 秒的实际价格变动,而非基于当前 OBI 的概率生成。合成数据中的标签生成方式仅用于演示代码可运行性,不反映真实市场规律。