一句话版:教科书给你方向,测试期 IC 是 −0.0074(负的,等于反向信号); 把方向交给数据,同一批因子变成 +0.0332。
我做了一件之前一直想做但没做的事:把基本面塞进 qlib 的高频价量里,混成一个趋势分, 然后把它变成能下注的组合,含换手、成本、基线对照。
结果比预想的诚实,也比预想的难看——先给结论,再讲过程。
一、先回答三个问题
① 还要不要用 qlib?
要。但只让它干一半的活:价量高频、标签、回测/组合模拟留在 qlib; 基本面不进 qlib 的 bin,改成外置的 PIT 财务库(parquet + 披露日对齐); 不重训 LightGBM,用「标准化 + 自动定向 + 线性加权」合成。
换框架的收益是负的。这个仓库里已经有 18 条 qlib 踩坑记录(bin 对齐、复权因子、 col_set 必须是元组、Windows 下 D.features 会无限 fork……),换个框架等于全部重踩一遍, 换到的还是同一个信号。
② 框架怎么搭?
四层:
数据层 qlib 价量面板 + 东财 F10 三个接口(财务 / 估值 / 业绩预告)
对齐层 按「披露日 ≤ t」as-of 对齐成日频面板,杜绝前视
打分层 winsorize → 行业中性化 → z-score → 限幅 → 分域加权
验证层 因子级 IC → 自动定向 → 权重网格 → 一次性测试期
③ 选哪些指标、参数怎么调?
45 个因子(价量 30 + 基本面 19)。方向不靠教科书,靠训练期 RankIC 的符号; 筛选门槛是 |IC| ≥ 0.008 且 |t| ≥ 2,留下 34 个。跨域权重只在验证期选,测试期只跑一次。
二、最贵的坑:基本面数据源,比想象中便宜
基本面数据的难点从来不是「哪里有」,而是能不能拿到带披露日的版本——不然就是前视偏差。
我实测了三个东方财富的公开接口,全部可用,而且免费:
| 接口 | 拿到什么 | 关键字段 |
|---|---|---|
| F10 财务指标 | 每期财报 165 个字段 | REPORT_DATE + NOTICE_DATE(披露日) |
| 个股估值分析 | 日频 PE/PB/PS/PEG + 行业名 | BOARD_NAME(行业中性化要用) |
| 业绩预告 | 预增幅度 + 公告日 | ADD_AMP_LOWER/UPPER |
有了 NOTICE_DATE,PIT 就是一行 merge_asof:
想知道 2023 年 5 月 10 日你当时能知道什么,就取披露日 ≤ 这一天的那一期财报。
637 只股票、3117 个交易日,一次全量抓取 390 秒:财务 35,866 行、估值 1,260,947 行、预告 14,128 行。 财务类因子覆盖率 82%~95%,估值类从 2018 年才有数据(三年分位需要 250 日最小窗口)。
三、45 个因子,四个域
| 域 | 因子 | 数据源 |
|---|---|---|
| 价量 30 个 | 动量 / 反转 / 波动 / 均线 / RSI / 量能 | qlib 现成面板 |
| 估值 | PE·PB·PS 三年分位、绝对估值、市值 | 东财估值 |
| 成长 | 营收与净利同比环比、剪刀差 | 东财 F10 |
| 质量 | ROE、ROIC、毛利率、负债率、现金流含金量 | 东财 F10 |
| 边际变化 | ROE 同比、每股净资产同比 | 东财 F10 |
| 事件 | 业绩预告增幅、预告新鲜度 | 东财预告 |
两个容易被忽略的设计:
估值用分位,不用绝对值。 PE=20 在白酒里是常态,在银行里是高位,绝对值没法比, 三年滚动分位才能跨行业比较。
基本面必须放「边际变化」。 只放水平值(ROE 多高、毛利率多高),高分股永远是高分股, 分数一年不动;变化量(ROE 同比、每股净资产同比)才带趋势信息。
四、方向定错了,整块信号就是反的
这是整件事里最贵的一个教训。
我一开始按教科书给方向:动量正向、反转负向、低波动正向、低估值正向。跑完一看——
| 变体 | 训练 IC | 验证 IC | 测试 IC |
|---|---|---|---|
| 纯价量(教科书先验方向) | −0.0099 | −0.0138 | −0.0074 |
| 纯价量(训练期自动定向) | +0.0372 | +0.0338 | +0.0332 |
同一批因子、同一份数据,方向一改,信号从负的变成正的。
45 个因子里 18 个先验方向被数据推翻。最有代表性的是 20 日动量:在 5 日的持有期上, 它的 IC 是 −0.035(t = −9.6)——涨得越猛,未来 5 天越差。A 股短周期是「短期动量 + 中期反转」, 而教科书默认你买的是中期动量。
所以参数的第一条规则是:方向由训练期 RankIC 的符号决定,不许拍脑袋。 第二条规则是门槛:|IC| ≥ 0.008 且 |t| ≥ 2,不达标的因子直接扔掉,别让噪声混进加权。
顺带一句:基本面块的 IC 是正的(测试期 +0.0093,t = 3.1),但比价量块弱一半以上,而且衰减更快 (训练 +0.0221 → 测试 +0.0093)。这跟直觉相反——很多人以为「基本面更稳」, 数据说的是:基本面在 A 股更稳地没有超额。
五、基本面该给多少权重?
验证期最优解把基本面给到 0.4,测试期最优却在 0.2~0.3。 选型不可外推,这仓库的老毛病又犯了一次。
所以我取两段曲线的共同高台区:基本面 0.2~0.4。
| 权重(价量/基本面) | 验证 IC | 测试 IC | 测试 IR |
|---|---|---|---|
| 1.0 / 0.0 | +0.0361 | +0.0344 | +0.309 |
| 0.8 / 0.2 | +0.0368 | +0.0341 | +0.309 |
| 0.7 / 0.3 | +0.0364 | +0.0331 | +0.304 |
| 0.5 / 0.5 | +0.0336 | +0.0283 | +0.275 |
| 0.4 / 0.6 | +0.0308 | +0.0248 | +0.250 |
建议 0.65 / 0.30 / 0.05(价量 / 基本面 / 事件)。不赌任何一段的极值,落在两段都靠前的地方。
六、IC 好看 ≠ 能赚钱
这里有个必须说的事实。测试期按分数分五档,看未来 20 日平均收益:
| 档位 | Q1 | Q2 | Q3 | Q4 | Q5 |
|---|---|---|---|---|---|
| 平均收益 | +0.63% | +0.81% | +0.86% | +0.79% | +0.61% |
不单调。 最高分档比中间档还差。IC 稳(+0.028,t = 11.3), 但「挑最高的那一档」拿不到超额——IC 的信息分布在中段,不在极端。
这直接决定了这套框架的定位:它是个打分/过滤信号,不是选股器。
七、变成策略:换手才是胜负手
参数搜索严格按协议来:K × 调仓频率 × 行业上限 × 权重方式,共 96 组,只用验证期 2020-2022 跑, 选出 K=50 / 每 40 个交易日调仓 / 每行业≤3 只 / 等权,然后测试期只跑一次。
成本按仓库老口径:买入 0.05%、卖出 0.15%、单笔最低 5 元、账户 100 万; 停牌不可交易、收盘涨停买不进;信号 T 日收盘出、T+1 日收盘成交。
测试期 2023-01 ~ 2026-10 的结果:
| 策略 | 年化 | 超额年化 | MDD | 换手/年 | 成本/年 |
|---|---|---|---|---|---|
| 策略(验证期选参) | +5.87% | +5.34% | −28.97% | 4.12 | 1.05pct |
| 同上,零成本对照 | +6.89% | +6.36% | −28.40% | 4.12 | 0 |
| 默认 top20 月调 | +7.05% | +6.90% | −33.69% | 8.87 | 2.05pct |
| 纯价量分 top20 月调 | −0.66% | −1.02% | −35.33% | 9.49 | 2.03pct |
| 纯基本面分 top20 月调 | −3.33% | −3.45% | −42.54% | 3.02 | 0.51pct |
| 池内等权 300 只 | +3.00% | +2.25% | −25.09% | 0 | 0 |
| 沪深300 买入持有 | +0.65% | 0 | −24.80% | 0 | 0 |
三件事必须一起看:
第一,测试期最高的那个不能用。 top20 月调 +7.05% 是全场最高, 但它在训练期是 −4.02%、验证期 −5.51%、全区间 −3.54%——只在测试期好看的配置不能上线。 验证期选出来的那套是训练 +1.47% / 验证 +1.24% / 测试 +5.87% / 全区间 +2.10%,三段都是正的。 这才是「分数能变钱」的最低证据。
第二,换手比因子更决定生死。 每 5 个交易日调仓的三个配置全部亏损(成本 4.34.7pct/年), 每 10 日勉强打平(+0.7%+1.2%),只有 ≥20 日才转正。
所以「基本面该不该加」这个问题,一半的答案是「别乱换手」。
第三,纯价量、纯基本面单独用都不行,混起来才行。 −0.66% 与 −3.33%,混起来 +5.87%。 基本面在组合里不是自己赚钱的角色,是改选股排序、砍掉价量信号里的坑。 这恰好是我最初设想「加权求和共同判断趋势」时没想到的收益来源。
八、诚实的结论
分期体检(同一套参数,只换时间窗):
| 区间 | 年化 | IR | MDD |
|---|---|---|---|
| 训练 2016-2019 | +1.47% | −0.40 | −33.95% |
| 验证 2020-2022 | +1.24% | +0.39 | −44.76% |
| 测试 2023-2026 | +5.87% | +0.68 | −28.97% |
| 全区间 2016-2026 | +2.10% | +0.11 | −48.16% |
四条必须记住的:
- +5.87% 不是预期收益。 超额高度集中在 2025:分年 2023 −8.3%、2024 +6.8%、 2025 +35.0%、2026 −5.9%。两年是亏的。
- 回撤仍然很大:测试期 −29%,全区间 −48%。年化 26% 配 3048% 的回撤, 这个风险收益比只够当组合里的一小块卫星仓,不适合当主仓。
- 这是「一次性测试期」的结果,而且我已经看过测试期数字了,任何后续调整都带污染。 想再用,必须换一段全新的样本外。
- 没做的事:波动率目标、行业中性权重、分歧度做减仓触发器、 接入实盘组合端到端验证。
如果只带走一句话:混合基本面和高频价量是对的,但真正决定成败的不是「加不加基本面」, 而是方向对不对和换手多不多。前者错了信号是反的,后者错了信号被成本吃掉。
*本文所有数字来自一次完整可复现的运行:qlib 本地行情(637 只沪深300 时点成分,2014-01-02 ~ 2026-10-30)
- 东方财富公开财务接口。测试期只跑一次,参数只在验证期选。*
完整版(含方法四步与数据口径)见原文链接。