第 9 章 · 06 日内特征与模型 本节摘要:前几节都在日频以上建模,本节把视野扩展到分钟级日内。日内数据与日频有三类本质差异:样本量爆炸(每只票每天几百根 1 分钟 bar)、噪声更厚(微观结构噪声主导)、特征工程更细致(成交档位、订单簿不平衡等)。本节讲清三件事:如何从 AlgoSeek NASDAQ100 的 TAQ(成交与报价)数据清洗出分钟级 OHLCV + 成交档位特征;如何构造分钟级前瞻收益(1/5/10 分钟)与滞后收益特征;以及如何用 LightGBM 训练一个高频日内模型,用 做严格的滚动评估,警惕样本外 IC 的急剧衰减。读完本节,你理解了高频日内建模的关键工程难点,以及为什么日内模型几乎不可能直接套用日频套路。 内容来源:原项目 、 ,汉化并套用体系化模板。
本节摘要:前几节都在日频以上建模,本节把视野扩展到分钟级日内。日内数据与日频有三类本质差异:样本量爆炸(每只票每天几百根 1 分钟 bar)、噪声更厚(微观结构噪声主导)、特征工程更细致(成交档位、订单簿不平衡等)。本节讲清三件事:如何从 AlgoSeek NASDAQ100 的 TAQ(成交与报价)数据清洗出分钟级 OHLCV + 成交档位特征;如何构造分钟级前瞻收益(1/5/10 分钟)与滞后收益特征;以及如何用 LightGBM 训练一个高频日内模型,用
MultipleTimeSeriesCV做严格的滚动评估,警惕样本外 IC 的急剧衰减。读完本节,你理解了高频日内建模的关键工程难点,以及为什么日内模型几乎不可能直接套用日频套路。
内容来源:原项目
12_gradient_boosting_machines/10_intraday_features.ipynb、11_intraday_model.ipynb,汉化并套用体系化模板。
⚠️ 学习提示:日内回测的 IC 衰减远比日频剧烈——大量虚假信号在微观噪声里冒出来。这里的模型仅供学习日内建模的流程,实盘还需考虑滑点、订单簿深度、市场冲击等微观结构因素,远超本节范围。
阅读完本节,你应当能够:
MultipleTimeSeriesCV 训练并滚动评估日内模型。把建模频率从「日」提到「分钟」,不是简单换个时间轴,而是进入完全不同的数据与噪声结构:
| 维度 | 日频 | 分钟级 |
|---|---|---|
| 样本量 | 每只票每年 ~252 行 | 每只票每天 ~390 行(美股) |
| 信噪比 | 相对较高 | 微观结构噪声主导 |
| 关键特征 | 动量、波动、基本面 | 成交档位、订单簿不平衡、买卖压力 |
| 交易成本 | 佣金为主 | 价差、冲击、机会成本为主 |
| 持有期 | 数日~数月 | 数分钟~数小时 |
日内样本量爆炸是双刃剑:一方面样本多到可以训复杂模型,另一方面噪声也成比例放大,「虚假显著」比比皆是。一根 1 分钟 bar 的预测 IC 即使是 0.05,也可能完全是噪声。
💡 核心心法:日内建模最大的陷阱是「样本多就觉得信号真」。样本量大让模型更容易过拟合到噪声——你必须用更严格的滚动评估、更短的训练-测试间隔、更警惕的 IC 解读,才能在日内噪声里淘到真信号。
notebook 10_intraday_features.ipynb 从 AlgoSeek NASDAQ100 的 Trade and Quote parquet 读取分钟级数据。原始列非常细,先做大量列重命名与筛选:
keep = ['firsttradeprice', 'hightradeprice', 'lowtradeprice', 'lasttradeprice', 'minspread', 'maxspread', 'volumeweightprice', 'nbboquotecount', 'tradeatbid', 'tradeatbidmid', 'tradeatmid', 'tradeatmidask', 'tradeatask', 'volume', 'totaltrades', 'finravolume', 'finravolumeweightprice', 'uptickvolume', 'downtickvolume', 'repeatuptickvolume', 'repeatdowntickvolume', 'tradetomidvolweight', 'tradetomidvolweightrelative'] columns = {'volumeweightprice': 'price', 'finravolume': 'fvolume', 'uptickvolume': 'up', 'downtickvolume': 'down', 'repeatuptickvolume': 'rup', 'repeatdowntickvolume': 'rdown', 'firsttradeprice': 'first', 'hightradeprice': 'high', 'lowtradeprice': 'low', 'lasttradeprice': 'last', 'nbboquotecount': 'nbbo', 'totaltrades': 'ntr'}
值得注意的特征类别:
tradeatbid / tradeatbidmid / tradeatmid / tradeatmidask / tradeatask——成交发生在买卖盘的哪个位置,反映真实的买卖压力,这是日频数据看不到的微观结构信息。uptickvolume / downtickvolume / repeatuptickvolume / repeatdowntickvolume——上涨 tick 与下跌 tick 的成交量,经典的订单流不平衡指标。minspread / maxspread——流动性度量,价差扩大的时段通常波动也大。清洗后构造多档前瞻收益作标签,以及多档滞后收益作特征:
# notebook 11_intraday_model.ipynb dates = data.index.get_level_values('date_time').date for i in range(1, 11): data[f'ret{i}min'] = data.groupby(['ticker', dates])[f'ret{i}min'].shift() data = data.dropna(subset=['fwd1min'])
关键细节是 groupby(['ticker', dates]):shift 必须按「股票 + 交易日」分组,绝对不能跨日 shift。否则昨天收盘 bar 的「未来 1 分钟收益」会指向今天开盘——这是前视偏差,且没有任何金融含义。日期分组保证「前瞻收益只在未来、滞后收益只在过去」。
| 特征类型 | 含义 |
|---|---|
ret1min~ret10min(滞后) |
过去 1~10 分钟的累计收益 |
fwd1min |
未来 1 分钟收益(标签) |
up / down / rup / rdown |
成交量订单流方向 |
notebook 11_intraday_model.ipynb 用 LightGBM 做回归,MultipleTimeSeriesCV 做严格滚动评估:
class MultipleTimeSeriesCV: """按 symbol + date 分组生成训练/测试折,purge 掉重叠样本""" def __init__(self, n_splits=3, train_period_length=126, test_period_length=21, lookahead=None, date_idx='date'): ... # 训练评估 for lookahead in [1, 5]: for train_idx, test_idx in cv.split(X): train_set = lgb.Dataset(X.loc[train_idx], y.loc[train_idx, label]) model = lgb.train(params, train_set) y_pred = model.predict(X.loc[test_idx]) ic = spearmanr(y.loc[test_idx, label], y_pred).correlation
MultipleTimeSeriesCV 在 lookahead 上 purge 掉与测试段标签重叠的训练样本——这是高频日内建模的关键,因为 1 分钟前瞻收益会让相邻样本的标签高度重叠,不做 purge 就会严重泄漏。
⚠️ purge 在日内尤其关键:日频标签 1 天一个,样本间标签独立;分钟级 1 分钟一个标签,前后 10 个样本的标签高度重叠。如果不 purge,训练集尾巴和测试集头部的标签共享原始数据,等于偷看——这是日内建模最隐蔽也最致命的 bug。
日内模型的样本外 IC 通常远低于样本内,而且衰减极快:
这就是为什么高频策略是「工业游戏」——单个量化在笔记本上很难稳定盈利,因为信号弱、成本高、容量小,需要极低延迟基础设施与精密的成本模型。本节的目标是让你理解日内建模的工程流程,而非给你一套能赚钱的高频策略。
💡 诚实的工作流:训练完一定先看样本外 IC 的分布(不是均值)——如果某些折 IC 是负的,说明信号不稳定;如果方差极大,说明对训练段选择敏感。把 IC 的不确定性(而非点估计)报出来,才是日内建模负责任的态度。
tradeatbid/mid/ask 反映买卖压力,up/down 量反映订单流,这是日频看不到的微观结构信息。groupby(['ticker', date]),跨日 shift 是前视偏差。MultipleTimeSeriesCV 必须按 lookahead purge,否则训练偷看测试。下一章,我们转向无监督学习与深度学习强化学习——从 PCA 提取隐性风险因子开始,到 DQN 训练强化学习交易 Agent,涵盖金融 ML 的另一片高阶天地。