🔗 开源项目地址:https://github.com/zer0quant/zer0factor

这是因子投研自动化系列的第一篇。前面两篇文章,我们已经把本地股票数据库搭起来了;从这篇开始,进入更有意思的一步:怎么从研报出发,自动生成可运行、可验证的因子代码。

前两篇文章主要在做一件事:搭建本地股票数据底座

到目前为止,这套本地数据系统已经支持:

  • 股票基础信息;
  • 交易日历;
  • 日线行情;
  • 前复权 / 后复权行情;
  • 本地 Parquet 存储;
  • DuckDB 查询。

有了这些基础数据之后,下一步自然就是做研究。

量化研究里,一个很经典的方向就是动量因子。市场里经常听到有人说“追涨杀跌”,背后其实就有一点动量效应的影子:

过去一段时间表现强的股票,未来一段时间可能继续表现更强。

当然,真实研究不会这么粗糙。一个“动量”主题下面,可以拆出很多不同口径的因子:收益率动量、成交量动量、残差动量、风险调整后的动量、不同窗口期的动量等等。

这篇文章,我就以一篇研报为例,试着把“读研报、提因子、写代码、验证因子”这条链路跑一遍。

研报选的是这篇:

【国信金工】动量类因子全解析

我的问题很直接:

都 2026 年了,LLM 已经这么强了,能不能让 AI 直接从研报里提取因子,并生成可运行的因子代码?

一、传统方式:研究员一个个手工复现

如果按以前的工作流,大概是这样:

  1. 研究员读研报;
  2. 手工整理因子定义;
  3. 把公式翻译成代码;
  4. 跑一遍数据验证;
  5. 发现字段、窗口、复权、截面处理有问题;
  6. 回头改代码;
  7. 再跑一遍。

这个流程当然可控,但也很慢。

尤其是研报里如果有几十个因子,很多工作其实是重复劳动。比如:

  • 从正文里提取因子名称;
  • 判断因子需要哪些字段;
  • 识别窗口期参数;
  • 把公式翻译成代码;
  • 写基本的样例和测试;
  • 检查因子值是否全空、是否异常、是否能跑通。

这些事情不一定都应该交给 AI 完全自动完成,但至少值得让 AI 参与进来。

于是我先找了一下有没有现成项目能做这件事。

Claude 给我推荐了一个项目:RDAgent

二、先试 RDAgent:它确实能跑,但很重

RDAgent 的思路挺吸引人:给它一篇金融研报,它可以尝试从里面提取因子,然后生成 Qlib 风格的因子代码,并自动运行验证。

听起来很美好,于是我开始安装。

但实际跑起来之前,光是安装和环境配置就踩了不少坑。

真正麻烦的是环境准备。RDAgent 本身依赖不少,跑因子任务时又会自动拉起 Qlib Docker 镜像,所以安装、构建和初始化都要花不少时间。

但 Docker 镜像构建也要等很久,国内网络偶尔还会卡住。中间又是换镜像源,又是换 pip 源,总之过程不算丝滑。

这个安装过程本身就能单独写一篇文章,今天先不展开。

折腾了很久,总算跑起来之后,我把研报 PDF 放进 RDAgent 的 workspace,然后执行命令:

rdagent fin_factor_report --report-folder=/data/rdagent-start

接下来,RDAgent 就开始尝试自动从研报里提取因子。

三、RDAgent 的整体流程:先提取摘要,再生成公式,再写代码

我观察了一下它的运行过程,整体链路大概是这样:

  1. 从 PDF 中提取研报内容;
  2. 生成研报摘要;
  3. 从摘要里提取候选因子;
  4. 结合 Qlib 的因子规范生成公式、描述和参数;
  5. 让大模型生成因子代码;
  6. 在 Qlib 环境里运行;
  7. 检查代码是否能执行,以及因子值是否合理;
  8. 如果失败,再重新生成代码并迭代。

第一步,它会先从研报里抽出一份总结:

接着,它会基于这些总结生成因子的文本描述、公式和参数。前端展示出来大概是这样:

然后再根据公式让大模型生成代码:

生成代码之后,RDAgent 会把因子放到 Qlib 里运行,并对因子值做一些基本检测。

