回测防坑体检

SKILL效率
效率 未标注权限 许可证不明确
安装这个技能

回测防坑体检——在你相信一份选股策略的回测结果之前,先把它照一遍。 未来函数、口径漂移、幸存者偏差、过拟合、被你悄悄剔掉的那 0.59% 跌停样本, 这些东西的共同特征是:让它好看,让你亏钱,而你在代码里看不出来。 本工具只有一条原理:把未来砍掉,看历史会不会变——变了,就是坑。 14 项逐条体检,每项给 PASS / FAIL / 未验证,不把空格子默认填绿。 第 0 项 口径对账(最关键):回测代码里的规则,和生产脚本、策略文档是不是同一件事。 实测过一套 75 条规则的选股体系,能忠实移植进回测的只有 18.7%,其余测的不是那个策略。 第 8 项 裁剪法(唯一能全自动抓最隐蔽错误的检查):全量跑一次、砍掉尾部重跑一次、 逐行比对,数字变了就说明用了未来数据。 其余各项覆盖:复权乘数法、幸存者偏差、4σ 脏数据、夏普而非年化、242 交易日、 无风险利率、lag1 仓位、参数不超过 5、样本外不少于三分之一、敏感性测试、 换手成本、模拟交易;第 14 项夏普 t 检验为我方补充。 什么时候该用它:回测夏普很高但不敢下真钱;自己写的策略不确定有没有偷看未来; 用了别人的选股 skill 想确认它测的是不是它说的那个策略;想把策略做成付费信号先过一遍。 另一类常见用法:策略实盘一直跑输回测,用它定位是哪一层出了假。 怎么用(按你手上有什么选,全部离线,不需要联网、不需要行情接口): 只有代码 → 静态巡检 30 秒,列出已知形态的坑; 代码 + 收益序列 → 裁剪法几分钟,直接判有没有未来函数; 代码 + 生产策略脚本 → 口径对账 1 分钟,判你测的是不是那个策略; 四样齐全 → 完整体检十几分钟,出 Markdown + 自包含 HTML 报告。 触发词:回测体检、回测防坑、查未来函数、这个回测是不是过拟合、我的策略回测靠谱吗、 这个策略能不能信、回测诈欺、策略体检、回测审一遍; 旧名「照妖镜」「照一照」「帮我检查这个回测」继续有效。 它不选股、不给买卖信号、不预测涨跌、不承诺收益,只回答一个问题:你这份回测有多少是假的。 与「炒股策略可信度检验」的分工:本工具查代码(回测是不是真的), 可信度检验查结论(就算真的,样本够不够撑起这句话)。 顺序是:先体检代码 → 再检验结论 → 才谈能不能用。

一句话选型结论

按资料字段整理

回测防坑体检是效率类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类效率 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_b35a0bc0/zhaoyaojing
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

效率
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_b35a0bc0仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验2026-11-06上游最后核验时间 · 数据更新 2026-11-06
正文体量29.5 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
整理待办与日程

把零散任务收进清单,排出优先级。

批量处理重复任务

把固定动作做成模板,重复执行。

把流程写成清单

把口头流程整理成可复用的步骤。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在效率场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
回测防坑体检当前 未标注权限 未标注 未标注 未标注 有
Nano PDF 文档 联网访问 ClawHub 市场 424.9 万 OpenClaw 有
自动更新程序 浏览器控制 ClawHub 市场 296.4 万 OpenClaw 有
Gemini 助手 联网访问 ClawHub 市场 254.7 万 OpenClaw 有
word DOCX 文档 联网访问 ClawHub 市场 239.6 万 OpenClaw 有
Excel XLSX 前端 联网访问 ClawHub 市场 227.0 万 OpenClaw 有

SKILL.md 全文

29.5 KB
模型实际读到的说明书原文,来自技能仓库

回测防坑体检

> 一份回测可以跑得很漂亮,同时完全是假的。
> 未来函数、过拟合、幸存者偏差、被你悄悄剔掉的那 0.59% 跌停样本,共同特征是
> 让它好看,让你亏钱,而你在代码里看不出来。
>
> 本工具只有一条原理——把未来砍掉,看历史会不会变。变了,就是坑。

一分钟看懂怎么用

