3. 盘口量比突变的滚动检测
为什么量比突变不能直接等同于异常
买一量与卖一量的比值(下称“一档量比”)在盘口中会因大单挂出、撤单、成交消耗而快速跳动。若用固定阈值(如量比 > 3 即报警),正常的大额挂单和撤单会被大量误报。本例采用滚动窗口 + 稳健Z分数:用中位数与MAD估计局部基线,对量比的对数做标准化,只有当突变幅度显著偏离近期波动水平、且盘口深度结构同步变化时才标记为候选异常。
指标构造与稳健Z分数计算
设第 t 个快照的买一量为 Vb1、卖一量为 Va1,一档量比定义为 r_t = Vb1 / Va1。量比是右偏的正值,直接做Z分数会被极端值拉偏,因此先取对数 x_t = ln(r_t),再在长度为 W 的滚动窗口内计算中位数 med 与中位绝对偏差 MAD = median(|x_i − med|),稳健Z分数为:
z_t = 0.6745 · (x_t − med_t) / MAD_t
常数 0.6745 使 MAD 在正态假设下与标准差一致。当 MAD_t 过小(盘口长期静止)时需设下限 MAD_min,否则微小波动会被放大成巨大Z值。判定候选突变的条件为 |z_t| ≥ Z_th(本例取 3.5),并要求该点前后各 1 个快照不连续触发,以抑制单点毛刺。
可运行的检测实现
import math
from statistics import median
W = 30 # 滚动窗口长度(快照数)
Z_TH = 3.5 # 稳健Z分数阈值
MAD_MIN = 1e-3 # MAD下限,防止静止盘口放大噪声
def robust_z_series(ratios, w=W, z_th=Z_TH, mad_min=MAD_MIN):
"""ratios: 一档量比序列 r_t。返回每个点的 (z, 是否候选突变)。"""
xs = [math.log(max(r, 1e-9)) for r in ratios]
out = []
for t in range(len(xs)):
lo = max(0, t - w + 1)
win = xs[lo:t + 1]
if len(win) < 5: # 窗口不足,暂不判定
out.append((0.0, False))
continue
med = median(win)
mad = median([abs(v - med) for v in win])
mad = max(mad, mad_min)
z = 0.6745 * (xs[t] - med) / mad
out.append((z, abs(z) >= z_th))
# 抑制单点毛刺:要求前后各一点也超阈
flags = [f for _, f in out]
confirmed = []
for t, (z, f) in enumerate(out):
prev = flags[t - 1] if t > 0 else False
nxt = flags[t + 1] if t + 1 < len(flags) else False
confirmed.append((z, f and (prev or nxt)))
return confirmed
# 教学示例:前段平稳,第 20 点买一量骤增(大单挂出)
ratios = [1.0, 1.1, 0.9, 1.05, 0.95, 1.0, 1.08, 0.92, 1.02, 0.98,
1.0, 1.03, 0.97, 1.01, 0.99, 1.0, 1.04, 0.96, 1.02, 1.0,
6.5, 6.2, 1.1, 1.0, 0.98, 1.02, 1.0, 0.99, 1.01, 1.0]
res = robust_z_series(ratios)
for i, (z, hit) in enumerate(res):
if hit:
print(f"t={i:2d} z={z:+.2f} 候选突变")
示例数据中第 20、21 点量比跳到 6.5 与 6.2,其余在 1.0 附近。运行后这两点会因 |z| 远超 3.5 且相邻点同时超阈而被标记为候选突变。注意这只是候选——它可能只是买一挂出大单,需要下一步的深度校验来区分。
用盘口深度变化区分“真异常”与“正常大单挂撤”
候选点出现后,比较突变前后各 3 个快照的盘口深度特征:
- 单侧深度变化率:
ΔVb1 / Vb1_prev与ΔVa1 / Va1_prev。正常大单挂出通常只改变单侧,另一侧几乎不动。 - 撤单占比:若买一量骤降且伴随买一价上移,多为撤单;若买一量骤增且价格未动,多为新挂单。
- 多档深度一致性:真异常(如流动性抽离)往往二至五档同步变薄,而单档大单只影响一档。
判读规则:候选突变点若仅单侧一档变化、多档深度基本稳定,判为“正常大单挂撤”,不报警;若多档深度同步异动或双侧同时收缩,判为确认异常。这样可把大量正常大单从报警中剔除。
结果验证与判读清单
| 检查项 | 通过条件 | 不通过时的处理 |
|---|---|---|
| 候选点数量 | 单只股票单日候选点占比 < 2% | 提高 Z_th 或增大 MAD_min |
| 毛刺抑制 | 无孤立单点触发 | 检查前后点确认逻辑是否生效 |
| 深度联动 | 确认异常均伴随多档深度异动 | 复核深度校验阈值 |
| 误报来源 | 正常大单挂撤被正确排除 | 补充撤单占比字段 |
验证时建议抽取 20 个候选点人工回看原始快照:记录突变方向、单双侧、涉及档位数与后续 1 分钟内价格变动,形成误报归因表,再据此微调 Z_th 与深度校验条件。