- 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 图表选型
173 lines
12 KiB
Markdown
173 lines
12 KiB
Markdown
# 开发计划(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 实现 + 对应测试
|