我拿一篇 45 页的华泰动量研报试了试 EVO:从45页研报到可运行策略

我是cyy我是cyy··14 浏览

先把不太好看的结果放前面:这次回测没有赚钱。

我用 EVO 复现的是华泰金工《多因子 4:华泰单因子测试之动量类因子》。最后一版总收益 -3.28%,年化 -0.70%,夏普 -0.67。没有高收益曲线,也没有一个可以直接拿去实盘的参数组合。

但这篇研报我确实从头跑到了尾:上传 45 页 PDF,载入研究上下文,让 EVO 提取 13 个动量因子,实际创建其中两条,跑完因子有效性分析,再生成策略、回测和调优,最后留下 2 个因子、1 个策略、4 个策略草稿。

接下来我分享一下:EVO 到底是什么,我从哪里开始,每一步输入了什么、页面出现了什么,以及我怎么判断该继续还是回头检查。

EVO 到底是什么

PandaAI 官网把自己定义为 AI 时代的 Trading OS,目标是让交易想法快速变成可验证的策略。这个说法比较大。就我这次实际用下来的感受,EVO 更像一个会动手的量化研究 Agent 工作台

它和普通聊天框最大的区别是:我说完要求后,它不只回复一段文字,还会在工作区里真的留下东西。

  • PDF 放在“资源”里,作为研究输入;
  • 公式和预处理落成“因子作品”,可以运行有效性分析;
  • 选股、调仓和成本规则落成“策略作品”,可以直接回测;
  • 每次修改策略会留下新草稿,旧结果不会被新结果覆盖;
  • 同一个策略里还能看定义、业绩、风险、适应性、归因和日志。

所以它做的不是“聊聊这篇研报”,而是把对话里的研究意图,变成可以运行和回看的研究对象。

工作区左边有“作品、资源、环境”三个入口。我的使用顺序基本是:先去资源里载入研报,再回作品里看 EVO 创建的因子和策略。中间区域会随着对象变化:打开因子时看定义、产出、有效性和稳健性;打开策略时看定义、业绩、风险、适应性和归因。研究助手负责理解任务并推进这些操作。

下面这张图是我全部跑完后的状态。左侧“全部 3”不是三段聊天,而是三个真实作品:两条因子和一个策略。中间打开的是策略定义,顶部还能切换草稿。

image.png

图 1:本次实际生成的 exp_wgt_return_6mwgt_return_1m,以及策略 htsc_momentum_reversal_1m

这次到底做什么

原研报研究的是 2005—2016 年的全 A 股,做的是月频动量因子测试。EVO 这次实际能直接跑的是平台当前可用数据和近 5 年样本。股票池、时间段、数据源不一致,IC 和收益不可能拿来一一对数。

所以我没有把“复现出研报里的收益”当成目标。我验收的是下面这条链路能不能走通:

上传研报 → 读出研究口径 → 创建因子 → 配置分析
→ 看懂因子方向 → 生成策略 → 跑出基线 → 派生草稿调优

这一步看起来像是在降低标准,其实不是。如果连运行口径都不同,却硬要求结果一致,最后很容易为了对数字去调参数。我的标准是:流程要完整,每一步要有产物,替换了什么口径要能讲清楚;效果好不好,照实记录。

第 1 步:把研报载入研究上下文

我先进入左侧“资源”,在 研究报告 文件夹中找到 PDF(内测群里发的,我不便发在这里,大家应该上网可以搜到):

【华泰金工】多因子4:华泰单因子测试之动量类因子20161220.pdf

文件约 3.8 MB,共 45 页。点击文件后,中间出现 PDF 预览,研究助手一侧显示已经载入这份文件作为研究上下文。看到这两个反馈后,我才开始下任务。

这个确认动作我觉得不能省。资源列表里有文件,只能说明上传过;打开预览并看到“已载入上下文”,才说明接下来的回答确实会基于它。否则助手即使给出一个听起来正确的动量策略,我也没办法确认它有没有真的读当前研报。

