基于 trader-backtest Skill 的 Ed25519 签名回测:ruflo-neural-trader 从 paper 到 live 的防篡改门禁实战
【免费下载链接】ruflo🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated项目地址: https://gitcode.com/GitHub_Trending/cl/ruflo
导读
本文聚焦 ruflo 生态中ruflo-neural-trader插件的trader-backtest技能:如何调用neural-trader(Rust/NAPI 引擎)执行历史回测,并依据 ADR-126 Phase 4 与 CWE-347 模式,用 Ed25519 对回测产物签名,为"paper 模拟盘 → live 实盘"晋升门提供密码学防篡改证据。读完本文,你将掌握一条完整、可复现的回测工作流——从 CLI 参数、指标捕获、keep-newest去重,到签名密钥解析、产物存储,以及下游trader-cloud-backtest的 fail-closed 验证门。
一、为什么回测结果需要签名:ADR-126 Phase 4 与 CWE-347
在量化交易中,paper→live 晋升门是最需要防篡改证据的时刻:一个被篡改的 Sharpe 值足以让未经验证的策略进入实盘。ADR-126(v3/docs/adr/ADR-126-neural-trader-substrate-integration.md)在背景分析中明确指出,此前trader-backtest/SKILL.md将回测结果以纯 JSON 存储,既无哈希也无签名,"paper→live promotion has no tamper evidence"。Phase 4 的决策即引入SignedBacktestArtifact信封,复用 ADR-103 的 witness 密钥与 CWE-347(Improper Verification of Cryptographic Signature)插件注册表模式——"用 Ed25519 签名、固定到可信密钥、fail-closed"。
该模式已被固化为三层自动化保障,见 scripts/smoke-neural-trader-backtest-signing.mjs:
- 静态契约检查
signed-artifact.{ts,mjs}的导出与形状; - 真实 Ed25519 密码学往返(篡改一字节必失败、换可信公钥必失败);
- 调用点字节检查
trader-cloud-backtest/SKILL.md必须包含验证调用与拒绝晋升的 fail-closed 分支。
二、trader-backtest 完整流程:从 CLI 回测到签名归档
trader-backtest技能的完整执行链位于 plugins/ruflo-neural-trader/skills/trader-backtest/SKILL.md,共九步。下面按步骤完整展开,并给出可复制命令。
1. 确保 neural-trader 可用
npm ls neural-trader 2>/dev/null || npm install --ignore-scripts neural-trader--ignore-scripts用于跳过安装钩子,插件依赖neural-trader的 Rust/NAPI 预编译二进制(8–19 倍于纯 JS 的引擎性能),该二进制随 npm 包分发。
2. 检索已保存的策略配置
通过 ruflo-core 的记忆 MCP 工具读取策略:
mcp__plugin_ruflo-core_ruflo__memory_retrieve({ key: "strategy-STRATEGY_NAME", namespace: "trading-strategies" })若未命中,则列出可用策略:
mcp__plugin_ruflo-core_ruflo__memory_search({ query: "strategy", namespace: "trading-strategies", limit: 10 })trading-strategies是 ADR-126 Phase 1 对齐后的五个规范命名空间之一(trading-{strategies,backtests,risk,analysis,signals}),存储策略定义、参数与 regime 条件映射。
3. 运行历史回测
单策略回测(含 walk-forward 前向验证):
npx neural-trader --backtest --strategy <name> --symbol <TICKER> --period <range> --walk-forward多指标策略示例(Kelly 仓位管理,SPY 2020–2024):
npx neural-trader --backtest --strategy multi-indicator --position-sizing kelly --symbol SPY --period 2020-2024参数语义:--backtest启动回测模式;--strategy选择策略名;--symbol指定标的(如 SPY);--period指定日期范围(如2020-2024);--walk-forward启用滚动前向验证,防止过拟合;--position-sizing kelly使用 Kelly 公式决定仓位。
4. 捕获性能指标
从输出中提取以下核心指标,作为后续签名与模式存储的依据:
| 指标 | 含义 |
|---|---|
| total return | 总收益率 |
| annualized return | 年化收益率 |
| Sharpe ratio | 夏普比率(风险调整后收益) |
| Sortino ratio | 索提诺比率(仅以下行波动为分母) |
| max drawdown | 最大回撤 |
| win rate | 胜率 |
| profit factor | 盈亏因子 |
| number of trades | 交易次数 |
5. 去重:同一(strategyId, paramsHash)只保留最新
在存储新回测前,先对同一策略 + 同一参数哈希的历史结果做keep-newest去重(ADR-125 生命周期 / ADR-126 Phase 2):
mcp__plugin_ruflo-core_ruflo__memory_search({ query: "backtest STRATEGY paramsHash:PARAMS_HASH", namespace: "trading-backtests", limit: 10 })对每个 key 匹配backtest-STRATEGY-*且存储的paramsHash等于本次运行哈希的条目,执行删除:
mcp__plugin_ruflo-core_ruflo__memory_delete({ key: "OLD_KEY", namespace: "trading-backtests" })即便不做内联去重,后台的MemoryConsolidator.dedup('keep-newest')(@claude-flow/memory@3.0.0-alpha.18引入,每 6 小时运行一次)最终也会收敛;内联执行的价值在于让memory_search在重跑后立即得到确定性结果。
从源码看,v3/@claude-flow/memory/src/consolidator.ts 中keep-newest的策略语义是:按内容哈希分桶后,保留updatedAt最大者,丢弃其余(keeper = bucket.reduce((acc, e) => e.updatedAt > acc.updatedAt ? e : acc));另有keep-oldest(按createdAt最小)与merge-tags(保留最新并合并标签集)两种策略可选。
6. 签名产物(ADR-126 Phase 4)
构造待签名 body——即SignedBacktestArtifact去掉签名字段后的部分:
{ "strategyId": "...", "paramsHash": "<sha256(canonical params JSON)>", "dataRange": { "from": "...", "to": "..." }, "metrics": { "sharpe": 1.8, "maxDrawdown": 0.11, "totalReturn": 0.42 }, "runsHash": "<sha256(canonical runs array JSON)>", "generatedAt": "2026-09-09T00:00:00.000Z" }字段规则:paramsHash = sha256(规范化参数 JSON),runsHash = sha256(规范化 runs 数组 JSON),generatedAt = new Date().toISOString()。
密钥解析顺序(第一个命中的生效,绝无折中):
- 环境变量
RUFLO_WITNESS_KEY_PATH——指向一个 JSON 文件,内容为{ "privateKey": "<hex>" }; verification/witness-key.json(ADR-103 默认路径,若存在)。
若密钥命中,调用 plugins/ruflo-neural-trader/src/signed-artifact.mjs 的signBacktestArtifact(body, privateKeyHex),返回携带schema、witnessPublicKey: "ed25519:<hex>"、witnessSignature: "<hex>"的完整SignedBacktestArtifact。
若两条路径都未命中,必须大声告警并降级为未签名存储,严禁静默回退。告警原文(直接可复用):
[WARN] ruflo-neural-trader: no witness signing key found (RUFLO_WITNESS_KEY_PATH unset, verification/witness-key.json missing) — storing backtest artifact in UNSIGNED degraded mode. paper→live promotion will be refused by trader-cloud-backtest until a signed artifact replaces this one.7. 存储到规范命名空间
mcp__plugin_ruflo-core_ruflo__memory_store({ key: "backtest-STRATEGY-TIMESTAMP", value: JSON.stringify(signedArtifact), namespace: "trading-backtests" })已签名的值携带witnessSignature+witnessPublicKey;下游消费方(trader-cloud-backtest)在将任何产物晋升到 live 之前,必须调用verifyBacktestArtifact(artifact, trustedPublicKey)。
8. 高收益模式沉淀
若 Sharpe > 1.5,将成功模式存入 agentdb:
mcp__plugin_ruflo-core_ruflo__agentdb_pattern-store({ pattern: "profitable-STRATEGY_TYPE", data: "PARAMS_AND_RESULTS" })9. 训练 SONA 学习循环
mcp__plugin_ruflo-core_ruflo__neural_train({ patternType: "trading-strategy", epochs: 10 })将本次结果反馈进 SONA 自学习管线,闭合 ADR-049 的 trajectory 循环。
三、密钥来源与轮换(ADR-103)
witness 密钥是32 字节 Ed25519 私钥,以{ "privateKey": "<64-hex-chars>" }形式存于RUFLO_WITNESS_KEY_PATH指向的 JSON 文件,严禁入库。本地开发一次性生成:
node -e "import('@noble/ed25519').then(async ed=>{const sk=crypto.getRandomValues(new Uint8Array(32));console.log(Buffer.from(sk).toString('hex'))})"写入~/.ruflo/witness-key.json。
生产部署时,将对应的公钥固定在项目配置中,作为trustedPublicKey传给verifyBacktestArtifact(...)——绝不信任产物上的witnessPublicKey字段(CWE-347 / #1922)。密钥轮换策略与 ADR-103 一致:用新密钥对既有回测条目重新签名,或将轮换前的产物显式标记为不可晋升。
四、源码级原理:签名与验证的密码学细节
signed-artifact.mjs 是运行时实现,signed-artifact.ts 是文档化的类型定义与规范源,二者必须保持同步(冒烟测试会契约检查.ts并运行时测试.mjs)。
签名侧(signBacktestArtifact):
- 私钥必须恰为 32 字节,否则抛错;
- 规范化字节 = 对待签名 body 做
JSON.stringify(无空白、无排序)后 UTF-8 编码——body 形状由签名方构造,键序确定性由构造保证,无需额外 canonicalizer; - 用
@noble/ed25519的signAsync签名,并同步导出ed25519:<hex>公钥。
验证侧(verifyBacktestArtifact)关键设计:固定到调用方传入的trustedPublicKey,而不是产物上的witnessPublicKey。原因正如源码注释所强调:witnessPublicKey是攻击者可控制的字段,固定到它等于未验证。验证时重新从产物中剥离两个签名字段构造规范 body,对trustedPublicKey去除ed25519:前缀后还原 32 字节公钥、校验 64 字节签名,任何异常(长度不符、解密失败)一律返回false。
五、下游验证门:trader-cloud-backtest 的 fail-closed 语义
plugins/ruflo-neural-trader/skills/trader-cloud-backtest/SKILL.md 是签名产物的主要消费方——它把重型回测(多年 walk-forward、大规模 Monte-Carlo、参数网格扫描、LSTM/Transformer/N-BEATS 训练)派发到 Anthropic Managed Agent 云容器执行,结果拉回本地后执行同样的签名与验证流程:
- 从云返回的指标、参数哈希、runs 哈希构造
SignedBacktestArtifactbody,本地用signBacktestArtifact签名(密钥解析顺序与trader-backtest一致); - 存储或晋升之前调用
await verifyBacktestArtifact(artifact, trustedPublicKey),trustedPublicKey为项目配置中固定的 Ed25519 公钥(不是artifact.witnessPublicKey字段,该字段攻击者可控制,见 CWE-347 / #1922); - 若验证返回
false:拒绝晋升,输出大声错误并提前返回:
[ERROR] ruflo-neural-trader: SignedBacktestArtifact signature INVALID against trusted key — refusing to promote to live strategy这是 ADR-126 规定的 fail-closed 门——验证失败即拒绝,绝不带病晋升。
六、测试保障:三层冒烟验证
scripts/smoke-neural-trader-backtest-signing.mjs 以三层方式锁定该门禁不被未来 PR 破坏:
- [1/3] 静态契约:断言
signed-artifact.{ts,mjs}导出两个函数、SignedBacktestArtifact接口包含schema/paramsHash/runsHash/witnessPublicKey/witnessSignature等字段、验证器必须接受trustedPublicKey参数且不得读取artifact.witnessPublicKey参与验证、规范消息必须是纯JSON.stringify(无空白无排序)。 - [2/3] 密码学往返:真实 Ed25519 签名的 fixture 用可信公钥验证通过;篡改一字节(如把
metrics.sharpe改成 99.9 试图通过晋升门)验证失败;空签名失败;空公钥失败;攻击者调换产物上的witnessPublicKey仍验证通过(证明固定到可信密钥生效);错误可信公钥验证失败(证明 pin 是真实的而非空操作)。 - [3/3] 调用点检查:断言
trader-cloud-backtest/SKILL.md包含verifyBacktestArtifact(...)调用、包含拒绝晋升的 fail-closed 分支与[ERROR]提示、并明确标注"固定可信密钥而非artifact.witnessPublicKey字段";同时断言trader-backtest/SKILL.md引用signBacktestArtifact、记录无密钥时的降级告警路径与RUFLO_WITNESS_KEY_PATH环境变量。
该冒烟可在仓库根目录直接运行:
node scripts/smoke-neural-trader-backtest-signing.mjs七、实践要点与注意事项
- 签名是晋升的前提,不是可选项:未签名(UNSIGNED degraded mode)的产物会先被大声告警标记,且在晋升到 live 前必然被
trader-cloud-backtest拒绝。 - 密钥安全边界:私钥永不入库;生产固定公钥于项目配置;轮换时要么重签历史产物,要么显式标记为不可晋升(ADR-103 模式)。
- 去重语义:
keep-newest依据updatedAt保留最新;内联去重保证重跑后memory_search立即确定,后台 6 小时周期是最终兜底。 - 指标质量门:Sharpe > 1.5 才沉淀为 agentdb 成功模式,避免低质量结果污染模式库;每次运行结束后将结果喂给 SONA 训练,形成持续学习闭环。
- 可在插件技能目录查阅更多配套技能:trader-cloud-backtest(云回测与晋升门)、trader-signal(信号事件,ADR-126 Phase 2 要求写入时带
expiresAt: now + 24h)、以及trader-portfolio、trader-risk、trader-regime、trader-train、trader-explain等技能,共同构成完整的策略研发管线。
把回测从"可复现"升级为"可验证",正是这条工作流对量化研发流程最核心的贡献:每一次 paper→live 晋升,都有密码学签名作为无可抵赖的证据链。
【免费下载链接】ruflo🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated项目地址: https://gitcode.com/GitHub_Trending/cl/ruflo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考