框架

续接任务提示词 · 回测引擎 v2.0 → 多资产组合(阶段 1)

回测/engine_v1/(20 个文件,独立可运行、只读 数据/、不接入 fetch.py 管线):

optimization · 资产·机制 · optimization/提示词/继续任务提示词_2026-09-27_回测引擎v2.0与多资产.md · 21656 B

续接任务提示词 · 回测引擎 v2.0 → 多资产组合(阶段 1)

生成:2026-09-27 | 仓库:/var/minis/mounts/DUCKERRY_Warehouse

用法:新对话直接粘贴本文件末节「八、供新对话粘贴的最小提示词」整段即可冷启动。

本文件是完整的离线上下文——上一轮会话很长,本文件已把「已完成的 / 已证伪的 / 待办的 / 会踩的坑 / 登记规范」全部固化,新会话不需要上一轮的对话历史。


零、开工前必读(iSH 环境纪律 —— 最容易翻车的一条)

纪律说明
单进程 ≤ 2 分钟iSH 上单个 Python 进程约 2 分钟被静默 kill:rc=0、无 traceback、nohup 也挡不住。长任务必须拆成多个 <2 分钟的短进程串行跑(例:walk-forward 逐折单独跑、绘图单独跑)
nohup 的正确写法nohup sh -c '…' >/dev/null 2>&1 & ✔ | A && nohup B & ✘ —— 会把 A 也放进后台,并随 shell 退出一起被杀
无 CJK 字体容器 fc-list 为空 → matplotlib 图例/标题一律 ASCII,否则满屏 Glyph missing 警告
算与画分家绘图步骤本身也可能跑过 2 分钟 → 先落盘数据,再由独立脚本出图(见 回测/engine_v1/plot_compare.py 的先例)
等待机制用 shell_execute 的 delay 参数轮询,不要在命令里 sleep

一、已完成、不要重做(可复核,勿破坏)

1.1 引擎 v2.0 已入库

回测/engine_v1/(20 个文件,独立可运行、只读 数据/、不接入 fetch.py 管线):

文件说明
duckerry_backtest.py主引擎约 1490 行:L0–L4 决策栈 + 四因子 A/B/C + 降频 + 核心卫星 + 否决权 + walk-forward
plot_compare.py独立绘图脚本(从已落盘 equity.csv 出图)
README.md使用说明与口径边界 → 回测/engine_v1/README
compare.csv / compare_curve.png六策略横向对比表与净值图(对数轴)
curves/{BuyHold,Cash6040,D-L0L2VT,W-Adp60,W-Adp60NoEv,M-Adp60}.csv各策略净值曲线(date, equity, dd, sat_pos)
wf/{oos_equity.csv,oos_summary.json,fold_0..5.json}样本外 walk-forward 全套(626 条周线,2014-01→2025-12)
metrics_weekly_core60.json主推配置完整指标 + 实际生效 config

工作区副本(可改):/var/minis/workspace/duckerry_backtest/;共享副本:/var/minis/shared/duckerry_backtest/。

1.2 三条设计指令已落地

  1. 强制降频:--freq D|W|M;重采样在指标计算之前;日频阈值按 √(252/ppy) 缩放(周 ×2.20 / 月 ×4.58);年化口径随频率切换
  2. 宏观主观否决权:L0 断路 + |收益|≥2.5σ + 规则化非农(--veto-scope auto 月频自动禁用);--veto-mode flat 卫星清仓
  3. 核心60%+卫星40%:总仓位 = core + (1−core)×卫星;成本只对卫星换手计;--strategy adaptive(趋势态顺势 / 震荡态均值回归)+ --l1-method trendstate(ADX + Kaufman 效率比 + Hurst)

1.3 已修的 4 个实现缺陷(留档,勿回退)

  • 月频事件否决「每月都被否 → 卫星永不交易」(→ --veto-scope auto)
  • 年化因子硬编码 252(周/月夏普被高估 √(252/ppy) 倍 → infer_ppy())
  • build_event_veto 每 bar 调 pd.date_range(34s → searchsorted 向量化 + 三层缓存)
  • tgt = tgt * w 使 int 变 float → f"{tgt:+d}" 崩溃(→ {tgt:+.2f})

1.4 自检状态(全绿,勿破坏)

arch_check 11/11 ✔(md=215 / 出链=770 / 死链 0 / 孤儿 0)|doc_sync_check --strict rc=0|moc_index 无需更新(复盘 96 / 归档 44)


二、核心结论(已论证,不要重新论证)

