Files
2026-08-01 10:33:19 +08:00

384 lines
15 KiB
Markdown
Raw Permalink 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.
# 比特骆驼行情采集分析 — 开发方案
> **独立仓库**,与 `eth_hedge_sim`(策略 / 中控)**无代码共用、无进程共用、无交易密钥共用**。
> 本系统只做:**行情采集 → 落库 → 分析统计 → 只读展示 / API**。
> **不下单、不持仓、不替代策略选约。**
> Git 仓库由负责人在 `git.bz121.com` 创建;本目录为方案与后续工程落点。
---
## 1. 命名与定位
| 项 | 约定 |
|----|------|
| **产品名** | **比特骆驼行情采集分析** |
| **项目名称(对外)** | 比特骆驼行情采集分析系统 |
| **仓库名称 / 工程名** | `market_intel` |
| **Git 地址(拟)** | `https://git.bz121.com/dekun/market_intel.git` |
| **安装目录(生产)** | `/opt/market_intel` |
| **部署操作系统** | **Ubuntu 22.04 LTS**(与策略仓一键脚本一致) |
| **运行方式** | **Docker Compose**(采集 + API + Web 同栈编排) |
| **一键入口** | `deploy/manage.sh` 交互菜单(对齐 `eth_hedge_sim` |
### 1.1 硬边界
- **只读行情**REST / WebSocket;禁止任何交易类 API。
- **与策略解耦**:策略机挂了,本系统仍可继续采;本系统挂了,策略仍可独立交易。
- **第一期标的**ETHOKX 指数 + ETH-USD_UM 期权盘口);架构预留多币种 / 多所,但实现标准先钉死 OKX ETH。
- **时区**:统计与「日 / 周 / 月」切分一律 **Asia/Shanghai**
### 1.2 核心分析目标(作战地图数据底座)
1. **期权杠杆 × 日内时段**
口径:`杠杆 = 标的指数 ÷ 期权卖一`(与策略选约门限一致)。
2. **该时段 → 期权到期 的波动点数**
口径:到期时刻指数 − 该时段代表指数(可同时存带符号与绝对值)。
3. **范围**:按 **日 / 周 / 月** 过滤样本,横轴均为 **日内时段桶**(默认 1 小时)。
---
## 2. 实现标准
### 2.1 技术栈
| 层 | 标准 |
|----|------|
| 语言 | Python 3.11+(采集 / API / 聚合) |
| Web API | FastAPI |
| 前端 | React + Vite(只读看板:采集状态、时段图、日周月切换) |
| 数据库 | 第一期 **SQLite**(volume 持久化);上量后可换 Postgres,表结构先按可迁移设计 |
| 容器 | Docker + Docker Compose v2 |
| 反向代理(可选) | 同 Compose 内 Caddy/Nginx,或宿主机已有反代 |
| 配置 | 仓库根 `.env`(密钥、交易所、采样间隔、端口);**已有非空值不覆盖** |
### 2.2 代码与工程规范
- 仓库根英文名固定 `market_intel`;文档可用中文。
- 配置项集中、可环境变量覆盖;禁止把 API Key 写进镜像层。
- 采集与 API **可同容器或分服务**Compose 内用服务名互访。
- 所有时间戳存 **UTC ms**;展示与「自然日」按上海转换。
- 杠杆 / 波动口径写进代码常量 + 本文档,变更需改版本号与迁移说明。
- 日志:结构化或按日滚动;脱敏(不打完整密钥)。
- 测试:采集解析、杠杆计算、时段聚合、到期回填 有单元测试。
### 2.3 采集标准(第一期)
| 项 | 标准 |
|----|------|
| 交易所 | OKX(只读) |
| 指数 | ETH-USD 指数(或与策略一致的 index) |
| 期权 | 最近合资格到期的 ATM Call + ATM Put(规则文档化:最接近指数的行权价) |
| 杠杆采样间隔 | 默认 **30s**(可配 15120s |
| 指数采样 | 可与杠杆同频,或单独 **60s** |
| 字段最小集 | `ts_ms, exchange, underlying, expiry_ymd, strike, side(C/P), index_px, ask, bid, ask_sz, bid_sz, leverage, inst_id` |
| 失败策略 | 单次失败记日志并跳过;连续失败告警(可选企微,后期) |
### 2.4 统计标准
| 项 | 标准 |
|----|------|
| 时段桶 | 默认 **1 小时**(0–23,上海);可扩展 30 分钟 |
| 日 | 上海自然日 `YYYY-MM-DD` |
| 周 | **滚动近 7 个上海自然日**(第一期);后期可加自然周 |
| 月 | **滚动近 30 日** 或自然月(设置可选,默认滚动 30 日) |
| 杠杆聚合 | 桶内:样本数、均值、中位数、P25/P75、≥`min_leverage` 占比 |
| 波动点数 | 到期后回填;桶内:均值/中位/分位;同时提供 **signed****abs** |
| 未到期 | API 标记 `pending_expiry=true`,不假装有完整「到到期」分布 |
### 2.5 安全与权限
- 仅行情只读 Key(若需要);无交易权限。
- Web / API 默认需登录或 Token(对齐策略仓简单鉴权即可)。
- 局域网部署时可绑 `127.0.0.1` / 内网 IP;公网必须 HTTPS + 强密码。
---
## 3. 系统架构
```text
┌─────────────────────────────────────┐
│ market_intel(本仓库 · Docker
OKX 行情 ────────►│ collector → SQLite/DB │
(REST/WS) │ analytics(日/周/月 · 时段聚合) │
│ api + web(只读看板) │
└─────────────────────────────────────┘
│ 可选:只读 API
人工浏览器 / 其它系统(后期)
```
- **不**嵌入 `eth_hedge_sim` 进程。
- 后期若中控要展示,由中控 **HTTP 调用本系统 API**,本仓仍独立演进。
---
## 4. 代码结构(目标仓库)
```text
market_intel/
├── README.md
├── 开发方案.md # 可从本文件迁入 docs/
├── .env.example
├── .gitignore
├── docker-compose.yml # 一键编排入口
├── Dockerfile # API + 采集(或多阶段)
├── requirements.txt
├── deploy/
│ ├── manage.sh # 交互式菜单(curl | bash
│ ├── bootstrap.sh # 缺 git/docker 时引导
│ └── lib/
│ ├── common.sh # 日志、读入、路径、.env 合并
│ ├── install.sh # 一键部署(clone + compose up
│ ├── update.sh # git pull + compose build/up
│ └── uninstall.sh # 停容器;可选保留 data volume
├── apps/
│ ├── collector/ # 行情采集进程
│ │ ├── __init__.py
│ │ ├── main.py # 入口:循环 / WS
│ │ ├── okx_rest.py
│ │ ├── okx_ws.py
│ │ └── selectors.py # ATM / 到期选择
│ ├── api/ # FastAPI
│ │ ├── main.py
│ │ ├── routes/
│ │ │ ├── health.py
│ │ │ ├── samples.py # 原始/明细(调试)
│ │ │ └── stats.py # 日周月 · 杠杆 · 波动
│ │ └── auth.py
│ └── worker/ # 可选:到期回填、日终聚合
├── packages/
│ ├── db/ # schema、迁移、repository
│ ├── domain/ # option_leverage、bucket、move_points
│ └── config/ # settings from env
├── web/ # React 看板
│ ├── package.json
│ └── src/
│ ├── pages/
│ │ ├── Dashboard.tsx # 采集心跳、最新杠杆
│ │ └── OpsMap.tsx # 作战地图:杠杆 + 波动 · 日/周/月
│ └── api/
├── data/ # 本地/挂载:SQLite.gitignore 内容)
├── scripts/
│ ├── smoke_collect.py
│ └── backfill_index.py # 可选:历史指数回填波动
└── tests/
├── test_leverage.py
├── test_buckets.py
└── test_move_points.py
```
> 实现时可把 `apps/` 收成单包 `src/market_intel/`,但 **deploy / docker / web / 采集与 API 分离** 的边界保持不变。
---
## 5. 数据模型(摘要)
### 5.1 `option_quotes`(杠杆明细)
| 字段 | 说明 |
|------|------|
| id | 自增 |
| ts_ms | UTC |
| exchange | `okx` |
| inst_id | 合约 ID |
| expiry_ymd | `YYMMDD` |
| strike | 行权价 |
| side | `C` / `P` |
| index_px | 指数 |
| ask / bid | 卖一 / 买一 |
| ask_sz / bid_sz | 可选 |
| leverage | `index_px / ask`ask>0 |
### 5.2 `index_ticks`(指数明细)
| 字段 | 说明 |
|------|------|
| ts_ms | UTC |
| underlying | `ETH` |
| index_px | 指数 |
### 5.3 `expiry_settlements`(到期锚点)
| 字段 | 说明 |
|------|------|
| expiry_ymd | 到期日 |
| settle_ts_ms | 到期时刻(OKXUTC 08:00 |
| settle_index_px | 结算/到期指数 |
波动点数:对历史某桶代表时刻 \(t\),
`move = settle_index_px - index_at(t)`(同 `expiry_ymd`)。
---
## 6. API 约定(第一期)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/health` | 存活;可选返回采集延迟 |
| GET | `/api/stats/leverage` | `range=day\|week\|month` + 日期;返回各时段桶聚合 |
| GET | `/api/stats/move_points` | 同上;返回时段→到期波动 |
| GET | `/api/stats/ops-map` | 一次返回杠杆 + 波动(看板主接口) |
| GET | `/api/meta/latest` | 最新一条 Call/Put 杠杆、采集时间 |
查询参数统一:`range``date`(锚点日)、`side=C|P|both``bucket_minutes=60`
---
## 7. Docker 运行标准
### 7.1 服务划分(Compose
| 服务名 | 职责 | 说明 |
|--------|------|------|
| `collector` | 写库 | 重启策略 `unless-stopped` |
| `api` | FastAPI + 静态前端(或挂 `web` 构建产物) | 默认端口 **5170**(可配,避开策略 5155 / 中控 5160 |
| `db` | 第一期可省略(SQLite 挂 volume | 后期 Postgres 再加 |
```yaml
# docker-compose.yml 示意(实现时落地)
services:
collector:
build: .
command: ["python", "-m", "apps.collector.main"]
env_file: .env
volumes:
- mi_data:/app/data
restart: unless-stopped
api:
build: .
command: ["uvicorn", "apps.api.main:app", "--host", "0.0.0.0", "--port", "5170"]
env_file: .env
ports:
- "${MI_PORT:-5170}:5170"
volumes:
- mi_data:/app/data
depends_on:
- collector
restart: unless-stopped
volumes:
mi_data:
```
### 7.2 本地开发(非必须 Docker
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python -m apps.collector.main # 终端 1
uvicorn apps.api.main:app --reload # 终端 2
cd web && npm i && npm run dev # 终端 3
```
**生产标准路径以 Docker Compose 为准。**
---
## 8. 一键部署(对齐 eth_hedge_sim
### 8.1 新机器(免克隆)
```bash
curl -fsSL https://git.bz121.com/dekun/market_intel/raw/branch/main/deploy/manage.sh | bash
```
要求:Ubuntu 22.04;脚本内检测并安装 **Git、Docker、Docker Compose 插件**(已有则跳过)。
### 8.2 已安装
```bash
bash /opt/market_intel/deploy/manage.sh
```
### 8.3 交互菜单(实现标准)
与策略仓 `deploy/manage.sh` 同级体验:**数字选项 + 读 `/dev/tty`**,支持 `curl | bash`
| 选项 | 作用 |
|------|------|
| **1) 一键部署** | 检测 Docker → clone 到 `/opt/market_intel` → 生成/补全 `.env`(已有非空不覆盖)→ `docker compose up -d --build` → 健康检查 |
| **2) 更新** | `git pull` + `compose build/up`;保留 `.env` 与 data volume |
| **3) 停止** | `docker compose stop` |
| **4) 启动** | `docker compose start` / `up -d` |
| **5) 查看状态** | `compose ps` + `/health` |
| **6) 一键卸载** | 停容器;询问是否删除 data volume;备份 `.env``/root/backups/market_intel/`;按确认删除 `/opt/market_intel` |
| **0) 退出** | — |
已存在安装目录时,选项 1 进入子菜单:**取消 / 修复(保留 .env 与数据)**,行为对齐策略仓 `install.sh`
### 8.4 `.env` 交互补全(首次部署)
脚本可交互询问(有默认值,回车采用默认):
- `OKX` API Key / Secret / Passphrase(只读;可留空若仅用公开行情)
- `MI_PORT`(默认 `5170`
- `SAMPLE_INTERVAL_SEC`(默认 `30`
- `MIN_OPTION_LEVERAGE`(统计达标线,默认 `100`
- 管理员密码 / `AUTH_SECRET`
原则:**文件中已有非空值不覆盖**(对齐中控 `.env.control` 行为)。
### 8.5 部署后验收
1. `curl -fsS http://127.0.0.1:5170/health` 返回 ok
2. 等待 ≥1 个采样周期后,库中有 `option_quotes`
3. 打开 Web 看板能看到最新杠杆
4. `manage.sh` → 更新 → 容器重建后数据 volume 仍在
---
## 9. Web 看板(第一期页面)
| 页面 | 内容 |
|------|------|
| 总览 | 采集是否正常、延迟、当前 ATM Call/Put 杠杆 |
| 作战地图 | 切换 **日 / 周 / 月**;上图时段杠杆;下图时段→到期波动点数 |
| 设置(简) | 只读展示当前采样参数(改参走 `.env` + 更新重启) |
UI 要求:暗色可与策略仓风格接近,但 **独立品牌标题「行情采集分析」**,避免与对冲策略页混淆。
---
## 10. 分期计划
| 阶段 | 交付 |
|------|------|
| **P0** | 仓库骨架、Docker Compose、manage.sh 菜单、健康检查 |
| **P1** | OKX 指数 + ATM Call/Put 采样落库 |
| **P2** | `/api/stats/leverage` 日周月;Web 作战地图杠杆图 |
| **P3** | 到期回填 + 波动点数统计与下图 |
| **P4** | 鉴权加固、企微采集异常推送、可选历史指数回填 |
| **P5** | (可选)中控只读嵌入;多 underlying |
---
## 11. 与 `eth_hedge_sim` 的关系(再强调)
| | `eth_hedge_sim` | `market_intel`(本仓) |
|--|-----------------|------------------------|
| 职责 | 对冲交易 / 中控运维 | 行情采集与统计分析 |
| 运行 | PM2(现状) | **Docker Compose** |
| 端口 | 5155 / 5160 | **5170**(默认) |
| 密钥 | 可含交易权限 | **仅只读行情** |
| 依赖 | 互不依赖 | 互不依赖 |
---
## 12. 验收清单(方案级)
- [ ] 仓库名 `market_intel`,产品名「比特骆驼行情采集分析」
- [ ] `curl | bash` 出交互菜单,可一键部署 / 更新 / 卸载
- [ ] 全程 Docker 运行,数据落 volume
- [ ] 杠杆口径 = 指数 ÷ 卖一;时段统计支持日 / 周 / 月
- [ ] 波动点数 = 时段指数 → 到期指数;未到期显式标记
- [ ] 零交易 API;与策略仓进程隔离
---
## 13. 文档修订
| 日期 | 说明 |
|------|------|
| 2026-07-31 | 初稿:独立仓、Docker、交互式一键部署、作战地图数据标准 |