docs(hub): 同步中控文档与故障实录
更新使用说明、部署文档与 README,反映已移除下单区、Web 登录与 PM2 验收流程;新增常见问题.md 整理部署排障。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+59
-162
@@ -1,203 +1,100 @@
|
||||
# 手工交易多账户中控(manual_trading_hub)
|
||||
# 复盘系统中控(manual_trading_hub)
|
||||
|
||||
> **完整操作说明见 [使用说明.md](./使用说明.md)**(监控区 / 系统设置、鉴权、四所能力与故障排查)。
|
||||
> **完整说明**:[使用说明.md](./使用说明.md) · **部署**:[部署文档.md](./部署文档.md) · **故障实录**:[常见问题.md](./常见问题.md)
|
||||
|
||||
本目录提供多账户 **监控 + 紧急全平**。人工下单、关键位、趋势回调请在各 `crypto_monitor_*` 实例网页操作;策略与复盘仍在各实例。
|
||||
多账户 **监控聚合 + 紧急全平**;**不在中控网页下单**。人工下单、关键位、趋势回调、复盘请在各 `crypto_monitor_*` 实例原网页操作(监控卡片 **「实例」** / **「复盘」** 跳转)。
|
||||
|
||||
---
|
||||
|
||||
## 功能概览
|
||||
## 当前能力
|
||||
|
||||
| 能力 | 说明 |
|
||||
|------|------|
|
||||
| 监控 | 汇总各子代理的永续持仓、未实现盈亏、余额(USDT)、持仓模式等 |
|
||||
| 单账户全平 | 对某一子代理发起市价减仓,尽量平掉该所 USDT 永续仓位 |
|
||||
| 全局全平 | 对当前「已开启监控」的子代理依次发起全平 |
|
||||
| 关闭某账户 | 网页上取消「参与监控」,或环境变量 `HUB_DISABLED_IDS`;被关闭的不轮询、不参与全局全平 |
|
||||
| 监控区 | 持仓、余额、关键位摘要、趋势计划、机器人单(只读) |
|
||||
| 紧急全平 | 单户 / 全局市价减仓 |
|
||||
| 系统设置 | `hub_settings.json` 管理四所 URL、启用状态、监控能力 |
|
||||
| Web 登录 | `.env` 设 `HUB_PASSWORD` 后用户名+密码保护(反代公网**务必**配置) |
|
||||
| ~~下单区~~ | **已移除**(避免与实例重复、减少故障面) |
|
||||
|
||||
---
|
||||
|
||||
## 架构说明
|
||||
## 架构
|
||||
|
||||
```
|
||||
浏览器 → 中控 hub.py(默认监听 0.0.0.0:5100,私网可访问;本机仍可用 127.0.0.1)
|
||||
↓ HTTP
|
||||
子代理 agent.py × N(默认 127.0.0.1:15200~15203,与 Flask 的 APP_PORT 错开)
|
||||
↓ ccxt
|
||||
各交易所 API
|
||||
浏览器 → hub.py (:5100) 监控 / 设置 / 登录
|
||||
├→ agent.py × N (:15200~15203) 持仓、全平
|
||||
└→ 各 Flask (:5000/5001/5002/5004) /api/hub/monitor 只读聚合
|
||||
```
|
||||
|
||||
- **中控(hub)**:读配置、并行请求各子代理 `/status`;全平时转发 `POST /emergency/close-all`。
|
||||
- **子代理(agent)**:每个进程绑定一个交易所 API Key,只做只读状态 + 紧急平仓;与 `crypto_monitor_*` 里的 Flask **独立进程**,互不影响日常手工/策略操作。
|
||||
|
||||
### 与四个 `crypto_monitor_*` 目录的关系(已对照 `app.py`)
|
||||
|
||||
各策略项目在**本目录**用 **`.env`**(由 **`cp .env.example .env`** 生成,勿提交 Git;`git pull` 不覆盖)加载配置(`load_env_file`),并用其中的 **`APP_HOST` / `APP_PORT`** 启动 **Flask 网页**(`app.py` 里 `HOST`、`PORT`)。这是你在浏览器里打开策略/监控后台用的端口,例如 `APP_PORT=5001`。
|
||||
|
||||
子代理 **不用 `APP_PORT`**,而是用环境变量 **`PORT`**(FastAPI/uvicorn 监听)。若子代理与 Flask 抢同一端口,后启动的会起不来,因此中控默认把子代理配在 **`15200`~`15203`**,与常见 `5000` 段 Flask 配置**错开**。
|
||||
|
||||
| 子代理 `PORT`(建议) | 对应策略目录 | `EXCHANGE` |
|
||||
|----------------------|--------------|------------|
|
||||
| 15200 | `crypto_monitor_binance` | `binance` |
|
||||
| 15201 | `crypto_monitor_okx` | `okx` |
|
||||
| 15202 | `crypto_monitor_gate` | `gate` |
|
||||
| 15203 | `crypto_monitor_gate_bot` | `gate` |
|
||||
|
||||
Flask 仍可继续用 `APP_HOST=0.0.0.0` 方便云服务器外网访问;**子代理**建议 **`HOST=127.0.0.1`**。中控默认 `HUB_HOST=0.0.0.0` 便于局域网打开页面;若只给自己用,设 `HUB_HOST=127.0.0.1` 或 `HUB_TRUST_LAN=0`。
|
||||
- 账户列表:**系统设置** 或默认 `settings_store.py`(不再使用环境变量 `HUB_AGENTS`)。
|
||||
- 四实例须注册 **hub_bridge**(仓库根 `hub_bridge.py`);PM2 建议 `PYTHONPATH=..`。
|
||||
|
||||
---
|
||||
|
||||
## 依赖
|
||||
|
||||
- Python 3.10+(与仓库其他项目相近即可)
|
||||
- 见 `requirements.txt`:`fastapi`、`uvicorn`、`httpx`、`ccxt`
|
||||
|
||||
安装:
|
||||
## 快速启动(Linux / PM2)
|
||||
|
||||
```bash
|
||||
cd manual_trading_hub
|
||||
cd /opt/crypto_monitor/manual_trading_hub
|
||||
python3 -m venv .venv && source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env
|
||||
# 编辑 .env:HUB_PASSWORD、HUB_BRIDGE_TOKEN、HUB_PUBLIC_ORIGIN 等
|
||||
|
||||
pm2 start ecosystem.config.cjs # 4 agent + hub
|
||||
pm2 save
|
||||
|
||||
bash scripts/verify_hub_deploy.sh
|
||||
curl -s http://127.0.0.1:5100/api/ping
|
||||
```
|
||||
|
||||
建议使用独立虚拟环境,避免与全局包冲突。
|
||||
浏览器:`http://<本机IP>:5100/monitor`(已设密码则先 `/login`)。
|
||||
|
||||
---
|
||||
|
||||
## 快速启动(本机)
|
||||
## 中控 `.env` 要点
|
||||
|
||||
### 1. 启动子代理(每个账户一个终端)
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `HUB_PASSWORD` / `HUB_USERNAME` | 非空密码即启用登录 |
|
||||
| `HUB_BRIDGE_TOKEN` | 与四实例一致 |
|
||||
| `HUB_DISABLED_IDS` | 默认 `1` 关闭 OKX |
|
||||
| `HUB_PUBLIC_ORIGIN` | 其它设备打开复盘/实例外链(替换 127.0.0.1) |
|
||||
| `HUB_COOKIE_SECURE` | HTTPS 反代建议 `true` |
|
||||
|
||||
在**对应策略目录**下加载该目录已有 `.env`(含 API 密钥与可选代理),再启动 agent,避免密钥分散维护两套。
|
||||
|
||||
**Binance(子代理端口 15200,与 Flask APP_PORT 无关)**
|
||||
|
||||
```powershell
|
||||
cd ..\crypto_monitor_binance
|
||||
$env:EXCHANGE="binance"
|
||||
$env:PORT="15200"
|
||||
$env:HOST="127.0.0.1"
|
||||
python ..\manual_trading_hub\agent.py
|
||||
```
|
||||
|
||||
**OKX(15201)**
|
||||
|
||||
```powershell
|
||||
cd ..\crypto_monitor_okx
|
||||
$env:EXCHANGE="okx"
|
||||
$env:PORT="15201"
|
||||
python ..\manual_trading_hub\agent.py
|
||||
```
|
||||
|
||||
**Gate / Gate-Bot(15202 / 15203)**
|
||||
|
||||
```powershell
|
||||
$env:EXCHANGE="gate"
|
||||
$env:PORT="15202" # Gate-Bot 用 15203
|
||||
python ..\manual_trading_hub\agent.py
|
||||
```
|
||||
|
||||
### 2. 启动中控
|
||||
|
||||
```powershell
|
||||
cd manual_trading_hub
|
||||
$env:HUB_HOST="0.0.0.0"
|
||||
$env:HUB_PORT="5100"
|
||||
# 可选:自定义各账户卡片标题(顺序与默认 HUB_AGENTS 一致:15200→15201→15202→15203)
|
||||
# $env:HUB_AGENT_NAMES="币安主号,OKX,Gate主号,Gate机器人"
|
||||
python hub.py
|
||||
```
|
||||
|
||||
浏览器打开:**http://127.0.0.1:5100/** 或 **http://本机局域网IP:5100/**
|
||||
详见 [.env.example](./.env.example)。
|
||||
|
||||
---
|
||||
|
||||
## 子代理(agent)环境变量
|
||||
## 子代理(agent)
|
||||
|
||||
| 变量 | 含义 | 默认 |
|
||||
|------|------|------|
|
||||
| `EXCHANGE` | `binance` / `okx` / `gate` | `binance` |
|
||||
| `HOST` | 监听地址 | `127.0.0.1` |
|
||||
| `PORT` | 子代理监听端口(勿与 Flask 的 `APP_PORT` 相同) | `15200` |
|
||||
| `CONTROL_TOKEN` | 若设置,请求须带头 `X-Control-Token` | 空 |
|
||||
每所策略目录单独进程,`EXCHANGE` + `PORT`(15200~15203),密钥来自**该目录 `.env`**。PM2 经 `scripts/run_agent.sh` 启动(自动 `source .env`、去 CRLF)。
|
||||
|
||||
**Binance**:`BINANCE_API_KEY`、`BINANCE_API_SECRET`;可选 `BINANCE_POSITION_MODE`(`hedge`/`oneway`)、`BINANCE_MARGIN_MODE`;代理 `BINANCE_SOCKS_PROXY` 或 `BINANCE_HTTP_PROXY` / `HTTPS_PROXY`。`/status` 的 `balance_usdt` 为 **U 本位永续合约**账户 USDT(与 `crypto_monitor_binance` 合约口径一致,非现货钱包)。
|
||||
|
||||
**OKX**:`OKX_API_KEY`、`OKX_API_SECRET`、`OKX_API_PASSPHRASE`;可选 `OKX_TD_MODE`、`OKX_POS_MODE`;代理 `OKX_SOCKS_PROXY` 等。
|
||||
|
||||
**Gate**:`GATE_API_KEY`、`GATE_API_SECRET`;可选 `GATE_TD_MODE`、`GATE_POS_MODE`;代理 `GATE_SOCKS_PROXY` 等。
|
||||
| PORT | 目录 |
|
||||
|------|------|
|
||||
| 15200 | crypto_monitor_binance |
|
||||
| 15201 | crypto_monitor_okx |
|
||||
| 15202 | crypto_monitor_gate |
|
||||
| 15203 | crypto_monitor_gate_bot |
|
||||
|
||||
---
|
||||
|
||||
## 中控(hub)环境变量
|
||||
## 运维脚本
|
||||
|
||||
| 变量 | 含义 | 默认 |
|
||||
|------|------|------|
|
||||
| `HUB_HOST` | 监听地址 | `0.0.0.0`(局域网可连);`127.0.0.1` 仅本机 |
|
||||
| `HUB_PORT` | 监听端口 | `5100` |
|
||||
| `HUB_AGENTS` | 子代理 base URL,逗号分隔 | `http://127.0.0.1:15200` … `15203` |
|
||||
| `HUB_AGENT_NAMES` | 与 `HUB_AGENTS` **顺序一一对应**的卡片显示名(逗号分隔)。不设则用内置默认名。改后需重启 hub,**所有访问该中控的浏览器**显示一致 | 内置与四目录对应的英文标签 |
|
||||
| `HUB_DISABLED_IDS` | 不参与监控与全局全平的账户 `id`,逗号分隔(如暂不用 OKX 写 `1`) | 空 |
|
||||
| `HUB_TRUST_LAN` | 默认 `true`;设为 `0`/`false`/`off` 则仅允许本机 IP 访问中控 | 开 |
|
||||
| `CONTROL_TOKEN` | 与子代理一致时,中控代发 `X-Control-Token` | 空 |
|
||||
| 脚本 | 作用 |
|
||||
|------|------|
|
||||
| [scripts/fix_hub_deps.sh](./scripts/fix_hub_deps.sh) | 安装/更新 venv 依赖 |
|
||||
| [scripts/verify_hub_deploy.sh](./scripts/verify_hub_deploy.sh) | 验收代码版本与 ping |
|
||||
| [scripts/fix_env_crlf.sh](./scripts/fix_env_crlf.sh) | 修复 .env 的 Windows 换行 |
|
||||
| [scripts/pm2_hub.sh](./scripts/pm2_hub.sh) | PM2 启停 hub+agent |
|
||||
| [scripts/后台运行-Ubuntu.md](./scripts/后台运行-Ubuntu.md) | screen / systemd |
|
||||
|
||||
---
|
||||
|
||||
## 网页操作说明
|
||||
## 文档索引
|
||||
|
||||
- **立即刷新 / 自动刷新**:拉取最新汇总;自动刷新默认约 3 秒一轮(仅请求已开启监控的账户)。
|
||||
- **账户显示名**:在运行 `hub.py` 的机器上设置环境变量 **`HUB_AGENT_NAMES`**(逗号分隔,顺序与 **`HUB_AGENTS`** 里每个子代理 URL 一致),重启中控后,任意电脑打开同一中控地址都会看到相同名称。名称里若含逗号,需整体用引号包裹或避免使用逗号。
|
||||
- **参与监控**:勾选则参与轮询与「全局一键全平」;取消则本浏览器记住(`localStorage` 键 `manual_trading_hub_excluded`),不再请求该子代理。
|
||||
- **该账户全平**:仅针对该子代理;与是否关闭「参与监控」无关(仍可直接调交易所紧急平仓)。
|
||||
- **全局一键全平**:只对当前「参与监控」且未被 `HUB_DISABLED_IDS` 关闭的账户发起全平;请求体中的 `exclude_ids` 与网页关闭状态一致。
|
||||
|
||||
服务端 `HUB_DISABLED_IDS` 与浏览器关闭**取并集**:任一方关闭即不轮询、不进全局全平。
|
||||
|
||||
---
|
||||
|
||||
## HTTP API(访问控制与浏览器一致)
|
||||
|
||||
允许来源:**本机**或 **RFC1918 私网 IPv4**(与 `HUB_TRUST_LAN` 开启时一致);`HUB_TRUST_LAN=0` 时仅本机。
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/` | 中控页面 |
|
||||
| GET | `/api/agents` | 当前配置的账户列表(id、name、url) |
|
||||
| GET | `/api/snapshot` | 聚合状态;可选查询参数 `exclude_ids`(逗号分隔 id) |
|
||||
| POST | `/api/close/{agent_id}` | 单账户紧急全平 |
|
||||
| POST | `/api/close-all` | JSON 体可选 `{"exclude_ids":["1"]}`,与 `HUB_DISABLED_IDS` 合并 |
|
||||
|
||||
子代理:
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/health` | 健康检查 |
|
||||
| GET | `/status` | 余额、持仓、盈亏汇总 |
|
||||
| POST | `/emergency/close-all` | 市价尽量平掉 USDT 永续仓位,并尝试撤该合约挂单 |
|
||||
|
||||
---
|
||||
|
||||
## 安全与边界
|
||||
|
||||
- 中控默认 **监听 0.0.0.0** 并放行私网访问,便于局域网使用;**公网非私网 IP** 仍会被中间件拒绝。
|
||||
- 若机器有公网 IP,请用 **防火墙** 限制 `HUB_PORT` 仅内网可进,或改为 `HUB_HOST=127.0.0.1` + `HUB_TRUST_LAN=0` 仅本机。
|
||||
- 子代理建议仍用 **`HOST=127.0.0.1`**,不要对局域网暴露交易所密钥通道。
|
||||
- 中控**不具备**开仓、改策略、划转账能力;全平为**市价减仓**,请谨慎操作。
|
||||
- 子代理与主策略进程共用密钥时,注意权限与 IP 白名单仍按交易所要求配置。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
**1. 某一行一直连不上**
|
||||
检查该端口上的 `agent.py` 是否已启动、防火墙是否放行本机回环、`.env` 密钥是否与交易所一致。
|
||||
|
||||
**2. 暂时不用 OKX**
|
||||
网页取消该行的「参与监控」,或启动中控前设置 `HUB_DISABLED_IDS=1`(默认 OKX 的 id 为 `1`)。
|
||||
|
||||
**3. 策略项目要不要改?**
|
||||
不需要改 `crypto_monitor_*` 代码;只需额外运行 `agent.py` 进程。
|
||||
|
||||
**5. 局域网里别的电脑打不开中控**
|
||||
默认应已可访问:中控监听 `0.0.0.0` 且 `HUB_TRUST_LAN` 默认开启。请检查:防火墙是否放行 `HUB_PORT`;浏览器是否使用 **中控机器的局域网 IP**(不要用另一台电脑上的 `127.0.0.1`)。若你曾设置 `HUB_TRUST_LAN=0` 或 `HUB_HOST=127.0.0.1`,改回默认或删掉环境变量后重启 hub。
|
||||
|
||||
**Linux 常驻(PM2)**:`pm2 start ecosystem.config.cjs` 会**同时**启动 4 路子代理 + 中控 `manual-trading-hub`。详见 **《部署文档.md》**。
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 页面、API、环境变量、日常流程 |
|
||||
| [部署文档.md](./部署文档.md) | Ubuntu、PM2、反代、升级 |
|
||||
| [常见问题.md](./常见问题.md) | 已遇到问题与处理 |
|
||||
| [.env.example](./.env.example) | 环境变量模板 |
|
||||
|
||||
Reference in New Issue
Block a user