2.1 等敞口公平对比 → 卫星没有 alpha

变体均敞口收益/夏普/回撤等敞口被动
周频·自适应+核心60%(事件否决)68.4%263.0% / 0.556 / −33.0%345.1% / 0.644 / −31.5%
周频·同上但无事件否决72.8%320.2% / 0.579 / −33.6%383.9% / 0.644 / −33.2%
月频·自适应+核心60%75.3%339.9% / 0.562 / −39.7%383.9% / 0.640 / −32.3%

2.2 但降频明确有效

样本外夏普:日频 0.286(落后基准 0.236)→ 周频 0.754(落后等敞口被动仅 0.058)。

2.3 事件否决的代价明确

同配置下非农否决:总收益 320% → 263%(−57pp),回撤仅改善 0.6pp。

2.4 ⭐ 多资产预检(这是下一步的依据,已用现成数据验证)

gold_pm.json + fred_NASDAQ100.csv,两条腿,零参数(60 日逆波动率加权),不做任何方向预测:

1986-01 → 2026-09(41 年 / 10475 交易日)年化波动夏普最大回撤卡玛
黄金 100%6.38%15.9%0.47−49%0.13
纳指 100%14.02%25.9%0.64−83%0.17
等权 金+纳指11.41%15.1%0.79−52%0.22
风险平价 金+纳指10.87%12.6%0.88−33%0.33

子区间(风险平价夏普 / 黄金夏普):1986–1999 0.77/0.00 | 2000–2009 0.64/0.79(唯一跑输) | 2010–2019 0.94/0.29 | 2020–2026 1.42/0.94

诚实口径:这不是"必胜"。2000–2009 组合跑输(那十年只有黄金好)。

它是用"放弃单一资产的极端表现"换全周期稳定性;但因为是无参数的,过拟合空间远小于前面的择时模型。

另一条重要发现:41 年黄金年化只有 6.38%、卡玛 0.13 —— "黄金 2006–2026 涨 7 倍"很大程度是选了个好窗口。

2.5 结论:换问题,不换参数

不继续调参(网格择优不稳定 + 单样本 + 无多重检验校正)。方向: ① 猜方向→管风险 | ② 单资产择时→多资产分散 | ③ 手搓 regime→统计 regime | ④ 单次网格→嵌套 WF + Deflated Sharpe


三、待办(按阶段,阶段 1 即本次任务)

阶段 1 ·【本次任务 · ✔ 已执行 2026-09-27】回测层多资产组合模块(仓库近乎零改动)

✔ 交付:回测/engine_multi/(使用说明);结论与口径修正见驾驶舱 §九 v5.2.5。

目标:在回测层验证「分散」是否真的优于「择时」,产出可复核的净值与指标。

  • 位置:新建 回测/engine_multi/(不要改 engine_v1/,v2.0 需保持可复现),只读 数据/
  • 资产池(全部现成,无需新数据):
资产源起始可交易性
黄金数据/gold_pm.json1968-04可交易
纳斯达克100数据/fred_NASDAQ100.csv1986-01可交易(期货)
标普500数据/fred_SP500.csv2016-09可交易(期货)
WTI 原油数据/fred_DCOILWTICO.csv1986-01可交易(期货)⚠ 见 §六坑 3
TLT / AGG数据/bond_{tlt,agg}.json2026-06可交易(样本极短,仅作参考)
  • 组合方法:① 等权 ② 逆波动率(风险平价)③ 风险预算 / HRP(PyPortfolioOpt、Riskfolio-Lib 思路,可先手写)
  • 必须产出的三张表:
  • 全样本(1986–2026 及 2006–2026 两个窗口)各资产 / 各组合 的 收益·波动·夏普·回撤·卡玛
  • 子区间稳健性表(1986–1999 / 2000–2009 / 2010–2019 / 2020–2026)
  • 等敞口公平对比(组合平均敞口 vs 同敞口被动;沿用报告 §3.2 的方法)
  • 可选的进阶:给"决策栈"换一个决策变量——不再猜方向,而是决定每期权重(风险预算);保留 L0 作为降杠杆开关(而非清仓开关)
  • 验收标准:① 三张表齐全且可复现;② 结论与 §2.4 一致或给出反例;③ arch_check 11/11 + doc_sync_check --strict rc=0;④ 产出 回测/engine_multi/README.md + 净值曲线 CSV

