27、冲击成本与机器学习:使用LSTM预测冲击成本、特征工程与模型选择
说实话,冲击成本这东西,做量化的人天天都在跟它打交道。但真正能把它算明白的人,不多。
我早年做高频策略的时候,吃过一次大亏。策略回测年化50%,实盘一跑,直接腰斩。后来一查,全是冲击成本惹的祸。从那以后,我就开始琢磨:能不能用机器学习来预测冲击成本?
今天我们就聊聊这个——用LSTM来预测冲击成本。别怕,我会把特征工程、模型选择这些坑,一个一个给你讲清楚。
为什么是LSTM?
冲击成本不是静态的。它跟市场状态、订单流、微观结构都有关系。说白了,它是一个时序问题。
你想想看,上午10点和下午2点的冲击成本能一样吗?大盘涨的时候和跌的时候能一样吗?
传统方法,比如线性回归,根本抓不住这种动态特征。而LSTM,天生就是处理时序数据的。它能记住过去一段时间的市场状态,然后预测下一秒的冲击成本。
我个人习惯用LSTM做这个任务,原因有三:
- 它能捕捉长期依赖关系——比如前10笔交易对当前的影响
- 它对噪声有一定的鲁棒性——高频数据里噪声多,LSTM能过滤一部分
- 它支持多变量输入——你可以把价格、成交量、波动率一股脑塞进去
核心观点:冲击成本预测,本质上是一个时序回归问题。LSTM是目前最成熟的方案之一。
特征工程:别小看这一步
我在项目中遇到过最头疼的事,不是模型不收敛,而是特征没选好。特征工程做不好,LSTM再牛也白搭。
那么,哪些特征对冲击成本有预测能力?我总结了几类:
| 特征类别 | 具体特征 | 说明 |
|---|---|---|
| 价格特征 | 最新价、中间价、买卖价差 | 价差越大,冲击成本通常越高 |
| 成交量特征 | 最近N笔成交量、累计成交量 | 成交量突然放大,冲击成本会飙升 |
| 订单簿特征 | 深度、斜率、不平衡度 | 订单簿越浅,冲击越大 |
| 波动率特征 | 已实现波动率、日内波动率 | 波动率高的时候,冲击成本也高 |
| 时间特征 | 距离开盘/收盘时间、时段 | 开盘和收盘时段冲击最大 |
嗯,这里要注意:特征不是越多越好。我见过有人塞了50个特征进去,结果模型过拟合得一塌糊涂。
我的经验:先选10-15个核心特征,跑一轮看看效果。如果效果不错,再逐步加特征。别一上来就搞大而全。
数据预处理:标准化是必须的
LSTM对输入数据的尺度很敏感。你想想看,价格可能是几百块,成交量可能是几万手,波动率可能是0.01。这些数据直接喂进去,模型根本学不动。
所以,标准化是必须的。我个人习惯用Z-score标准化:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
另外,还要注意数据的时间对齐。冲击成本的计算,通常需要用到未来1-2秒的数据。这里有个坑:你不能用未来数据去预测未来。我曾经犯过这个错,回测结果漂亮得不行,实盘直接翻车。
避坑指南:做特征工程时,一定要保证所有特征都是「当前时刻已知」的。别把未来数据泄露到特征里。
模型结构:怎么搭LSTM?
LSTM的结构设计,其实没有标准答案。但我可以给你一个常用的模板:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
model = Sequential()
model.add(LSTM(64, return_sequences=True, input_shape=(timesteps, n_features)))
model.add(Dropout(0.2))
model.add(LSTM(32, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(16, activation='relu'))
model.add(Dense(1)) # 输出冲击成本
这个结构里,我用了两层LSTM。为什么是两层?因为一层可能学不到复杂的时序模式,三层又容易过拟合。两层是个不错的折中。
timesteps这个参数很关键。它决定了模型看多长的历史窗口。我一般设成20-50,也就是看过去20-50个时间步。太短了信息不够,太长了计算量太大。
模型选择:LSTM vs 其他
你可能会问:LSTM是不是唯一的选择?当然不是。
我试过几种模型,简单对比一下:
| 模型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 线性回归 | 简单、可解释性强 | 无法捕捉非线性关系 | 低频、特征少 |
| 随机森林 | 对特征交互友好 | 无法处理时序依赖 | 特征工程做得好时 |
| LSTM | 擅长时序建模 | 训练慢、调参复杂 | 高频、数据量大 |
| Transformer | 并行计算、长序列 | 数据需求大、部署成本高 | 超高频、大资金 |
我个人建议:如果你刚开始做,先用LSTM。它成熟、稳定、社区支持好。等你有经验了,再试试Transformer。
训练与评估:别只看MSE
模型训练的时候,损失函数一般用MSE。但评估的时候,我建议你多看几个指标:
- MAE:平均绝对误差,直观反映预测偏差
- MAPE:平均绝对百分比误差,看相对误差
- R²:看模型解释了多少方差
我曾经遇到过一个情况:MSE很低,但MAPE很高。后来发现,是因为模型在大冲击时预测不准,但小冲击时预测得很好。MSE被小样本的误差拉低了。
所以,我建议你按冲击成本的大小分层评估。比如,把样本分成「小冲击」「中冲击」「大冲击」三组,分别看预测效果。
关键点:冲击成本预测的难点,往往在尾部——也就是大冲击的时候。模型在小冲击上表现好,不代表它在大冲击上也靠谱。
可视化:看看模型学到了什么
下面这张图,是我用LSTM预测冲击成本时的核心流程。你可以看到,从原始数据到特征工程,再到模型训练和评估,每一步都有讲究。
这张图里,我最想强调的是那个反馈循环。很多人在做冲击成本预测时,模型训完就完了。其实不是的。你要根据评估结果,回去调整特征、改模型结构、调超参数。这是一个迭代的过程。
部署与监控
模型训好了,怎么用?
我建议用滚动预测的方式。每来一笔新数据,就更新一次模型的状态。LSTM有个好处,它可以在线更新——你只需要把新的时间步喂进去,模型会自动更新内部状态。
但要注意:模型会漂移。市场结构变了,冲击成本的特征也会变。我一般每周重新训练一次模型,用最近一个月的数据。
一个小技巧:部署的时候,把模型的预测值和实际冲击成本做个实时对比。如果偏差持续变大,说明模型需要重新训练了。
好了,关于LSTM预测冲击成本,我就讲这么多。核心就三件事:特征工程要扎实、模型结构要合理、评估要分层。把这三点做好了,你的冲击成本预测就不会差。