# 接口文档

> 本文档由 `backend/tests/export_api_inventory.py` 从 FastAPI 运行时路由表自动生成，
> 共 **88 个接口 / 71 个路径**。代码改了重新跑一次脚本即可同步。

---

## 目录

- [认证与账号](#认证与账号) — 7 个接口 · 注册、登录、验证码、密码管理
- [用户中心](#用户中心) — 7 个接口 · 个人资料、Webhook 推送配置、券商配置
- [策略管理](#策略管理) — 8 个接口 · 策略 CRUD、复制、模板套用
- [回测执行](#回测执行) — 4 个接口 · 运行回测、查询报告、删除记录
- [行情监控](#行情监控) — 7 个接口 · 监控任务 CRUD、启停、立即执行、调度器状态
- [信号管理](#信号管理) — 5 个接口 · 信号查询、已读标记、失败重推
- [订单交易](#订单交易) — 5 个接口 · 模拟撮合下单、撤单、live 模式二次确认
- [行情数据](#行情数据) — 4 个接口 · K 线、快照、搜索、缓存统计
- [系统信息](#系统信息) — 1 个接口 · 平台版本与运行状态
- [管理后台 · 用户](#管理后台--用户) — 6 个接口 · 用户 CRUD、封禁解锁、重置码
- [管理后台 · 系统](#管理后台--系统) — 12 个接口 · 系统设置、角色权限、IP 黑名单、缓存
- [管理后台 · 日志与模板](#管理后台--日志与模板) — 13 个接口 · 操作日志、报错日志、策略模板
- [管理后台 · 全站资源](#管理后台--全站资源) — 5 个接口 · 全站数据、全站监控、全站策略

---

## 一、通用约定

### 1.1 基础地址

生产环境（正式域名）：

```
https://quant.quasarxode.cn/api
```

本地开发：`http://127.0.0.1:8000/api`

### 1.2 认证方式

除公开接口外，所有接口都需要在请求头携带 Bearer Token：

```http
Authorization: Bearer <access_token>
```

Token 由 `POST /api/auth/login` 或 `POST /api/auth/register` 获取，
有效期默认 **720 分钟**（可在系统设置中调整）。

### 1.3 响应格式

**成功**：直接返回业务数据，无统一外层包装。

```json
{
  "id": 1,
  "name": "双均线策略",
  "status": "running"
}
```

**失败**：统一返回 `detail` 字段。

```json
{ "detail": "权限不足，需要：strategy:write" }
```

参数校验失败（422）会额外带 `errors` 数组，字段已拍平：

```json
{
  "detail": "请求参数校验失败",
  "errors": [
    { "field": "username", "message": "用户名需字母开头，仅含字母数字下划线，3-20 位" }
  ]
}
```

> 未捕获异常**绝不回传堆栈**（含文件路径等内部信息），
> 只写入 `error_logs` 表与日志文件，客户端收到通用错误提示。

### 1.4 状态码约定

| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 业务校验失败（验证码错、密码错、状态不允许等） |
| 401 | 未登录或 Token 失效 |
| 403 | 已登录但权限不足 / 操作被禁 |
| 404 | 资源不存在（**越权访问他人资源也返回 404**，不泄露资源存在性） |
| 422 | 参数校验失败 |
| 429 | 触发限流 |
| 500 | 服务端内部错误 |

### 1.5 限流规则

滑动窗口，按 **客户端 IP + 路由分组** 计数。命中硬上限的路径用独立阈值：

| 路径前缀 | 上限 | 粒度 | 说明 |
|---|---|---|---|
| `/api/auth/login` | 10 | 次/分钟/IP | 登录失败会同时触发账号锁定 |
| `/api/auth/register` | 5 | 次/分钟/IP | 注册 |
| `/api/auth/captcha` | 30 | 次/分钟/IP | 取验证码 |
| `/api/auth/password/reset` | 5 | 次/分钟/IP | 用重置码改密 |
| `/api/backtests/run` | 20 | 次/分钟/IP | 运行回测（计算量大） |
| `/api/admin/settings` | 30 | 次/分钟/IP | 修改系统设置 |
| 其余所有接口 | 120 | 次/分钟/IP | 全局默认阈值（系统设置可调） |

触发限流返回 `429`，响应头带 `Retry-After`（秒）。

> Nginx 反代时 `X-Forwarded-For` 用 `$remote_addr` **覆盖**而非追加，
> 防止客户端伪造该头绕过限流。

### 1.6 权限点

细粒度 RBAC，权限码格式 `域:动作`。角色可自由组合，用户可拥有多个角色，权限取并集。
管理员角色拥有通配权限 `*`。

| 权限码 | 名称 | 分组 |
|---|---|---|
| `strategy:read` | 查看策略 | strategy |
| `strategy:write` | 创建/修改策略 | strategy |
| `strategy:delete` | 删除策略 | strategy |
| `backtest:read` | 查看回测 | backtest |
| `backtest:run` | 运行回测 | backtest |
| `monitor:read` | 查看监控 | monitor |
| `monitor:write` | 管理监控任务 | monitor |
| `signal:read` | 查看信号 | signal |
| `signal:push` | 推送信号 | signal |
| `order:read` | 查看订单 | order |
| `order:write` | 下单 | order |
| `admin:user` | 用户管理 | admin |
| `admin:setting` | 系统设置 | admin |
| `admin:log` | 日志查看 | admin |
| `admin:template` | 策略模板管理 | admin |
| `admin:cache` | 缓存管理 | admin |
| `admin:role` | 角色权限管理 | admin |
| `admin:ip` | IP 黑名单管理 | admin |
| `admin:order` | 全站订单管理 | admin |

普通注册用户默认拥有全部 `strategy` / `backtest` / `monitor` / `signal` / `order` 共 11 个权限点。

---

## 二、接口详情

> 鉴权列含义：**公开** = 无需登录；**登录** = 需 Bearer Token；
> **权限** = 需特定权限码；**管理员** = 需 admin 角色。

### 认证与账号

注册、登录、验证码、密码管理 · 7 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/auth/captcha` | 获取图形验证码 | 🔓 无需登录 |
| `POST` | `/api/auth/login` | 用户登录 | 🔓 无需登录 |
| `POST` | `/api/auth/logout` | 退出登录 | 👤 登录用户 |
| `GET` | `/api/auth/me` | 获取当前登录用户 | 👤 登录用户 |
| `POST` | `/api/auth/password/change` | 修改自己的密码 | 👤 登录用户 |
| `POST` | `/api/auth/password/reset` | 用管理员发放的重置码改密 | 🔓 无需登录 |
| `POST` | `/api/auth/register` | 用户注册 | 🔓 无需登录 |

#### `GET /api/auth/captcha`

**获取图形验证码**

- **鉴权**：public — 无需登录
- **响应 `200`**：`CaptchaOut`（函数返回类型注解）
  - 返回字段：
    - `captcha_id`（str，必填）
    - `image`（str，必填）

#### `POST /api/auth/login`

**用户登录**

- **鉴权**：public — 无需登录
- **请求体**（`LoginIn`）：
  - `username`（str，必填）
  - `password`（str，必填）
  - `captcha_id`（str，必填）
  - `captcha_code`（str，必填）
- **响应 `200`**：`TokenOut`（函数返回类型注解）
  - 返回字段：
    - `access_token`（str，必填）
    - `token_type`（str，可选）
    - `expires_in`（int，必填）
    - `user`（UserOut，必填）

#### `POST /api/auth/logout`

**退出登录**

- **鉴权**：auth — 登录用户
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/auth/me`

**获取当前登录用户**

- **鉴权**：auth — 登录用户
- **响应 `200`**：`UserOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `username`（str，必填）
    - `email`（str，必填）
    - `nickname`（str，可选）
    - `phone`（str，可选）
    - `is_active`（bool，可选）
    - `ban_reason`（str，可选）
    - `webhook_url`（str，可选）
    - `webhook_mode`（str，可选）
    - `webhook_enabled`（bool，可选）
    - `auto_trade_enabled`（bool，可选）
    - `last_login_at`（Optional，可选）
    - `created_at`（Optional，可选）
    - `roles`（list，可选）
    - `permissions`（list，可选）

#### `POST /api/auth/password/change`

**修改自己的密码**

- **鉴权**：auth — 登录用户
- **请求体**（`ChangePasswordIn`）：
  - `old_password`（str，必填）
  - `new_password`（str，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/auth/password/reset`

**用管理员发放的重置码改密**

- **鉴权**：public — 无需登录
- **请求体**（`ResetPasswordIn`）：
  - `username`（str，必填）
  - `token`（str，必填）
  - `new_password`（str，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/auth/register`

**用户注册**

- **鉴权**：public — 无需登录
- **请求体**（`RegisterIn`）：
  - `username`（str，必填）
  - `email`（str，必填）
  - `password`（str，必填）
  - `captcha_id`（str，必填）
  - `captcha_code`（str，必填）
- **响应 `200`**：`TokenOut`（函数返回类型注解）
  - 返回字段：
    - `access_token`（str，必填）
    - `token_type`（str，可选）
    - `expires_in`（int，必填）
    - `user`（UserOut，必填）

### 用户中心

个人资料、Webhook 推送配置、券商配置 · 7 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/users/broker` | 查看券商配置（密码不回显） | 👤 登录用户 |
| `PUT` | `/api/users/broker` | 配置券商账号（加密存储） | 👤 登录用户 |
| `GET` | `/api/users/orders` | 我的订单列表 | 👤 登录用户 |
| `GET` | `/api/users/profile` | 获取个人资料 | 👤 登录用户 |
| `PUT` | `/api/users/profile` | 修改个人资料 | 👤 登录用户 |
| `PUT` | `/api/users/webhook` | 配置 QXBot 推送 Webhook | 👤 登录用户 |
| `POST` | `/api/users/webhook/test` | 测试 Webhook 连通性 | 👤 登录用户 |

#### `GET /api/users/broker`

**查看券商配置（密码不回显）**

- **鉴权**：auth — 登录用户
- **响应 `200`**：`dict`（函数返回类型注解）

#### `PUT /api/users/broker`

**配置券商账号（加密存储）**

- **鉴权**：auth — 登录用户
- **请求体**（`BrokerUpdateIn`）：
  - `broker_account`（str，可选，默认 `''`）
  - `broker_password`（str，可选，默认 `''`）
  - `auto_trade_enabled`（bool，可选，默认 `False`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/users/orders`

**我的订单列表**

- **鉴权**：auth — 登录用户
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/users/profile`

**获取个人资料**

- **鉴权**：auth — 登录用户
- **响应 `200`**：`UserOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `username`（str，必填）
    - `email`（str，必填）
    - `nickname`（str，可选）
    - `phone`（str，可选）
    - `is_active`（bool，可选）
    - `ban_reason`（str，可选）
    - `webhook_url`（str，可选）
    - `webhook_mode`（str，可选）
    - `webhook_enabled`（bool，可选）
    - `auto_trade_enabled`（bool，可选）
    - `last_login_at`（Optional，可选）
    - `created_at`（Optional，可选）
    - `roles`（list，可选）
    - `permissions`（list，可选）

#### `PUT /api/users/profile`

**修改个人资料**

- **鉴权**：auth — 登录用户
- **请求体**（`ProfileUpdateIn`）：
  - `nickname`（Optional，可选，默认 `None`）
  - `phone`（Optional，可选，默认 `None`）
  - `email`（Optional，可选，默认 `None`）
- **响应 `200`**：`UserOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `username`（str，必填）
    - `email`（str，必填）
    - `nickname`（str，可选）
    - `phone`（str，可选）
    - `is_active`（bool，可选）
    - `ban_reason`（str，可选）
    - `webhook_url`（str，可选）
    - `webhook_mode`（str，可选）
    - `webhook_enabled`（bool，可选）
    - `auto_trade_enabled`（bool，可选）
    - `last_login_at`（Optional，可选）
    - `created_at`（Optional，可选）
    - `roles`（list，可选）
    - `permissions`（list，可选）

#### `PUT /api/users/webhook`

**配置 QXBot 推送 Webhook**

- **鉴权**：auth — 登录用户
- **请求体**（`WebhookUpdateIn`）：
  - `webhook_url`（str，可选，默认 `''`）
  - `webhook_mode`（str，可选，默认 `'xml'`）
  - `webhook_enabled`（bool，可选，默认 `True`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/users/webhook/test`

**测试 Webhook 连通性**

- **鉴权**：auth — 登录用户
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

### 策略管理

策略 CRUD、复制、模板套用 · 8 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/strategies` | 我的策略列表 | 🔑 查看策略 |
| `POST` | `/api/strategies` | 创建策略 | 🔑 创建/修改策略 |
| `GET` | `/api/strategies/templates/list` | 可用策略模板 | 🔑 查看策略 |
| `POST` | `/api/strategies/templates/{template_id}/apply` | 套用模板创建策略 | 🔑 创建/修改策略 |
| `DELETE` | `/api/strategies/{strategy_id}` | 删除策略 | 🔑 删除策略 |
| `GET` | `/api/strategies/{strategy_id}` | 策略详情 | 🔑 查看策略 |
| `PUT` | `/api/strategies/{strategy_id}` | 修改策略 | 🔑 创建/修改策略 |
| `POST` | `/api/strategies/{strategy_id}/copy` | 复制策略 | 🔑 创建/修改策略 |

#### `GET /api/strategies`

**我的策略列表**

- **鉴权**：perm — 查看策略
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `keyword`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/strategies`

**创建策略**

- **鉴权**：perm — 创建/修改策略
- **请求体**（`StrategyIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `mode`（str，可选，默认 `'both'`）
  - `stock_pool`（list，可选，默认 `PydanticUndefined`）
  - `start_date`（str，可选，默认 `'2020-01-01'`）
  - `end_date`（str，可选，默认 `''`）
  - `initial_capital`（float，可选，默认 `100000`）
  - `fast_ma`（int，可选，默认 `5`）
  - `slow_ma`（int，可选，默认 `20`）
  - `vol_window`（int，可选，默认 `20`）
  - `vol_threshold`（float，可选，默认 `0.3`）
  - `max_position_pct`（float，可选，默认 `0.2`）
  - `max_drawdown_pct`（float，可选，默认 `0.2`）
  - `max_consec_loss`（int，可选，默认 `3`）
  - `pause_days`（int，可选，默认 `5`）
  - `commission_rate`（float，可选，默认 `0.00025`）
  - `min_commission`（float，可选，默认 `5.0`）
  - `stamp_tax_rate`（float，可选，默认 `0.001`）
  - `slippage_rate`（float，可选，默认 `0.0005`）
- **响应 `200`**：`StrategyOut`（函数返回类型注解）
  - 返回字段：
    - `name`（str，必填）
    - `description`（str，可选）
    - `mode`（str，可选）
    - `stock_pool`（list，可选）
    - `start_date`（str，可选）
    - `end_date`（str，可选）
    - `initial_capital`（float，可选）
    - `fast_ma`（int，可选）
    - `slow_ma`（int，可选）
    - `vol_window`（int，可选）
    - `vol_threshold`（float，可选）
    - `max_position_pct`（float，可选）
    - `max_drawdown_pct`（float，可选）
    - `max_consec_loss`（int，可选）
    - `pause_days`（int，可选）
    - `commission_rate`（float，可选）
    - `min_commission`（float，可选）
    - `stamp_tax_rate`（float，可选）
    - `slippage_rate`（float，可选）
    - `id`（int，必填）
    - `owner_id`（int，必填）
    - `created_at`（Optional，可选）
    - `updated_at`（Optional，可选）

#### `GET /api/strategies/templates/list`

**可用策略模板**

- **鉴权**：perm — 查看策略
- **响应 `200`**：`list[TemplateOut]`（函数返回类型注解）

#### `POST /api/strategies/templates/{template_id}/apply`

**套用模板创建策略**

- **鉴权**：perm — 创建/修改策略
- **参数**：
  - `path` `template_id`（int，必填）
  - `query` `name`（str，可选，默认 ``）
- **响应 `200`**：`StrategyOut`（函数返回类型注解）
  - 返回字段：
    - `name`（str，必填）
    - `description`（str，可选）
    - `mode`（str，可选）
    - `stock_pool`（list，可选）
    - `start_date`（str，可选）
    - `end_date`（str，可选）
    - `initial_capital`（float，可选）
    - `fast_ma`（int，可选）
    - `slow_ma`（int，可选）
    - `vol_window`（int，可选）
    - `vol_threshold`（float，可选）
    - `max_position_pct`（float，可选）
    - `max_drawdown_pct`（float，可选）
    - `max_consec_loss`（int，可选）
    - `pause_days`（int，可选）
    - `commission_rate`（float，可选）
    - `min_commission`（float，可选）
    - `stamp_tax_rate`（float，可选）
    - `slippage_rate`（float，可选）
    - `id`（int，必填）
    - `owner_id`（int，必填）
    - `created_at`（Optional，可选）
    - `updated_at`（Optional，可选）

#### `DELETE /api/strategies/{strategy_id}`

**删除策略**

- **鉴权**：perm — 删除策略
- **参数**：
  - `path` `strategy_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/strategies/{strategy_id}`

**策略详情**

- **鉴权**：perm — 查看策略
- **参数**：
  - `path` `strategy_id`（int，必填）
- **响应 `200`**：`StrategyOut`（函数返回类型注解）
  - 返回字段：
    - `name`（str，必填）
    - `description`（str，可选）
    - `mode`（str，可选）
    - `stock_pool`（list，可选）
    - `start_date`（str，可选）
    - `end_date`（str，可选）
    - `initial_capital`（float，可选）
    - `fast_ma`（int，可选）
    - `slow_ma`（int，可选）
    - `vol_window`（int，可选）
    - `vol_threshold`（float，可选）
    - `max_position_pct`（float，可选）
    - `max_drawdown_pct`（float，可选）
    - `max_consec_loss`（int，可选）
    - `pause_days`（int，可选）
    - `commission_rate`（float，可选）
    - `min_commission`（float，可选）
    - `stamp_tax_rate`（float，可选）
    - `slippage_rate`（float，可选）
    - `id`（int，必填）
    - `owner_id`（int，必填）
    - `created_at`（Optional，可选）
    - `updated_at`（Optional，可选）

#### `PUT /api/strategies/{strategy_id}`

**修改策略**

- **鉴权**：perm — 创建/修改策略
- **参数**：
  - `path` `strategy_id`（int，必填）
- **请求体**（`StrategyIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `mode`（str，可选，默认 `'both'`）
  - `stock_pool`（list，可选，默认 `PydanticUndefined`）
  - `start_date`（str，可选，默认 `'2020-01-01'`）
  - `end_date`（str，可选，默认 `''`）
  - `initial_capital`（float，可选，默认 `100000`）
  - `fast_ma`（int，可选，默认 `5`）
  - `slow_ma`（int，可选，默认 `20`）
  - `vol_window`（int，可选，默认 `20`）
  - `vol_threshold`（float，可选，默认 `0.3`）
  - `max_position_pct`（float，可选，默认 `0.2`）
  - `max_drawdown_pct`（float，可选，默认 `0.2`）
  - `max_consec_loss`（int，可选，默认 `3`）
  - `pause_days`（int，可选，默认 `5`）
  - `commission_rate`（float，可选，默认 `0.00025`）
  - `min_commission`（float，可选，默认 `5.0`）
  - `stamp_tax_rate`（float，可选，默认 `0.001`）
  - `slippage_rate`（float，可选，默认 `0.0005`）
- **响应 `200`**：`StrategyOut`（函数返回类型注解）
  - 返回字段：
    - `name`（str，必填）
    - `description`（str，可选）
    - `mode`（str，可选）
    - `stock_pool`（list，可选）
    - `start_date`（str，可选）
    - `end_date`（str，可选）
    - `initial_capital`（float，可选）
    - `fast_ma`（int，可选）
    - `slow_ma`（int，可选）
    - `vol_window`（int，可选）
    - `vol_threshold`（float，可选）
    - `max_position_pct`（float，可选）
    - `max_drawdown_pct`（float，可选）
    - `max_consec_loss`（int，可选）
    - `pause_days`（int，可选）
    - `commission_rate`（float，可选）
    - `min_commission`（float，可选）
    - `stamp_tax_rate`（float，可选）
    - `slippage_rate`（float，可选）
    - `id`（int，必填）
    - `owner_id`（int，必填）
    - `created_at`（Optional，可选）
    - `updated_at`（Optional，可选）

#### `POST /api/strategies/{strategy_id}/copy`

**复制策略**

- **鉴权**：perm — 创建/修改策略
- **参数**：
  - `path` `strategy_id`（int，必填）
- **响应 `200`**：`StrategyOut`（函数返回类型注解）
  - 返回字段：
    - `name`（str，必填）
    - `description`（str，可选）
    - `mode`（str，可选）
    - `stock_pool`（list，可选）
    - `start_date`（str，可选）
    - `end_date`（str，可选）
    - `initial_capital`（float，可选）
    - `fast_ma`（int，可选）
    - `slow_ma`（int，可选）
    - `vol_window`（int，可选）
    - `vol_threshold`（float，可选）
    - `max_position_pct`（float，可选）
    - `max_drawdown_pct`（float，可选）
    - `max_consec_loss`（int，可选）
    - `pause_days`（int，可选）
    - `commission_rate`（float，可选）
    - `min_commission`（float，可选）
    - `stamp_tax_rate`（float，可选）
    - `slippage_rate`（float，可选）
    - `id`（int，必填）
    - `owner_id`（int，必填）
    - `created_at`（Optional，可选）
    - `updated_at`（Optional，可选）

### 回测执行

运行回测、查询报告、删除记录 · 4 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/backtests` | 我的回测记录 | 🔑 查看回测 |
| `POST` | `/api/backtests/run` | 运行回测 | 🔑 运行回测 |
| `DELETE` | `/api/backtests/{run_id}` | 删除回测记录 | 🔑 查看回测 |
| `GET` | `/api/backtests/{run_id}` | 回测详情（含曲线与交易明细） | 🔑 查看回测 |

#### `GET /api/backtests`

**我的回测记录**

- **鉴权**：perm — 查看回测
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `strategy_id`（int | None，可选，默认 `None`）
  - `query` `status_filter`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/backtests/run`

**运行回测**

- **鉴权**：perm — 运行回测
- **请求体**（`BacktestIn`）：
  - `strategy_id`（int，必填）
  - `ts_codes`（Optional，可选，默认 `None`）
  - `start_date`（Optional，可选，默认 `None`）
  - `end_date`（Optional，可选，默认 `None`）
- **响应 `200`**：`BacktestOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `strategy_id`（Optional，可选）
    - `strategy_name`（str，必填）
    - `ts_codes`（list，可选）
    - `start_date`（str，必填）
    - `end_date`（str，必填）
    - `initial_capital`（float，必填）
    - `status`（str，必填）
    - `error`（str，可选）
    - `metrics`（dict，可选）
    - `data_source`（str，可选）
    - `duration_ms`（int，可选）
    - `created_at`（Optional，可选）

#### `DELETE /api/backtests/{run_id}`

**删除回测记录**

- **鉴权**：perm — 查看回测
- **参数**：
  - `path` `run_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/backtests/{run_id}`

**回测详情（含曲线与交易明细）**

- **鉴权**：perm — 查看回测
- **参数**：
  - `path` `run_id`（int，必填）
- **响应 `200`**：`BacktestDetailOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `strategy_id`（Optional，可选）
    - `strategy_name`（str，必填）
    - `ts_codes`（list，可选）
    - `start_date`（str，必填）
    - `end_date`（str，必填）
    - `initial_capital`（float，必填）
    - `status`（str，必填）
    - `error`（str，可选）
    - `metrics`（dict，可选）
    - `data_source`（str，可选）
    - `duration_ms`（int，可选）
    - `created_at`（Optional，可选）
    - `result`（dict，可选）
    - `params_snapshot`（dict，可选）

### 行情监控

监控任务 CRUD、启停、立即执行、调度器状态 · 7 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/monitors` | 我的监控任务 | 🔑 查看监控 |
| `POST` | `/api/monitors` | 创建监控任务 | 🔑 管理监控任务 |
| `GET` | `/api/monitors/scheduler/status` | 调度器运行状态 | 🔑 查看监控 |
| `DELETE` | `/api/monitors/{task_id}` | 删除监控任务 | 🔑 管理监控任务 |
| `PUT` | `/api/monitors/{task_id}` | 修改监控任务 | 🔑 管理监控任务 |
| `POST` | `/api/monitors/{task_id}/run-now` | 立即执行一次扫描 | 🔑 管理监控任务 |
| `POST` | `/api/monitors/{task_id}/toggle` | 启动/停止监控 | 🔑 管理监控任务 |

#### `GET /api/monitors`

**我的监控任务**

- **鉴权**：perm — 查看监控
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/monitors`

**创建监控任务**

- **鉴权**：perm — 管理监控任务
- **请求体**（`MonitorIn`）：
  - `strategy_id`（int，必填）
  - `name`（str，可选，默认 `''`）
  - `interval_minutes`（int，可选，默认 `30`）
  - `trading_time_only`（bool，可选，默认 `True`）
  - `push_enabled`（bool，可选，默认 `True`）
- **响应 `200`**：`MonitorOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `strategy_id`（int，必填）
    - `name`（str，必填）
    - `is_running`（bool，必填）
    - `interval_minutes`（int，必填）
    - `trading_time_only`（bool，必填）
    - `push_enabled`（bool，必填）
    - `last_run_at`（Optional，可选）
    - `last_result`（str，可选）
    - `run_count`（int，可选）
    - `created_at`（Optional，可选）

#### `GET /api/monitors/scheduler/status`

**调度器运行状态**

- **鉴权**：perm — 查看监控
- **响应 `200`**：`dict`（函数返回类型注解）

#### `DELETE /api/monitors/{task_id}`

**删除监控任务**

- **鉴权**：perm — 管理监控任务
- **参数**：
  - `path` `task_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `PUT /api/monitors/{task_id}`

**修改监控任务**

- **鉴权**：perm — 管理监控任务
- **参数**：
  - `path` `task_id`（int，必填）
- **请求体**（`MonitorIn`）：
  - `strategy_id`（int，必填）
  - `name`（str，可选，默认 `''`）
  - `interval_minutes`（int，可选，默认 `30`）
  - `trading_time_only`（bool，可选，默认 `True`）
  - `push_enabled`（bool，可选，默认 `True`）
- **响应 `200`**：`MonitorOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `strategy_id`（int，必填）
    - `name`（str，必填）
    - `is_running`（bool，必填）
    - `interval_minutes`（int，必填）
    - `trading_time_only`（bool，必填）
    - `push_enabled`（bool，必填）
    - `last_run_at`（Optional，可选）
    - `last_result`（str，可选）
    - `run_count`（int，可选）
    - `created_at`（Optional，可选）

#### `POST /api/monitors/{task_id}/run-now`

**立即执行一次扫描**

- **鉴权**：perm — 管理监控任务
- **参数**：
  - `path` `task_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/monitors/{task_id}/toggle`

**启动/停止监控**

- **鉴权**：perm — 管理监控任务
- **参数**：
  - `path` `task_id`（int，必填）
- **响应 `200`**：`MonitorOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `strategy_id`（int，必填）
    - `name`（str，必填）
    - `is_running`（bool，必填）
    - `interval_minutes`（int，必填）
    - `trading_time_only`（bool，必填）
    - `push_enabled`（bool，必填）
    - `last_run_at`（Optional，可选）
    - `last_result`（str，可选）
    - `run_count`（int，可选）
    - `created_at`（Optional，可选）

### 信号管理

信号查询、已读标记、失败重推 · 5 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/signals` | 我的信号列表 | 🔑 查看信号 |
| `POST` | `/api/signals/read-all` | 全部标记已读 | 🔑 查看信号 |
| `GET` | `/api/signals/stats` | 我的信号统计 | 🔑 查看信号 |
| `POST` | `/api/signals/{signal_id}/push` | 手动重推信号 | 🔑 推送信号 |
| `POST` | `/api/signals/{signal_id}/read` | 标记已读 | 🔑 查看信号 |

#### `GET /api/signals`

**我的信号列表**

- **鉴权**：perm — 查看信号
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `side`（str，可选，默认 ``）
  - `query` `ts_code`（str，可选，默认 ``）
  - `query` `pushed`（str，可选，默认 ``）
  - `query` `is_read`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/signals/read-all`

**全部标记已读**

- **鉴权**：perm — 查看信号
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/signals/stats`

**我的信号统计**

- **鉴权**：perm — 查看信号
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/signals/{signal_id}/push`

**手动重推信号**

- **鉴权**：perm — 推送信号
- **参数**：
  - `path` `signal_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/signals/{signal_id}/read`

**标记已读**

- **鉴权**：perm — 查看信号
- **参数**：
  - `path` `signal_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

### 订单交易

模拟撮合下单、撤单、live 模式二次确认 · 5 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/orders` | 我的订单列表 | 🔑 查看订单 |
| `POST` | `/api/orders` | 创建订单 | 🔑 下单 |
| `GET` | `/api/orders/capabilities` | 当前下单能力说明 | 🔑 查看订单 |
| `POST` | `/api/orders/{order_id}/cancel` | 撤单 | 🔑 下单 |
| `POST` | `/api/orders/{order_id}/confirm` | 确认订单（live 模式二次确认） | 🔑 下单 |

#### `GET /api/orders`

**我的订单列表**

- **鉴权**：perm — 查看订单
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `status_filter`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/orders`

**创建订单**

- **鉴权**：perm — 下单
- **请求体**（`OrderCreateIn`）：
  - `ts_code`（str，必填）
  - `side`（str，必填）
  - `amount`（Optional，可选，默认 `None`）
  - `volume`（Optional，可选，默认 `None`）
  - `signal_id`（Optional，可选，默认 `None`）
  - `mode`（str，可选，默认 `'paper'`）
- **响应 `200`**：`OrderOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `ts_code`（str，必填）
    - `stock_name`（str，可选）
    - `side`（str，必填）
    - `mode`（str，必填）
    - `price`（float，必填）
    - `volume`（int，必填）
    - `amount`（float，必填）
    - `fee`（float，必填）
    - `status`（str，必填）
    - `reject_reason`（str，可选）
    - `created_at`（Optional，可选）
    - `filled_at`（Optional，可选）

#### `GET /api/orders/capabilities`

**当前下单能力说明**

- **鉴权**：perm — 查看订单
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/orders/{order_id}/cancel`

**撤单**

- **鉴权**：perm — 下单
- **参数**：
  - `path` `order_id`（int，必填）
- **响应 `200`**：`OrderOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `ts_code`（str，必填）
    - `stock_name`（str，可选）
    - `side`（str，必填）
    - `mode`（str，必填）
    - `price`（float，必填）
    - `volume`（int，必填）
    - `amount`（float，必填）
    - `fee`（float，必填）
    - `status`（str，必填）
    - `reject_reason`（str，可选）
    - `created_at`（Optional，可选）
    - `filled_at`（Optional，可选）

#### `POST /api/orders/{order_id}/confirm`

**确认订单（live 模式二次确认）**

- **鉴权**：perm — 下单
- **参数**：
  - `path` `order_id`（int，必填）
- **响应 `200`**：`OrderOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `ts_code`（str，必填）
    - `stock_name`（str，可选）
    - `side`（str，必填）
    - `mode`（str，必填）
    - `price`（float，必填）
    - `volume`（int，必填）
    - `amount`（float，必填）
    - `fee`（float，必填）
    - `status`（str，必填）
    - `reject_reason`（str，可选）
    - `created_at`（Optional，可选）
    - `filled_at`（Optional，可选）

### 行情数据

K 线、快照、搜索、缓存统计 · 4 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/market/cache/stats` | 行情缓存统计 | 🔑 查看策略 |
| `GET` | `/api/market/kline` | 日线 K 线数据 | 🔑 查看策略 |
| `GET` | `/api/market/quote` | 最新行情快照 | 🔑 查看策略 |
| `GET` | `/api/market/search` | 股票搜索 | 🔑 查看策略 |

#### `GET /api/market/cache/stats`

**行情缓存统计**

- **鉴权**：perm — 查看策略
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/market/kline`

**日线 K 线数据**

- **鉴权**：perm — 查看策略
- **参数**：
  - `query` `ts_code`（str，必填） — 股票代码，如 000001.SZ
  - `query` `start`（str，可选，默认 ``） — 开始日期 YYYY-MM-DD
  - `query` `end`（str，可选，默认 ``） — 结束日期 YYYY-MM-DD
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/market/quote`

**最新行情快照**

- **鉴权**：perm — 查看策略
- **参数**：
  - `query` `ts_codes`（str，必填） — 逗号分隔的股票代码
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/market/search`

**股票搜索**

- **鉴权**：perm — 查看策略
- **参数**：
  - `query` `keyword`（str，可选，默认 ``）
  - `query` `limit`（int，可选，默认 `20`）
- **响应 `200`**：`dict`（函数返回类型注解）

### 系统信息

平台版本与运行状态 · 1 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/system/info` | 系统信息（登录后可见） | 🔓 无需登录 |

#### `GET /api/system/info`

**系统信息（登录后可见）**

- **鉴权**：public — 无需登录
- **响应 `200`**：`dict`（函数返回类型注解）

### 管理后台 · 用户

用户 CRUD、封禁解锁、重置码 · 6 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/admin/users` | 用户列表 | 🛡️ 管理员 |
| `POST` | `/api/admin/users` | 新增用户 | 🛡️ 管理员 |
| `DELETE` | `/api/admin/users/{user_id}` | 删除用户 | 🛡️ 管理员 |
| `PUT` | `/api/admin/users/{user_id}` | 修改用户 | 🛡️ 管理员 |
| `POST` | `/api/admin/users/{user_id}/reset-token` | 生成一次性密码重置码 | 🛡️ 管理员 |
| `POST` | `/api/admin/users/{user_id}/unlock` | 解锁账号 | 🛡️ 管理员 |

#### `GET /api/admin/users`

**用户列表**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `keyword`（str，可选，默认 ``）
  - `query` `is_active`（str，可选，默认 ``）
  - `query` `role`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/admin/users`

**新增用户**

- **鉴权**：admin — 管理员
- **请求体**（`AdminUserCreateIn`）：
  - `username`（str，必填）
  - `email`（str，必填）
  - `password`（str，必填）
  - `role_names`（list，可选，默认 `PydanticUndefined`）
- **响应 `200`**：`UserOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `username`（str，必填）
    - `email`（str，必填）
    - `nickname`（str，可选）
    - `phone`（str，可选）
    - `is_active`（bool，可选）
    - `ban_reason`（str，可选）
    - `webhook_url`（str，可选）
    - `webhook_mode`（str，可选）
    - `webhook_enabled`（bool，可选）
    - `auto_trade_enabled`（bool，可选）
    - `last_login_at`（Optional，可选）
    - `created_at`（Optional，可选）
    - `roles`（list，可选）
    - `permissions`（list，可选）

#### `DELETE /api/admin/users/{user_id}`

**删除用户**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `user_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `PUT /api/admin/users/{user_id}`

**修改用户**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `user_id`（int，必填）
- **请求体**（`AdminUserUpdateIn`）：
  - `email`（Optional，可选，默认 `None`）
  - `nickname`（Optional，可选，默认 `None`）
  - `is_active`（Optional，可选，默认 `None`）
  - `ban_reason`（Optional，可选，默认 `None`）
  - `role_names`（Optional，可选，默认 `None`）
- **响应 `200`**：`UserOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `username`（str，必填）
    - `email`（str，必填）
    - `nickname`（str，可选）
    - `phone`（str，可选）
    - `is_active`（bool，可选）
    - `ban_reason`（str，可选）
    - `webhook_url`（str，可选）
    - `webhook_mode`（str，可选）
    - `webhook_enabled`（bool，可选）
    - `auto_trade_enabled`（bool，可选）
    - `last_login_at`（Optional，可选）
    - `created_at`（Optional，可选）
    - `roles`（list，可选）
    - `permissions`（list，可选）

#### `POST /api/admin/users/{user_id}/reset-token`

**生成一次性密码重置码**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `user_id`（int，必填）
- **请求体**（`AdminResetPasswordIn`）：
  - `new_password`（Optional，可选，默认 `None`）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/admin/users/{user_id}/unlock`

**解锁账号**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `user_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

### 管理后台 · 系统

系统设置、角色权限、IP 黑名单、缓存 · 12 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `POST` | `/api/admin/cache/clear` | 清理缓存 | 🛡️ 管理员 |
| `GET` | `/api/admin/cache/stats` | 缓存统计 | 🛡️ 管理员 |
| `GET` | `/api/admin/ip-blacklist` | IP 黑名单列表 | 🛡️ 管理员 |
| `POST` | `/api/admin/ip-blacklist` | 添加 IP 黑名单 | 🛡️ 管理员 |
| `DELETE` | `/api/admin/ip-blacklist/{item_id}` | 移除 IP 黑名单 | 🛡️ 管理员 |
| `GET` | `/api/admin/permissions` | 全部权限点 | 🛡️ 管理员 |
| `GET` | `/api/admin/roles` | 全部角色 | 🛡️ 管理员 |
| `POST` | `/api/admin/roles` | 新建角色 | 🛡️ 管理员 |
| `DELETE` | `/api/admin/roles/{role_id}` | 删除角色 | 🛡️ 管理员 |
| `PUT` | `/api/admin/roles/{role_id}` | 修改角色权限 | 🛡️ 管理员 |
| `GET` | `/api/admin/settings` | 读取全部系统设置 | 🛡️ 管理员 |
| `PUT` | `/api/admin/settings` | 批量修改系统设置 | 🛡️ 管理员 |

#### `POST /api/admin/cache/clear`

**清理缓存**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `target`（str，可选，默认 `all`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/admin/cache/stats`

**缓存统计**

- **鉴权**：admin — 管理员
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/ip-blacklist`

**IP 黑名单列表**

- **鉴权**：admin — 管理员
- **响应 `200`**：`list[dict]`（函数返回类型注解）

#### `POST /api/admin/ip-blacklist`

**添加 IP 黑名单**

- **鉴权**：admin — 管理员
- **请求体**（`IpBlacklistIn`）：
  - `ip`（str，必填）
  - `reason`（str，可选，默认 `''`）
  - `days`（int，可选，默认 `0`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `DELETE /api/admin/ip-blacklist/{item_id}`

**移除 IP 黑名单**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `item_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/admin/permissions`

**全部权限点**

- **鉴权**：admin — 管理员
- **响应 `200`**：`list[dict]`（函数返回类型注解）

#### `GET /api/admin/roles`

**全部角色**

- **鉴权**：admin — 管理员
- **响应 `200`**：`list[dict]`（函数返回类型注解）

#### `POST /api/admin/roles`

**新建角色**

- **鉴权**：admin — 管理员
- **请求体**（`RoleIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `permission_codes`（list，可选，默认 `PydanticUndefined`）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `DELETE /api/admin/roles/{role_id}`

**删除角色**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `role_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `PUT /api/admin/roles/{role_id}`

**修改角色权限**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `role_id`（int，必填）
- **请求体**（`RoleIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `permission_codes`（list，可选，默认 `PydanticUndefined`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/admin/settings`

**读取全部系统设置**

- **鉴权**：admin — 管理员
- **响应 `200`**：`dict`（函数返回类型注解）

#### `PUT /api/admin/settings`

**批量修改系统设置**

- **鉴权**：admin — 管理员
- **请求体**（`SettingsUpdateIn`）：
  - `items`（list，可选，默认 `PydanticUndefined`）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

### 管理后台 · 日志与模板

操作日志、报错日志、策略模板 · 13 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/admin/data/backtests` | 全站回测记录 | 🛡️ 管理员 |
| `GET` | `/api/admin/data/orders` | 全站订单 | 🛡️ 管理员 |
| `GET` | `/api/admin/data/signals` | 全站信号记录 | 🛡️ 管理员 |
| `GET` | `/api/admin/logs/audit` | 操作日志 | 🛡️ 管理员 |
| `GET` | `/api/admin/logs/audit/export` | 导出操作日志 CSV | 🛡️ 管理员 |
| `GET` | `/api/admin/logs/errors` | 报错日志 | 🛡️ 管理员 |
| `POST` | `/api/admin/logs/errors/clear` | 清空报错日志 | 🛡️ 管理员 |
| `DELETE` | `/api/admin/logs/errors/{log_id}` | 删除单条报错日志 | 🛡️ 管理员 |
| `GET` | `/api/admin/overview` | 管理后台概览数据 | 🛡️ 管理员 |
| `GET` | `/api/admin/templates` | 全部策略模板（含未公开） | 🛡️ 管理员 |
| `POST` | `/api/admin/templates` | 新建模板 | 🛡️ 管理员 |
| `DELETE` | `/api/admin/templates/{template_id}` | 删除模板 | 🛡️ 管理员 |
| `PUT` | `/api/admin/templates/{template_id}` | 修改模板 | 🛡️ 管理员 |

#### `GET /api/admin/data/backtests`

**全站回测记录**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/data/orders`

**全站订单**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
  - `query` `status_filter`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/data/signals`

**全站信号记录**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/logs/audit`

**操作日志**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
  - `query` `module`（str，可选，默认 ``）
  - `query` `action`（str，可选，默认 ``）
  - `query` `success`（str，可选，默认 ``）
  - `query` `ip`（str，可选，默认 ``）
  - `query` `start`（str，可选，默认 ``）
  - `query` `end`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/logs/audit/export`

**导出操作日志 CSV**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `username`（str，可选，默认 ``）
  - `query` `module`（str，可选，默认 ``）
  - `query` `action`（str，可选，默认 ``）
  - `query` `success`（str，可选，默认 ``）
  - `query` `ip`（str，可选，默认 ``）
  - `query` `start`（str，可选，默认 ``）
  - `query` `end`（str，可选，默认 ``）
- **响应 `200`**：`StreamingResponse`（函数返回类型注解）

#### `GET /api/admin/logs/errors`

**报错日志**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `keyword`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/admin/logs/errors/clear`

**清空报错日志**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `days`（int，可选，默认 `0`） — 清理多少天前的，0=全部
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `DELETE /api/admin/logs/errors/{log_id}`

**删除单条报错日志**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `log_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/admin/overview`

**管理后台概览数据**

- **鉴权**：admin — 管理员
- **响应 `200`**：`dict`（函数返回类型注解）

#### `GET /api/admin/templates`

**全部策略模板（含未公开）**

- **鉴权**：admin — 管理员
- **响应 `200`**：`list[dict]`（函数返回类型注解）

#### `POST /api/admin/templates`

**新建模板**

- **鉴权**：admin — 管理员
- **请求体**（`TemplateIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `params`（dict，可选，默认 `PydanticUndefined`）
  - `is_public`（bool，可选，默认 `True`）
- **响应 `200`**：`TemplateOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `name`（str，必填）
    - `description`（str，可选）
    - `params`（dict，可选）
    - `is_public`（bool，可选）
    - `created_at`（Optional，可选）

#### `DELETE /api/admin/templates/{template_id}`

**删除模板**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `template_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `PUT /api/admin/templates/{template_id}`

**修改模板**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `template_id`（int，必填）
- **请求体**（`TemplateIn`）：
  - `name`（str，必填）
  - `description`（str，可选，默认 `''`）
  - `params`（dict，可选，默认 `PydanticUndefined`）
  - `is_public`（bool，可选，默认 `True`）
- **响应 `200`**：`TemplateOut`（函数返回类型注解）
  - 返回字段：
    - `id`（int，必填）
    - `name`（str，必填）
    - `description`（str，可选）
    - `params`（dict，可选）
    - `is_public`（bool，可选）
    - `created_at`（Optional，可选）

### 管理后台 · 全站资源

全站数据、全站监控、全站策略 · 5 个接口

| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| `GET` | `/api/admin/monitors` | 全站监控任务 | 🛡️ 管理员 |
| `POST` | `/api/admin/monitors/{task_id}/toggle` | 启停全站监控任务 | 🛡️ 管理员 |
| `GET` | `/api/admin/strategies` | 全站策略 | 🛡️ 管理员 |
| `POST` | `/api/admin/strategies/{strategy_id}/disable` | 停用全站策略 | 🛡️ 管理员 |
| `POST` | `/api/admin/strategies/{strategy_id}/enable` | 恢复全站策略 | 🛡️ 管理员 |

#### `GET /api/admin/monitors`

**全站监控任务**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
  - `query` `status_filter`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/admin/monitors/{task_id}/toggle`

**启停全站监控任务**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `task_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `GET /api/admin/strategies`

**全站策略**

- **鉴权**：admin — 管理员
- **参数**：
  - `query` `page`（int，可选，默认 `1`）
  - `query` `page_size`（int，可选，默认 `20`）
  - `query` `username`（str，可选，默认 ``）
  - `query` `keyword`（str，可选，默认 ``）
  - `query` `mode`（str，可选，默认 ``）
- **响应 `200`**：`dict`（函数返回类型注解）

#### `POST /api/admin/strategies/{strategy_id}/disable`

**停用全站策略**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `strategy_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

#### `POST /api/admin/strategies/{strategy_id}/enable`

**恢复全站策略**

- **鉴权**：admin — 管理员
- **参数**：
  - `path` `strategy_id`（int，必填）
- **响应 `200`**：`MsgOut`（函数返回类型注解）
  - 返回字段：
    - `message`（str，可选）

---

## 三、附录

### 3.1 在线交互式文档

服务内置 Swagger UI 与 OpenAPI 规范，**仅在 `DEBUG=true` 时开启**
（`backend/app/main.py` 里的 `docs_url` / `openapi_url` 条件）：

```
https://quant.quasarxode.cn/api/docs          # 仅 DEBUG 模式
https://quant.quasarxode.cn/api/openapi.json   # 仅 DEBUG 模式
```

> **生产环境默认关闭**（避免把完整接口结构暴露给未授权访问者）。
> 需要临时开启时，在 `.env` 里设 `DEBUG=true` 并重启服务即可。
> 本文档本身包含了全部接口的说明，不依赖 Swagger。

### 3.2 核心数据模型

| 模型 | 用途 | 关键字段 |
|---|---|---|
| `Strategy` | 策略配置 | `name` / `fast_ma` / `slow_ma` / `vol_window` / `vol_threshold` / `codes` / `mode` |
| `BacktestRun` | 回测记录 | `strategy_id` / `status` / `total_return` / `max_drawdown` / `sharpe_ratio` / `equity_curve` |
| `MonitorTask` | 监控任务 | `strategy_id` / `is_running` / `interval_minutes` / `last_run_at` |
| `Signal` | 买卖信号 | `code` / `direction` / `price` / `reason` / `is_read` / `pushed` |
| `Order` | 订单 | `code` / `direction` / `volume` / `price` / `status` / `mode` / `idempotency_key` |
| `User` | 用户 | `username` / `email` / `nickname` / `roles` / `is_active` / `failed_attempts` / `locked_until` |
| `Role` | 角色 | `name` / `permission_codes` |
| `AuditLog` | 操作审计 | `user_id` / `action` / `ip` / `path` / `status_code` / `duration_ms` |
| `ErrorLog` | 异常日志 | `path` / `method` / `message` / `traceback` |

### 3.3 关键业务约束

| 约束 | 说明 |
|---|---|
| 幂等去重 | 下单请求带 `idempotency_key`，10 秒窗口内相同键返回同一订单 |
| 信号去重 | 数据库唯一索引兜底，并发下不会产生重复信号 |
| 交易时段 | 监控扫描仅在 A 股交易时段生效（可配置） |
| 订单整手 | 股数必须是 100 的整数倍 |
| live 二次确认 | live 模式订单先进入 `pending`，需显式确认才生效 |
| 越权返回 404 | 访问他人资源统一 404，不暴露资源存在性 |
| 合成数据标记 | 无 tushare token 时 `data_source="mock"`，前端显著警示 |

### 3.4 错误码对照

| 场景 | 状态码 | detail 示例 |
|---|---|---|
| 验证码错误 | 400 | `验证码错误或已过期` |
| 密码错误 | 400 | `用户名或密码错误` |
| 账号锁定 | 400 | `账号已锁定，请 15 分钟后重试` |
| Token 失效 | 401 | `登录已过期，请重新登录` |
| 权限不足 | 403 | `权限不足，需要：strategy:write` |
| 非管理员 | 403 | `该操作仅限管理员` |
| 资源不存在 | 404 | `策略不存在` |
| 触发限流 | 429 | `请求过于频繁，请稍后再试` |
| 服务端异常 | 500 | `服务器内部错误，请稍后重试` |