阶段 2 ·(阶段 1 验证后再做)面板与分析层小改

  • scripts/dkpanel.py:build() 的 FRED 循环加新 asset 列(加列不改行数,doc_sync_check 第 10 项不受影响)
  • CORE = ["gold_pm","10y_nom","10y_tips"] 不动 → G1 闸门不受影响
  • scripts/dkanalysis.py:283 的 s = T["gold_pm"] → 加参数 series="gold_pm"(向后兼容,黄金调用不变)
  • 新增 scripts/portfolio.py(等权 / 逆波动率 / 风险预算)——每日只算权重、只记录,不下单
  • 数据/ 新资产数据 → 在 数据库说明 §〇·五·一 登记来源与口径

阶段 3 ·(真·大改,先别做)执行层与复盘层

文件为什么是真活
scripts/paper_engine.py现在是单标的模型(buy_amount/short_amount/cash,无"品种"概念)→ 多腿权重 + 再平衡,约等于重写
复盘模板 + duckerry-daily-review SKILL全是黄金单标的叙事(L0-1 金/美同跌、L1 黄金5日动量、A/B/C 黄金主导因子)→ 每日 SOP 变重、失败点 ×N
predict_regime_conditional.py / pattern_abc.py / brier_calibration.py整条黄金预测链 → 要么 per-asset(成本 ×N),要么保持黄金专用

必须先回答的设计问题:你要的是「组合层资产配置」(黄金只是其中一条腿 → 大改),还是「黄金择时增强」(黄金仍是主角、其他资产只当分散器 → 小改,阶段 2 就够)?

建议后者——整个仓库的叙事/技能/预测链都围绕黄金建立,没必要推倒。若选后者,则阶段 2 完成即收工。


四、GitHub 资源与整合方式(用户正在下载)

4.1 放哪里 / 怎么登记(重要)

  • 解压到 /var/minis/mounts/武器库/(与现有 PyBackLab-main / akshare-main / convex-main / fixed-income-mcp-main / trace-data-pipeline-main 同级)
  • 在 数据库说明 §〇·五·一「外部思路源」段落登记,遵循既有红线原文:

「两者均未安装、无 pip 网络,只作设计参考,不接入、不 import」

  • 不要把第三方库 import 进 scripts/ 生产链;需要用时在 回测/ 下自建独立脚本

4.2 已核实仓库清单(2026-09-27 经 GitHub API 实测;★为当时星数)

