Files
Simon 82240e383d docs: 同步操作说明/架构/路线图(归档操作、图表基座、数据库目标硬约束)
- USAGE 新增 §6.3.1「归档的日常操作」:查看 / 筛选(回写 URL)/ 导出完整 JSON /
  以此参数再跑 / 删除(写明「删除即失去结果,结果只存归档一份」)/
  历史归档用 restore_experiment_from_job 按原 id 重建;并说明归档完整度如何标注
- USAGE/README 更正技术栈与图表基座:TradingView Lightweight Charts 4.2.3 为唯一
  图表基座(ECharts 已从 package.json、pnpm-lock.yaml、node_modules、文档与
  架构图标注中全部清除),并记录实测证据(个股页图表根节点为
  div.tv-lightweight-charts,页面 canvas 无一来自其它图表库)
- ARCHITECTURE 更正「当前数据库」(原写 SQLite/未来 MySQL):现为本机 MariaDB 10.11,
  §6 补目标库硬约束;USAGE 补服务器身份与实测连接证据
- AGENT.md 新增 §0.1:数据库目标只允许本机 MariaDB,禁止 192.168.1.10,
  由 config.py::assert_db_target_allowed 硬拦截(命中直接抛错,不静默降级)
- DEV_PLAN_DIVIDEND_BACKTEST 记录三轮实施与验证、归档恢复边界(§12.5)、已知限制
- DEV_PLAN v2/v3 标注为历史记录(避免把当时的远端库地址当现状照抄);
  ROADMAP 更正 M3 图表选型
2026-09-20 07:31:20 +08:00

