SAF 重构迁移方案

日期: 2026-04-13 目标: 将 SAF 提升到与 StrategeFactoryFlow/TSS 并列层次,废弃两者中与 SAF 重叠的部分 范围: StrategeFactoryFlow, TSS, SAF 三个项目的回测/数据/评估层


1. 当前架构状态

1.1 三个项目现状

qmt/
├── SAF/                          # 新共享内核(重构骨架)
│   ├── src/saf/
│   │   ├── capability/           # ✅ 策略能力检测
│   │   ├── data/                # ⚠️ 框架完成,实现缺失
│   │   ├── engine/               # ⚠️ 框架完成,时序实现待补全
│   │   ├── evaluation/           # ⚠️ 框架完成,评分实现缺失
│   │   ├── models/               # ✅ 强类型对象模型
│   │   ├── orchestrator/         # ✅ 编排层框架
│   │   ├── storage/              # ✅ 接口定义
│   │   └── strategy/             # ✅ 策略解析器
│   └── tests/
│
├── StrategeFactoryFlow/          # 策略工厂(待迁移/废弃)
│   ├── evaluate/
│   │   ├── engine.py            # ❌ 与 SAF engine 重复 → 废弃
│   │   ├── fast_screen_policy.py # ✅ 保留(SAF 暂无对应)
│   │   └── scorer.py            # ⚠️ 与 SAF evaluation 重复 → 迁移/废弃
│   ├── run_evaluate.py          # ✅ 保留(批量编排)
│   └── pipeline/                 # ⚠️ 部分迁移
│
└── tss/                          # 策略运营(待迁移/废弃)
    ├── data_loader.py            # ❌ 与 SAF data 重复 → 废弃
    ├── run_*_comparison.py       # ⚠️ 保留(多策略对比)
    ├── vnpy_backtest_runner.py   # ⚠️ SAF vnpy_adapter 替代
    └── ...

1.2 SAF 能力 vs 现有实现 (2026-04-13 更新)

模块SAF 现状StrategeFactoryFlowTSS结论
策略拓扑检测✅ 完整✅ 完整❌ 无SAF 优,废弃 SFF
FailureCode✅ 完整❌ 散落字符串❌ 无SAF 优,废弃 SFF
对象模型✅ 完整❌ pd.DataFrame❌ 无SAF 优
时序回测引擎✅ 完整✅ 完整⚠️ 简单实现SAF 已可替代 SFF
截面回测引擎✅ 完整✅ 完整❌ 无SAF 已可替代 SFF
配对回测引擎⚠️ 骨架定义❌ 无❌ 无SAF 框架已定义,实现待补
vnpy 适配器⚠️ 骨架定义❌ 无✅ 完整迁移到 SAF vnpy_adapter
数据加载⚠️ 协议定义❌ 直接用 DataService✅ 完整迁移 data_loader 到 SAF
评分系统⚠️ 简化版✅ 6维评分❌ 无迁移 6维到 SAF evaluation
编排/批量✅ 框架完整✅ 完整⚠️ 脚本SAF orchestrator 已可替代
快筛重试❌ 无✅ 完整❌ 无SFF 保留或迁移到 SAF

2. 迁移原则

2.1 三不原则

  1. 不删除代码:所有待废弃代码移入 legacy/ 目录,保留历史
  2. 不中断开发:迁移期间现有流水线照常运行
  3. 不破坏接口:SAF 接口先稳定再对接

2.2 迁移顺序

Phase 1: 稳固 SAF 内核(共享层先完成)
Phase 2: 废弃 StrategeFactoryFlow 中对应模块
Phase 3: 废弃 TSS 中对应模块
Phase 4: 清理 legacy/ 目录

3. 完整迁移方案

3.1 Phase 1: 稳固 SAF 内核 ✅ 已完成 (2026-04-13)

目标: 补全 SAF 中缺失的关键实现,使其能够承接废弃模块

已完成 ✅

#任务实现位置状态
1.1TimeSeriesExecutionEngine(含 equity curve)saf/engine/time_series.py✅ 已完成
1.2PanelExecutionEngine(含 DataFrame 信号支持)saf/engine/panel.py✅ 已完成
1.3Sandbox(超时、异常处理、DataFrame 支持)saf/engine/sandbox.py✅ 已完成
1.4BacktestConfig + CostModelsaf/engine/config.py✅ 已完成
1.5CapabilityResolver + StrategyTopologyDetectorsaf/capability/resolver.py, detector.py✅ 已完成
-CapabilityResult dataclass + SupportMatrixsaf/capability/support_matrix.py✅ 已完成
-JobExecutorImpl + BatchExecutorsaf/orchestrator/orchestrator.py, batch.py✅ 已完成
-RetryPolicy + RetryableErrorsaf/orchestrator/retry.py✅ 已完成