你手上有什么 跑什么 多久 得到什么
回测代码 静态巡检 30 秒 已知形态的坑,逐条列出来
回测代码 + 收益序列 裁剪法 几分钟 有没有未来函数(唯一能全自动抓出来的一项)
回测代码 + 生产策略脚本 口径对账 1 分钟 你测的是不是那个策略
以上齐全 完整体检 十几分钟 14 项 PASS/FAIL 清单 + 修复建议 + 报告

不需要联网,不需要行情接口,不需要任何金融数据 MCP。有代码就能查。

一句话分工:本工具查代码(回测是不是真的),「炒股策略可信度检验」查结论(就算真的,样本够不够撑起这句话)。

0. 先读这一段(定位与免责)

这不是选股工具,不产生任何买卖信号。

它只做一件事:在你把真钱押上去之前,告诉你这份回测有多少是假的。

三个必须先接受的判断:

  1. 回测是筛子,不是保证书。 通过体检只代表「没有明显的错」,不代表「能赚钱」。
  2. 大部分漂亮回测死在检查环节,不是死在市场。 我实测过一份 75 条规则的选股体系,能忠实移植进回测的只有 18.7%,50.7% 属于重度漂移——代码能跑、不报错、数字很干净,但它测的不是那个策略。
  3. 本工具能抓到「已知形态」的错,抓不到「你想不到」的错。 所以它降低风险,不消除风险。

如果用户想要的是「帮我找个能赚钱的策略」,请直接说明:这件事我做不到,任何人说能做到都是在骗你。 然后推荐他去看本 skill 能提供的三样东西——诚实的测量、明确的边界、可查证的状态。


1. 什么时候用 / 什么时候别用

该用:

  • 刚写完一份回测,数字很好看(尤其夏普 > 1.5、年化 > 30%),想在上真钱前过一遍
  • 拿到别人的策略/指标/公众号方案,想快速判断可信度
  • 自己的策略实盘一直跑输回测,想定位是哪一层出了问题
  • 要给一份策略写报告,需要一段可查证的「已验证到什么程度」

别用:

  • 还没写回测(先去写,别拿体检表当回测替代品)
  • 想要参数寻优(这是过拟合的加速器,本工具反对)
  • 只有一两个月的样本(几乎所有项都会判「数据不足」,先攒样本)

2. 四段漏斗(先定位,再体检)

快筛  →  细查  →  模拟  →  实盘
阶段 允许跳过什么 不许声称什么
快筛 可跳过部分检查,先判有没有潜力 不许说「策略有效」
细查 13 条逐条过,一条不许跳 不许说「可以上实盘」
模拟 paper trading 跑几个月,让隐藏问题自己浮出来 不许说「已证明」
实盘 小仓位,运行后反复研究、回填修正 —

每份报告必须带一行元数据:验证阶段 = 快筛 / 已验证样本外区间 = ____。
这样「这个策略回测过」就变成了可查证的状态,而不是一句笼统的自信。

体检时用 --stage quick|detail|paper|live 声明当前阶段。


3. 13 项体检表(速查)

工具会自动判定前 13 项 + 补充第 14 项,状态为 PASS / FAIL / MANUAL。
动手之前先做第 0 步 —— 口径对账。它过不了,后面 14 项全白做。

# 层级 检查项 自动判?
0 前置 回测规则 = 生产脚本?(rule_parity.py 对数字,实跑对逻辑) 自动(v1.3.0 新增)
1 数据 复权用乘数法,不是减法 半自动(扫代码)
2 数据 幸存者偏差已声明(股票池含不含退市股) 需 --universe
3 数据 日收益 >4σ 先查脏数据 自动
4 度量 只看夏普 + 最大回撤,不看年化收益 自动
5 度量 年化系数用 242,不是 252 自动
6 度量 无风险利率扣除规则正确 需 --rf
7 偏差 PnL 必须乘 lag1 仓位 半自动(扫代码)
8 偏差 裁剪法验未来函数 自动(核心)
9 过拟合 参数 ≤ 5,数据点 ≥ 参数 × 252 自动
10 过拟合 样本外 ≥ 1/3,按时序切 需 --oos-frac
11 过拟合 敏感性测试,微调就崩 = 过拟合 需 --sensitive
12 成本 成本按换手率逐日扣,不为零 自动
13 验证 最终检验 = 模拟交易 需 --stage
14 补充 夏普过 t 检验(我方补充,原书没有) 自动