如果你照着做,这一步至少确认三件事:

  1. 文件名确实是目标研报,不是同目录里的另一版;
  2. PDF 在中间能正常预览,不是只有一个空文件条目;
  3. 助手明确提示当前文件已经进入研究上下文。

第 2 步:不要只说“帮我复现这篇研报”

我一开始最容易犯的错误,就是把“复现”想得很具体,但只给 EVO 两三个字。对人来说,复现可能默认包括公式、样本、预处理、分组、策略和回测;对 Agent 来说,它也可能只是帮我总结全文。

这次我最后使用的任务描述大致如下,可以直接作为起点:

请结合当前载入的研报,完整复现研报中的研究流程,不要只做摘要。

请先提取并列出:
1. 因子定义和经济含义;
2. 样本区间、股票池、频率和预测周期;
3. 缺失值、去极值、标准化和中性化方法;
4. 因子方向、分组方式、调仓规则和组合构建方式;
5. 回测和评价指标。

确认上述口径后,再在 EVO 中依次创建因子、完成因子分析、
生成策略并回测。

本次以流程跑通、每一步留下可检查的产物为成功标准,
不要求收益率、IC 和夏普等数值与原文完全一致。

如果平台当前数据或能力不能使用原文口径,请同时列出:
原文口径、当前替代口径、替代原因、对结果可比性的影响。

这里面最管用的是三句话:先列口径再创建、不要只做摘要、口径变化要单独说明。没有这几句,任务很容易从“复现研究”慢慢滑成“帮我找一个动量因子”。

EVO 随后分三次读取 PDF:1—22 页22—40 页40—45 页。最后梳理出 13 个动量类因子,并从 exp_wgt_return_6m 开始。

我没有让它一次性创建 13 条。这里是我第一次真正感觉到“少做一点反而更快”:如果第一轮同时建 13 条,任何一处窗口或预处理不对,都不知道要从哪一条查。我先用 exp_wgt_return_6m 确认中期动量的分析链路,再用 wgt_return_1m 继续走到策略。

拿到研报提取结果后,不要急着点运行。我当时先核对了这些内容:报告名称和页数是否正确、样本是不是 2005—2016、股票池是不是全 A、是否识别出动量方向、选中的因子是否真的在研报里。只有这几个基本事实对上,后面的自动创建才有意义。

第 3 步:因子创建后,别只看代码能不能跑

第一条因子 exp_wgt_return_6m 是为了确认完整的因子分析流程。它跑完后,我又创建了短周期的 wgt_return_1m,后面的策略主要基于第二条。

第一条并不是跑完就被我略过去了。它的 Rank IC 均值是 -0.0358,IC 均值 -0.0089,ICIR -0.08,Newey-West t 值 -1.44,p-value 0.151,覆盖度 87.11%,换手率 6.29%,页面判定稳健性未通过。

这个结果对“选一个强因子”没有太大帮助,但对测试流程是有用的:因子定义、预处理、元数据、任务提交和结果页都能连起来。我没有为了救这条结果马上改参数,而是顺着研报继续做 wgt_return_1m。这样第二条因子既能复用已经确认过的分析流程,也能测试短周期反转方向能不能继续变成策略。

因子作品创建后,真正影响结果的内容分成两类:一类是因子定义本身,另一类是运行元数据和预处理。公式写对了,后面这部分配错,结果照样没有可比性。

我在 wgt_return_1m 上最终使用的是:

配置项 本次设置 我为什么检查它
回看窗口 20 个交易日 把“1 个月”落实成可计算窗口
预测周期 T+20 因子值对应未来约 1 个月收益
分组数 5 组 用于观察分位组合差异和单调性
复权方式 后复权 避免分红送转造成价格序列断点
缺失值 开启处理 防止大量股票因空值直接丢失
去极值 MAD 降低异常收益对截面排序的影响
标准化 Z-score 让不同截面的因子值更便于比较
中性化 行业 + 市值 尽量分离行业和规模暴露
样本范围 近 5 年 本次平台实际可运行口径

