Legacy 项目参考指南
适用对象:未来新项目的设计、开发、数据导入和评审协作。
参考项目:当前stock_data_analyse。
配套目标:docs/TARGET_ARCHITECTURE.md。
本文定义参考规则,不改变当前项目代码和运行方式。
1. 文档定位
当前项目是新项目的 Legacy Reference,不是新项目的代码基座、运行时依赖或架构模板。
新项目应遵循以下优先级:
新项目已确认目标架构
> 新项目领域模型与公共契约
> 新项目当前实现和测试
> 当前项目现状文档
> 当前项目源代码
> 历史设计和废弃实现
原项目可以回答“过去实际上怎么做、数据是什么、遇到过什么问题”,但不能单独回答“新项目应该怎么设计”。
2. 新旧项目边界
flowchart LR
TARGET[新项目目标架构] --> DESIGN[新项目设计与实现]
CONTRACT[新项目领域契约] --> DESIGN
LEGACY[当前项目 Legacy Reference] --> FACTS[事实查证]
FACTS --> DESIGN
LEGACY -.禁止代码依赖.-> DESIGN
LEGACY -.禁止数据库运行时依赖.-> DESIGN
LEGACY -.禁止默认继承旧规则.-> DESIGN
允许继承的内容
- 已确认的产品目标和业务闭环。
- 经过讨论确认的业务概念和领域边界。
- 外部数据源的可用性、限流、字段和异常经验。
- 历史数据的格式、覆盖范围和质量事实。
- 旧系统的运行问题、性能问题和安全问题。
- 经重新评审后确认仍然有价值的投资逻辑。
不允许直接继承的内容
- 当前项目的目录结构和模块命名。
- 当前项目的类、函数和数据库表作为新项目接口。
core/engine.py的大一统分析编排方式。- 旧
strategy/、backtest/、portfolio/的运行时实现。 - 旧 API、页面、调度器和后台任务入口。
portfolio.db、job_runs.db、meta.db的运行时依赖。- v4.5、V6 或其他旧规则的默认行为。
- 未经质量审查的旧数据和未经验证的历史计算结果。
3. 何时读取原项目
原项目代码按任务、按文件、按问题读取,不作为每次会话的默认完整上下文。
| 任务 | 建议读取 | 读取目的 |
|---|---|---|
| 设计新数据源适配器 | datasource/、相关采集器、数据样例 |
查外部接口、字段、限流和失败模式 |
| 设计数据集 schema | warehouse/、Parquet schema、数据文档 |
查历史字段、代码格式、日期和覆盖范围 |
| 设计数据导入 | 旧数据库 schema、导出脚本、样例数据 | 建立映射、识别不可迁移字段 |
| 设计历史策略评估 | 指定的 strategy/、backtest/ 文件 |
理解历史假设,不作为新规则模板 |
| 分析性能和稳定性 | 任务、监控、日志、测试 | 识别资源峰值、限流和失败恢复问题 |
| 复核历史页面行为 | 指定路由、模板、前端脚本 | 了解用户实际操作,不复制页面实现 |
| 评估通知方案 | notifier/、通知测试和配置 |
了解渠道约束、重试和去重问题 |
除非任务明确要求,不读取整个原项目目录、所有测试或全部历史文档。
4. 读取原项目的标准流程
flowchart TB
TASK[明确本次问题]
TASK --> SCOPE[限定读取范围]
SCOPE --> PURPOSE[写明读取目的]
PURPOSE --> READ[读取指定文件 / 样例]
READ --> FACT[提取可验证事实]
FACT --> REVIEW[与新项目目标架构比对]
REVIEW --> DECIDE{是否值得采用}
DECIDE -->|是| REDESIGN[按新项目契约重新设计]
DECIDE -->|否| DISCARD[仅记录为历史参考或问题]
REDESIGN --> TEST[新项目测试与验证]
每次读取原项目后,应明确区分:
历史事实:原项目确实如此实现
设计结论:新项目决定如此设计
实现决定:新项目将如此编码
三者不能混写。例如:
历史事实:原项目使用 baostock 获取日线。
设计结论:新项目通过 SourceAdapter 隔离外部数据源。
实现决定:新项目实现 BaostockAdapter,并返回标准 MarketBar Dataset。
5. Token 使用策略
5.1 设计阶段
默认只提供:
docs/TARGET_ARCHITECTURE.md- 新项目领域模型和公共契约。
- 当前要设计的业务范围。
- 必要的非功能约束。
设计阶段不默认读取原项目大量实现,避免旧目录、旧命名和旧逻辑影响新架构。
5.2 实现阶段
只补充完成当前任务所需的 Legacy 资料:
实现 SourceAdapter
-> 旧数据源相关方法 + 字段样例 + 异常记录
实现历史导入
-> 旧 schema + 数据样例 + 新 schema
评估历史策略
-> 指定规则文件 + 回测结果 + 数据依赖
不要把无关页面、测试和历史模块一起放入上下文。
5.3 评审阶段
评审新项目时优先检查:
- 是否符合目标架构。
- 是否引入当前项目的隐式依赖。
- 是否复制旧表结构或旧业务入口。
- 是否把旧规则当成默认新规则。
- 是否有数据版本、质量和来源记录。
6. 各类 Legacy 内容的使用规则
6.1 外部数据源
旧项目的数据源实现具有较高事实参考价值,尤其用于确认:
- 请求参数和返回字段。
- 代码、日期和单位转换。
- 连接、重试、限流和降级行为。
- 不同源之间的字段差异。
新项目必须重新封装为:
SourceAdapter
-> RawBatch
-> NormalizedRecord
-> DatasetBuilder
-> QualityGate
-> PublishedDataset
不能直接复制 StockDataFetcher 或让领域服务调用旧类。
6.2 历史数据
旧 Parquet、CSV、SQLite 和 JSON 只作为导入输入,不作为新项目正式数据集。
flowchart LR
OLD_DATA[旧数据文件 / 数据库] --> READONLY[只读读取]
READONLY --> PROFILE[字段 / 类型 / 范围分析]
PROFILE --> MAP[映射到新 Schema]
MAP --> QUALITY[完整性 / 重复 / 口径检查]
QUALITY -->|通过| STAGING[新项目导入暂存区]
QUALITY -->|不通过| ARCHIVE[只保留归档,不进入运行时]
STAGING --> IMPORT[一次性导入]
IMPORT --> NEW[新项目 Dataset 或 business.db]
导入时必须保留:
- 原始来源名称。
- 原始记录 ID 或文件路径。
- 导入批次。
- 映射版本。
- 导入时间。
- 质量检查结果。
- 无法映射字段和被拒绝记录的数量。
6.3 历史策略
历史策略只能经过重新评审后实现:
历史规则
-> 投资假设提取
-> 数据依赖提取
-> 风险假设审查
-> 时间穿越 / 未来函数审查
-> 独立回测验证
-> 决定:重写、改写或放弃
评审结论可能是:
- 作为新策略重新实现。
- 只保留其中的投资思想。
- 作为对照基线,不进入生产策略。
- 因为数据依赖、风险或不可解释性而放弃。
不能将旧类直接包装成新项目的 RuleExecutor 就视为迁移完成。
6.4 历史页面和 API
历史页面用于确认真实用户操作和信息需求:
- 用户需要查看什么信息。
- 哪些操作需要异步处理。
- 哪些状态需要明确展示。
- 哪些交互存在重复提交或误操作风险。
新项目重新设计 API DTO、页面状态和权限,不复制旧路由和模板结构。
7. 新项目开发时的上下文模板
7.1 设计任务模板
项目角色:新项目独立重建。
目标架构:以 docs/TARGET_ARCHITECTURE.md 为准。
当前任务:[填写任务]
目标边界:[填写本次只解决什么]
验收标准:[填写可验证结果]
Legacy 使用规则:
- 当前项目仅作事实参考,不是代码模板。
- 只有为解决当前任务所必需时,才读取指定旧文件。
- 旧实现不得直接决定新项目的目录、接口、表结构或规则。
- 如读取旧代码,必须区分历史事实与新项目设计决定。
7.2 实现任务模板
新项目模块:[模块名]
本次目标:[功能目标]
新项目契约:[接口 / 实体 / 状态]
允许参考的 Legacy 文件:[明确列出文件]
参考目的:[字段 / 外部接口 / 历史行为 / 性能问题]
禁止继承:[旧实现 / 旧表 / 旧规则 / 旧 API]
验证方式:[测试 / 构建 / 冒烟 / 数据校验]
7.3 历史导入任务模板
导入对象:[portfolio / market data / reports / other]
旧来源:[只读文件或数据库]
新目标:[新 Dataset 或新业务实体]
字段映射:[映射文档]
质量要求:[完整性、去重、时间、口径]
拒绝规则:[无法映射或不可信数据如何处理]
回滚方式:[暂存区清理或导入事务回滚]
8. 判断是否被 Legacy 误导
出现以下情况时,应暂停实现并重新检查设计边界:
- 新项目目录只是当前项目目录改名。
- 新项目出现
core/engine.py,且重新承担所有业务流程。 - 新业务服务直接 import 当前项目模块。
- 新项目数据库表直接照抄旧表名和字段。
- 新策略只是给旧策略类增加一层包装。
- 页面根据旧 API 字段直接设计,而没有新 DTO。
- 业务服务直接读旧 Parquet 路径或旧数据库。
- 旧库被设置成新项目的 fallback。
- 为兼容旧项目而新增大量 if/else、旧状态和旧字段。
- 设计文档频繁出现“先兼容、以后再收口”,但没有明确退出条件。
判断标准:
如果去掉当前项目后,新项目无法独立设计、启动或测试,
说明 Legacy 已经从参考源变成了隐式依赖。
9. 参考资料索引
当前项目中可按需读取的主要资料:
| 资料 | 用途 | 参考级别 |
|---|---|---|
docs/CURRENT_ARCHITECTURE.md |
当前系统边界、双轨现状和部署事实 | 默认事实索引 |
README.md |
功能、命令、数据源和运行方式概览 | 快速事实参考 |
datasource/ |
历史外部数据源和指标实现 | 按任务读取 |
warehouse/ |
历史数据采集、分区、版本和发布实现 | 按任务读取 |
biz/ |
当前新版业务模型和服务试验实现 | 只参考业务事实,不复制结构 |
portfolio/ |
旧持仓、交易、自选和建议实现 | 仅用于历史行为/导入评估 |
strategy/、backtest/ |
历史策略和回测逻辑 | 仅用于规则评审 |
tests/ |
历史行为、边界和已知问题 | 按问题读取 |
docs/HLD.md |
历史目标设计和演进背景 | 不作为新项目最终基线 |
新项目最终设计以 docs/TARGET_ARCHITECTURE.md 和新项目自身文档为准。
10. 最终原则
原项目用于查事实,不用于定架构。
原项目用于找问题,不用于复制实现。
原项目用于评估历史数据,不用于绑定新数据库。
原项目用于复盘历史规则,不用于默认继承策略。
新项目必须独立设计、独立实现、独立测试、独立运行。
一句话总结:
让模型知道原项目,但只在需要时让它看到原项目;让目标架构决定新项目,而不是让历史实现决定新项目。
还没有评论,来第一个吧