如果中间失败,它会重新生成因子代码,继续尝试,直到成功或者达到迭代上限。

从设计上说,这条链路是完整的。它不是只让大模型“写一段代码”,而是有提取、生成、运行、检测、修复的闭环。

但真正跑起来之后,我很快遇到了另一个问题:太慢了

四、全自动能跑,但代价不小

这篇研报里大概有 40 多个因子。

我一开始也想直接让 RDAgent 全部跑完,但很快发现这个流程耗时太长。为了先验证链路,我改成只跑 5 个因子,并设置 10 轮迭代。

最后结果是:5 个因子里,有 1 个没有生成成功。

我又让 Claude Code 帮我做了一下耗时分析:

结果大概是:5 个因子跑了 1.5 个小时左右

我用的模型是 DeepSeek V4 Pro,token 成本其实不高,大概花了 3 块钱左右。真正的问题不是 token 贵,而是整个框架的执行效率偏低。

如果只是偶尔跑一次,这个成本可以接受。

但如果我想把它变成一个高频使用的研究工作流,这个速度就有点难受了。

更重要的是,我开始意识到一件事:

从研报生成因子,不一定非要追求全自动。

全自动当然看起来很省心,但研究场景里,很多关键步骤其实需要人工判断。比如:

  • 研报里的因子定义有没有歧义;
  • 大模型提取的公式是否符合原文;
  • 参数窗口是不是理解错了;
  • 代码生成是否偷换了数据口径;
  • 因子是否依赖未来数据;
  • 因子值虽然能跑,但逻辑是否可信。

这些地方,如果全部交给自动迭代,最后可能会出现一个很尴尬的结果:

代码跑通了,但你不确定它到底是不是你想要的因子。

所以我后面改变了思路。

五、我更想要的是“半自动”:AI 生成,人来卡关键节点

我问了一下 AI,它也给了一个类似判断:

我觉得更适合个人研究者的方式,不是把整条链路完全交给自动化系统,而是做成一个半自动工作流

  • AI 负责从研报里提取候选因子;
  • AI 负责生成因子摘要、公式和字段依赖;
  • 人负责 review 因子定义;
  • AI 再根据确认后的定义生成代码;
  • 人和测试一起检查代码是否可信;
  • 最后把因子沉淀成标准化模块。

这样做会慢一点吗?

单个步骤看起来可能需要人介入,但整体反而更快。因为人工 review 可以在早期拦住错误,避免后面在代码执行阶段反复失败、反复修。

这也是我后来决定自己做一个 skill 的原因。

六、用 skill-creator 做一个“从研报到因子”的工作流

既然 RDAgent 的全自动流程太重,我就想把里面有价值的部分拆出来,做成一个更适合自己使用的 skill。

于是我用 /skill-creator:skill-creator 开始创建一个新 skill。

这个 skill 的目标不是“替代研究员”,而是把重复、机械、容易出错的部分标准化:

  • 从研报中提取候选因子;
  • 为每个因子生成结构化摘要;
  • 明确输入字段、窗口参数和计算逻辑;
  • 在生成代码前让人确认;
  • 按统一规范生成因子代码;
  • 输出执行记录和后续检查建议。

做这个过程中,我又看到了另一个项目:QuantaAlpha

它也有从研究报告里提取因子的逻辑,整体思路和 RDAgent 有相似之处,但它在因子生成之后多了一些质量检测和相关性检测。

这部分对我很有启发。

因为从研报里生成因子,最容易掉进一个坑:只关注“代码能不能跑”,但忽略“因子值是否合理”“因子之间是否高度重复”“有没有明显异常”。

所以我决定融合 RDAgent 和 QuantaAlpha 的思路,重新设计一套更适合自己的流程。

七、关键问题:不能再只适配 Qlib

RDAgent 和 QuantaAlpha 这类项目,默认都会围绕 Qlib 的因子规范来设计。

这很合理。Qlib 是一个成熟的量化研究框架,生态也比较完整。

但我的情况不太一样。

前两篇文章里,我已经手搓了一套本地数据系统:zer0share。它的数据存储、字段命名、查询方式,都不是原生 Qlib 结构。

如果继续完全按 Qlib 的因子函数规范来生成代码,那么生成出来的因子就很难直接接到我的本地数据系统上。

