3、冰山订单识别算法:基于成交量异常检测、基于时间序列模式匹配、基于订单簿斜率变化
好,咱们直接进入正题。冰山订单这东西,说白了就是大资金不想让别人知道自己在买或者卖。我当年刚接触量化交易时,第一次在盘口看到那种「怎么砸都砸不穿」的买单,还以为是市场情绪坚挺,后来才知道——人家用的是冰山订单,一层一层挂,吃完了再补。
识别冰山订单,核心就三个思路:成交量异常检测、时间序列模式匹配、订单簿斜率变化。这三种方法各有侧重,我一个个讲清楚。
3.1 基于成交量异常检测
这个方法最直观。你想想看,正常交易中,成交量分布应该是相对平滑的。但如果有人在偷偷挂冰山单,就会出现一种现象:某个价位上的成交量突然暴增,然后又迅速回落。
为什么会这样?因为冰山订单的机制是:你挂1000手,但只显示100手。市场吃掉这100手后,系统自动再补100手。于是你就会看到——同一个价位上,成交量像「脉冲」一样反复出现。
我在项目中遇到过这样一个案例:某只股票在10.00元价位上,平时每分钟成交也就200手左右。但某天突然连续5分钟,每分钟成交都超过800手,而且每次成交后价格几乎不动。嗯,这明显是有人在用冰山单吸筹。
具体算法实现上,我习惯用Z-Score来做异常检测:
import numpy as np
def detect_iceberg_by_volume(volume_series, window=20, threshold=3):
"""
基于成交量异常检测冰山订单
:param volume_series: 成交量时间序列
:param window: 滚动窗口大小
:param threshold: Z-Score阈值
"""
rolling_mean = volume_series.rolling(window).mean()
rolling_std = volume_series.rolling(window).std()
z_scores = (volume_series - rolling_mean) / rolling_std
# 标记异常点
anomalies = np.where(np.abs(z_scores) > threshold)[0]
return anomalies
3.2 基于时间序列模式匹配
这个方法更精细一些。冰山订单在时间序列上会留下独特的「指纹」——锯齿状的成交量模式。
你想想看,正常的买卖是随机的,成交量曲线应该是杂乱无章的。但冰山单不一样:它会在短时间内反复出现「放量-缩量-放量」的循环。这个循环的周期,正好对应冰山单的「补单间隔」。
我常用的方法是动态时间规整(DTW),说白了就是拿一个标准的「冰山模式」去跟实际数据做匹配。如果匹配度超过某个阈值,就认为存在冰山订单。
from dtaidistance import dtw
def detect_iceberg_by_pattern(series, pattern, threshold=0.2):
"""
基于模式匹配检测冰山订单
:param series: 实际成交量序列
:param pattern: 标准冰山模式(例如 [1, 0.3, 1, 0.3, 1])
:param threshold: DTW距离阈值
"""
# 滑动窗口计算DTW距离
for i in range(len(series) - len(pattern) + 1):
window = series[i:i+len(pattern)]
distance = dtw.distance(window, pattern)
if distance < threshold:
print(f"发现冰山模式,位置: {i}")
return i
return None
3.3 基于订单簿斜率变化
这个方法是我个人最喜欢的。因为它不需要看成交数据,只看订单簿就能判断。
原理是这样的:正常情况下,订单簿的买卖挂单应该是相对平滑的。但冰山订单出现时,会在某个价位上反复「补单」,导致该价位的挂单量异常高,形成斜率突变。
具体来说,我会计算订单簿的累积深度曲线的斜率。如果某个价位上的斜率突然变陡,而且这个现象反复出现,那基本可以断定有冰山单。
def detect_iceberg_by_slope(order_book, depth_levels=10):
"""
基于订单簿斜率变化检测冰山订单
:param order_book: 订单簿数据(价格, 挂单量)
:param depth_levels: 检测深度
"""
prices = [level[0] for level in order_book[:depth_levels]]
volumes = [level[1] for level in order_book[:depth_levels]]
# 计算累积深度
cum_volumes = np.cumsum(volumes)
# 计算斜率(一阶差分)
slopes = np.diff(cum_volumes) / np.diff(prices)
# 检测斜率突变
mean_slope = np.mean(slopes)
std_slope = np.std(slopes)
for i, slope in enumerate(slopes):
if abs(slope - mean_slope) > 2 * std_slope:
print(f"发现斜率异常,价位: {prices[i]}")
return prices[i]
return None
知识体系总览
下面这张图是我整理的冰山订单识别算法的完整框架,你可以对照着理解:
嗯,这三种方法讲完了。我个人建议你从成交量异常检测入手,因为这个最简单,也最容易看到效果。等你熟悉了,再慢慢加上模式匹配和斜率分析。
记住一点:没有完美的算法,只有最适合当前市场的策略。我在实盘中经常需要根据市场状态动态调整参数,这个后面会详细讲。
公众号:蓝海资料掘金营,微信deep3321