动量BETA因子择时与ALPHA构建
> Pay Skill 范式:履约型(fulfill)
> 履约型:输入文本由服务端 LLM 处理并返回业务结果,Agent 只负责传参与支付。
Overview
将 WorkBuddy 转变为一名深耕量化选股因子研究的分析助手,基于海通证券《选股因子系列(九十六):动量 BETA 的择时、优选与 ALPHA 因子构建》的框架与方法,帮助用户:① 确定动量因子的最优回看窗口;② 计算三类「动量失效」择时信号以决定何时回避/反向动量;③ 构建「高动量 Beta 优选组合」;④ 用短期反转对动量做非线性调整得到更稳定的「增强动量 Alpha 因子」。所有方法均给出可运行的 Python 实现与明确参数阈值。本技能不连接任何行情数据库;用户需自行提供价格/财务数据(CSV 或 DataFrame 结构说明),技能据此生成因子计算代码与择时/组合方案。
When to Use(触发条件)
- 用户问「动量因子怎么构造」「回看窗口选几个月」「为什么我的动量策略在某个阶段失效」
- 用户要求「给我一个动量择时信号」「判断当前市场适不适合做动量」
- 用户要「构建一个高动量组合」「高动量 Beta 优选 100 组合怎么做」
- 用户希望「改进简单动量因子,让它更稳定」「增强动量因子怎么算」
- 用户提供股票/指数价格数据,要求输出因子值、分层回测思路或 Python 代码
Workflow(工作流)
- 明确需求类型 → 调用
references/rules.md对应章节(窗口选择 / 择时信号 / 组合构建 / 增强因子)。 - 给出方法定义 + 参数阈值(如回看窗口 [t-11,t-5]、拥挤度阈值 80% & 1.1 倍、波动率调整口径)。
- 若用户需要代码 → 调用
references/implementation.md中对应函数,按用户数据列名做适配说明。 - 若用户要求择时判断 → 用
references/rules.md第二章的三类信号逐条判定,输出「当前是否处于动量失效情景」的结论。 - 出具结果 → 使用
references/output_templates.md的模板(因子代码块 / 择时结论 / 组合清单格式)。
Output(输出规范)
- 严格使用
references/output_templates.md的模板。 - 因子公式用「中文定义 + 数学式 + Python 函数签名」三段式呈现,参数阈值高亮。
- 择时结论必须给出「三类信号各自是否触发 + 综合判定(失效 / 有效)」。
- 不臆造回测收益;若用户未提供数据,明确说明「需提供 XX 数据后方可计算」,不假设数值。
Notes / Constraints(约束)
- 本技能方法基于 2005–2024 历史统计,存在因子失效与规律漂移风险,不构成投资建议。
- 所有收益 / IC 数字来自海通证券研报,仅作方法说明,不代表未来表现。
- 不访问外部行情系统;取数由用户负责。
- 波动率调整、分位调整等口径有多种写法,本技能采用研报默认口径;用户如需其它口径请明确。
Pay Skill 模式(履约型,按次付费,已接入 X402)
本 Skill 为付费技能(Pay Skill),按次收费,已通过腾讯 SkillHub +
微信支付 Agent Pay X402 协议接入。不存在免费运行模式——
未完成支付授权前,服务端不返回任何业务结果,Agent 不得输出付费内容。
> 使用者须已安装并开通 weixinpay_pay 插件(微信 AI 支付 / AI 专属卡)。
> Step 0 检查不通过时不发起付费调用,直接引导开通后重试。
履约型:输入文本由服务端 LLM 处理并返回结果,Agent 只负责传参与支付。
- 统一网关主接口:
POST https://pay.zerone-iteration.com/api/invoke
(请求体{"skill": "momentum-beta-factor", "skill_version": "1.0.1", "query": "...", "amount": 990}) - 兼容入口:
POST https://pay.zerone-iteration.com/api/resource(等价于默认 Skill) - 支付回调:
POST https://pay.zerone-iteration.com/api/pay/notify - 退款回调:
POST https://pay.zerone-iteration.com/api/refund/notify - 实现:透明网关(nginx + Java 17 / Spring Boot + WechatPay-Java,微信支付公钥模式);
skill/skill_version仅做格式校验后透传进 X402 预下单,不查 SkillHub(不查注册表、不反查是否真实存在/已发布/版本匹配);
无本地白名单,新增 Skill 免 Java 注册、免改 JAR、免重启,直接POST /api/invoke传正确 slug+版本即可 - 状态:待联调实测(包生成于 2026-08-29,尚未跑通生产真扣链路;
DEV_MODE=true下可纯模拟验证 402 结构与支付码透传,生产须置MOMENTUM_BETA_FACTOR_DEV_MODE=false并填齐微信/ SkillHub 密钥)。
Agent 侧调用规范(含付费前置插件检查)
Step 0 付费前置插件检查(必须,缺失则不得发起付费调用)
- 检测当前环境中
weixinpay_pay插件(微信支付 Agent Pay / AI 专属卡)是否已安装并已开通; - 若不存在或未开通:不调用
/api/invoke,改为提示用户先安装/开通微信 AI 支付,完成后再继续; - 若可用:继续 Step 1。
Step 1 调用统一网关:POST /api/invoke,请求体:
{
"skill": "momentum-beta-factor",
"skill_version": "1.0.1",
"query": "待处理的输入……",
"amount": 990
}
skill:必填,固定为本 Skill 的 slugmomentum-beta-factor(与 SkillHub 已发布的一致;透明网关下传错 slug 时错误延后到 SkillHub/微信预下单环节才返回);skill_version:必填,当前版本号1.0.1(缺失返回400 MISSING_SKILL_VERSION);amount:必填,单位分,服务端校验为大于 0 的整数(小数/布尔/零/负数一律400 INVALID_AMOUNT,不静默截断);
区间不强制,价格由 SkillHub 产品定价约束。
Step 2 支付触发(X402 预下单 → 402):未支付时服务端依次执行——
- 生成订单号
out_trade_no(402 响应头X-Out-Trade-No与响应体out_trade_no均会返回,Agent 须记下); - 调用微信支付 Native 下单,获取
code_url; - 用 SkillHub 开发者私钥(SHA256withRSA)对 X402 AI 预下单请求签名;
- 调用
POST https://payapp.weixin.qq.com/palmpayminiapp/clawagentpay/preorder换取payment_code; - 返回 HTTP 402,响应头
WeixinPay-Required与 bodyWeixinPay块中
同时携带 X402 预下单返回的payment_code(必须是 X402 的payment_code,
不能直接把微信code_url当作payment_code返回),并回显本单amount与out_trade_no。
⚠️ body 的WeixinPay嵌套结构最易遗漏:缺失时 weixinpay 插件从 body 解析不到
payment_code,会报「当前支付订单已过期」,该报错常被误判为「返回了 code_url」。
Step 3 用户支付授权:Agent 将 WeixinPay-Required 头(或 body WeixinPay 块)中的
payment_code 作为 paymentCode 交给 weixinpay_pay 插件,向用户申请支付授权。
Step 4 二次调用履约:用户完成支付后,Agent 再次调用 POST /api/invoke
(请求体同 Step 1,带请求头 X-Out-Trade-No: <402 返回的订单号>);
服务端按订单号主动向微信查单验证支付成功(不依赖回调到达)后幂等履约并返回结果,
响应含 transaction_id 与 already_fulfilled 标记。
支付未确认前,不向用户输出任何付费内容(未支付重试返回 402 {"code":"NOT_PAID"})。
异常处理说明(Agent 与服务端两侧)
| 异常场景 | 处理方式 |
|---|---|
weixinpay_pay 插件不可用 |
不发起付费调用,引导用户安装/开通微信 AI 支付后重试 |
| 用户拒绝支付 / 支付取消 | 如实告知用户支付未完成,不推进后续流程、不输出付费内容;可重新发起(服务端生成新订单) |
| 支付失败(余额不足/风控拦截) | 如实转达失败原因,引导稍后重试;失败订单作废,不据此履约 |
payment_code 过期(最长 15 分钟) |
提示订单已过期,Agent 重新调用获取新订单与新 payment_code,不得复用旧码 |
| 报错「当前支付订单已过期」 | 先查 402 响应体是否有 WeixinPay 嵌套结构,其次才是 code_url 方向 |
| 支付成功但二次调用仍 402(回调延迟) | 等待 3~5 秒后重试,最多 3 次(指数退避),携带 X-Out-Trade-No、订单号不变;仍失败则告知用户稍后凭原订单号重试,不得伪造已支付状态 |
| 网络异常 / 5xx | 指数退避重试(1s/2s/4s,上限 3 次);持续失败告知服务暂不可用 |
| 金额校验失败(400 INVALID_AMOUNT) | 修正 amount 为大于 0 的整数分后重试 |
| skill 传错 / 未发布(错误延后到 X402/微信预下单环节) | 核对 skill/skill_version 与 SkillHub 已发布条目一致后重试,不得随便换 slug |
| skill_version 缺失(400 MISSING_SKILL_VERSION) | 补上当前版本号 1.0.1 后重试 |
| 未支付即重试(402 NOT_PAID) | 等待用户完成支付授权后按 Step 4 重试,不得跳过支付环节 |
| 退款 | 服务端经 /api/refund/notify 接收回调;已退款订单的 payment_code 失效,再次调用将重新走支付流程 |
> 核心原则(SkillHub 官方教程 FAQ):支付失败/未确认时必须如实告知用户,绝不据此推进后续流程。
核心特征对照表(供审核查验)
| # | 核心特征 | 实现位置 |
|---|---|---|
| 1 | X402 AI 预下单换取 payment_code(开发者私钥 SHA256withRSA 签名,调官方 preorder 接口;WeixinPay-Required 返回 payment_code 而非微信 code_url) |
pay/server.py skillpay_x402_preorder();链路 Step 2.3~2.5 |
| 2 | 支付触发(未支付返回 402 + WeixinPay-Required 头/体双通道) |
pay/server.py _handle_invoke();链路 Step 2.5 |
| 3 | 订单号传递(out_trade_no 全链路关联:下单→预下单→回调置位→X-Out-Trade-No 重试→二次调用) |
pay/server.py generate_trade_no() / mark_paid / 402 响应 X-Out-Trade-No 头 |
| 4 | 重试机制(402 回调延迟重试带 X-Out-Trade-No、5xx 指数退避、订单过期重新下单) |
上表「异常处理说明」 |
| 5 | 付费前置插件检查(weixinpay_pay 可用性检测,缺失不发起付费调用) |
链路 Step 0 |
| 6 | 异常处理说明(支付失败/取消/过期/退款/未知 skill 等全场景) | 上表「异常处理说明」 |
| 7 | 透明网关(skill/skill_version 仅做格式校验后透传,不查 SkillHub、不查注册表) |
pay/server.py resolve_skill()(无 SKILL_REGISTRY,免 Java 注册/重启) |
包内 pay/server.py 为 Python 参考实现(含 APIv3 签名、X402 预下单、回调验签解密、
主动查单、幂等履约、透明网关无需注册表),部署说明见 PAY_SKILL_UPGRADE.md 与 pay_skill.yaml。
注意:本 Skill 涉及两套独立密钥/证书——
- 微信支付 API 证书(
wechat_pay):用于微信 Native 下单与主动查单; - SkillHub 开发者密钥(
skillhub):用于 X402 预下单签名。
私钥均不得写入 Skill 包或仓库,须通过环境变量注入服务端。