行业资讯

加入亿拓客·流量大师 撬动财富之门!!!

从研报到PTrade实盘:ETF动量轮动加AGRU择时的六阶段落地实录

wang 2026-09-20 行业资讯
从研报到PTrade实盘:ETF动量轮动加AGRU择时的六阶段落地实录

声明:本内容为个人业余研究,所有标的代码仅做为示例,回测收益不代表未来,不做为投资建议。

上一篇文章研报收藏吃灰?我用 AI 把一篇券商策略变成了可回测代码把广发金工《神经网络择时与截面叠加的 ETF 绝对收益策略》变成了本地可回测的代码,复现口径下今年以来收益 26.42%。到那一步,研报的承诺只兑现了一半:数字跑出来了,策略还躺在本地脚本里,离真正下单还隔着模型部署、平台上传、线上推理这一公里。这篇文章记录的就是这一公里怎么走完:从研报解析、模型训练、本地回测,到模型导出上传、PTrade 回测验证,最后停在实盘就绪的位置。全程重点讲清一件事——哪套数字能信,哪套数字只是机制验证。

一、全链路总览:六个阶段与一个双模式设计

整条链路分六段:研报解析生成策略骨架;历史数据训练模型并产出逐日信号;本地回测给出权威绩效;导出模型权重上传 PTrade;PTrade 回测验证平台机制;模拟盘过渡到实盘。