仓库★对应阶段用途
[pst-group/pysystemtrade](https://github.com/pst-group/pysystemtrade)(原 robcarver17,已改名)3.5k1·2首选。Rob Carver 系统化交易:"不要预测,要分散"、多品种小仓位、forecast scaling、风险目标化
[stefan-jansen/machine-learning-for-trading](https://github.com/stefan-jansen/machine-learning-for-trading)21.0k1·3regime detection 专章(HMM/GMM,可替换手搓 ADX/Hurst)+ 回测陷阱章节
[hmmlearn/hmmlearn](https://github.com/hmmlearn/hmmlearn)3.4k3标准 HMM;仓库已有 regime_hybrid.py,应对齐而非另起一套
[polakowo/vectorbt](https://github.com/polakowo/vectorbt)9.2k1向量化,参数扫描 / walk-forward 极快
[pmorissette/bt](https://github.com/pmorissette/bt)3.0k1·2组合层回测,天然支持分腿与再平衡
[kernc/backtesting.py](https://github.com/kernc/backtesting.py)9.0k1轻量引擎,内置优化器
[mementum/backtrader](https://github.com/mementum/backtrader)23.3k1最成熟;注意最后 push 2024-08,维护放缓
[stefan-jansen/zipline-reloaded](https://github.com/stefan-jansen/zipline-reloaded)1.9k1Zipline 现代维护版
[PyPortfolio/PyPortfolioOpt](https://github.com/PyPortfolio/PyPortfolioOpt)6.1k1·2HRP / Black-Litterman / 有效前沿 → 正式求解核心-卫星配比,替代拍脑袋的 60/40
[dcajasn/Riskfolio-Lib](https://github.com/dcajasn/Riskfolio-Lib)4.5k1·2风险预算 / 风险平价 / 最差回撤优化
[cvxgrp/cvxportfolio](https://github.com/cvxgrp/cvxportfolio)1.3k2Boyd 组凸优化组合回测(多期 + 含交易成本),理论上最严谨
[ranaroussi/quantstats](https://github.com/ranaroussi/quantstats)7.7k1一键全套绩效报告,可替换手写 performance()
[stefan-jansen/pyfolio-reloaded](https://github.com/stefan-jansen/pyfolio-reloaded)6162组合/风险归因
[stefan-jansen/alphalens-reloaded](https://github.com/stefan-jansen/alphalens-reloaded)6573检验"四因子到底有没有信息量"(IC / 分层回测)
[wilsonfreitas/awesome-quant](https://github.com/wilsonfreitas/awesome-quant)29.8k—量化资源总索引
[wangzhe3224/awesome-systematic-trading](https://github.com/wangzhe3224/awesome-systematic-trading)5.2k—系统化交易索引(期货/持仓方向更全)

⚠ 先明确一件事:以上几乎全是引擎/工具/方法论,没有一个是"现成的能赚钱的策略公式"。

换仓库拿到的是更可靠的流程与更少的自欺,不是 alpha。


五、仓库登记规范(加文件后必须做,否则自检失败)

规范内容
地图计数口径arch_check.MAP_DIRS:回测/optimization/框架/资产/因子/概念/顶层文档 = all_direct(只数直属文件,不数目录);复盘 = md_direct;audit_evidence = md_recursive。新增子目录不改变声明数
新 .md 必须有入链任何新 md 至少一条 [[wiki 链接]] 入链,否则判孤儿 → 在驾驶舱 §〇·五 加一行即可
§九 必须含最新日期doc_sync_check 第 8 项:扫 optimization/*.md 全量取文件名内最大日期,该日期必须出现在 §九 区块内
frontmatter 更新时间不能随手改doc_sync_check 第 1 项要求驾驶舱 frontmatter 更新时间 = latest.json 的 generated_at 日期(当前 2026-09-26),不是今天
§九 版本倒序check_versions 只解析 ^### v(\d+)\.(\d+) 并要求单调倒序 → 新条目放 §九最前
SKIP_DIRSscripts/、数据/、tests/、.obsidian、__pycache__ 不计入链接/孤儿扫描
收尾三件套python3 scripts/moc_index.py → python3 scripts/arch_check.py(期望 11/11)→ python3 scripts/doc_sync_check.py --strict(期望 rc=0)
⚠ 改前快照(v1.1 补)「纯新增」不等于「可以不做快照」:即使只新增目录/新增若干行,也必须先做改前快照并记录 md5,再动手。理由:本次阶段 1 就漏做过一次(两处均为纯新增 → 回滚虽精确但无 pre 件可 diff 核对)。做法:cp 目标文件到 /var/minis/shared/backup/DUCKERRY_pre_<主题>_<日期>/ + md5sum 清单 + REVERT.md
iSH 长任务纪律(v1.1 补)即便把 --task all 拆成逐子进程分派,单个子进程仍可能被静默 kill 且 rc=0 假成功(实测表 D g3-erc、表 C 四资产各丢过一整块)→ 拆到「池 × 方法 × 子区间」粒度 + 逐块增量落盘 + 跑完核对行数(本模块表行数应为 A=29 / B=44 / B2=20 / C=45 / D=108 / E=24)

六、已知坑清单(别重踩)

  1. 月频 + 事件否决:若按"月内有非农"整月否决 → 每月都被否 → 卫星永不交易(交易次数 0),结果会退化成"60%金+40%现金"却看不出来。已用 --veto-scope auto 修。
  2. 年化因子:任何多资产/降频计算,年化期数必须随频率切换(252/52/12),否则夏普与波动会被放大 √(252/ppy) 倍。
  3. ⚠ WTI 负价:fred_DCOILWTICO.csv 在 2020-04-20 = −36.98 美元,pct_change 直接变 −302%,会把任何含它的组合算崩(实测把等权组合算到"总收益 −109%")。多资产必须加负价格/极端值守卫。
  4. pd.date_range 别放进逐行循环:1084 次调用 = 28.5s。用 searchsorted 向量化。
  5. iSH kill:见 §零。全折 walk-forward 单折约 140s(周频,含 swap 等待)→ 必须逐折独立进程。
  6. matplotlib 无 CJK:图例一律 ASCII。
  7. 缓存:engine_v1 内置三层缓存(原始帧 / 降频帧 / 层级判定),新增资产时注意 _frame_key / _layer_key 是否包含了新维度(漏加会导致串结果——本轮的 veto_scope 就漏过一次)。

七、纪律红线

  • 回测口径 ≠ 实盘 ≠ 生产管线(数据/panel.csv + paper_engine.py),数字不可互相引用;产出必须并列"不构成投资建议"。
  • 引擎是只读消费者:只读 数据/,不写生产文件、不接入 fetch.py 管线。
  • 不改 scripts/ 任何生产脚本、不改 框架/数据口径定义、不动归档区与已发布复盘、不动 predictions.jsonl。
  • 四因子权重是主观先验 [待验证];A/B/C 是可计算操作化代理;L0 阈值 [待验证]。单次样本内结果不构成证据——关键结论一律以等敞口对比 + 样本外 + 子区间为准。
  • 收尾用 memory_write 写当日记忆,并回报:变更文件清单 / 自检结果 / 回滚点。

八、供新对话粘贴的最小提示词

读取仓库交接件(**完整离线上下文,不要另外找历史**):
/var/minis/mounts/DUCKERRY_Warehouse/optimization/继续任务提示词_2026-09-27_回测引擎v2.0与多资产.md
并读记忆 /var/minis/memory/2026-09-27.md(回测引擎 v2.0 相关的两条)。
仓库:/var/minis/mounts/DUCKERRY_Warehouse(挂载,可写)。环境:iSH,注意交接件「零、环境纪律」。

任务:执行交接件的「三、阶段 1」——在 `回测/engine_multi/` 新建**多资产组合回测模块**
(资产池用现成的 gold_pm / NASDAQ100 / SP500 / WTI;方法:等权 / 逆波动率 / 风险预算;
必须产出①全样本②子区间③等敞口公平对比 三张表)。
**不要改 `回测/engine_v1/`,不要碰 `scripts/` 生产脚本,不要接入 fetch 管线。**

执行顺序:
1) 先只读交接件 + 抽查 `回测/engine_v1/duckerry_backtest.py` 与 `数据/` 目录,确认资产可用性;
2) 给出**执行计划(文件清单 + 验收标准 + 预计耗时)**让我确认,**确认后再开工**;
3) 开工后按交接件「五、仓库登记规范」登记新文件,收尾跑 `moc_index` / `arch_check`(期望 11/11) / `doc_sync_check --strict`(期望 rc=0);
4) 最后用 memory_write 写当日记忆并回报变更清单与回滚点。

注意坑:WTI 在 2020-04-20 是负价(−36.98),必须加负值守卫;iSH 单进程约 2 分钟被静默 kill,长任务拆短进程跑。

附 A · 关键数字速查

  • 有效窗口:2006-01-03 → 2026-09-25(20.6 年);日频 5199 bar / 周频 1082 / 月频 249
  • 成本:6bps 单边(1bp 佣金 + 5bps 滑点);核心底仓不计换手
  • 买入持有(2006–2026):703.5% / 年化 10.63% / 波动 18.2% / 夏普 0.646 / 回撤 −44.6%
  • 被动 60/40(金/现金):279.3% / 6.68% / 10.9% / 0.646 / −28.7% / 卡玛 0.233
  • 周频·自适应+核心60%:263.0% / 6.39% / 12.6% / 0.556 / −33.0%
  • 样本外(2014-01→2025-12,626 周):策略 126.2% / 夏普 0.754 / 回撤 −15.7%;等敞口被动(67.6%) 139.8% / 0.812 / −16.3%
  • 41 年多资产预检:风险平价 金+纳指 夏普 0.88 / 回撤 −33% / 卡玛 0.33(vs 黄金 0.47 / −49% / 0.13)

附 B · 文件地图

用途路径
本交接件optimization/继续任务提示词_2026-09-27_回测引擎v2.0与多资产.md
v2.0 完整报告optimization/四因子框架回测引擎v2.0_报告_2026-09-27.md
引擎与资产曲线回测/engine_v1/(+ README.md、curves/、wf/)
工作区副本(可改)/var/minis/workspace/duckerry_backtest/
共享副本/var/minis/shared/duckerry_backtest/
数据源数据/(gold_pm.json、fred_*.csv、bond_*.json)
生产管线(勿动)scripts/fetch.py → dkpanel.py → dkanalysis.py → paper_engine.py
外部资源(只作参考)/var/minis/mounts/武器库/

修订记录

  • 2026-09-27 v1.1:状态改为「阶段 1 已执行」;§五 规范补两条(改前快照:纯新增也要做、iSH 子进程静默 kill 的拆法与行数核对);§三 阶段 1 标注交付物。
  • 2026-09-27 v1.0:首版。固化回测引擎 v2.0 的已完成项、核心结论(含等敞口否定式发现与多资产预检)、三阶段待办、16 个已核实 GitHub 仓库与武器库登记方式、仓库登记规范、7 条已知坑、环境纪律,并给出可直接粘贴的最小提示词。