我觉得这一步最容易被忽略的是“预测周期”。回看 20 日只说明因子用了过去多少数据,T+20 才说明它要解释未来多长时间的收益。两者不是一个参数。

“月末调仓”也是同样的问题。自然语言写起来只有四个字,代码里却要明确是自然月最后一天、月末最后一个交易日,还是跨月后遇到的第一个交易日。后面我的第一次调优,主要就是在这里花的时间。

运行前我还做了一个对照,避免自己过两天就忘了:

项目 研报原始口径 本次实际口径 能否直接比较
样本期 2005—2016 近 5 年 不能
股票池 全 A 沪深 300,后续调优到中证 1000 不能
频率 月频研究 wgt_return_1m 使用 T+20 只能比较研究逻辑
因子方向 动量/反转分别检验 本次结果指向反向使用 可以检查方向是否合理

这个小表很朴素,但对研报复现很重要。否则结果出来后,人会本能地拿两组数字作比较,忘了它们其实不是同一场实验。

第 4 步:因子分析页到底怎么看

提交后,任务会从排队中、0%,进入计算中,最后显示完成。完成以后我打开因子作品里的“有效性”页,而不是只看助手给我的一句结论。

wgt_return_1m 实际跑出来的数据是:

指标 结果 我当时怎么理解
Rank IC 均值 -0.0429 排序关系偏负,先考虑反向使用
IC 均值 -0.0146 线性相关同样偏负
ICIR -0.14 稳定性不强,不能只看平均 IC
Newey-West t 值 -1.95 接近常用显著性边界,但不宜说得太满
p-value 0.052 高于 0.05,本次页面也判为不显著
IC 胜率 45.9% 正向胜率不到一半
换手率 15.90% 后续进入策略时要考虑交易成本
覆盖度 97.50% 大部分样本都有因子值

image.png

图 2:wgt_return_1m 的实际有效性页面。顶部同时给出了回测区间、61 期月度展示和 T+20 收益口径。

我第一次看到 Rank IC 为负,也下意识觉得这条因子是不是写反了。但继续看分组单调性和 EVO 给出的方向判断,低分位更值得关注,逻辑上对应的是短期反转:过去一个月相对弱的股票,在后一个月存在反弹倾向。

这也是读因子页时一个挺实用的顺序:

  1. 先看正负号,判断是正向还是反向;
  2. 再看分组是否按这个方向排列,而不是只盯一个均值;
  3. 再看 ICIR、t 值和 p-value,判断关系稳不稳;
  4. 最后看覆盖度和换手率,判断它落成策略后是否可能被样本缺失和成本拖累。

这组结果不能叫强因子。p-value = 0.052 并没有通过常用的 5% 阈值,ICIR 也不好看。但它至少给出了一个可继续验证的方向。我没有在这里反复改参数“刷”到显著,而是保留原结果,继续测试它落成交易规则后会怎么样。

第 5 步:从因子结果走到第一个策略

因子方向确认后,我让 EVO 根据 wgt_return_1m 的低分位反转思路创建策略 htsc_momentum_reversal_1m

如果从头再做一次,我会把这一步写成下面这样,避免只说“生成策略”以后让选股方向又被猜一遍:

请基于已经完成分析的 wgt_return_1m 创建一条 A 股策略草稿。

因子按反向使用:选择因子值最低的一组,而不是最高组。
先沿用当前 20 日窗口和 T+20 研究口径,以沪深 300 为初始股票池和基准,
每次选择因子值最低的 20 只股票等权持有,并写入交易成本。

创建后先不要继续调参。请打开并说明策略定义中的:
股票池、基准、回测区间、调仓触发、持仓数量、单票上限、
总仓位、佣金、印花税和滑点。

完成静态检查和第一次回测,把该草稿保留为原始基线。

这里的 20 只并不是研报证明过的最优持仓数,只是把第一版策略的规则明确下来。第一轮最重要的是留一个不再移动的基线,而不是一开始就追求最优参数。