Architecture: StrategyKind (业务分类) → CapabilityResolverStrategyTopology (执行路由) → ExecutionEngine

StrategyKind.TIME_SERIES     → StrategyTopology.TIME_SERIES     → TimeSeriesExecutionEngine
StrategyKind.CROSS_SECTIONAL → StrategyTopology.CROSS_SECTIONAL → PanelExecutionEngine
StrategyKind.PAIRS           → StrategyTopology.PAIR           → PairExecutionEngine (待实现)

待完成 ⚠️

#任务实现位置状态优先级
1.6迁移 6 维评分saf/evaluation/scorer.py⚠️ 待实现P1
1.7迁移切片评分saf/evaluation/slices.py⚠️ 待实现P2
1.8PairBundle + PairExecutionEnginesaf/engine/pair.py⚠️ 骨架待实现P3

废弃模块对照表(更新)

待废弃(SFF)替代(SAF)状态
evaluate/engine.py 时序engine/time_series.py✅ SAF 已完成
evaluate/engine.py 截面engine/panel.py✅ SAF 已完成
evaluate/scorer.pyevaluation/scorer.py⚠️ SAF 简化版已有,6维待迁移
evaluate/fast_screen_policy.py新建 evaluation/fast_screen.py❌ 待新建
pipeline/orchestrator/⚠️ 部分重叠
待废弃(TSS)替代(SAF)状态
data_loader.pydata/providers.py⚠️ 协议定义已有,实现待迁移
vnpy_backtest_runner.pyengine/vnpy_adapter.py⚠️ 骨架已有,实现待对齐

剩余工作量估算: 2-3 人天(原计划 5 人天,已完成大部分)


3.2 Phase 2: 迁移 StrategeFactoryFlow(2-3 天)

2.1 目录重组

StrategeFactoryFlow/
├── SAF/                    # 保持(作为独立包)
├── SAF_new/                # 新建:指向 qmt/SAF/src/saf
│   └── (symlink or pyproject path)
├── legacy/                 # 新建:废弃代码归档
│   ├── evaluate/
│   │   ├── engine.py      # 移入(废弃)
│   │   └── scorer.py     # 移入(废弃)
│   └── pipeline/          # 移入(废弃)
├── evaluate/               # 重写:对 SAF 的 thin wrapper
│   ├── engine_adapter.py   # 新建:SAF engine 适配器
│   ├── scorer_adapter.py  # 新建:SAF scorer 适配器
│   └── fast_screen.py     # 保留(SAF 暂无)
├── run_evaluate.py        # 修改:调用 SAF_new
└── ...

2.2 迁移步骤

Step 1: 创建 legacy/ 目录,移入废弃代码

mkdir -p StrategeFactoryFlow/legacy/evaluate
mv StrategeFactoryFlow/evaluate/engine.py legacy/evaluate/
mv StrategeFactoryFlow/evaluate/scorer.py legacy/evaluate/
mv StrategeFactoryFlow/pipeline legacy/pipeline

Step 2: 创建 evaluate/ 新实现(thin wrapper)

# evaluate/engine_adapter.py
from saf.engine import TimeSeriesExecutionEngine, PanelExecutionEngine
from saf.engine.protocols import BacktestRequest, BacktestBundle

class SAFTimeSeriesAdapter:
    """SFF wrapper around SAF TimeSeriesExecutionEngine."""
    ...

class SAFPanelAdapter:
    """SFF wrapper around SAF PanelExecutionEngine."""
    ...

Step 3: 更新 run_evaluate.py 使用 SAF

Step 4: 保留以下模块(不迁移到 SAF):

  • fast_screen_policy.pyevaluate/fast_screen.py
  • run_pipeline.py → 评估后处理,保留
  • pipeline/backfill_claims.py → 迁移到 SAF 或保留

3.3 Phase 3: 迁移 TSS(1-2 天)

3.1 目录重组

tss/
├── legacy/                 # 新建:废弃代码归档
│   ├── data_loader.py
│   ├── run_*_comparison.py  # 保留(多策略对比,非回测核心)
│   └── vnpy_*.py
├── SAF/                    # 新建:指向 qmt/SAF/src/saf
├── data/                   # 重写:SAF data provider 封装
│   └── provider_adapter.py
└── ...

3.2 迁移步骤

Step 1: 创建 legacy/ 目录

mkdir -p tss/legacy
mv tss/data_loader.py tss/legacy/

Step 2: 实现 tss/data/ 基于 SAF 协议

Step 3: 废弃 vnpy_backtest_runner.py,使用 SAF/engine/vnpy_adapter.py


3.4 Phase 4: 清理与验证(1 天)

4.1 最终目录结构

