204 lines
9.4 KiB
Markdown
204 lines
9.4 KiB
Markdown
# 手工交易多账户中控(manual_trading_hub)
|
||
|
||
> **完整操作说明见 [使用说明.md](./使用说明.md)**(监控区 / 系统设置、鉴权、四所能力与故障排查)。
|
||
|
||
本目录提供多账户 **监控 + 紧急全平**。人工下单、关键位、趋势回调请在各 `crypto_monitor_*` 实例网页操作;策略与复盘仍在各实例。
|
||
|
||
---
|
||
|
||
## 功能概览
|
||
|
||
| 能力 | 说明 |
|
||
|------|------|
|
||
| 监控 | 汇总各子代理的永续持仓、未实现盈亏、余额(USDT)、持仓模式等 |
|
||
| 单账户全平 | 对某一子代理发起市价减仓,尽量平掉该所 USDT 永续仓位 |
|
||
| 全局全平 | 对当前「已开启监控」的子代理依次发起全平 |
|
||
| 关闭某账户 | 网页上取消「参与监控」,或环境变量 `HUB_DISABLED_IDS`;被关闭的不轮询、不参与全局全平 |
|
||
|
||
---
|
||
|
||
## 架构说明
|
||
|
||
```
|
||
浏览器 → 中控 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)**:读配置、并行请求各子代理 `/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`。
|
||
|
||
---
|
||
|
||
## 依赖
|
||
|
||
- Python 3.10+(与仓库其他项目相近即可)
|
||
- 见 `requirements.txt`:`fastapi`、`uvicorn`、`httpx`、`ccxt`
|
||
|
||
安装:
|
||
|
||
```bash
|
||
cd manual_trading_hub
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
建议使用独立虚拟环境,避免与全局包冲突。
|
||
|
||
---
|
||
|
||
## 快速启动(本机)
|
||
|
||
### 1. 启动子代理(每个账户一个终端)
|
||
|
||
在**对应策略目录**下加载该目录已有 `.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/**
|
||
|
||
---
|
||
|
||
## 子代理(agent)环境变量
|
||
|
||
| 变量 | 含义 | 默认 |
|
||
|------|------|------|
|
||
| `EXCHANGE` | `binance` / `okx` / `gate` | `binance` |
|
||
| `HOST` | 监听地址 | `127.0.0.1` |
|
||
| `PORT` | 子代理监听端口(勿与 Flask 的 `APP_PORT` 相同) | `15200` |
|
||
| `CONTROL_TOKEN` | 若设置,请求须带头 `X-Control-Token` | 空 |
|
||
|
||
**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` 等。
|
||
|
||
---
|
||
|
||
## 中控(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` | 空 |
|
||
|
||
---
|
||
|
||
## 网页操作说明
|
||
|
||
- **立即刷新 / 自动刷新**:拉取最新汇总;自动刷新默认约 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》**。
|