第二章:对手行为建模——识别对手类型、行为模式分类与历史数据特征提取
做量化交易这些年,我越来越觉得,市场就是个巨大的牌桌。你手里的策略再牛,如果看不懂对面坐的是谁,迟早得栽跟头。这一章,咱们就聊聊怎么给对手“画像”——说白了,就是通过行为数据,把散户、机构、量化基金这些不同类型的交易者给认出来。
2.1 对手类型识别:先搞清楚跟谁在玩
我个人习惯,把市场上的参与者分成三大类。每一类的行为特征,差异非常大。你想想看,一个拿工资的散户,跟一个管理百亿资金的基金经理,下单逻辑能一样吗?
| 对手类型 | 资金规模 | 交易频率 | 订单特征 | 持仓周期 |
|---|---|---|---|---|
| 散户 | 小(<10万) | 中低频 | 整手、限价单为主 | 数天至数周 |
| 机构 | 大(>1000万) | 中频 | 大单拆分、算法单 | 数周至数月 |
| 量化基金 | 中到大 | 高频 | 小单、冰山单、对倒 | 秒级至小时级 |
嗯,这里要注意:光看资金量还不够。我在项目中遇到过,有些游资伪装成机构,用大单砸盘诱多。所以,我们得结合行为模式来综合判断。
2.2 行为模式分类:他们到底在干嘛?
识别出对手类型后,下一步就是看他们的行为模式。我一般把常见行为分成四类:
- 趋势跟随型:追涨杀跌,散户最爱。特征:价格突破时放量,回调时缩量。
- 均值回归型:高抛低吸,机构常用。特征:价格偏离均线时反向开仓。
- 套利型:吃价差,量化基金专属。特征:双边挂单,成交后迅速撤单。
- 操纵型:挂假单、对倒、拉抬。特征:盘口出现大量挂单但成交稀疏。
为什么会这样?因为每种模式背后,对应的是不同的盈利逻辑。比如量化基金做套利,赚的是流动性溢价,所以他们的订单一定是“快进快出”。
避坑指南:我曾经把一次“对倒”行为误判为“趋势启动”,结果跟进去被套了。后来我加了一个规则:如果同一价位频繁出现“成交-撤单-再成交”的循环,大概率是量化基金在做市或对倒,千万别追。
2.3 历史数据特征提取:把行为变成数字
光靠肉眼盯盘肯定不行。我们需要从历史数据里提取特征,用数字说话。我常用的特征分三类:
2.3.1 订单簿特征
- 买卖价差:价差突然扩大,说明流动性枯竭,可能是机构在撤单。
- 订单深度:前五档挂单量变化率。量化基金喜欢用冰山单,深度会突然变化。
- 撤单率:挂单后未成交就撤掉的比例。散户撤单率低,量化基金撤单率极高。
2.3.2 成交特征
- 大单占比:单笔成交超过平均单量3倍以上的比例。机构行为。
- 成交间隔:相邻两笔成交的时间差。量化基金成交间隔极短且均匀。
- 主动买卖比:主动买入量 vs 主动卖出量。散户容易追涨,主动买卖比会极端化。
2.3.3 时间序列特征
- 波动率聚类:高波动后往往跟着高波动。机构喜欢在波动率低时建仓。
- 自相关性:价格序列的自相关系数。量化基金策略会引入负自相关(均值回归)。
- 成交量分布:一天中成交量集中在哪些时段。散户喜欢开盘和收盘交易。
我的经验:提取特征时,别贪多。我刚开始做的时候,一口气提取了50多个特征,结果模型过拟合得一塌糊涂。后来我只保留了10个核心特征,效果反而更好。记住:特征不是越多越好,关键是每个特征都要有明确的业务解释。
2.4 实战:用Python快速识别对手类型
光说不练假把式。下面我给出一段代码,用来从Level-2行情数据里提取特征,并做简单的对手分类。代码不长,但核心逻辑都在里面了。
import pandas as pd
import numpy as np
def extract_opponent_features(df):
"""
从逐笔成交数据中提取对手行为特征
df: 包含['time', 'price', 'volume', 'side']的DataFrame
"""
features = {}
# 1. 大单占比(单笔成交量 > 平均量3倍)
avg_vol = df['volume'].mean()
large_trades = df[df['volume'] > avg_vol * 3]
features['large_trade_ratio'] = len(large_trades) / len(df)
# 2. 主动买卖比
buy_vol = df[df['side'] == 'buy']['volume'].sum()
sell_vol = df[df['side'] == 'sell']['volume'].sum()
features['buy_sell_ratio'] = buy_vol / (sell_vol + 1e-8)
# 3. 成交间隔均值(秒)
df['time_diff'] = df['time'].diff().dt.total_seconds()
features['avg_trade_interval'] = df['time_diff'].mean()
# 4. 撤单率(假设有撤单标记列)
if 'cancel' in df.columns:
features['cancel_rate'] = df['cancel'].sum() / len(df)
return features
# 示例:判断对手类型
def classify_opponent(features):
if features['large_trade_ratio'] > 0.3 and features['avg_trade_interval'] < 1.0:
return '量化基金'
elif features['large_trade_ratio'] > 0.1 and features['buy_sell_ratio'] > 1.5:
return '机构(主动买入)'
else:
return '散户/其他'
注意:上面的代码只是演示逻辑。实际生产中,你需要处理数据对齐、缺失值、以及不同交易所的数据格式差异。我踩过的坑是:某交易所的撤单标记字段是空的,导致撤单率一直为0,模型把量化基金全判成了散户。后来我加了一个“挂单存活时间”的替代特征才解决。
2.5 知识体系总览
下面这张图,是我自己画的知识结构。每次做对手建模前,我都会先过一遍这张图,确保没有遗漏关键环节。
这张图从下往上看,就是整个建模流程。我个人习惯,每次拿到新数据,都先按这个框架走一遍,确保每个环节都覆盖到。
2.6 小结
这一章我们聊了对手行为建模的三个核心步骤:识别类型、分类模式、提取特征。说白了,就是先知道对面是谁,再猜他要干嘛,最后用数据验证你的猜测。嗯,这里要提醒一句:模型永远只是辅助,市场里总有你意想不到的“新物种”。保持敬畏,持续迭代,才是长久之道。
公众号:蓝海资料掘金营,微信deep3321