研报解析 ──→ AI提炼核心逻辑,生成本地策略骨架(PTrade语法)             产物:strategies/ptrade/ETF绝对收益V1_动量轮动AGRU择时.py   ↓模型训练 ──→ 历史数据 walk-forward 逐月重训,记录各折验证 IC/RMSE             产物:data/signals/nn_timing_signals.csv + models/*.npz   ↓本地回测 ──→ signal_mode='csv',逐日无前视信号,权威绩效口径   ↓模型导出 ──→ export_agru_weights.py 导出最近一折权重+归一化统计量             上传 PTrade 研究环境 nn_timing/models/(一次性)   ↓PTrade回测 ─→ signal_mode='model',线上自动推理,机制验证   ↓模拟盘/实盘 → 每月或周末重训,覆盖上传权重即可更新模型

支撑这条链路的是策略里的一个双模式开关 g.signal_mode:

  • csv 模式:读取 walk-forward 逐月重训产出的逐日信号文件,预测 T 日只用 T-1 前的数据,无前视,本地权威回测用这个口径;
  • model 模式:加载上传的模型权重,每个交易日开盘前线上自动推理,PTrade 回测和实盘统一用它,权重文件缺失时自动回退读 csv。

这样设计的出发点很简单:本地回测引擎(mtzQuant)能严格控制无前视,PTrade 平台的回测做不到同等口径,那就不要让一套数字勉强服务两个目的——权威绩效留在本地,线上只验证机制。

二、研报解析:AI 把券商框架变成策略骨架

把研报交给 AI,让它提炼五件事:核心逻辑是择时加截面叠加还是纯择时、因子定义、调仓频率、回测区间、关键参数。落到代码上,就是 strategies/ptrade/ETF 绝对收益 V1_动量轮动 AGRU 择时.py,骨架是 V28.3 固定池动量轮动前 10 等权,外面叠一层 AGRU 大盘择时三档仓位,文件头按固定纪律写清职责:

# coding:utf-8# @author      : 木头左# @create_time        : 2026/08/30 20:26:20# @update_time        : 2026/09/05 18:10:00# @description : ETF绝对收益V1:V28.3固定池动量轮动前10等权 + AGRU择时(PTrade 回测+实盘双模式)

择时的三档映射是整个策略的中枢,源码第 418 行:

def map_to_timing_pos(pred, lo=-0.0005, hi=0.0005):    """预测值 → 三档仓位(>hi 满仓1.0 / <lo 空仓0.0 / 其余 半仓0.5)。"""    if pred > hi:        return 1.0    if pred < lo:        return 0.0    return 0.5

其余关键设计有三处。档位变化当日立即调仓,档位不变时每 5 个交易日轮动刷新多头组;实盘用 run_interval 60 秒周期执行撤单、止损、卖出、买入,限价单按 ±2% 挂出,覆盖平台价格笼子;候选池做成交额过滤,剔除近 20 日日均成交额不足 100 万的标的。

三、模型训练:walk-forward 把无前视写进流程

训练脚本 train_agru_timing.py 以沪深 300(000300.SH)为基准序列,构造过去 20 日乘 7 个特征(日收益、5/10/20 日偏离度、5 日波动率、量比、成交额比值),模型是 GRU 加加法注意力再加全连接,PyTorch CPU 训练,seed 固定 42。

关键是训练方式:walk-forward 扩展窗,逐月重训,每一折只用截止 T-1 的样本预测 T 日,验证折记录 IC 和 RMSE。这样产出的逐日信号天然无前视,直接喂给 csv 模式。本轮全量训练的验证指标落在 data_end 2026-08-14 的模型快照里:val_ic 0.2709,val_rmse 0.0146,达到预设合格线(val_ic 大于 0.2、val_rmse 小于 0.02)。

信号映射与线上完全一致:预测次日收益超过 +0.0005(涨超 5bp)给 1.0 满仓,低于 -0.0005(跌超 5bp)给 0.0 空仓,其余落在 ±5bp 中性带里的给 0.5 半仓。这个死区是有意留的:对量级只有几个 bp 的预测值,中性带能避免档位在满仓与空仓之间被噪声来回切换。想严格对齐原文的中证全指(000985.CSI),加 --index 参数重训即可;只想冒烟验证链路,--quick 三轮训练出近 180 日信号,一分钟左右。

四、本地回测:140.61% 背后的权威口径

本地用 mtzQuant 跑权威回测,之前写过PTrade 回测一轮十几分钟?我用 AI 加本地回测把迭代速度提了一个量级,工具链不再展开。任务配置里两处口径值得注意:费率双边千一,撮合按 T 日决策、T+1 开盘成交;本地权威回测把 signal_mode 手动切到 csv。本机 akshare 网络不通时加 --check-only 跳过缺失段自动下载,避免长时间卡住。

回测会话 2026-08-30 跑完,净值曲线横跨约 2023 年中至 2026 年 8 月:

指标
数值
总收益
140.61%
年化收益
29.11%
最大回撤
17.60%
夏普
1.22

核对绩效之外更要核对过程:日志里择时档位序列与多头组买卖是否符合预期,订单、成交、持仓、净值是否自洽。这一套数字是全链路里唯一无前视的绩效,后面所有对比都以它为锚。

五、模型导出与上传:纯 numpy 推理的最后一公里

PTrade 环境没有 PyTorch,模型上线前要先做一步转换。export_agru_weights.py 把最近一折的权重连同归一化统计量导出成两个文件:agru_timing_weights.npz 装全部权重,agru_timing_config.json 记录 seq_len=20、特征清单、阈值 ±0.0005、hidden_size=32 这些推理所需的元信息。PTrade 侧用纯 numpy 复现前向,与 PyTorch 逐参数验证误差小于 1e-8,线上推理不引入任何第三方依赖。

第一次在 PTrade 上跑回测,连续踩了两个坑。先是 initialize 直接报错,定位到平台不支持 log.warn,换成 log.info 解决;再跑,模型文件找不到,PTrade 的路径里既没有 nn_timing/models 也没有 models 目录。结论很直白:权重文件必须手动传到研究环境。

在研究环境建好 nn_timing/models 目录,把两个文件传上去:

策略文件本身默认就是 model 模式,上传后不用改,npz 在就自动走线上推理。整轮交付的内容用一张清单说清楚:

本地对应关系也交代一下:本地模型放在 strategies/ptrade/nn_timing/models/,通过符号链接 data/models/ 让 get_research_path() 的取文件逻辑两边一致。以后每月或周末重训完,重跑一次导出脚本、覆盖上传两个文件,模型就算更新了。

六、PTrade 回测:65.35% 是机制验证,不是可预期收益

先看线上推理的机制。每个交易日开盘前,策略加载 npz 推理当日信号。pred_ret 的量级通常只有几个 bp,比如 0.000436(预测次日涨 4.4bp),落在 ±5bp 中性带里,档位给 0.5 半仓;某天日志里出现 0.002912(29bp),明显越过上限,档位给 1.0 满仓。档位的作用方式是仓位缩放:单只目标市值等于总资产乘档位再除以持仓只数,起始资金 10 万、档位 1.0、持仓 10 只时单只恰好 1 万,与日志吻合;档位切到 0.5,总敞口立刻减半。

回测区间 2025-01-01 至 2026-09-04,起始资金 10 万,基准沪深 300,全程逐日推理、日志无一次失败。绩效面板逐项摊开:

指标
数值
指标
数值
策略收益
65.35%
基准收益
15.58%
超额收益
46.43%
策略年化
36.19%
基准年化
9.30%
年化波动
26.40%
夏普比率
1.46
索提诺比率
2.06
最大回撤
18.17%
信息比率
1.12
Alpha
0.29
Beta
0.48
日胜率
51.11%
盈亏次数
207/187
平均持仓时长
10.33 天

几个数字值得单独说。Beta 只有 0.48:择时档位常年压不满十成,市场敞口平均只有一半左右,46.43% 的超额里择时贡献的成分看得见。平均持仓时长 10.33 天,与档位不变时每 5 个交易日轮动刷新多头组的节奏对得上。日胜率 51.11%、盈亏次数 207 比 187,胜率并不漂亮,收益靠的不是胜率。最大回撤 18.17%,三档仓位对下行段的保护在。

但这套数字的定位要说死:PTrade 回测里的模型是固定最近一折权重,训练样本包含了回测区间之后的数据,属于轻微前视,收益天然偏高。它证明的是模型加载、逐日推理、三档降档、动量轮动、撮合下单这条链路在平台上完整跑通,不构成对实盘收益的预期。

七、两套数字为什么不能直接比

本地 csv 口径(无前视,约 2023 年中至 2026 年 8 月):总收益 140.61%,年化 29.11%,夏普 1.22,最大回撤 17.60%。PTrade model 口径(含轻微前视,2025-01-01 至 2026-09-04):策略收益 65.35%,年化 36.19%,夏普 1.46,最大回撤 18.17%。

两组数字之间隔着四个变量:回测区间不同,前视口径不同,费率不同(本地双边千一,PTrade 平台默认万八双向,实盘另加印花税),撮合不同(本地 T+1 开盘成交,PTrade 回测的日线决策点在 14:50,实盘限价 ±2%、60 秒周期执行)。变量叠在一起,两组数字没有可比性,硬比只会得出错误结论。策略真实成色以本地 csv 无前视口径为准,原文复现时今年以来 26.42% 是更诚实的参照。

到这里,从研报到实盘的六段路走完了五段半。剩下的是把策略挂上模拟盘验证一段时间,再开实盘任务,日常运维浓缩成一句话:每月或周末重训模型,重跑导出脚本,覆盖上传两个文件。最后一公里走完的方式,不是把回测数字原样搬上线,而是把无前视的口径留在本地,把推理搬上线。

PS: 源码下载,请移步知识星球!

星球中整理了文章中涉及到的源码,加入后即可以看到之前发的源码,三天内不满意可以退款。也会将收集到的机构研报,优秀策略源码,群友常咨询的问题整理到不同标签下,做为知识库沉淀下来。

所有策略仅用于学习和研究,不保证交易收益,不作为投资建议,风险自负,所有收益仅表示历史回测收益,不表示未来收益。大QMT和ptrade请充分使用模拟盘测试,miniQMT使用模拟账号测试。

相关文章:

小白也能做量化:零门槛QMT/Ptrade免费送

量化python代码解析:QMT回测龙头打首板和连板的策略

听了群友的建议,年化收益达到了70%,增加了动态仓位权重调整后的全球核心资产轮动策略(含python代码解析)

欢迎扫描下方二维码,备注【开通】,开通QMT或Ptrade;备注【加群】,加入量化交易交流群;备注【电子书】,赠送QMT或Ptrade入门操作指南。

免责声明:

仅做知识整理,本公众号对这些信息的准确性和完整性不作任何保证,本材料不构成任何投资意见。投资有风险,入市需谨慎。

猜你喜欢

发表评论

发表评论: