文档
系统分四层:akshare 落库 → PostgreSQL 18 + TimescaleDB → FastAPI 量化引擎 → Next.js 前端。
快速开始
1. 安装依赖并配置数据库连接(.env 填 PGPASSWORD):
pip install -r requirements.txt
cp .env.example .env # 填入 PGPASSWORD2. 建表 + 落库 + 清洗:
# 依次执行 ddl/01~05.sql
python -m bp_ingest run # 拉行情 + 刷新清洗表
python -m bp_ingest clean # (可选)全量重建清洗表3. 启动后端与前端:
uvicorn bp_api.main:app --reload --port 8000
cd web && npm run dev # http://localhost:3000开发环境请使用 --reload,确保 PUT 编辑等新增路由生效。
权限模型
- 访客:可浏览 Dashboard 示例组合,不可新建或编辑
- 管理员:可编辑/重算任意组合,可将组合设为示例(可多个)
- 白名单用户(bp_admin_user 表):可新建/编辑/删除组合
- 超级管理员(默认 xingyuliu@outlook.sg):上述权限 + /admin/users 用户管理
API 一览
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/assets | 可选资产清单(供组合构建器) |
| GET | /api/auth/me | 当前登录用户角色(is_admin / is_super_admin) |
| POST | /api/auth/login | 白名单用户登录 |
| GET | /api/admin/users | 列出白名单用户(超级管理员) |
| POST | /api/admin/users | 添加白名单用户(超级管理员) |
| DELETE | /api/admin/users/{email} | 删除白名单用户(不可删超级管理员) |
| GET | /api/portfolios | 组合列表 |
| GET | /api/portfolios/{id} | 组合详情(含四象限成分与 max_weight 等参数, 供编辑预填) |
| POST | /api/portfolios | 新建组合(异步): 立即返回 portfolio_id, 后台回测 |
| PUT | /api/portfolios/{id} | 编辑组合(异步): 原地更新配置并重算; running 时 409 |
| DELETE | /api/portfolios/{id} | 删除组合(管理员) |
| GET | /api/portfolios/{id}/status | 轮询回测状态: running / done / error |
| POST | /api/portfolios/{id}/recompute | 强制重算(异步, 返回 running) |
| PATCH | /api/portfolios/{id}/demo | 设为/取消示例组合(管理员) |
| GET | /api/portfolios/demo?portfolio_id= | 示例组合结果(可多个 demo, 可指定 id / method / benchmark) |
| GET | /api/portfolios/{id}/result?method= | 组合回测结果(净值/调仓/指标/持仓/相关性) |
组合创建/编辑请求体
POST / PUT 共用字段。默认对比基准 benchmark_key=bond6040(60/40 经典股债); 默认单资产最大权重 max_weight=0.3333(33.33%)。 须满足「独立品种数 × max_weight ≥ 1」,否则返回 400。
{
"name": "我的组合",
"description": "组合描述",
"method": "quadrant_inner_sharpe_outer_rp",
"ratio": "sharpe",
"lookback_days": 156,
"start_date": "2022-01-01",
"benchmark_key": "bond6040",
"max_weight": 0.3333,
"rebalance_band": 0.05,
"assets": [
{ "symbol": "510300", "source": "etf", "quadrant": "recovery", "display_name": "沪深300ETF" }
]
}回测采用成分逐步纳入:短历史品种不拖后全体起点;effective_start_date 为实际可优化起始日(≥ 用户设定的 start_date)。 Dashboard 净值图在切换近1年/近3年/全部时,窗口首日归一化为 1.0。
数据更新调度
每 6 小时增量更新行情并刷新清洗表:
python -m bp_ingest schedule本工具所示数据与方案仅供研究参考,不构成任何投资建议。