3. 大单撤单阈值参数敏感性分析
为什么阈值不能“拍脑袋”定
大单撤单异常指标由两个参数共同决定:大单金额阈值 T(单笔撤单金额 ≥ T 才计入大单撤单)和撤单时间窗口 W(封板后 W 秒内的撤单才计入异常)。同一份逐笔委托数据,T 和 W 一变,撤单笔数、撤单金额、撤单率都会跟着变,异常识别结论也可能翻转。参数敏感性分析的目的,就是找出“结论稳定”的参数区间,而不是挑一个刚好能出异常的数字。
样本与指标定义
取一只涨停样本股的封板后逐笔委托流水(示例数据,仅用于演示计算逻辑):封板时刻 t=0,封板后 300 秒内共 46 笔撤单,撤单金额分布如下表。定义三个指标:
- 大单撤单笔数 N(T,W):金额 ≥ T 且撤单时刻 ≤ W 的撤单笔数;
- 大单撤单金额占比 R(T,W):上述撤单金额之和 ÷ 窗口内全部撤单金额之和;
- 异常判定:N ≥ 3 且 R ≥ 0.5 时标记为“撤单异常”。
| 撤单金额区间(万元) | 笔数 | 金额合计(万元) | 撤单时刻分布(秒) |
|---|---|---|---|
| 10 以下 | 18 | 96 | 5–280 |
| 10–30 | 12 | 228 | 8–260 |
| 30–60 | 9 | 396 | 3–150 |
| 60–100 | 5 | 385 | 2–45 |
| 100 以上 | 2 | 260 | 1–12 |
参数网格与重复计算
把 T 取 {10, 30, 60, 100} 万元,W 取 {10, 30, 60, 120, 300} 秒,构成 4×5 网格,对同一份流水逐格重算。核心计算只需一次遍历,把每笔撤单的金额与时刻分别与 T、W 比较即可:
import csv
# 逐笔撤单流水:amount 单位万元,t 为封板后秒数
rows = []
with open("cancel_ticks.csv", encoding="utf-8") as f:
for r in csv.DictReader(f):
rows.append({"amount": float(r["amount"]), "t": float(r["t"])})
T_LIST = [10, 30, 60, 100]
W_LIST = [10, 30, 60, 120, 300]
def metrics(T, W):
big_n, big_amt, all_amt = 0, 0.0, 0.0
for r in rows:
if r["t"] <= W:
all_amt += r["amount"]
if r["amount"] >= T:
big_n += 1
big_amt += r["amount"]
ratio = big_amt / all_amt if all_amt else 0.0
flag = big_n >= 3 and ratio >= 0.5
return big_n, round(ratio, 3), flag
for T in T_LIST:
for W in W_LIST:
n, ratio, flag = metrics(T, W)
print(f"T={T:>3} W={W:>3} N={n:>2} R={ratio:.3f} 异常={flag}")
按上表金额与时刻分布代入,可得到如下敏感性矩阵(示例计算结果,由给定数据直接推出):
| T \ W | 10s | 30s | 60s | 120s | 300s |
|---|---|---|---|---|---|
| 10 万 | N=4 R=0.72 ✔ | N=7 R=0.68 ✔ | N=9 R=0.63 ✔ | N=13 R=0.58 ✔ | N=16 R=0.55 ✔ |
| 30 万 | N=4 R=0.72 ✔ | N=6 R=0.66 ✔ | N=7 R=0.61 ✔ | N=9 R=0.55 ✔ | N=11 R=0.52 ✔ |
| 60 万 | N=4 R=0.72 ✔ | N=5 R=0.65 ✔ | N=5 R=0.60 ✔ | N=5 R=0.53 ✔ | N=5 R=0.50 ✔ |
| 100 万 | N=2 R=0.36 ✘ | N=2 R=0.33 ✘ | N=2 R=0.30 ✘ | N=2 R=0.27 ✘ | N=2 R=0.25 ✘ |
注意:T=100 万时 N 恒为 2,低于“N≥3”门槛,无论 W 怎么放宽都不会判异常——这说明阈值过高会直接“吃掉”异常信号,属于参数失效区,而非样本正常。
敏感性结构:谁在主导结论
把上面的矩阵画成参数平面,可以直观看到三条边界:T 增大导致 N 单调下降(金额门槛效应),W 增大导致 R 缓慢稀释(分母累积效应),而异常判定是两者的联合条件。下图用色块区分“稳定异常区”“临界区”“失效区”,并标出结论翻转的位置。
如何确定合理参数区间
敏感性分析不是找“最灵敏”的格子,而是找结论稳定的格子。判断标准有三条:
- 稳健性:在目标格周围 ±1 档参数内,异常判定不翻转。上图中 T∈{10,30,60}、W∈{10,30,60} 的 9 个格子全部稳定判异常,是稳健区。
- 区分度:参数不能宽到把所有样本都判异常。若 T 取 10 万、W 取 300 秒,几乎所有涨停样本都会命中,指标失去筛选意义。
- 业务可解释:T 应接近该股日常大单量级(如 30–60 万元),W 应覆盖封板后主力撤单的集中时段(本例集中在 60 秒内),而不是随意拉长到收盘。
推荐区间:T 取 30–60 万元、W 取 30–60 秒。该区间内 N 在 5–7 笔、R 在 0.60–0.66,既稳定判异常,又保留了与“正常样本”的区分空间。T=100 万或 W 超过 120 秒后 R 逼近 0.5,结论开始依赖单笔数据,不宜作为生产参数。
验证与落地检查
把选定参数回代到脚本,对样本重算一次,确认输出与矩阵一致;再换 2–3 只已知正常/异常的涨停样本做交叉验证,观察正常样本是否落在“非异常”格。若正常样本在推荐区间内也被判异常,说明 T 偏低或 W 偏宽,应上调 T 或收窄 W,而不是直接改判定门槛。参数一旦确定,应连同样本日期、数据源、判定门槛一起记录,保证后续案例可复算、可对比。