docs: 同步 README/USAGE 至 M6–M8(选股系统主线 + MySQL + 新 API/Agent 工具/限制)

- README:架构分层示意(Selection/Signal/Portfolio/Composite Engine)、MySQL 默认配置、
  核心能力表、里程碑 M0–M8
- USAGE:概览模块与页面清单、引擎分层 §6.0、API 表新增 /api/selections /api/signals
  /api/strategies /api/composites、Agent 10 工具、已知限制(M8.4 延后/全市场选股同步耗时)
This commit is contained in:
Simon
2026-09-09 06:29:51 +08:00
parent db147c4232
commit 314bfc159f
2 changed files with 91 additions and 41 deletions
+39 -17
View File
@@ -1,6 +1,6 @@
# qlib-platform # qlib-platform
个人 A 股量化研究平台:**选股 · 因子研究 · 回测**,面向低频 / 中低频交易研究。 个人 A 股量化研究平台:**股票筛选 · 因子研究 · 交易信号 · 选股回测**,面向低频 / 中低频交易研究。
> 核心量化引擎:[Qlib](https://github.com/microsoft/qlib) · 首选数据源:Tushare(新浪财经为备用)· 当前数据库:MySQL(业务层无感切换;SQLite 仅兜底) > 核心量化引擎:[Qlib](https://github.com/microsoft/qlib) · 首选数据源:Tushare(新浪财经为备用)· 当前数据库:MySQL(业务层无感切换;SQLite 仅兜底)
@@ -16,13 +16,17 @@
详见 [AGENT.md](./AGENT.md)(开发约束)与 [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)(架构文档),**改代码前必须阅读**。 详见 [AGENT.md](./AGENT.md)(开发约束)与 [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)(架构文档),**改代码前必须阅读**。
```text ```text
Web 前端 (frontend/web) Web 前端 (frontend/web:总览 / 股票池 / 股票筛选 / 因子研究 / 因子组合 / 交易信号 / 选股回测 / 实验)
↓ REST / SSE ↓ REST / SSE(异步 Job 状态机)
FastAPI (backend) FastAPI (backend:业务对象 API,见下「核心能力」)
↓ Research Specification ↓ Research Specification(统一研究契约)
Application Service ── Quant Service ── Qlib Adapter ── Qlib Application Service(SelectionService / SignalService / ResearchService / Strategy …)
├── Selection Engine(条件选股 / 因子评分 / as_of 历史与当前一致)
├── Signal Engine(BUY / WATCH / SELL + 理由)
├── Portfolio Engine(等权;约束预留并如实标注)
└── Quant Service ── Composite Engine ── Qlib Adapter ── Qlib
↓ ↓ ↓ ↓
Repository / DAO Parquet / MySQL Repository / DAO MySQL(默认)/ Parquet
``` ```
### 目录结构 ### 目录结构
@@ -35,7 +39,8 @@ qlib/
│ │ ├── application/ # 用例 / 应用服务(编排,不含框架细节) │ │ ├── application/ # 用例 / 应用服务(编排,不含框架细节)
│ │ ├── domain/ # 领域实体 + Repository Protocol │ │ ├── domain/ # 领域实体 + Repository Protocol
│ │ ├── infrastructure/ # SQLAlchemy / Alembic 等基础设施实现 │ │ ├── infrastructure/ # SQLAlchemy / Alembic 等基础设施实现
│ │ ├── quant/qlib_adapter/ # Qlib 适配层(业务禁止直接 import qlib) │ │ ├── quant/ # 因子 / composite / universe / selection / signal / portfolio 引擎
│ │ │ └── qlib_adapter/ # Qlib 适配层(业务禁止直接 import qlib)
│ │ ├── agent/ # AI Research Agent(Phase 5,仅 Tool 访问) │ │ ├── agent/ # AI Research Agent(Phase 5,仅 Tool 访问)
│ │ └── core/ # 配置、通用组件 │ │ └── core/ # 配置、通用组件
│ └── tests/ │ └── tests/
@@ -75,21 +80,38 @@ uv run uvicorn app.main:app --reload --port 8000
# 交互文档:http://127.0.0.1:8000/docs # 交互文档:http://127.0.0.1:8000/docs
``` ```
### 数据库迁移(Alembic,已就位) ### 数据库(默认 MySQL)
- 连接在根目录 `config.yaml → database.mysql`(host/port/db/user/charset),密码放 `.env` 的
`MYSQL_PASSWORD`;URL 优先级:`DATABASE_URL` 环境变量 > `database.mysql` > SQLite 兜底。
- 结构变更(Model → Migration → Test):
```bash ```bash
cd backend cd backend
uv run alembic upgrade head # 首次运行会在 data/quant.db 建立版本表 uv run alembic upgrade head # 在当前配置指向的库上建表(默认 MySQL qlib)
uv run alembic revision --autogenerate -m "add xxx table" # 修改 Model 后生成迁移 uv run alembic revision --autogenerate -m "add xxx table"
``` ```
## 开发阶段(对应架构文档 §20) ## 核心能力(现状)
- **Phase 1 数据**:Tushare → 标准化 → MySQL(stock / daily / 复权因子 / 交易日历 / 财务指标),Parquet 导出 | 能力 | 说明 / 入口 |
- **Phase 2 Qlib**:Parquet → Qlib Dataset → 因子(Alpha158 / 自定义)→ LightGBM → 回测 |---|---|
- **Phase 3 Web**:股票池 / 因子研究 / 选股 / 回测 / 结果可视化(Next.js + ECharts) | 股票筛选 | `POST /api/selections`(A 条件选股 / B 因子评分 TopN,`as_of` 当前/历史,结果可解释可复现);Web `/selection` |
- **Phase 4 Experiment**:所有研究自动可复现存档 | 因子目录 | `factor_definition` 落库;`GET /api/factors`;组合可保存复用 `POST /api/composites` |
- **Phase 5 AI Agent**:自然语言 → Research Plan → 受控 Tool → Experiment | 因子研究 | Job 异步 IC / RankIC / 分层测试(`/api/jobs`) |
| 交易信号 | `POST /api/signals`:评分排名 + 趋势规则 → BUY/WATCH/SELL + 理由;Web `/signals` |
| 选股回测 | `POST /api/backtests`(成本/涨跌停近似;与当前选股共用同一评分引擎,v2 §25 一致性) |
| 策略资产 | `strategy` 落库 + `/api/strategies`(命名配置,可展开为回测 spec) |
| Experiment | 每次研究自动归档 + 一键复跑 + SSE 进度 |
| AI Agent | `POST /api/agent/chat`,10 个受控 Tool(含 screen_stocks / explain_selection / generate_signals / create_strategy) |
## 里程碑(详见 [ROADMAP.md](./docs/ROADMAP.md) 与 [docs/DEV_PLAN_v2.md](./docs/DEV_PLAN_v2.md))
- **M0–M5**:工程骨架 → 数据层 → 研究引擎 → Web → Experiment/Job → AI Agent
- **M-DB**:SQLite 全量迁移 MySQL(config.yaml 配置化 + 迁移工具 + 一致性校验)
- **M6**:选股系统主线(Universe + Selection A/B + 落库/API + 回测共用 + Web)
- **M7**:因子层(因子定义入库 + Composite 模块化 + 行情口径显式化)
- **M8**:Signal / Portfolio / Strategy / Agent 工具 / Web 做实(M8.4 Qlib 模型选股按需延后)
## 约定速查 ## 约定速查
+51 -23
View File
@@ -1,8 +1,8 @@
# qlib-platform 使用说明 # qlib-platform 使用说明
> 适用代码版本:M1–M5 全部完成,含 QlibEngine v1(Qlib 数据管线)与 Parquet 导出 > 适用代码版本:M0–M5 + M-DB + **M6 选股系统 / M7 因子层 / M8(Signal·Portfolio·Strategy·Agent·Web)**
> (HEAD ≈ `fc12ba8`);若文档与代码不一致,以代码与 > 全部完成(数据库已切换 MySQL);若文档与代码不一致,以代码与
> [ARCHITECTURE.md](./ARCHITECTURE.md) / [ROADMAP.md](./ROADMAP.md) 为准。 > [ROADMAP.md](./ROADMAP.md) / [DEV_PLAN_v2.md](./DEV_PLAN_v2.md) 为准。
> >
> 本文覆盖:安装配置、数据同步、启动前后端、研究 API、研究引擎与 Qlib 接入、 > 本文覆盖:安装配置、数据同步、启动前后端、研究 API、研究引擎与 Qlib 接入、
> AI Agent、测试门禁、已知限制。 > AI Agent、测试门禁、已知限制。
@@ -15,14 +15,17 @@
| 模块 | 位置 / 说明 | | 模块 | 位置 / 说明 |
|---|---| |---|---|
| 数据层 | `backend/app/domain`、`infrastructure/data_sources`:Tushare 首选 + 新浪备用(Failover 审计);SQLite 存储 + 日线 Parquet 导出(未来 MySQL 可切换) | | 数据层 | `backend/app/domain`、`infrastructure/data_sources`:Tushare 首选 + 新浪备用(Failover 审计);**默认 MySQL**(`config.yaml database.mysql`)+ 日线 Parquet 导出 |
| 研究引擎 | `backend/app/quant`:ResearchSpec → 因子 → IC/RankIC/分层 → TopK 低频回测 → 标准化 `BacktestResult`;**双引擎**:LocalEngine(默认,纯 pandas)与 QlibEngine v1(QLibDataset 数据管线) | | 选股系统 | `quant/selection.py` + `application/services/selection_service.py`:条件选股(A)/ 因子评分 TopN(B),`as_of` 当前/历史一致;结果落库可复现、可解释 |
| Qlib 接入 | `quant/qlib_adapter/`:SQLite 行情按官方二进制格式落盘 → `D.features` 读取 → 回测(详见 §6.1 与 docs/QLIB_VERIFICATION.md) | | 因子层 | `factor_definition` 入库(`/api/factors` 读库)+ Composite Engine(`quant/composite.py`,组合落库 `/api/composites`)+ 行情口径显式化(`price_adjustment`) |
| Web | `frontend/web`:Next.js(TS)+ECharts —— 总览 / 股票池 / 因子研究 / 回测 / 实验 | | 交易信号 | `quant/signal.py`:评分排名 + 趋势规则 → BUY/WATCH/SELL + 理由,落库 `/api/signals` |
| 研究/回测 | `backend/app/quant`:ResearchSpec → 因子 → IC/RankIC/分层 → TopK 低频回测 → 标准化 `BacktestResult`;**双引擎**:LocalEngine(默认)与 QlibEngine v1 |
| 策略 | `strategy` 落库 + `/api/strategies`(命名策略,可展开为回测 spec) |
| Web | `frontend/web`:总览 / 股票池 / **股票筛选** / 因子研究 / 因子组合 / **交易信号** / 选股回测 / 实验 |
| 异步与归档 | Job 状态机 + Experiment 自动归档 + 一键复跑 + SSE 进度 | | 异步与归档 | Job 状态机 + Experiment 自动归档 + 一键复跑 + SSE 进度 |
| AI Agent | 受控工具白名单 + LLM 编排(需配置模型 Key) | | AI Agent | 10 个受控工具 + LLM 编排(需配置模型 Key) |
**技术栈**:Python 3.12(uv) · FastAPI · SQLAlchemy 2 · Alembic · SQLite · pandas · pyarrow(Parquet) · pyqlib 0.9.8.dev32(源码安装) · LightGBM · Next.js 15 · ECharts **技术栈**:Python 3.12(uv) · FastAPI · SQLAlchemy 2 · Alembic · **MySQL(pymysql)**(SQLite 兜底)· pandas · pyarrow(Parquet) · pyqlib 0.9.8.dev32(源码安装) · LightGBM · Next.js 15 · ECharts · Redis(本机 127.0.0.1:6379 已就绪,触发时接入)
--- ---
@@ -182,6 +185,18 @@ pnpm dev
## 6. 研究 API 与研究引擎 ## 6. 研究 API 与研究引擎
### 6.0 引擎分层(M6–M8)
研究/选股链路自 M6 起分层:`Composite Engine`(因子复合分)→ `Selection Engine`
(条件/评分选股)→ `Signal Engine`(买卖信号)→ `Portfolio`(组合权重)→ 回测。
**当前选股与历史回测共用同一评分引擎**(`quant/composite.build_score_panel`),
保证 v2 §25「历史回测与当前选股用同一套逻辑」(一致性由测试锁定)。
- 选股:`POST /api/selections`,body 为 `SelectionQuery`(universe / factors / top_n /
as_of / method);结果候选含 `factor_values` 与 `selection_reason`(为什么选它)。
- 信号:`POST /api/signals`,body `{query, rules}`;rules 含买入排名阈值/趋势 MA/卖出区间。
- 策略:`POST /api/strategies` 保存命名策略 → `POST /{id}/expand` 补 period 展开为 spec 提交回测。
### 6.1 研究引擎:LocalEngine(默认)与 QlibEngine v1 ### 6.1 研究引擎:LocalEngine(默认)与 QlibEngine v1
服务通过 `QuantEngine` Protocol 注入引擎(`backend/app/quant/engine.py`): 服务通过 `QuantEngine` Protocol 注入引擎(`backend/app/quant/engine.py`):
@@ -228,7 +243,14 @@ curl -X POST http://127.0.0.1:8000/api/backtests \
| `GET /api/health` | 健康检查 | | `GET /api/health` | 健康检查 |
| `GET /api/stocks?q=600519&limit=20` | 股票列表/搜索 | | `GET /api/stocks?q=600519&limit=20` | 股票列表/搜索 |
| `GET /api/stocks/{symbol}` | 单只股票详情 | | `GET /api/stocks/{symbol}` | 单只股票详情 |
| `GET /api/factors` | 因子目录(公式/lookback/方向) | | `GET /api/factors` | 因子目录(读 `factor_definition` 表;空表自动 seed) |
| `POST /api/composites` / `GET /api/composites` | 因子组合保存 / 列表(方向由注册表填充) |
| `POST /api/selections` | 执行选股(`method=score` 评分 TopN / `condition` 条件)→ `SelectionResult` 并落库 |
| `GET /api/selections/{id}` / `GET /api/selections` | 读回 / 历史选股(`as_of`、`method` 过滤) |
| `POST /api/signals` | 生成 BUY/WATCH/SELL 信号(评分+规则)→ 落库 |
| `GET /api/signals/{id}` / `GET /api/signals` | 读回 / 历史信号 |
| `POST /api/strategies` / `GET /api/strategies` | 保存 / 列表命名策略 |
| `POST /api/strategies/{id}/expand` | 展开为回测 ResearchSpec(period + 初始资金) |
| `POST /api/factor-tests` | 同步单因子测试 → `FactorTestReport` | | `POST /api/factor-tests` | 同步单因子测试 → `FactorTestReport` |
| `POST /api/backtests` | 同步回测 → `BacktestResult`(默认 LocalEngine) | | `POST /api/backtests` | 同步回测 → `BacktestResult`(默认 LocalEngine) |
| `GET /api/backtests/last` | 最近一次同步回测 | | `GET /api/backtests/last` | 最近一次同步回测 |
@@ -269,10 +291,13 @@ curl -X POST http://127.0.0.1:8000/api/agent/chat \
} }
``` ```
Agent 能力边界(内置受控工具,只读): Agent 能力边界(10 个内置受控工具,只读 + 受控写库):
- `search_stocks` / `get_market_data`:查询 - `search_stocks` / `get_market_data`:查询
- `test_factor` / `run_backtest`:研究并**自动归档 Experiment** - `test_factor` / `run_backtest`:研究并**自动归档 Experiment**
- `screen_stocks` / `explain_selection`:按因子评分选股(传 `symbols` 白名单避免全市场长任务)/ 解释某次选股理由
- `generate_signals`:生成 BUY/WATCH/SELL 信号
- `create_strategy`:保存命名策略
- `get_experiment` / `compare_experiments`:读取/对比归档 - `get_experiment` / `compare_experiments`:读取/对比归档
**不提供** shell / 任意代码执行 / 删改数据 / 修改配置与凭证。未配置 Key 时接口返回 **不提供** shell / 任意代码执行 / 删改数据 / 修改配置与凭证。未配置 Key 时接口返回
@@ -286,7 +311,7 @@ Agent 能力边界(内置受控工具,只读):
```bash ```bash
cd backend cd backend
uv run ruff check app tests && uv run ruff format --check app tests uv run ruff check app tests && uv run ruff format --check app tests
uv run pytest # 当前 86 passed uv run pytest # 全量测试(每个里程碑提交前均须通过)
cd frontend/web cd frontend/web
pnpm run typecheck pnpm run typecheck
@@ -302,18 +327,21 @@ pnpm run build
## 9. 已知限制与说明 ## 9. 已知限制与说明
1. **QlibEngine v1 边界**:数据管线(落盘→D.features→回测)已打通,见 1. **Qlib 模型选股(Selection 模式 C)未实现**:当前选股为条件(A)/因子评分(B);
docs/QLIB_VERIFICATION.md;**Alpha158 全特征 + LightGBM walk-forward 预测信号仍未实现**, 模型预测选股(Alpha158 + LightGBM walk-forward,M8.4)为「按需」延后项
当前 QlibEngine 使用共享因子分回测(ROADMAP §2 备注为该增强 TODO)。 (见 docs/DEV_PLAN_v2.md §6.4)。
2. **数据规模**:仓库自带示例数据为 20 只权重股 2023–2024 日线(`sync --all` 可扩展 2. **全市场选股为同步请求**:无白名单的全市场选股约需 60s+;Agent 工具要求传 `symbols`
全市场,注意耗时与 Tushare 积分限制)。 白名单,全市场请在 Web 页执行(后续可迁异步 Job)。
3. **回测为近似建模**:涨跌停按收盘相对上一有效收盘判定、成交假设调仓日收盘,未建模 3. **数据规模**:当前 MySQL 已同步全市场(stock 5556 只、stock_daily 约 780 万行、
开盘一字 / 集合竞价 / 盘中路径(详见结果 `unimplemented`)。 adjust_factor 约 790 万行,2026-09 由 SQLite 迁移并校验一致)。
4. **Agent 结论质量取决于模型**:编排只保证「经受控工具 + 归档留痕」,研究有效性判断 4. **回测为近似建模**:涨跌停按收盘相对上一有效收盘判定、成交假设调仓日收盘,
Portfolio v1 仅等权(单股/行业上限约束字段已预留但未建模,设置后会在结果
`unimplemented` 如实标注)(详见结果 `unimplemented`)。
5. **Agent 结论质量取决于模型**:编排只保证「经受控工具 + 归档留痕」,研究有效性判断
需要人复核;接不同厂商模型请核对 `config.yaml` 的 `base_url` 与 `model` 命名。 需要人复核;接不同厂商模型请核对 `config.yaml` 的 `base_url` 与 `model` 命名。
5. **SSE 与 Job 为单进程本地执行**:重启进程后未完成 Job 需重新提交(第一阶段刻意 6. **SSE 与 Job 为单进程本地执行**:重启进程后未完成 Job 需重新提交(第一阶段刻意
不引入 Redis/Celery)。 不引入 Redis/Celery;本机 Redis 已就绪,出现排队/长任务需求时按 DEV_PLAN §7 接入)。
6. **Qlib 数据为进程内单例初始化**:`qlib.init` 以 provider_uri 为键幂等,切换不同 7. **Qlib 数据为进程内单例初始化**:`qlib.init` 以 provider_uri 为键幂等,切换不同
qlib_dir 会重新初始化;测试环境建议注入独立临时目录。 qlib_dir 会重新初始化;测试环境建议注入独立临时目录。
--- ---