Files
qlib/docs/ROADMAP.md
T
Simon d9be75a98f feat: Phase 5 — AI Research Agent(受控工具白名单 + LLM 编排 + API)
- agent/tools.py:Tool 元数据(JSON Schema)+ 白名单调用(异常转可读反馈,不中断对话)
- agent/tools_impl.py:6 个受控工具 search_stocks / get_market_data / test_factor / run_backtest / get_experiment / compare_experiments —— 全部只读经 Job/Experiment 链路,研究自动归档;无 shell/任意执行/写删数据能力
- agent/llm.py:LLMClient 抽象 + OpenAI 兼容客户端(LLM_API_KEY/LLM_BASE_URL/LLM_MODEL 走 .env,未配置给出引导提示)+ 研究纪律 system prompt(反过拟合/样本外/成本)
- agent/service.py:编排循环(tool/final JSON 决策 → 执行 → 回喂 → 结论),轮次上限兜底,未知工具拒绝
- /api/agent/chat;httpx 移至主依赖;Job 默认工厂抽取(api/agent/executor 复用)
- 测试 6 项(白名单无 shell、完整研究循环产出、未知工具拒绝、轮次兜底),全量 79 passed / ruff clean
2026-09-06 17:22:05 +08:00

156 lines
9.2 KiB
Markdown
Raw 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 可切换
> 现处:**M0 已完成(工程骨架 + 可运行后端)**,下一步进入 **Phase 1 数据层**
---
## 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(本轮)· 79 tests |
每阶段结束时同步更新: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):pyqlib 官方 wheel 仅支持 x86_64 / macOS / Windows 且最高 Python 3.8 构建;
> 本项目开发机为 Linux aarch64 + Python 3.12,无法安装 Qlib(已实测 pip 解析不可满足)。
> 依据 AGENT.md §40「更简单、可替换优先」与 Qlib 经 Adapter 隔离的约束,M2 交付**引擎接口 + 默认自研轻量引擎**(pandas 实现因子/评估/低频回测,完整可测);
> `quant/qlib_adapter/` 保留桥接边界,在支持平台安装 pyqlib 后填充 Qlib Dataset / LightGBM 工作流实现,业务层不感知切换。
> 目标:用 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) + ECharts(按 README 与架构 §12/§13/§26 初始化)
- 页面: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 实现 + 对应测试