Files
qlib/docs/USAGE.md
T
Simon b8f67f99ae feat(quant): QlibEngine v1 — 本地行情落盘 QlibDataset → D.features 读取 → 因子回测
- qlib_adapter/provider.py:SQLite 行情按 qlib 0.9.8 二进制格式落盘(起始索引头 + 逐日 float32、instruments 3 列、小写 instrument、晚上市 offset)
- qlib_adapter/dataset.py:qlib.init 幂等({'day': uri})+ D.features 读取 close 面板
- qlib_adapter/engine.py:QlibEngine(QuantEngine)v1 —— Qlib 数据管线回测与 LocalEngine 同记账规则(无未来函数/成本/涨跌停标注),factor_test 复用共享实现;Alpha158+LightGBM 为 TODO
- 真实 20 股验证:qlib 落盘 142 文件→读取→回测(-12.81%,Local 对照 -12.97%,差异为 qlib float32 存储)
- tests/test_qlib_engine.py 5 项(格式/roundtrip/晚上市 offset/回测/因子测试)→ pytest 86 passed / ruff clean
2026-09-06 18:20:28 +08:00

261 lines
10 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.
# qlib-platform 使用说明
> 适用代码版本:M1–M5 全部完成(`d9be75a` 及之后);若文档与代码不一致,以代码与
> [ARCHITECTURE.md](./ARCHITECTURE.md) / [ROADMAP.md](./ROADMAP.md) 为准。
>
> 本文覆盖:安装配置、数据同步、启动前后端、研究 API 调用、AI Agent、测试门禁、已知限制。
---
## 1. 项目概览(当前完成度)
个人 A 股中低频量化研究平台,当前已完成:
| 模块 | 位置 / 说明 |
|---|---|
| 数据层 | `backend/app/domain`、`backend/app/infrastructure/data_sources`:Tushare 首选 + 新浪备用(Failover 审计),SQLite(未来 MySQL 可切换) |
| 研究引擎 | `backend/app/quant`:ResearchSpec → 因子 → IC/RankIC/分层 → TopK 低频回测 → 标准化 `BacktestResult` |
| Web | `frontend/web`:Next.js(TS)+ECharts —— 总览 / 股票池 / 因子研究 / 回测 / 实验 |
| 异步与归档 | Job 状态机 + Experiment 自动归档 + 一键复跑 + SSE 进度 |
| AI Agent | 受控工具白名单 + LLM 编排(需配置模型 Key) |
**技术栈**:Python 3.12(uv) · FastAPI · SQLAlchemy 2 · Alembic · SQLite · pandas · Next.js 15 · ECharts
---
## 2. 环境准备
```bash
# 工具(本机已装则跳过)
python3 -m pip install uv
# Node 18+ 与 pnpm: https://pnpm.io/installation
# 1) 后端依赖(backend/.python-version 固定 3.12)
cd backend
uv sync # 基础依赖
uv sync --extra datasource-tushare # 数据同步需要 Tushare SDK(首次)
```
前端:
```bash
cd frontend/web
pnpm install # 依赖使用 npmmirror 镜像时较快
cp .env.local.example .env.local # NEXT_PUBLIC_API_BASE 默认 http://127.0.0.1:8000/api
```
---
## 3. 配置
### 3.1 根目录 `.env`(密钥,不入库)
```bash
cp .env.example .env
```
按需填写:
| 变量 | 必填 | 说明 |
|---|---|---|
| `TUSHARE_TOKEN` | 同步数据时必填 | Tushare Pro token |
| `LLM_API_KEY` | 使用 Agent 时必填 | 大模型 API Key |
| `DATABASE_URL` | 否 | 留空使用 SQLite `<项目根>/data/quant.db` |
| `APP_SECRET_KEY` | 否 | 应用密钥(未接登录,可暂不改) |
> 约定:**密钥只放 `.env`**;URL、模型名等可配置项放 `config.yaml`(见下)。`.env` 已被 gitignore,严禁提交。
### 3.2 根目录 `config.yaml`(可配置项,可入库)
常用字段:
```yaml
app: {name, version, debug, secret_key_env}
api: {prefix: "/api"} # API 前缀
database: {url_env: "DATABASE_URL", echo: false, migrations_dir: ...}
data_source: {primary: "tushare", fallback: "sina", tushare_token_env: "TUSHARE_TOKEN"}
storage: {parquet_dir, qlib_dir, ...} # 相对项目根
agent:
llm: # ← AI Agent 模型接入
base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1" # URL 在这里配
model: "qwen-plus" # 模型名在这里配
api_key_env: "LLM_API_KEY" # Key 仍从 .env 读
```
- **换模型**:改 `config.yaml → agent.llm.model`(例如 `deepseek-chat` / `qwen-max` 等
OpenAI 兼容接口模型),并同步 `base_url`(如有平台差异)。
- 也可以用 `.env` 的 `LLM_BASE_URL` / `LLM_MODEL` 覆盖 yaml 值(两种都支持,env 优先)。
### 3.3 数据库迁移
```bash
cd backend
uv run alembic upgrade head # 建表(首次会自动建 data/quant.db)
# 开发中改 Model 后:
uv run alembic revision --autogenerate -m "desc"
uv run alembic upgrade head
```
---
## 4. 数据同步
```bash
cd backend
uv run python -m app.cli.sync basic # 股票基础信息(全市场)
uv run python -m app.cli.sync calendar --start 20240101 --end 20241231
uv run python -m app.cli.sync daily --symbols 600519.SH,000858.SZ --start 20230101
uv run python -m app.cli.sync daily --all --start 20240101 --resume # 全市场 + 断点续传
uv run python -m app.cli.sync financial --symbols 600519.SH
uv run python -m app.cli.sync verify --symbol 600519.SH # 新浪交叉验证
```
说明:
- 每次拉取写入 `sync_log` 审计(来源 / 成功与否 / 行数 / 区间),禁止静默切换数据源。
- `daily` 同时写入日线与复权因子;`--resume` 从本地最新交易日续传。
- 新浪(`verify`)仅用于交叉验证,返回**前复权**口径,不会并入不复权主库。
- 财务指标带 `announce_date`(公告日),研究侧只允许使用已公告数据(防未来函数)。
---
## 5. 启动
```bash
# 后端(端口 8000)
cd backend
uv run uvicorn app.main:app --reload --port 8000
# 交互文档:http://127.0.0.1:8000/docs 健康检查:/api/health
# 前端(端口 3000)
cd frontend/web
pnpm dev
# 打开 http://127.0.0.1:3000
```
页面:`总览` → `股票池`(搜索/列表)→ `因子研究`(目录 + 单因子 IC/RankIC/分层)→
`回测`(参数 → 净值/回撤/月度/持仓/未建模标注)→ `实验`(归档列表 / 详情 / 一键复跑)。
---
## 6. 研究 API(curl 示例)
所有研究输入 = ResearchSpec(统一结构,前端 / API / Agent 同构):
```bash
curl -X POST http://127.0.0.1:8000/api/backtests \
-H 'Content-Type: application/json' \
-d '{
"type": "backtest",
"universe": {"exclude_st": true, "min_listing_days": 0},
"factors": [{"name": "momentum_60", "weight": 1.0}],
"selection": {"top_n": 5},
"rebalance": "monthly",
"period": ["2024-03-01", "2024-12-31"]
}'
```
| 端点 | 说明 |
|---|---|
| `GET /api/stocks?q=600519&limit=20` | 股票列表/搜索 |
| `GET /api/factors` | 因子目录(含公式/lookback/方向) |
| `POST /api/factor-tests` | 同步单因子测试 → `FactorTestReport` |
| `POST /api/backtests` | 同步回测(小样本)→ `BacktestResult` |
| `GET /api/backtests/last` | 最近一次同步回测 |
| `POST /api/jobs` | 创建异步 Job(同 spec),返回 `{"job_id","status":"queued"}` |
| `GET /api/jobs/{id}` | 查询状态;成功时内嵌 `result` |
| `GET /api/jobs/{id}/events` | SSE 进度(`curl -N ...`) |
| `GET /api/experiments` | 实验归档列表(含收益摘要/代码版本) |
| `GET /api/experiments/{id}` | 实验详情(spec + 完整结果) |
| `POST /api/experiments/{id}/rerun` | 一键复跑 → 新 Job |
| `POST /api/agent/chat` | AI 研究助手(见 §7) |
**防未来函数与真实性**:回测在调仓日收盘成交、自次日起计收益;财务数据只使用
`announce_date` 之前已公告内容;成本(佣金/印花税/滑点)、涨跌停、停牌已建模;
未建模约束(如开盘一字路径)会写入结果的 `unimplemented` 数组,前端如实展示。
---
## 7. AI Agent
前置:`config.yaml → agent.llm`(URL/模型名已配好,默认阿里云百炼 qwen-plus),
`.env` 中设置 `LLM_API_KEY`。
```bash
curl -X POST http://127.0.0.1:8000/api/agent/chat \
-H 'Content-Type: application/json' \
-d '{"message": "帮我测试 momentum_60 因子并跑一次 Top5 月度回测,评估是否值得深入"}'
```
返回:
```json
{
"reply": "(最终结论,中文)",
"actions": [
{"tool": "test_factor", "args": {...}, "output": "因子测试完成(Experiment EXP-…)..."},
{"tool": "run_backtest", "args": {...}, "output": "回测完成(Experiment EXP-…)..."}
]
}
```
Agent 能力边界(内置受控工具,只读):
- `search_stocks` / `get_market_data`:查询
- `test_factor` / `run_backtest`:研究并自动归档 Experiment
- `get_experiment` / `compare_experiments`:读取/对比归档
**不提供** shell / 任意代码执行 / 删改数据 / 修改配置与凭证。未配置 Key 时接口返回
400 引导信息。研究纪律写入系统提示:禁止仅凭单次样本内高收益判定策略有效,需说明
样本外、过拟合、look-ahead bias、成本、参数敏感性等(未验证项要明说)。
---
## 8. 测试与质量门禁
```bash
cd backend
uv run ruff check app tests && uv run ruff format --check app tests
uv run pytest # 当前 79 passed
cd frontend/web
pnpm run typecheck
pnpm run build
```
覆盖重点:Provider 归一化与 Failover 审计、Repository 幂等与「未来函数阻断」
(`as_of_date`/`announce_date`)、Alembic 迁移、因子/IC/分层、回测记账与成本/涨跌停、
Job 状态机与 Experiment 归档、Agent 工具白名单与编排、API 端到端。
---
## 9. 已知限制与说明
1. **Qlib 引擎(v1 数据管线)**:pyqlib 已通过源码安装可用(qlib 0.9.8.dev32,见
docs/QLIB_VERIFICATION.md)。`app/quant/qlib_adapter/` 提供 QlibEngine:本地行情按官方
二进制格式落盘 QlibDataset → `D.features` 读取 → TopK 因子回测(与 LocalEngine 同记账
规则)。默认研究引擎仍为 LocalEngine;切换只需向 ResearchService 注入 QlibEngine。
Alpha158 特征 + LightGBM 预测信号(walk-forward)为下一步 TODO。
2. **数据规模**:仓库自带示例数据为 20 只权重股 2023–2024 日线;`sync --all` 可扩展
全市场,注意耗时与 Tushare 积分限制。
3. **回测为近似建模**:涨跌停按收盘相对上一有效收盘判定、成交假设调仓日收盘,未建模
开盘一字 / 集合竞价 / 盘中路径(详见结果 `unimplemented`)。
4. **Agent 结论质量取决于模型**:编排只保证「经受控工具 + 归档留痕」,研究有效性判断
需要人复核;接不同厂商模型请核对 `base_url` 与 `model` 命名。
5. **SSE 与 Job 为单进程内存/本地执行**:重启进程后未完成 Job 需重新提交(后续如需
可换 Redis/Celery,第一阶段刻意不引入)。
---
## 10. 常见问题(FAQ)
- **同步报「缺少 TUSHARE_TOKEN」**:把 token 填入根目录 `.env` 的 `TUSHARE_TOKEN`。
- **同步报「未安装 tushare 客户端」**:`cd backend && uv sync --extra datasource-tushare`。
- **Agent 报 400「未配置 LLM」**:`.env` 设置 `LLM_API_KEY`;换模型改 `config.yaml`。
- **前端连不上后端**:确认后端运行在 8000、`frontend/web/.env.local` 的
`NEXT_PUBLIC_API_BASE` 正确、CORS 白名单含 `localhost:3000 / 127.0.0.1:3000`。
- **数据库被改动想重置**:删除 `data/quant.db` 后 `uv run alembic upgrade head` 重建
表结构(行情需重新同步)。
- **想切换 MySQL**:`.env` 设 `DATABASE_URL=mysql+pymysql://user:pass@host/db`,
业务层无需改动(Repository 已隔离)。