这篇是系列的收尾实战——从一篇量化研报出发,把公式转化为因子脚本、配置 YAML、跑通 Dashboard、生成报告。学完这篇,你就掌握了”从想法到可交付成果”的完整闭环。
导言
假设你读到了一篇中信建投的研报《基于高频非流动性的 A 股选股因子》,想把里面的 ILLIQ 因子复现到 Betalens 里。
完整流程是:
1 | 研报公式 → Python 计算脚本 → YAML 配置 → Dashboard 发现 → 跑回测 → 绩效报告 |
这篇以 ILLIQ_v2 为例,走一遍全流程。
步骤 1:理解研报公式
研报中的 ILLIQ_v2 公式:
$$ILLIQ_v2 = \frac{1}{D} \sum_{d=1}^{D} \frac{|r_d|}{VOL_d}$$
其中:
- $r_d$:第 $d$ 日收益率(%)
- $VOL_d$:第 $d$ 日成交额(万元)
- $D$:月度窗口(通常 20 个交易日)
实现思路:对每只股票,计算过去 20 个交易日的日收益率绝对值之和 / 日成交额之和。
步骤 2:写因子计算脚本
在 betalens-factor/ 下创建目录结构:
1 | betalens-factor/ |
编写 factor_ILLIQ_v2.py
1 | """ |
编写 factor_ILLIQ_v2.yaml
1 | meta: |
步骤 3:在 Dashboard 里发现并运行
重启 Dashboard(或刷新因子列表):
1 | # 在 betalens 仓库根目录 |
打开 http://127.0.0.1:5173,在”截面因子”页面找到 citic_hf_behavior/ILLIQ_v2。
点击”运行”,等待回测完成。下载 Excel 报告,查看 ICIR、分组收益、净值曲线。
步骤 4:调试与迭代
如果报告结果不理想,从以下角度排查:
因子值全是 NaN
1 | # 检查输入数据是否正确 |
ICIR 太低
- 检查
direction是否设反了(positivevsnegative) - 检查是否做了行业中性化(
use_industry: true) - 尝试增大/减小
window_days
收益和 IC 不一致
- IC 衡量的是”预测能力”,收益衡量的是”实际交易结果”。
- 两者可能出现背离(IC 强但收益差 → 说明交易成本太高或整数手约束影响大)。
步骤 5:用 factor-forge skill 自动化(可选)
如果研报是 PDF/DOCX 格式,可以用 factor-forge skill 自动抽取公式并生成脚本:
1 | # 在 Cursor 里输入: |
factor-forge 会根据研报内容生成因子 YAML 和 Python 脚本的初稿,你再根据 Betalens 的接口规范做微调。
开发者侧:因子脚本的约束
回顾 Betalens 因子脚本的关键约定:
- import 时不跑回测、不写文件:脚本只声明算子,
compute函数里不能直接调用BacktestBase。 - 暴露
spec、FactorPipeline、build_spec:供 Dashboard 的FactorPipeline.run()动态调用。 compute参数名匹配factor_spec.inputs的 key:inputs里的 key 必须和compute的参数名一致。- CLI 只支持
--config PATH:不要加其他命令行参数。
常见错误
1. YAML 中 inputs key 和 Python 参数名不一致
1 | # YAML |
2. direction 设错
1 | # ILLIQ 是"越低越好",设成 positive 会导致高流动性股票被做空 |
3. 输出没有对齐调仓日
compute 函数返回的 DataFrame 的 index 必须和 run.start_date 到 run.end_date 的调仓日对齐。FactorPipeline 会自动处理这个对齐,但如果你手动调用 compute,需要注意。
延伸阅读
- Betalens 新手系列 · 12:参数扫描与滚动窗口——如何优化因子参数。
- Betalens 新手系列 · 13:因子库巡礼——现有因子家族参考。
- Betalens 新手系列 · 19:稳健性检验——如何验证因子稳健性。
docs/guide/factor-pipeline.rst——因子 YAML 规范。