shy3130
4696fef959
feat(composite): 新增叠加策略(composite)支持选股与回测
...
引入第四种执行后端 composite: 声明式引用多个子策略, 复用现有注册表/缓存/撮合全链路。
核心设计:
- 退出采用来源投影(每个子策略 exit 仅在自己持仓窗口生效, 不串平其他子策略仓位)
- 评分用标准化排名加权(跨子策略可比, 不依赖 per-strategy 的 min-max 量纲)
- 来源归因(entry_signal_code 标记来源子策略)
后端:
- engine.py: CompositeSpec 数据模型, 两阶段引用校验(孤儿移除/嵌套禁止/asset_types 子集/≤8 上限), _run_composite_strategy 选股执行, find_dependents 删除防护, override_loader 注入保证子策略与单独跑同口径
- composite.py(新): 选股 merge_results + 回测 merge_signal_matrices 合并器(退出投影/排名融合/归因)
- backtest/strategy.py: composite 回测分支(特征计划合并/逐子信号/统一风控/basic_filter/归因)
- api/strategy.py: POST /composite/save 端点, _strategy_detail 返回 composite_children(含 name/source), 删除依赖 409 防护
- monitor.py: 实时监控 fail-closed(回退盘后缓存)
- walkforward.py: 对 composite 显式中文报错
- worker.py: _strategy_dirs 补 composite 目录(修复回测子进程找不到 composite 的 bug)
前端:
- CompositeStrategyDialog(新): 创建/编辑弹窗(自动生成 composite_ ID, 权重归一, 类型标签, 增删子策略)
- StrategySettingsDialog: composite 设置面板(子策略增删改/归一/类型标签)
- StrategyBacktest: 回测页 composite 适配(分组/参数区/结果区展示子策略构成)
- api.ts: 类型扩展(source/backend 加 composite, composite_children 含 name/source)
测试: 36 个 composite 专项测试(加载/选股/回测退出投影/排名/归因/override 透传/API/删除防护), 端到端验证真实内置策略回测通过
2026-08-02 10:56:03 +08:00
shy3130
34eaba3010
fix: handle uncovered walk-forward folds
2026-07-17 14:00:16 +08:00
lytem28
b6cf0495e1
feat: complete matrix-native backtest engine
...
Unify strategy execution across backtest, screener, and monitoring; isolate backtest workloads in spawn workers; and add shared matrix caching plus valid-bar indicator acceleration.
2026-07-16 12:17:27 +08:00
im47cn
e4262d9951
fix(walkforward): IS 训练折强制 position 模式, 堵前视泄漏
...
对抗式审查发现: WF UI 暴露 full 模式, 选中时训练折(end=train_end)未平仓的持仓
会用 train_end 之后(即 OOS 区间)的真实 K 线平仓 -> IS 分数被未来数据污染, 优化选出
的最优参数乐观偏移, 使过拟合被掩盖 (对专门检测过拟合的 WF 工具危害尤重)。
修复: IS 训练区间优化强制 mode="position" (只看正式区间表现), OOS 回测保留用户
所选 mode。新增测试: 用户选 full 时断言每折 IS 得到 position、OOS 保留 full。
2026-07-12 21:48:13 +08:00
im47cn
db535c8004
feat(panelcache): IO 遥测量化跨折重复扫盘占比
...
walk-forward 各折 train 窗口日历重叠 ~75%, 但 PanelCache key 精确到区间,
跨折永不命中 -> 每折重复扫盘。为判断是否值得做"整区间加载一次+切片"优化,
先埋轻量遥测再决策 (避免盲优化)。
- PanelCache 累加真实扫盘耗时/次数 + 命中/single-flight 复用次数, 暴露 stats();
BacktestEngine.cache_stats() 透传 (不让上层伸手进私有 _cache)。
- WalkForwardService.run 首尾快照, 返回 cache_telemetry.load_panel_pct
(扫盘耗时/WF总耗时) + scans/hits/reuses, 并 logger.info 一行。
- 测试: PanelCache 计数 (miss扫盘/命中/并发复用); WF 测试补最小 engine 桩
(生产路径不加 getattr 兜底, 避免静默吞掉真缺 engine 的 bug)。
2026-07-12 00:52:32 +08:00
im47cn
32d27a0a6e
fix(walkforward): 子代理审查修复 — 折有效性/前视泄漏/方向退化/NaN序列化/净值曲线
...
三份子代理审查 (核心/API/前端) 发现的真实 bug:
核心正确性 (walkforward.py):
- [高] 折有效性抽象: best_params=None (训练全组失败) 或 OOS error 的折原会用默认
参数硬跑/按0收益混入复利, 伪装成有效折污染 OOS 净值与退化指标。改为分流 ——
有效折进 folds, 无效折进 skipped(带原因), 聚合只看有效折。一次修掉 H1/H2/M1。
- [高] 前视泄漏: train_end==test_start 使该日 K 线同时进训练与 OOS 首日。test_start
后移一天隔断。
- [中] degradation 方向感知: 原 avg_is-avg_oos 对 min 类目标 (avg_holding_days) 符号
反了。归一到越大越好空间再相减; 每折加 oos_degraded 方向感知标志。
- consistency 改为 OOS 盈利折占比 (与目标方向无关, 更直观)。
API (backtest.py):
- [高] 单折 guard: WF 缺 guard, start=None 默认拉 3 年, 每折训练窗口可能 OOM。按
单折窗口 (train/test) 而非总区间 guard —— 总区间长本是 WF 正常形态, 按总区间拦会误杀。
- [中] NaN/inf 序列化: json.dumps(default=str) 处理不了 nan/inf, 输出非法 JSON 崩前端。
加 _json_safe 递归清洗, 优化器与 WF 两处 done 分支都套上。
前端 (StrategyWalkForward.tsx):
- n_folds=0 门控: 全跳过时不再渲染误导性全0卡, 改显示'未产生有效折'+跳过原因。
- 渲染 OOS 拼接净值曲线 (walk-forward 核心产出, 原后端算了前端没画)。
- 每折退化标红改用后端方向感知的 oos_degraded (min 类目标 oos<is 未必退化)。
测试新增: 前视泄漏隔断 / 方向感知退化(min目标) / best_params=None跳过 /
OOS error跳过。后端 173 测试通过; 前端 tsc 无新增错误。
2026-07-11 19:20:31 +08:00
im47cn
586d9a4699
feat(walkforward): 真·walk-forward 优化后端 — 滚动窗口 IS 优化 + OOS 验证
...
PR2b 后端 (叠在 PR2a 优化器上):
app/backtest/walkforward.py:
- generate_folds: 滚动窗口切分 (训练固定长度 + 紧邻测试窗口 + step 前移),
测试超出 end 即停; 放不下一折抛错; 非正窗口拒绝。
- aggregate_oos: 从各折 OOS 结果聚合 — 复利净值曲线 / IS-vs-OOS 退化
(样本内目标均值 - 样本外目标均值, 正值=过拟合信号) / 一致性 (OOS 目标为正的折占比)。
- WalkForwardService.run: 每折在训练区间调 PR2a 优化器选最优参数, 再在测试区间
用该参数做 OOS 回测。核心产出是纯 OOS 拼接 + 每折 IS/OOS 对比 — 单次样本内
回测的过拟合一眼看穿。支持进度回调 (fold i/N) 与 cancel。
API app/api/backtest.py:
- GET /walkforward/stream (SSE, 复用 _BacktestJob + job_key 回吐) + POST
/walkforward/cancel (按回吐 key 查表)。
测试 13 例: fold 切分 (滚动/边界/不足/非正) + OOS 聚合 (复利/退化/一致性/空) +
编排 (训练优化→测试OOS/退化上报/取消) + API (job_key 区分窗口/cancel按key)。
全量 169 测试通过。
2026-07-11 19:20:30 +08:00