qmt/
├── SAF/                              # 统一共享内核
│   └── src/saf/
│       ├── capability/                # ✅ 完整
│       ├── data/                     # ✅ 完整(迁移后)
│       ├── engine/                   # ✅ 完整(迁移后)
│       ├── evaluation/                # ✅ 完整(迁移后)
│       ├── models/                   # ✅ 完整
│       ├── orchestrator/             # ✅ 完整(迁移后)
│       ├── strategy/                  # ✅ 完整
│       └── storage/                   # ✅ 完整
│
├── StrategeFactoryFlow/              # 策略工厂应用
│   ├── legacy/                       # 归档(可删除)
│   ├── evaluate/                     # SAF thin wrapper
│   │   ├── engine_adapter.py
│   │   ├── scorer_adapter.py
│   │   └── fast_screen.py
│   ├── run_evaluate.py               # 批量评估入口
│   └── ...
│
├── tss/                              # 策略运营应用
│   ├── legacy/                       # 归档(可删除)
│   ├── data/                         # SAF data wrapper
│   ├── strategies/                   # 策略池
│   └── ...
│
└── qdata/                            # 数据服务(保留,供 SAF 调用)

4.2 验证清单

  • SAF 时序引擎输出与 SFF 旧引擎一致(误差 < 0.01%)
  • SAF 截面引擎输出与 SFF 旧引擎一致
  • SAF 评分系统输出与 SFF 旧系统一致
  • run_evaluate.py 端到端运行成功
  • TSS 数据加载使用 SAF 协议
  • 所有测试通过

4. 详细任务分解

4.1 Phase 1 任务(SAF 内核补全)✅ 已完成

#任务状态优先级
1.1迁移 SFF SignalBacktester 逻辑到 SAF TimeSeriesExecutionEngine✅ 已完成P0
1.2迁移 SFF CrossSectionalBacktester 逻辑到 SAF PanelExecutionEngine✅ 已完成P0
1.3实现 execute_signal_function 超时与异常处理✅ 已完成P0
1.4迁移 CostModel 和成本计算到 SAF engine/config.py✅ 已完成P1
1.5CapabilityResolver + StrategyTopologyDetector✅ 已完成P0
1.6迁移 SFF 6维评分到 SAF evaluation/scorer.py⚠️ 待实现P1
1.7迁移切片评分到 SAF evaluation/slices.py⚠️ 待实现P2
1.8实现 PairBundlePairExecutionEngine 骨架⚠️ 待实现P3

4.2 Phase 2 任务(SFF 迁移)

#任务负责人优先级依赖
2.1创建 legacy/ 并移入废弃代码-P01.1, 1.2, 1.3
2.2实现 evaluate/engine_adapter.py (SAF wrapper)-P01.1, 1.2
2.3实现 evaluate/scorer_adapter.py (SAF wrapper)-P01.6
2.4更新 run_evaluate.py 使用 SAF adapter-P02.2, 2.3
2.5保留 fast_screen_policy.pyevaluate/fast_screen.py-P1
2.6端到端验证-P02.4

4.3 Phase 3 任务(TSS 迁移)

#任务负责人优先级依赖
3.1创建 tss/legacy/ 并移入废弃代码-P01.5
3.2实现 tss/data/provider_adapter.py-P01.5
3.3废弃 vnpy_backtest_runner.py,使用 SAF adapter-P11.1, 1.2
3.4端到端验证-P03.2

4.4 Phase 4 任务(清理)

#任务负责人优先级依赖
4.1删除 legacy/ 目录(或保留备查)-P2Phase 2, 3 完成
4.2更新文档-P1Phase 2, 3 完成
4.3全面测试验证-P0Phase 4 完成

5. 影响评估

5.1 功能影响

废弃项影响缓解措施
SFF engine.py时序/截面回测依赖SAF 补全前不删除
SFF scorer.py评分系统依赖SAF 补全前不删除
TSS data_loader.py数据加载依赖SAF 补全前不删除
SFF fast_screen_policy.py快筛重试依赖保留为独立模块

5.2 风险与缓解

风险影响缓解
SAF 引擎输出与旧引擎不一致策略排名变化严格对比测试,误差 > 0.01% 则回退
迁移期间开发中断影响日常工作Phase 1 可并行,不影响 SFF/TSS 运行
SAF data provider 性能下降回测速度变慢验证性能无显著下降

5.3 依赖关系

Phase 1: SAF 内核补全(可 5 人并行)
├── 1.1 TimeSeriesEngine ← 无依赖,立即可启动
├── 1.3 Sandbox ← 无依赖,立即可启动
├── 1.5 DataProvider ← 无依赖,立即可启动
├── 1.8 PairEngine ← 无依赖,立即可启动
├── 1.2 PanelEngine ← 无依赖,立即可启动(可与1.1并行)
├── 1.4 CostModel ← 依赖 1.1
├── 1.6 Scoring ← 依赖 1.1, 1.2
└── 1.7 Slices ← 依赖 1.6