策略出现后,我先回到左侧“作品”确认它确实已经创建。打开策略,中间顶部能看到“定义、业绩、风险、适应性、归因”几个页面。定义页里又分“策略定义”和“护栏”,右上角显示当前草稿和“定义锁定”。

我主要核对定义里的 META 和策略说明:

  • universe:股票池;
  • benchmark:业绩比较基准;
  • adjust:复权方式;
  • freq:运行频率;
  • rangeStart / rangeEnd:回测时间;
  • builder:持仓数、权重上限、总仓位;
  • cost:佣金、印花税和滑点;
  • generate_signal:选股和调仓到底在什么条件下触发。

这里我最大的体会是:策略说明写着“低分位反转、月末调仓”,只是研究意图;真正决定回测行为的是下面的代码和元数据。两边都要看,不能只读那几行中文注释。

草稿 1 使用沪深 300 作为股票池和基准。回测完成后,业绩页生成了累计净值、基准对比、回撤和月度收益,结果是:

  • 总收益 -40.27%
  • 年化收益 -10.34%
  • 最大回撤 -42.68%
  • 夏普 -2.09
  • 卡玛 -0.24
  • 索提诺 -2.35
  • 月度胜率 30.0%

到这一步,“研报 → 因子 → 策略 → 回测”的流程其实已经闭环了,只是效果很差。

我没有直接输入“帮我把收益优化到正数”。这种要求太容易让 Agent 同时改窗口、股票池、持仓数和调仓逻辑。最后曲线即使变好,我也不知道是哪一处改动造成的。所以后面的原则变成了:先留基线,一轮只问一个问题。

第 6 步:四个草稿是怎么一步步出来的

EVO 的草稿机制在这次调优里挺实用。已经锁定的草稿不会被直接覆盖,要修改就从指定草稿派生一个新草稿。于是草稿 1 的原始结果、草稿 2 的失败结果、草稿 3 和草稿 4 的回测都能来回切换。

image.png

图 3:右上角切换草稿时,四次尝试和各自的夏普都还在。

草稿 1:先留下最原始的基线

草稿 1 就是 EVO 自动生成的沪深 300 版本。虽然亏损很大,我仍然先保存它,因为没有这个版本,后面所有“改善了多少”都没有参照。

草稿 2:静态检查通过,但回测全是 0

我先让 EVO 重新读草稿 1 的 definition.py,核对月末调仓。第一轮修改生成草稿 2,静态体检显示 14 项,0 项不通过,1 项未查,随后回测也正常跑完。

但我打开业绩页后发现,总收益、年化和最大回撤全部是 0.00%,夏普和卡玛没有值,月度收益也全是 0。日志能看到回测跑完了 1191 根 bar,时间覆盖 2021-09-22 到 2026-08-21。

这时候要特别小心:任务显示“完成”,只能说明回测程序结束了;静态检查通过,也只能说明代码没有被检查项拦住。它们都不能证明策略真的触发了信号和交易。

我当时的判断路径是:

回测是否完成?       是
净值是否有变化?     否
月度收益是否非零?   否
风险指标是否有值?   否
=> 这不是“策略特别稳”,而是本轮没有产生有效交易

所以草稿 2 没有继续往下当基线。

草稿 3:回到草稿 1,重新处理调仓判断

因为草稿 2 已经锁定,我重新从草稿 1 派生草稿 3,再修改调仓逻辑。静态体检仍是 14 项,0 项不通过,1 项未查,这次业绩页终于出现正常波动:总收益 -7.89%,年化 -1.73%,最大回撤 -12.36%,夏普 -0.92

相对草稿 1,这几个数字明显收窄,但我没有把它写成“月末调仓已经验证有效”。因为调仓日期的自然语言、代码实现和实际交易日还需要逐项核对。这轮能确认的是:修改后产生了交易,回测结果也能和基线比较。

草稿 4:只把股票池和基准换成中证 1000

