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
+51 -23
View File
@@ -1,8 +1,8 @@
# qlib-platform 使用说明
> 适用代码版本:M1–M5 全部完成,含 QlibEngine v1(Qlib 数据管线)与 Parquet 导出
> (HEAD ≈ `fc12ba8`);若文档与代码不一致,以代码与
> [ARCHITECTURE.md](./ARCHITECTURE.md) / [ROADMAP.md](./ROADMAP.md) 为准。
> 适用代码版本:M0–M5 + M-DB + **M6 选股系统 / M7 因子层 / M8(Signal·Portfolio·Strategy·Agent·Web)**
> 全部完成(数据库已切换 MySQL);若文档与代码不一致,以代码与
> [ROADMAP.md](./ROADMAP.md) / [DEV_PLAN_v2.md](./DEV_PLAN_v2.md) 为准。
>
> 本文覆盖:安装配置、数据同步、启动前后端、研究 API、研究引擎与 Qlib 接入、
> AI Agent、测试门禁、已知限制。
@@ -15,14 +15,17 @@
| 模块 | 位置 / 说明 |
|---|---|
| 数据层 | `backend/app/domain`、`infrastructure/data_sources`:Tushare 首选 + 新浪备用(Failover 审计);SQLite 存储 + 日线 Parquet 导出(未来 MySQL 可切换) |
| 研究引擎 | `backend/app/quant`:ResearchSpec → 因子 → IC/RankIC/分层 → TopK 低频回测 → 标准化 `BacktestResult`;**双引擎**:LocalEngine(默认,纯 pandas)与 QlibEngine v1(QLibDataset 数据管线) |
| Qlib 接入 | `quant/qlib_adapter/`:SQLite 行情按官方二进制格式落盘 → `D.features` 读取 → 回测(详见 §6.1 与 docs/QLIB_VERIFICATION.md) |
| Web | `frontend/web`:Next.js(TS)+ECharts —— 总览 / 股票池 / 因子研究 / 回测 / 实验 |
| 数据层 | `backend/app/domain`、`infrastructure/data_sources`:Tushare 首选 + 新浪备用(Failover 审计);**默认 MySQL**(`config.yaml database.mysql`)+ 日线 Parquet 导出 |
| 选股系统 | `quant/selection.py` + `application/services/selection_service.py`:条件选股(A)/ 因子评分 TopN(B),`as_of` 当前/历史一致;结果落库可复现、可解释 |
| 因子层 | `factor_definition` 入库(`/api/factors` 读库)+ Composite Engine(`quant/composite.py`,组合落库 `/api/composites`)+ 行情口径显式化(`price_adjustment`) |
| 交易信号 | `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 进度 |
| 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.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
服务通过 `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/stocks?q=600519&limit=20` | 股票列表/搜索 |
| `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/backtests` | 同步回测 → `BacktestResult`(默认 LocalEngine) |
| `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`:查询
- `test_factor` / `run_backtest`:研究并**自动归档 Experiment**
- `screen_stocks` / `explain_selection`:按因子评分选股(传 `symbols` 白名单避免全市场长任务)/ 解释某次选股理由
- `generate_signals`:生成 BUY/WATCH/SELL 信号
- `create_strategy`:保存命名策略
- `get_experiment` / `compare_experiments`:读取/对比归档
**不提供** shell / 任意代码执行 / 删改数据 / 修改配置与凭证。未配置 Key 时接口返回
@@ -286,7 +311,7 @@ Agent 能力边界(内置受控工具,只读):
```bash
cd backend
uv run ruff check app tests && uv run ruff format --check app tests
uv run pytest # 当前 86 passed
uv run pytest # 全量测试(每个里程碑提交前均须通过)
cd frontend/web
pnpm run typecheck
@@ -302,18 +327,21 @@ pnpm run build
## 9. 已知限制与说明
1. **QlibEngine v1 边界**:数据管线(落盘→D.features→回测)已打通,见
docs/QLIB_VERIFICATION.md;**Alpha158 全特征 + LightGBM walk-forward 预测信号仍未实现**,
当前 QlibEngine 使用共享因子分回测(ROADMAP §2 备注为该增强 TODO)。
2. **数据规模**:仓库自带示例数据为 20 只权重股 2023–2024 日线(`sync --all` 可扩展
全市场,注意耗时与 Tushare 积分限制)。
3. **回测为近似建模**:涨跌停按收盘相对上一有效收盘判定、成交假设调仓日收盘,未建模
开盘一字 / 集合竞价 / 盘中路径(详见结果 `unimplemented`)。
4. **Agent 结论质量取决于模型**:编排只保证「经受控工具 + 归档留痕」,研究有效性判断
1. **Qlib 模型选股(Selection 模式 C)未实现**:当前选股为条件(A)/因子评分(B);
模型预测选股(Alpha158 + LightGBM walk-forward,M8.4)为「按需」延后项
(见 docs/DEV_PLAN_v2.md §6.4)。
2. **全市场选股为同步请求**:无白名单的全市场选股约需 60s+;Agent 工具要求传 `symbols`
白名单,全市场请在 Web 页执行(后续可迁异步 Job)。
3. **数据规模**:当前 MySQL 已同步全市场(stock 5556 只、stock_daily 约 780 万行、
adjust_factor 约 790 万行,2026-09 由 SQLite 迁移并校验一致)。
4. **回测为近似建模**:涨跌停按收盘相对上一有效收盘判定、成交假设调仓日收盘,
Portfolio v1 仅等权(单股/行业上限约束字段已预留但未建模,设置后会在结果
`unimplemented` 如实标注)(详见结果 `unimplemented`)。
5. **Agent 结论质量取决于模型**:编排只保证「经受控工具 + 归档留痕」,研究有效性判断
需要人复核;接不同厂商模型请核对 `config.yaml` 的 `base_url` 与 `model` 命名。
5. **SSE 与 Job 为单进程本地执行**:重启进程后未完成 Job 需重新提交(第一阶段刻意
不引入 Redis/Celery)。
6. **Qlib 数据为进程内单例初始化**:`qlib.init` 以 provider_uri 为键幂等,切换不同
6. **SSE 与 Job 为单进程本地执行**:重启进程后未完成 Job 需重新提交(第一阶段刻意
不引入 Redis/Celery;本机 Redis 已就绪,出现排队/长任务需求时按 DEV_PLAN §7 接入)。
7. **Qlib 数据为进程内单例初始化**:`qlib.init` 以 provider_uri 为键幂等,切换不同
qlib_dir 会重新初始化;测试环境建议注入独立临时目录。
---