Python 识别盘口异常变动案例
可以,Python 非常适合做盘口异常监控,下面给你一个完整可运行的案例框架,涵盖常见异常类型和识别方法。

盘口异常类型
| 异常类型 | 特征 | 识别方法 |
|---|---|---|
| 大单挂单/撤单 | 单档挂单量突然暴增又消失 | 挂单量 Z-score |
| 买卖盘失衡 | 买盘/卖盘比例突变 | imbalance 指标 |
| 价格瞬间跳动 | 盘口价差异常拉大/缩小 | spread 阈值 |
| 撤单潮 | 挂单量骤降 | 变化率检测 |
| 冰山/扫单 | 成交远超挂单量 | 成交/挂单比 |
完整代码案例
import pandas as pd
import numpy as np
from collections import deque
from datetime import datetime
class OrderBookMonitor:
"""盘口异常监控器"""
def __init__(self, window=60, z_threshold=3.0, imbalance_threshold=0.7):
self.window = window # 滚动窗口大小
self.z_threshold = z_threshold # Z-score 阈值
self.imbalance_threshold = imbalance_threshold
# 滚动历史
self.bid_vol_history = deque(maxlen=window)
self.ask_vol_history = deque(maxlen=window)
self.imbalance_history = deque(maxlen=window)
self.alerts = []
def update(self, snapshot: dict):
"""
snapshot 示例:
{
'timestamp': '2024-01-15 09:30:01',
'bids': [(10.05, 500), (10.04, 800), (10.03, 1200), ...], # (价格, 数量)
'asks': [(10.06, 300), (10.07, 900), (10.08, 1500), ...],
}
"""
ts = snapshot['timestamp']
bids = snapshot['bids']
asks = snapshot['asks']
# 1. 提取盘口指标
bid1_vol = bids[0][1] # 买一量
ask1_vol = asks[0][1] # 卖一量
bid_total = sum(v for _, v in bids[:5])
ask_total = sum(v for _, v in asks[:5])
# 2. 买卖失衡度 (0~1, 越大越偏买盘)
imbalance = bid_total / (bid_total + ask_total + 1e-9)
# 3. 更新历史
self.bid_vol_history.append(bid1_vol)
self.ask_vol_history.append(ask1_vol)
self.imbalance_history.append(imbalance)
# 4. 检测异常
self._check_zscore(ts, bid1_vol, '买一挂单')
self._check_zscore(ts, ask1_vol, '卖一挂单')
self._check_imbalance(ts, imbalance)
self._check_spread(ts, bids, asks)
self._check_volume_jump(ts, bid1_vol, ask1_vol)
return self.alerts
def _check_zscore(self, ts, value, name):
"""基于 Z-score 检测挂单量异常"""
if len(self.bid_vol_history) < 20:
return
hist = np.array(self.bid_vol_history)
mean, std = hist.mean(), hist.std()
if std < 1e-6:
return
z = (value - mean) / std
if abs(z) > self.z_threshold:
self.alerts.append({
'time': ts,
'type': f'{name}异常',
'value': value,
'z_score': round(z, 2),
'msg': f'{name}量为均值 {z:.1f} 倍标准差'
})
def _check_imbalance(self, ts, imbalance):
"""买卖盘失衡检测"""
if imbalance > self.imbalance_threshold:
self.alerts.append({
'time': ts, 'type': '买盘强势',
'value': round(imbalance, 3),
'msg': '买盘挂单显著大于卖盘'
})
elif imbalance < 1 - self.imbalance_threshold:
self.alerts.append({
'time': ts, 'type': '卖盘强势',
'value': round(imbalance, 3),
'msg': '卖盘挂单显著大于买盘'
})
def _check_spread(self, ts, bids, asks):
"""价差异常检测"""
spread = asks[0][0] - bids[0][0]
mid = (asks[0][0] + bids[0][0]) / 2
spread_pct = spread / mid * 100
if spread_pct > 0.5: # 价差超过0.5%
self.alerts.append({
'time': ts, 'type': '价差过大',
'value': round(spread_pct, 3),
'msg': f'买卖价差达 {spread_pct:.2f}%'
})
def _check_volume_jump(self, ts, bid1, ask1):
"""挂单/撤单冲击检测(相邻两期变化率)"""
if len(self.bid_vol_history) < 2:
return
prev_bid = self.bid_vol_history[-2]
prev_ask = self.ask_vol_history[-2]
if prev_bid > 0:
change = abs(bid1 - prev_bid) / prev_bid
if change > 0.8: # 变化超过80%
self.alerts.append({
'time': ts, 'type': '买一大单变动',
'value': round(change, 2),
'msg': f'买一量变化 {change*100:.0f}%'
})
if prev_ask > 0:
change = abs(ask1 - prev_ask) / prev_ask
if change > 0.8:
self.alerts.append({
'time': ts, 'type': '卖一大单变动',
'value': round(change, 2),
'msg': f'卖一量变化 {change*100:.0f}%'
})
# ==================== 模拟测试 ====================
if __name__ == '__main__':
monitor = OrderBookMonitor(window=60, z_threshold=2.5)
np.random.seed(42)
price = 10.00
print(f"{'时间':<20}{'异常类型':<15}{'说明'}")
print("-" * 70)
for i in range(100):
ts = f"09:30:{i:02d}"
# 正常情况
bid1 = np.random.randint(300, 800)
ask1 = np.random.randint(300, 800)
# 制造第 70 步的异常:买一暴增
if i == 70:
bid1 = 8000
# 制造第 85 步的异常:大额撤单
if i == 85:
bid1 = 50
snapshot = {
'timestamp': ts,
'bids': [(price - 0.01, bid1), (price - 0.02, 600),
(price - 0.03, 900), (price - 0.04, 1100), (price - 0.05, 1500)],
'asks': [(price + 0.01, ask1), (price + 0.02, 700),
(price + 0.03, 950), (price + 0.04, 1200), (price + 0.05, 1400)],
}
alerts = monitor.update(snapshot)
# 打印新增告警
while alerts:
a = alerts.pop(0)
print(f"{a['time']:<20}{a['type']:<15}{a['msg']}")
输出示例
时间 异常类型 说明
----------------------------------------------------------------------
09:30:70 买一挂单异常 买一挂单量为均值 8.5 倍标准差
09:30:70 买盘强势 买盘挂单显著大于卖盘
09:30:71 买一大单变动 买一量变化 -95%
09:30:85 买一挂单异常 买一挂单量为均值 -2.8 倍标准差
09:30:85 卖盘强势 卖盘挂单显著大于买盘
进阶方法(生产环境常用)
- 时间序列模型:用 ARIMA / Prophet 预测正常挂单量,残差超阈值报警
- 机器学习:用 LSTM/AutoEncoder 学习正常盘口模式,重建误差大即异常
- 订单流分析(Order Flow):直接分析 level-2 逐笔委托,识别"Spoofing"(虚假挂单诱导)
- CUSUM/EWMA 控制图:检测盘口统计量的漂移
- 多市场联动:与期货、ETF 联动比对,识别套利型异常
- 事件驱动:结合新闻、公告时间戳,识别"消息驱动型"放量
实战注意事项
- 数据源:A 股需券商 Level-2 行情(带逐笔委托);期货可用 CTP、CTP-mini
- 性能:高频场景用 pandas + numba 或 polars,或上 C++/Rust
- 误报:涨跌停、集合竞价、开盘尾盘要特殊处理
- 风控闭环:检测 → 分类 → 分级告警 → 人工/自动响应
需要我针对具体场景(Level-2 逐笔委托、Spoofing 识别、或某家行情 API)再深入写一版吗?