逐条详解与 A 股适配见 references/13条铁律.md。做体检前必读第 8 条、第 12 条、第 14 条。


4. 核心:裁剪法(第 8 条,唯一能自动抓未来函数的检查)

原理

未来函数的本质是:某一天的决策用到了那一天还不可能知道的信息。
那么——把未来的数据砍掉,必然改变那一天的输出。

全量跑        A = run(全部数据)
截断跑        B = run(只保留 <= D 的数据)
A 只留 ≤ D 的行,与 B 逐行比对

完全一致   →  D 这个截断点上不存在未来函数
有任何差异 →  存在未来函数,或跨日状态泄漏

★★ 关键:两种实现模式,效果天差地别

原理简单,但「怎么砍掉数据」决定了检测是否真的有效。这是本工具最重要的一条工程结论,来自我自己的实测踩坑。

模式 A 契约式 模式 B 文件切片式 ★推荐
怎么砍 把 end_date 传给策略,靠策略自觉不去读未来数据 工具直接把数据文件临时替换成「只含 ≤D 行」的版本,在干净子进程里重新 import 策略
策略要不要改 要,必须实现 end_date 契约 一行都不用改
能不能被绕过 能——策略直接读全局数组就绕过了 不能——它读的就是被切过的数据
实测结论 会给出假阴性 可靠

我实测过:一个用「明天收益率」筛股的坏策略,在契约式下 5/5 截断点全部判「一致通过」。
原因很简单:end_date 只过滤了输出日期,数据可见性一点没动——策略照样读到完整的未来。

所以:能用模式 B 就一定用模式 B。 模式 A 只在「数据源不是单一 CSV、无法切片」时才退而求其次,且必须知道它的结论不可靠。

模式 C:面板切片式(.npz 面板 + meta.json)★ 量化引擎最常见形态

很多回测引擎不是读 CSV,而是读「OHLCV 二维面板 + 独立 meta」:

panel.npz   O/H/L/C/V 等 (N 只 × T 日) 数组
meta.json   {dates:[...], codes:[...], names:{...}}

工具会把面板沿日期轴截断,同时把 meta 的 dates 同步切短,再跑子进程。两个文件都在 finally 里还原。

python scripts/truncation_test.py --module my_engine.py --entry generate \
  --data-file panel_hist.npz --panel-meta meta_hist.json --date-axis 1
  • --date-axis:日期在哪一维。(股票×日期) 布局是 1(默认)。
  • 必填 --panel-meta:面板和 meta 必须同步切,否则数组长度与日期错位。
  • 会先备份两个文件、最后必定还原;但切 200MB 面板会写盘,跑之前自己再备一份。

★★ --settle-lag:输出含收益时必须设

如果策略输出里含收益,而收益要 T+2 才结算(或有跌停顺延),那截断到 D 时,D 和 D-1 的信号天然算不出收益。
这会在裁剪法里表现为「全量有、截断无」的假分歧。

正确做法不是去改策略,而是把比较截止日往前推:

# 结算需要 2 天、最大顺延 5 天 → lag = 7
--settle-lag 7

判断方法:先 --settle-lag 0 跑一遍,看分歧是否全部落在截断日当天与前一天。
是 → 边界效应,加 lag;不是(更早的日期也在缺、或出现「凭空多出」/「值差」)→ 真问题,继续查。

模式 B 的用法(推荐)

python scripts/truncation_test.py \
  --module my_strategy.py \
  --data-file prices.csv \
  --data-date-col date

工具会:备份 prices.csv → 逐点写入截断版 → 子进程重跑 → 比对 → finally 恢复原文件(即使中途报错也会恢复)。

对策略的唯一要求:从 --data-file 那个文件读行情,或者从环境变量 BT_AUDIT_DATA 读路径(工具会自动设置)。

模式 A 的用法(退路)

python scripts/truncation_test.py --module my_strategy.py --entry generate

要求策略暴露:

def generate(end_date=None):
    """
    end_date : 'YYYY-MM-DD' 或 None
               非 None 时,只允许使用交易日 <= end_date 的数据
    """

工具额外做契约检查:generate(D) 的输出里不许有 date > D 的行。这能抓「完全无视契约」的策略,但抓不到「遵守了日期、却偷读全局数组」的。