所以我需要先做一件事:

基于 zer0share 的数据结构,制定一套标准化的因子规范。

我认为这里有几个点很重要。

第一,因子逻辑要和数据源解耦

因子代码不应该直接写死“去哪里读 Parquet”“怎么连 DuckDB”“字段从哪个目录来”。这些事情应该由数据适配层负责。因子本身只关心输入字段和计算逻辑。

否则以后只要数据源变了,因子代码就要跟着改。

第二,每个因子要声明最小依赖窗口

比如一个 20 日动量因子,至少需要 20 条历史数据才能计算;如果又叠加波动率调整,可能还需要更长窗口。

这个窗口信息必须显式写出来,否则后面做批量计算、回测、缺失值处理时会很混乱。

第三,因子要有结构化元数据

不只是代码,还要记录:

  • 因子名称;
  • 因子类别;
  • 输入字段;
  • 参数;
  • 输出含义;
  • 计算频率;
  • 是否需要复权价格;
  • 是否可能引入未来函数;
  • 适用的数据范围。

最后设计出来的因子规范大概是这样:

这一步很关键。

因为只有先把因子规范定下来,AI 生成的代码才不会变成一堆风格各异、难以维护的脚本。

八、真正跑一遍:从研报提取到代码生成

规范确定之后,我开始实现这个 skill,并尝试打通整个流程。

实现完成后,我把这个 skill 装到 Codex 里,开始用它从研报里生成因子。

这次我还是先拿 5 个因子做测试。

和 RDAgent 不同的是,这个流程里我保留了人工 review 节点:

  1. AI 先从研报里提取因子摘要;
  2. 我确认摘要是否符合原文;
  3. AI 再生成因子代码;
  4. 运行基础检查;
  5. 最后输出执行记录。

实际体验下来,这种方式效率高很多。

生成出来的因子代码大概是这样:

这里最关键的变化是:AI 不再试图一口气从 PDF 跑到最终代码,而是把中间结果显式暴露出来,让人可以在关键节点做判断。

这对因子研究很重要。

因为研究不是单纯的代码生成。代码能跑,只是第一步;因子定义有没有被正确理解,才是更核心的问题。

九、这次最大的收获:不是全自动,而是可控自动化

这次折腾下来,我最大的感受是:

AI 做因子投研,最重要的不是全自动,而是可控自动化。

全自动系统很有吸引力,但在研究场景里,它有一个天然问题:你很难知道中间到底错在哪里。

所以我更倾向于把 AI 放在两个位置:

第一,让它做重复劳动。比如提取候选因子、整理字段依赖、生成样板代码、补执行记录。

第二,让它做辅助检查。比如检查是否有未来函数风险、输入字段是否缺失、窗口期是否足够、因子值是否明显异常。

而真正的关键节点,仍然应该让人确认。

这样做出来的系统,可能没有“全自动生成 40 个因子”听起来震撼,但它更适合长期使用。

十、写在最后

到这里,我从“本地数据系统”往“因子投研系统”迈出了第一步。

目前已经完成的是:

  • 调研并跑通 RDAgent;
  • 观察它从研报提取因子、生成代码、自动验证的流程;
  • 分析全自动方案的效率和可控性问题;
  • 参考 QuantaAlpha 的质量检测思路;
  • 设计一套适配 zer0share 本地数据的因子规范;
  • 实现一个从研报到因子代码的 Codex skill;
  • 开源 zer0factor 项目。

项目地址在这里:

https://github.com/zer0quant/zer0factor

后面我会继续沿着这条线往下做:

  • 接入因子质量检测;
  • 接入因子评估;
  • 接入本地回测;
  • 最终把“数据底座 → 因子生成 → 因子验证 → 策略研究”这条链路串起来。

如果说前两篇文章是在搭数据地基,那么这篇文章开始,就是在地基上搭第一层研究工作流。

参考链接

如果这篇文章对你有帮助

  • ⭐ Star 一下项目:https://github.com/zer0quant/zer0factor
  • 也可以看看前面的本地数据系统项目:https://github.com/zer0coldai/zer0share
  • 关注公众号,后面继续更新因子投研自动化、AI agent 和本地量化系统

我们下篇见。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