173 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 开发计划(Roadmap)
> 依据:[AGENT.md](./AGENT.md)(开发约束)、[docs/ARCHITECTURE.md](./ARCHITECTURE.md)(架构)
> 引擎:Qlib 只做计算引擎 · 数据源:Tushare 第一、Sina 备用 · 数据库:SQLite 起步、SQLAlchemy 保证 MySQL 可切换
> 现处:**M5 已完成(AI Agent Phase 5)**;**M6 起的下一阶段见 [docs/DEV_PLAN_v2.md](./DEV_PLAN_v2.md)**
> (选股系统为主线:Universe 选股范围 + Selection Engine A条件/B评分 + 结果落库/API +
> 回测共用引擎 + Web 选股页 → M7 因子层 → M8 Signal/Portfolio/Strategy/Agent)
> 2026-09 增补:数据库已切 MySQL(见 M-DB 行),本文件 M0–M5 为历史记录,新计划以 DEV_PLAN_v2 为准。
> 2026-09:M6–M8(DEV_PLAN_v2)已完成;**下一阶段按 [docs/DEV_PLAN_v3.md](./DEV_PLAN_v3.md)**
> (v3:Chart Service / Signal↔Fill / 个股研究页 / 复权口径 / 数据底座)。
---
## 0. 总览与里程碑
| 里程碑 | 内容 | 状态(2026-09 已实施) |
|---|---|---|
| M0 ✅ | 工程初始化 | commit 2a52ee5 |
| M1 ✅ | Phase 1 数据层(Tushare→SQLite/Parquet、Failover 审计、防未来函数) | commit 2da2342 · 38 tests |
| M2 ✅ | Phase 2 研究引擎(Spec→因子→评估→低频回测→标准结果;Qlib 桥接占位见 §2 备注) | commit e9f59d3 · 60 tests |
| M3 ✅ | Phase 3 Web(业务 API + Next.js 前端闭环) | commit 92627f5 · 68 tests |
| M4 ✅ | Phase 4 Experiment 归档 + Job/SSE 异步(一键复跑) | commit 0ea229d · 73 tests |
| M5 ✅ | Phase 5 AI Agent(受控 Tool 白名单 + LLM 编排;Key 配置见 .env) | commit(M5)· 79 tests |
| M-DB ✅ | 数据库 SQLite → MySQL(config.yaml database.mysql 配置化 + 迁移脚本 + 一致性校验) | 2026-09 · 见 DEV_PLAN_v2 §1 |
| M6 ✅ | 选股系统主线(Universe + Selection A条件/B评分 + 落库/API + 回测共用 + Web 页) | 2026-09 · f3586ad…0ab9038 |
| M7 ✅ | 因子层(factor_definition 入库 + Composite 模块化/落库 + 口径显式化) | 2026-09 · 8f47b5b…ef09d5b |
| M8 ✅ | Signal/Portfolio/Strategy + Agent 工具(10) + Web 做实 | 2026-09 · ba52edc…e5a23f1(M8.4 模型选股:按需延后) |
| V3-M9 ✅ | v3 主线:Chart Service/API + Signal↔Fill 历史 + 个股研究页 + 双图库 + 复权口径 + Bar Replay | 2026-09 · 995ed08…03fb463 |
| V3-S ✅ | 支撑线:B1 指数历史成分、C1 因子相关、C2 单股上限、D1 Job stage/取消、D2 选股 Job 化、D4 Agent 14 工具 | 2026-09 · 9cc4bfc…861a405 |
| V3-DEFERRED | B2/B3(停牌·ST·三大报表,依赖真实数据权限)、B4(结果实体化)、C3(Qlib 模型选股)、D3(Redis 触发) | 按需延后 · 见 DEV_PLAN_v3 §1 |
每阶段结束时同步更新:README / AGENT.md 相关清单 / 文档;**禁止跨阶段提前堆量**(AGENT.md §38)。
---
## 1. Phase 1 —— 数据层(M1,当前下一步)
> 目标:让系统拥有可追溯、可增量、无未来函数风险的 A 股数据资产。
### 1.1 Domain / DTO(先定契约)
- `domain/entities`:`Stock`(symbol/name/industry/listing_date…)、`TradingCalendar`、`StockDaily`(含 adjust 字段)、`AdjustFactor`、`FinancialIndicator`、`SyncLog`
- `domain/repositories`:`StockRepository / TradingCalendarRepository / StockDailyRepository / SyncLogRepository`(Protocol)
- Pydantic DTO:`StockFilter`、`SyncRequest`、`SyncLogQuery`
### 1.2 Data Provider(接口 + 双实现)
- `MarketDataProvider`(Protocol):`get_daily / get_stock_basic / get_trade_cal / get_financial / get_adjust_factor`,签名支持 `as_of_date`
- `TushareProvider`:封装 `tushare.pro`,token 从 `.env` 读;请求限流、错误分类(限频/无权限/网络)
- `SinaProvider`:仅补缺失/交叉校验(**备用**,业务代码不得直连新浪实现)
- **Failover + 审计**(AGENT.md §7):每次拉取写 `SyncLog`:`source / request_time / success / failure_reason / row_count / data_date`,禁止静默切换
### 1.3 标准化与校验
- 字段统一:`symbol`(如 `600519.SH`)、`trade_date`;财务字段区分 `report_date / announce_date`
- 校验器:空值率、量价非负、涨跌幅超限告警、复权因子单调性(日线复权因子不递减)
- 未来函数红线:**财务数据只允许在 `announce_date` 之后可见**(表结构与查询都体现)
### 1.4 持久化与迁移
- SQLAlchemy Model:stock / trading_calendar / stock_daily / adjust_factor / financial_indicator / sync_log / data_source_status
- Alembic:每个 Model 一版迁移;`render_as_batch` 已配置兼容 SQLite
- 规模策略:日线等明细写 SQLite 同时按年导出 Parquet(`data/parquet`),后续切 DuckDB/Qlib 用 Parquet(AGENT.md §13)
### 1.5 同步调度(第一版从 CLI 起步)
- `scripts/` 下 CLI:`sync basic|calendar|daily|financial [--start --end --symbols]`,支持断点续传(按 `data_date` 上限续拉)
- 全部耗时操作留 Job 形态(状态机 queued/running/success/failed/cancelled),API 异步化放 M3/M4
### 1.6 验收测试
- Provider failover:Tushare 抛错 → 自动尝试 Sina → 审计记录正确
- 未来函数:财务在 announce_date 前查询返回空
- Repository:DAO 层 CRUD + 幂等 upsert(`(symbol, trade_date)` 唯一)
- 迁移:`alembic upgrade head` 幂等可重放
**里程碑 M1 完成的判定**:`python -m scripts.sync daily --start 2024-01-01` 全量跑通,`sync_log` 完整,`data/quant.db` + `data/parquet` 均有产物,测试通过。
---
## 2. Phase 2 —— 研究引擎(M2)
> 实施备注(2026-09 更新):PyPI `pyqlib` 官方 wheel 仅支持 x86_64 / macOS / Windows,在 Linux aarch64 上 pip 解析不可满足(旧备注);
> 现已改用 **microsoft/qlib 源码 git 安装**并验证成功:开发机 Linux aarch64 + CPython 3.12(backend/.venv,uv 管理),
> 依赖已注册进 `backend/pyproject.toml`(`pyqlib @ git+https://github.com/microsoft/qlib.git@79633dd`,固定 commit,随 uv.lock 固化);
> numpy/pandas/scipy/lightgbm/pyarrow 等使用 aarch64 PyPI wheel,qlib 的两个 Cython 扩展(rolling/expanding)源码构建通过,
> 已验证 `import qlib` / `qlib.init()` / LightGBM 训练预测正常。源码 checkout 保留在项目外 `/home/pi/project/qlib-src`(供查阅/二次开发);
> 网络下载困难时按 AGENT.md §0 使用 HTTP 代理(192.168.1.160:3128)。
> M2 依据 AGENT.md §40「更简单、可替换优先」与 Qlib 经 Adapter 隔离的约束,交付**引擎接口 + 默认自研轻量引擎**(pandas 实现因子/评估/低频回测,完整可测);
> `quant/qlib_adapter/` 为桥接边界,现可在本机填充 Qlib Dataset / LightGBM 工作流实现(Phase 2 后续),业务层不感知切换。
> 目标:用 Research Specification 驱动「因子 → 评估 → 低频选股回测」闭环,产出标准化结果。
### 2.1 Qlib Adapter(`quant/qlib_adapter/`)
- `provider.py`:把 MarketDataProvider / Parquet 喂给 Qlib(QlibDataset 或 D/1d handler 数据源)
- `dataset.py`:Parquet → Qlib bin 特征集(`data/qlib`),含交易日历/股票池口径
- `feature.py`:Alpha158 / 自定义因子注册(因子元数据见 §3.1)
- `model.py`:LightGBM 训练/预测封装(参数收敛、seed 固定、可复现)
- `backtest.py`:TopK 低频回测封装,输出标准化 BacktestResult
### 2.2 Research Specification 驱动
- Pydantic Schema:universe / factors(含权重) / selection / rebalance / period / cost 参数
- Validator:禁止未来函数字段(financial 用 `as_of`)、范围检查、成本非负
- Strategy Builder:Spec → 具体策略对象(**不直接拼 Qlib YAML**)
### 2.3 回测真实性(AGENT.md §24)
手续费/印花税/滑点/涨跌停/停牌/换仓频率逐项落实;未实现项必须在结果中显式标注「未建模」,禁止默认无成本假设。
### 2.4 输出标准化(ARCHITECTURE §14)
统一 `BacktestResult`:summary / equity_curve / drawdown / monthly_returns / yearly_returns / positions / trades / turnover / risk_metrics / factor_exposure,前端只依赖该结构。
**M2 判定**:命令行传入一份 Research Specification JSON → 产出标准 BacktestResult + 图表数据;因子 IC/分层测试可跑;Qlib 全部调用位于 qlib_adapter。
---
## 3. Phase 3 —— Web 前端(M3)
> 目标:业务导向 UI(股票池/因子/选股/回测/结果),不暴露 Qlib 内部概念。
- `frontend/web`:Next.js(TS) + **TradingView Lightweight Charts**(按 README 与架构 §12/§13/§26 初始化)
> 注:M3 期曾用 ECharts,后已下线并移除依赖(含锁文件),全站唯一图表基座为 `components/charts/LwChart.tsx`。
- 页面:Dashboard → 股票池 → 因子研究 → 选股 → 回测 → 结果(Experiment 视角)
- API 对齐业务对象(AGENT.md §17):`/api/stocks /api/universes /api/factors /api/factor-tests /api/strategies /api/backtests /api/experiments /api/jobs`
- 交互:参数清晰、结果可视化;耗时任务显示 job 进度(轮询起步,SSE 视需要)
- DTO 前后端共享 Schema(OpenAPI 生成 TS 类型)
**M3 判定**:浏览器完成「选池→配因子→回测→看图」闭环,UI 无任何 Qlib/SQL 字样。
---
## 4. Phase 4 —— Experiment 与异步化(M4)
- `experiment` 模型落地:experiment_id / data_version / code_version / strategy_version / universe / factors / model / parameters / backtest_config / period / result(含 git commit 记录)
- Job 体系:queued→running→(success|failed|cancelled) + 阶段事件(factor_calculation/model_training/backtesting…),FastAPI BackgroundTasks 起步,不引 Redis/Celery(AGENT.md §15/§38)
- SSE:`/api/jobs/{id}/events` 推送进度
- 复跑:任意历史 Experiment 可从存档配置重放(数据版本需存在)
**M4 判定**:一次研究自动落 Experiment;网页可查看历史实验并一键复跑。
---
## 5. Phase 5 —— AI Research Agent(M5)
- `agent/tools`:search_stocks / get_market_data / test_factor / create_strategy / run_backtest / get_experiment / compare_experiments(只读 + 沙箱,AGENT.md §28 禁令表)
- Agent 编排:自然语言 → Research Plan → 逐步 Tool 调用 → 产出 Experiment → 结论分析(§29 假设-实验-分析循环)
- 反过拟合纪律:IC/RankIC/ICIR/分层/换手/行业市值暴露/样本外 walk-forward;不得以单次 Sharpe 高宣布有效
- 接入:先本地(LLM API Key 走 .env),后续可视需要提供 API
**M5 判定**:对 Agent 说「找适合 A 股月度调仓的低频因子」→ Agent 产出因子测试报告 + Experiment,结论包含稳健性讨论。
---
## 6. 贯穿全程的硬约束(每次提交自查,AGENT.md §41)
- [ ] 是否违反 ARCHITECTURE.md / 绕过 DAO / 把 SQLite 写死?
- [ ] 是否直接依赖 Qlib 内部实现(应只在 `quant/qlib_adapter/`)?
- [ ] 是否可能引入未来函数 / 数据泄露(as_of_date、announce_date、历史成分股)?
- [ ] 新表是否走 Model → Migration → Test?
- [ ] API 契约是否变?文档是否同步?
- [ ] 是否有测试(至少相关模块)?是否运行通过?
- [ ] 是否把 secret / 数据库 / 大文件提交进 Git?
- [ ] 是否做了不必要的大规模重构(应最小修改)?
## 7. 最近三个可执行项(建议顺序)
1. 定义 Phase 1 的 Domain 实体与 Repository Protocol(纯接口,无数据库依赖)
2. 实现 `TushareProvider` + `SinaProvider` + Failover 审计(先用 .env 配好的 token 实测拉 1 只股票日线)
3. 落 SQLite Model + Alembic 首版迁移 + Repository 实现 + 对应测试