三个实操要点

  1. 单点通过不代表整体清白。 默认 11 个等距截断点,都必须在实际出过信号的日期上(工具已自动处理,早期没信号的日期不会浪费一个检查位)。
  2. 截断日别贴样本末尾,每个点后至少留 5 个交易日间隔。
  3. 两种分歧特征指向不同病因:
    - 「全量有、截断无」 → 策略依赖了「下一日才存在」的数据(典型:明日收益率、次日开盘价)
    - 「截断凭空多出」 → 策略用未来数据改了基准(典型:整段样本最高价、全样本分位数)

★ 它抓不到什么(诚实边界)

盲区 为什么抓不到 怎么抓
未来信息以字面量写死在代码里 没走数据通道,切片不影响输出 人工代码审查。看到像股票代码的魔法常量、神秘数字列表就该警觉;查 git diff 看谁加的
策略从第二个未被切片的文件读未来信息 只切了 --data-file 那一个 把该文件也纳入切片,或改成单一数据入口
未来信息来自网络请求 / 数据库实时查询 同属第二条通道 同上

这条边界不是缺陷,是原理决定的。任何宣称「能抓所有未来函数」的检测都在撒谎。

scripts/_verify.py 会把这四种情况(含假阴性用例)跑成验收表,你可以自己验:

python scripts/_verify.py

它会输出一张 4 行对照表,其中 bad_hardcoded(写死的未来赢家)预期就是「通过」——用来演示边界,不是 bug。


5. 完整体检流程

第零步:口径对账(v1.3.0 新增,一分钟)

python scripts/rule_parity.py --prod 生产脚本.py --bt 回测规则.py

拿生产脚本里的每一个数值阈值,去回测代码里找。找不到就是两套口径。

为什么它排在最前面:口径不对时,其余 14 项全能通过 —— 因为它们检查的是「这段代码内部自不自洽」,而口径漂移是「这段代码和那个策略不是一回事」,两者正交。

真实代价:某策略回测缺一个 vr5 >= 2.2332 放量门,可结算命中 8,692 笔虚增成 45,314 笔,alpha 从 +0.2754% 被稀释成 +0.0894%(只剩 1/3),t 值 3.432 掉到 2.548 —— 一个能过 Bonferroni 的结论,被这个漏洞拖成「不显著」。裁剪法当时 4/4 零偏差照样通过。

判定分层:

生产侧 回测里找不到 处理
策略常量(VR5_MIN = 2.2332) FAIL 必须补齐,重跑,别在原结果上做结论
工程常量(NBARS / VR5_SOFT) SKIP 数据规模、观察池、并发数,天然不必进回测
内联字面量(*1.2 / <0.02) WARN 可能换了等价写法,人工核

> ⚠️ 它只比数字,不比逻辑。 两端数字都在、但一边写成 V &gt; vma5*1.2、另一边写成 V &gt; vma5*0.8333(语义已崩),它看不出来。数字对齐只是及格线,必须再实跑一次 parity:同一天、同规则,比对命中票集合与指标值,重合率 < 90% 不予采信。

> ⚠️ 注释能骗过朴素实现。 工具比对的是剥离注释与字符串之后的代码文本。首版用全文正则时,把门槛偷改成 9.9999 而注释里仍留着 2.2332,它照样报 PASS —— 这个坑实测踩过,别再用全文搜索。

第一步:静态巡检(30 秒)

python scripts/audit.py --code my_strategy.py