Phase 2: SFF 迁移 ← 依赖 1.1, 1.2, 1.3
Phase 3: TSS 迁移 ← 依赖 1.5
Phase 4: 清理 ← 依赖 Phase 2, 3 完成

6. 推荐执行顺序

第一步(今天即可开始)

创建 SAF 分支并补全 Phase 1.1-1.3(时序引擎核心)

第二步(明天)

完成 Phase 1.4-1.6(数据+评分)

第三步

Phase 2 SFF 迁移,废弃 legacy/evaluate/engine.py

第四步

Phase 3 TSS 迁移,废弃 legacy/data_loader.py

第五步

Phase 4 清理与验证


7. 一句话总结

以 SAF 为共享内核,废弃 evaluate/engine.pyscorer.pydata_loader.py,其余保留在应用层。


8. 并行执行方案(更新 2026-04-13)

8.1 依赖关系图(已更新)

Phase 1: SAF 内核补全 ✅ 已完成
│
├── 1.1 TimeSeriesEngine ──────────┐ ✅ 已完成
├── 1.2 PanelEngine ───────────────┤ ✅ 已完成
├── 1.3 Sandbox ───────────────────┤ ✅ 已完成
├── 1.4 CostModel ─────────────────┘ ✅ 已完成
├── 1.5 CapabilityResolver ───────── ✅ 已完成
│
│    ⚠️ 剩余工作
│
├── 1.6 Scoring ───────────────────┐ ⚠️ 待实现
└── 1.7 Slices ───────────────────┘ ⚠️ 待实现(依赖1.6)
         │
         │    Phase 2: SFF 迁移 (依赖1.6)
         │    Phase 3: TSS 迁移 (依赖1.6)
         │         ↓
         │    可并行执行

8.2 Phase 1 并行任务分配(更新)

#任务状态
1.1 TimeSeriesEngine✅ 已完成
1.2 PanelEngine✅ 已完成
1.3 Sandbox✅ 已完成
1.4 CostModel✅ 已完成
1.5 CapabilityResolver✅ 已完成
1.6 Scoring⚠️ 待实现
1.7 Slices⚠️ 待实现
1.8 PairEngine⚠️ 待实现
任务依赖可并行
1.1 TimeSeriesEngine
1.2 PanelEngine
1.3 Sandbox
1.5 DataProvider
1.8 PairEngine
1.4 CostModel1.1⏳ 等 1.1
1.6 Scoring1.1, 1.2⏳ 等 1.1+1.2
1.7 Slices1.6⏳ 等 1.6

8.3 Phase 2/3 并行(更新)

人员任务Phase 1 依赖
人 1Phase 2: SFF wrapper 适配1.6 Scoring 完成后
人 2Phase 3: TSS wrapper 适配1.6 Scoring 完成后

注:Engine 部分 (1.1-1.5) 已完成,Phase 2/3 可在 1.6 完成后立即开始。

8.4 推荐分工方案(更新 2026-04-13)

Phase 1 核心已完成,剩余工作大幅减少

简化分工(1-2 人即可)

人 1 (主):
├── Phase 1.6 Scoring (P1) ← 最高优先级
├── Phase 1.7 Slices (P2)
└── Phase 2: SFF wrapper 适配

人 2 (可选):
├── Phase 1.8 PairEngine (P3)
├── Phase 3: TSS wrapper 适配
└── DataProvider 实现对齐

原 5 人并行方案已不需要 - Phase 1 核心引擎已由 SAF 重构完成。

8.5 任务启动条件(更新 2026-04-13)

任务启动条件状态
1.1, 1.2, 1.3, 1.4, 1.5✅ 已完成-
1.6 6维评分立即可启动⚠️ 待实现
1.7 切片评分1.6 完成后⚠️ 待实现
1.8 PairEngine可并行⚠️ 待实现
Phase 2 SFF迁移1.6 完成后可开始 engine 部分等待 1.6
Phase 3 TSS迁移1.6 完成后可开始等待 1.6

8.6 关键路径(更新 2026-04-13)

关键路径: 1.6 → 1.7 → Phase 2/3 → Phase 4
最短工期估算(已更新):
- Phase 1: 1.1,1.2,1.3,1.4,1.5 ✅ 已完成
- Phase 1.6 (6维评分): 约 0.5 天
- Phase 1.7 (切片评分): 约 0.5 天
- Phase 2,3 (SFF/TSS wrapper): 1-2 天 (并行)
- Phase 4 (清理验证): 0.5 天
总计剩余: 2-3 个工作日(原估算 5 天,已大幅缩短)

8.7 风险控制(更新)

风险缓解
Phase 1 已完成✅ 核心引擎已验证通过
1.6/1.7 延期阻塞 Phase 2 的 scorer 部分,但 engine 部分可先做
人力不足优先保证 1.6 (评分),1.7/1.8 可后续补充