第二轮调优以草稿 3 为基线,只改两处对应同一个实验变量:股票池从沪深 300 换成中证 1000,基准也同步换成中证 1000。

我明确要求 20 日窗口、选股方向、top 20、单票上限、总仓位、交易成本、回测区间和调仓代码全部保持不变。静态体检后再跑回测,得到草稿 4。

image.png

图 4:草稿 4 的业绩页。策略总收益仍是负数;页面同时展示了中证 1000 基准和累计净值。

四个草稿放在一起看更直观:

草稿 本轮处理的问题 总收益 年化收益 最大回撤 夏普
草稿 1 原始基线,沪深 300 -40.27% -10.34% -42.68% -2.09
草稿 2 第一次修改调仓判断 0.00% 0.00% 0.00% N/A
草稿 3 从草稿 1 重新修改调仓判断 -7.89% -1.73% -12.36% -0.92
草稿 4 从草稿 3 切换到中证 1000 -3.28% -0.70% -15.24% -0.67

草稿 4 相比草稿 3,总收益、年化、夏普和月度胜率有所改善,月度胜率从 35.0%38.3%;但最大回撤从 -12.36% 扩大到 -15.24%,波动率也从 4.99% 升到 5.26%

所以我最后只敢下一个很有限的结论:在当前近 5 年样本和这套固定参数下,中证 1000 版本比沪深 300 版本少亏了一些,但承担的回撤更大。它不能证明小盘股短期反转长期有效,更不能说明策略已经调好。

如果你也想复现一篇研报,我建议按这个顺序检查

这是我实际跑完后会保留的顺序:

  1. 确认文件真的被载入。 能预览,并且助手明确显示已进入研究上下文。
  2. 先让 EVO 列口径。 因子、样本、股票池、频率、预处理、方向和评价指标先对上。
  3. 先跑一条最小链路。 长研报不要第一轮就批量建全部因子。
  4. 创建因子后再核对元数据。 尤其是回看窗口、预测周期、复权和中性化。
  5. 因子页先判方向。 负 IC 可能是反向因子,不要直接当成创建失败。
  6. 保留第一个策略作为基线。 结果再差也先别覆盖。
  7. 回测完成后确认真的有交易。 看净值、月度收益、风险指标和日志,不能只看任务状态。
  8. 每轮只改一个实验变量。 从指定草稿派生,并写清哪些参数不能动。
  9. 同时比较收益和风险。 收益少亏不代表回撤也会改善。
  10. 最后再写结论。 把研报口径和当前口径并排放着,别把样本内变化写成普遍规律。

最后说点真实感受

这次让我觉得有用的,不是 EVO 给了一个“正确答案”,而是它把原来很分散的研究动作接在了一起。

以前读一篇研报,我可能在 PDF 里做笔记,在本地写因子代码,换一个地方跑回测,再自己用文件名保存 final_v2_new。这次我在资源区载入研报后,研究助手能继续创建因子;因子分析完能生成策略;策略效果不好,又能从指定草稿继续改。回过头看时,两条因子、四个草稿和每次结果还在同一个工作区里。

但它也不是按一下就能交卷。特别是时间窗口、因子方向、调仓日期和是否实际成交,这些地方仍然需要人做判断。EVO 把“想法变成实验”的门槛降下来了,并不等于研究责任也交出去了。

我最后停在草稿 4,没有继续把参数调到正收益。再往下当然还可以试窗口、持仓数和过滤条件,但如果一直盯着这 5 年数据调,很快就会变成在样本里找最好看的答案。对这次测试来说,把流程跑通、把失败草稿留下、知道下一步应该验证什么,比硬凑一条正收益曲线更有价值。毕竟现在2026年了,追求这个正收益也很难上实盘,跑通流程倒是可以帮我以后用得更顺畅,尝试自己的策略。


本文仅记录一次研报复现和历史回测过程,不代表未来表现,也不构成投资建议。

评论

还没有评论,来说点什么吧
0 / 2000