扫三类已知危险写法:

  • 未来函数:负向 shift(-、iloc[i+1]、center=True、bfill、np.roll 负偏移、无窗口 cummax/expanding、对整段序列直接 .max()
  • lag1 缺失:收益直接乘当期仓位
  • 成本缺失:cost = 0、完全没有成本变量

命中 HIGH 级会直接判对应铁律 FAIL。

> ⚠️ 静态扫描只能发现已知形态。 它命中不代表一定错(可能是注释或误报),它没命中更不代表没问题。能证明没有未来函数的是裁剪法,不是它。

第二步:裁剪法(核心,几分钟)

见第 4 节。把结果存成 JSON。

第三步:完整体检 + 出报告

python scripts/audit.py \
  --code my_strategy.py \
  --signals 信号.csv \
  --params 3 \
  --oos-frac 0.33 \
  --cost-bp 20 \
  --rf 0.02 \
  --n-per-year 242 \
  --universe current \
  --sensitive stable \
  --stage detail \
  --truncation-json trunc.json \
  --md 体检报告.md

输出:13+1 行体检表 + 实测指标(夏普 / t 值 / 最大回撤 / 年化)+ 一句话结论 + Markdown 报告。

信号表格式:至少 date、code 两列,有 ret 列则自动算夏普、回撤、4σ 异常点。


6. 最常见的一批病(都是真实踩过的)

按出现频率排,这七种占了绝大多数:

① 口径漂移:回测的根本不是那个策略

症状:代码能跑、不报错、数字干净,但测的和实际执行的不是一回事。

四种形态:

形态 例子
「全部必中」被写成「≥N」 生产要求 4 个条件同时满足,回测写成「满足任意 N 个」——命中数差 100 倍
「N 选 1」被写成「1 条」 生产是「5 条中取最强 1 条」,回测写成「满足第 1 条」
时序反向 生产是「先跌后涨」,回测写成「先涨后跌」——交集为 0,代码不报错,最隐蔽
核心字段用代理未标注 换手率用 vr20 代替、市值用 pos60 代替,但报告里仍写「换手率」

铁律:回测规则必须逐字移植生产脚本;不许为「能跑起来」自行简化;文档与代码冲突时以生产脚本为准。
新增规则先进 parity 测试,重合率 < 90% 不许进回测。

v1.3.0 起这一步有工具了:python scripts/rule_parity.py --prod 生产.py --bt 回测.py
(此前只写了要求没给工具,只能人工逐条对账 —— 代价就是漏掉了上面那个 vr5 门槛,见第 5 节第零步。)

② 把跌停样本剔掉(打板类专吃这个)

症状:卖出日跌停的样本直接剔除,不带走。

后果:这类样本占比可能只有 0.59%,但剔除它会把「必亏」洗成「可重仓」——实测某条规则从 −0.85% 变成 +0.55%,另一条从 −1.38% 变成 +0.98%。符号翻转,不改变任何其他设置。

正确做法:必须顺延卖出(≤5 个交易日),禁止剔除样本。

③ 用整段极值而不是「至今极值」

week_high = high[week_days].max()          # ❌ 含未来日
week_high = np.fmax.accumulate(...)        # ✅ 只取本周至今

实测:这条 bug 曾造出一个「+3.55%、t=13.66」的假发现,修正后是 −0.16%。

④ shift() 对 bool 数组补 NaN,NaN 被当 True

np.full_like(A, nan)     # ❌ bool 数组里 nan → True
np.zeros_like(A, bool)   # ✅ 补 False

后果:所有「历史上 N 天内出现过 X」的判断,在序列开头凭空多出 N 天「全市场命中」。实测因此生出 13,391 个假事件。

⑤ 分组键跨年撞号

key = year * 100 + isoweek          # ❌ 2024-12-30 与 2024-01-01 混进同一周
wk_start = (dts - to_timedelta(dts.dayofweek)).normalize()   # ✅

⑥ 用「年化收益率」代替夏普做判断

年化收益可被杠杆任意放大。10 倍杠杆把 5% 做成 50%,数字漂亮,风险也 10 倍。只看夏普 + 最大回撤。

⑦ 忽略夏普的统计显著性

这是最普遍、也最不容易被接受的一条:

真实夏普 达到 95% 显著所需样本
0.25 63.4 年
0.50 17.3 年
1.00 5.8 年
2.00 2.9 年

低夏普策略在统计上永远无法被证明。 一份 3 年样本、夏普 0.8 的回测,它和「什么都没有」在统计上无法区分。这不是策略不好,是样本不够。

「3 日持有 + 涨 10%」这类短线口径,单次交易的 t 值只有 0.111,比显著门槛低 17.6 倍。单次盈亏不含任何关于策略优劣的信息。


⑧ 8 位紧凑日期被当成纳秒时间戳(工具自己也踩过)

pd.read_csv 在 pandas 3.0 返回 StringDtype,pd.to_datetime 会把 &#x27;20190403&#x27; 当纳秒时间戳,
结果全部变成 1970-01-01,样本塌缩成 1 天,而且不抛异常。

后果:夏普、t 值、回撤全错,报「样本只有 1 天」。或更糟——裁剪法把上千个交易日压成同一天,
比对时 key 全撞在一起,可能给出假阴性。

v1.2.0 起 audit.py 与 truncation_test.py 都加了 _date_to_iso():先判断是否 >90% 为 8 位纯数字,
是则用 format=&quot;%Y%m%d&quot; 显式解析。

自查:跑完体检先看「样本期数」是否等于你预期的交易日数。差一个数量级就是踩了这个坑。

7. 拿真实 skill 开刀:适配层怎么写

现有选股 skill 基本都是逐只 HTTP 拉数据的扫描器,没有一个可以被 --data-file 切片的数据文件。所以必须先写一层适配,规则本体不动。

两条铁律

  1. 规则函数原样 import,一个字都不许改。 例:隔日法的 judge() 直接从 scan_today.py import,只重写「取数 + 循环 + 阶段流程」。
  2. 阶段流程也要照搬。 隔日法是两阶段的:先用不复权价粗筛,再对候选做前复权复核。只跑其中一种,测的就不是那个策略。

标准做法

① 把行情落成单一长表 CSV(date, code, open_raw, close_raw, open_qfq, close_qfq, vol)
   两套价都要有 —— 因为生产是两阶段的,缺一套就只能测半个策略。

② 适配层 generate(end_date=None):
   for 每只股票:
       for 每个交易日 t:
           judge(c_raw[:t+1], v[:t+1], o_raw[:t+1])        # 阶段一
           若过:judge(c_qfq[:t+1], v[:t+1], o_qfq[:t+1])   # 阶段二
           两者都过才算命中

③ 只传最近 260 根(与生产 NBARS 一致)
   judge 最长回看是 vma60s[-20],需要 v[-79:],260 根足够,
   且与传全历史结果完全一致 —— 但速度快几十倍。

④ 跑 parity:用生产自己的 fetch_kline + truncate + qfq_close 跑 HTTP 数据,
   与适配层的本地面板结果逐项对比。**重合率 &lt; 90% 不许进回测。**

⑤ 跑裁剪法:--data-file 指向 ①的那个 CSV

性能参考

judge() 单次约 246 µs。500 只 × 1800 天 × 2 阶段 ≈ 180 万次 ≈ 7 分钟/轮。
所以实操要把样本压到 200~300 只 × 700~900 天(约 40 秒/轮),信号量仍在 200 笔上下,足够做裁剪法比对。

信号密度参考:224 只子样本 → 204 个信号 / 171 个交易日。但平均每日仅 1.19 只,84.7% 的交易日只有 1 只票。这时「组合日收益」退化成「单笔收益」,夏普与 t 值稳定性很差 —— 子样本数字不能拿去肯定或否定策略,它只用来验证链路和统计检验能不能跑。


8. 输出规范

一句话结论(必须放在最前面)

三档,不许模糊:

情况 话术
0 项 FAIL、0 项未验证 「全部通过。可以进入模拟交易阶段验证。」
0 项 FAIL、有未验证 「无硬伤,但 N 项未验证。补齐后才能谈「策略有效」。」
1–3 项 FAIL 「不通过:N 项硬伤(第 x、y 项),修完重跑。」
≥4 项 FAIL 「不通过:N 项硬伤。当前回测结论不可采信,先修问题再看数字。」

硬性要求

  • 未验证 不许写成 通过。 空格子就是空格子,不能默认填绿。
  • 任何「命中率 XX%」必须同时给样本量,并标注 n&lt;50 探索期 / 50–200 观察期 / ≥200 可下结论。
  • 报告末尾必须写边界:静态扫描只抓已知形态;通过体检 ≠ 能赚钱。
  • 用户要求出报告时,按用户既定铁律交付 MD + 自包含 HTML 双文件(同目录同名、0 外链、浅色、涨红 #c62828 跌绿 #2e7d32、@media print、表格横向滚动)。

9. 与其它 skill 的关系

本 skill 不选股、不给信号,只审别人的结果。

被审对象 审什么
短线 / 抄底 / 野渡技术 / 一夜持股法 回测代码是否忠实移植生产脚本(病①)、跌停是否顺延(病②)、夏普是否显著(病⑦)
隔日选股法 裁剪法零偏差已验证;重点看成本敏感性与样本外
任何外来策略 先跑静态巡检 + 裁剪法,两项都过再谈细节
炒股策略可信度检验(evidence-grade,配套) 代码审完之后再判结论:样本量配不配得上「策略有效」这句话

审别的 skill 时的第一条永远是:代码里的规则,和生产脚本是不是同一个东西? 这条过不了,后面 12 条全白做。


10. 版权与出处

  • 方法论来源:Ernest P. Chan《量化交易从入门到精通:如何构建你的算法交易系统》第 3 章,姜军略 译,人民邮电出版社,ISBN 978-7-115-56103-9。
  • 本文档性质:方法论转述 + A 股制度适配 + 可执行检查动作,非原文转录。引用时请注明来源,不得大段复制原书文字。
  • 我方原创补充:第 14 条夏普 t 检验、A 股 242 交易日口径、T+1 合规持有期(T 选→T+1 买→T+2 卖)、涨跌停顺延规则、单笔成本生死线 10,204 元、以及第 6 节全部真实踩坑案例——原书均未涉及。

11. 工具清单

文件 作用
scripts/rule_parity.py 口径对账(铁律 ①)。拿生产脚本的策略常量去回测代码里找,剥离注释后比对;注释里留着旧数字骗不过。只比数字,逻辑等价仍需实跑 parity
scripts/truncation_test.py 裁剪法自动检验(铁律 8)。三模式:契约式 / 文件切片式 / npz 面板切片式;--settle-lag 可排除结算窗口造成的假分歧
scripts/audit.py 13+1 项体检主程序,静态巡检 + 动态指标 + Markdown 报告
scripts/_verify.py 工具自检,4 个已知好/坏用例跑验收表,证明工具有效且边界明确
scripts/_selftest.py 自检用的伪行情生成器 + 4 个测试策略
scripts/_run_entry.py 内部运行器(文件切片式用子进程保证干净 import),不面向用户
references/13条铁律.md 逐条详解与 A 股适配,做体检前必读

依赖:Python 3 + pandas + numpy。无需联网,无需任何行情 MCP。

装完先自检(30 秒)

cd scripts
python _selftest.py     # 造假行情
python _verify.py       # 跑验收表

预期输出:

用例                真相                  预期      实际      判定
good              清白策略                通过      通过      符合
bad_future_ret    用明日收益率              不通过     不通过     符合
bad_future_peak   用整段最高价              不通过     不通过     符合
bad_hardcoded     写死的未来赢家             通过      通过      符合

第 4 行「通过」是故意的——它是已知盲区,用来提醒你边界在哪。什么时候第 4 行变成「不通过」了,说明有人把工具改坏了(或者加了静态常量扫描)。

如果前 3 行有任何一个不符预期,这个工具就不可用,别拿它的结论去做决策。

实测记录(v1.0.1)

首次真实数据审计对象 = 野渡隔日选股法。产物在 E:/workfwb/_audit/:

文件 内容
_build_audit_data.py 面板 → 可切片长表(含复权前后两套价,带列序校验)
_audit_geri.py 适配层,judge() 从生产脚本原样 import
_parity_geri.py 口径一致性校验
回测体检_野渡隔日选股法.md/.html 完整体检报告

结果:口径 parity 5/5 = 100%(命中票的 dist25/vr5 精确到 6 位小数一致)、裁剪法 5/5 零偏差、3 项硬伤(参数 9 个超上限、幸存者偏差、夏普 t=0.90 不显著)。

这次实测还抓出本工具自己的两个 bug,已修(v1.0.0 → v1.0.1):
1. 静态巡区分大小写 → 漏报 COST = 0.0020、qfq_close。已改 re.IGNORECASE 并支持「名字在前、数值在后」写法。
2. 4σ 检查把「单票集中度」误报成「脏数据」→ 平均每日信号 < 1.5 只时改判「未验证」并说明原因。

常见问题

5 问
答案由本站依据条目字段整理
回测防坑体检怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_b35a0bc0/zhaoyaojing。安装方式为未标注。装完刷新技能列表或重开客户端。

回测防坑体检支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

回测防坑体检权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

回测防坑体检收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

回测防坑体检用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 2026-11-06。