Files
crypto_monitor/manual_trading_hub/README.md
T
2026-05-22 11:38:20 +08:00

204 lines
9.4 KiB
Markdown
Raw 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.
# 手工交易多账户中控(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:1520015203,与 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
```
**OKX15201**
```powershell
cd ..\crypto_monitor_okx
$env:EXCHANGE="okx"
$env:PORT="15201"
python ..\manual_trading_hub\agent.py
```
**Gate / Gate-Bot15202 / 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》**。