# 多账户交易中控 — 使用说明

本文档说明 **manual_trading_hub** 的架构、启动方式、界面操作与故障排查。中控聚合四所 **持仓/条件单/余额/关键位/趋势计划监控 + 撤单/紧急全平**，并提供 **资金概况**、**行情区 K 线** 与 **内照明心（复盘语录 + 永久 K 线）**；**人工下单、关键位、策略交易（趋势回调 / 顺势加仓）、交易复盘** 均在各实例网页操作（点监控卡片 **「实例」**）。资金概况见 **[资金概况说明.md](./资金概况说明.md)**；行情区细则见 **[行情区说明.md](./行情区说明.md)**；内照明心见 **[docs/hub-symbol-archive-kline.md](../docs/hub-symbol-archive-kline.md)**。

---

## 1. 架构总览

```
浏览器
  ├─ /funds     资金概况
  ├─ /plan      开仓计划（计划录入 / 进行中 / 历史胜率）
  ├─ /monitor   监控区（持仓、关键位、趋势计划、全平）
  ├─ /market    行情区（K 线、技术指标、持仓价格线）
  ├─ /archive   内照明心（复盘语录 + 交易记录 + 永久 5m K 线）
  ├─ /funds     资金概况（总资金曲线、分户资金与回撤）
  ├─ /dashboard 数据看板（四户当日总览，SSE 推送；见 [数据看板说明.md](./数据看板说明.md)）
  ├─ /ai        AI 教练（交易教练 / 普通聊天；见 [AI教练说明.md](./AI教练说明.md)）
  └─ /settings  系统设置（hub_settings.json）

中控 hub.py（默认 :5100）
  ├─ HTTP → 子代理 agent.py × N（/status、/emergency/close-all）
  └─ HTTP → 各实例 Flask（/api/hub/monitor、/api/price_snapshot 等只读聚合）
```

| 组件 | 职责 | 默认端口（可在设置页改） |
|------|------|-------------------------|
| **hub.py** | 聚合 UI、监控 API、全平 | `5100` |
| **agent.py** | 交易所只读状态、挂单/条件单查询与撤销 + 紧急市价全平 | 币安 `15200`、OKX `15201`、Gate `15202`、Gate趋势 `15203` |
| **crypto_monitor_*.app** | 策略库、关键位、人工单、趋势预览/执行 | 币安 `5001`、Gate `5000`、Gate趋势 `5002`、OKX `5004` |

### 1.1 四账户默认配置

| id | 名称 | Flask | Agent | 监控能力（设置页勾选） | 默认启用 |
|----|------|-------|-------|------------------------|----------|
| 0 | 币安 | :5001 | :15200 | 关键位 | 是 |
| 1 | OKX | :5004 | :15201 | 关键位 + 趋势计划（建议） | **否**（`HUB_DISABLED_IDS=1`，需用时在设置页启用） |
| 2 | Gate 训练 | :5000 | :15202 | 关键位 | 是 |
| 3 | Gate 趋势 | :5002 | :15203 | 趋势计划（默认不勾关键位） | 是 |

- **Gate 趋势户**：默认只勾 **监控趋势计划**；一般不勾关键位（该户多用于趋势回调）。策略操作在实例 **`/strategy`**。
- **币安 / Gate 训练 / OKX**：四所均已支持 **策略交易**；中控可同时勾 **监控关键位** + **监控趋势计划**（见 §4.2、§5）。
- **OKX**：默认关闭；需要时在「系统设置」勾选启用，并去掉环境变量 `HUB_DISABLED_IDS` 中的 `1`。

### 1.2 实例侧改动（最小）

各 `crypto_monitor_*` 仅增加：

1. `login_required` 走 `hub_auth.request_allowed`（支持请求头 `X-Hub-Token`）。
2. 文件末尾 `hub_bridge.install_on_app(...)` 注册 `/api/hub/*`。

业务逻辑、数据库、复盘页面 **未改**；复盘请打开各实例 `/records`（设置里的「复盘链接」）。

---

## 2. 环境准备

### 2.1 依赖安装

```bash
cd /opt/crypto_monitor/manual_trading_hub
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

### 2.2 鉴权令牌（推荐生产启用）

四实例 Flask 与中控、子代理需 **同一密钥**：

| 变量 | 作用 |
|------|------|
| `HUB_BRIDGE_TOKEN` | 中控 → Flask 使用头 `X-Hub-Token`；各实例 `hub_auth` 校验 |
| `CONTROL_TOKEN` | 可与上相同；中控 → 子代理使用头 `X-Control-Token` |

中控 `hub.py` 会读取 `HUB_BRIDGE_TOKEN`，若无则回退 `CONTROL_TOKEN`。

**开发本机**可临时在各实例 `.env` 设 `APP_AUTH_DISABLED=true`，则 Flask 不校验令牌（仍建议子代理设 `CONTROL_TOKEN` 防误暴露）。

### 2.3 强制关闭某账户

```bash
# 在 manual_trading_hub/.env 中设置，或临时：
export HUB_DISABLED_IDS=1    # 默认即关闭 OKX（id=1）
```

与设置页「启用」取 **与** 关系：环境变量强制关闭时，网页勾选框会灰掉且无法启用。

### 2.4 Web 登录（反代公网强烈建议）

在 `manual_trading_hub/.env` 中配置：

| 变量 | 说明 |
|------|------|
| `HUB_USERNAME` | 登录用户名；未设且已设密码时默认为 `admin` |
| `HUB_PASSWORD` | **非空即启用登录**；所有页面与 API（除登录页、`/api/ping`、`/assets`）须先登录 |
| `HUB_SESSION_SECRET` | 会话签名密钥（建议单独随机串） |
| `HUB_COOKIE_SECURE` | 建议 `true`：仅 **HTTPS** 访问时 Cookie 带 Secure；**HTTP 内网 IP:5100 仍可登录** |
| `HUB_SESSION_DAYS` | 登录保持天数，默认 `7` |

- 登录页：`http://<中控地址>:5100/login`
- 顶栏 **退出** 清除会话。
- **域名（HTTPS）** 与 **内网 IP（HTTP）** Cookie 不共用，需分别登录一次。

更多登录/Cookie 问题见 **[常见问题.md](./常见问题.md)** 第二节。

### 2.5 配置文件

- 路径：`manual_trading_hub/hub_settings.json`（在网页 **系统设置 → 保存设置** 后写入）。
- 未保存前使用 `settings_store.py` 内置默认四所地址。
- 建议 **不要** 把含内网 IP 的 `hub_settings.json` 提交到公开仓库。
- 环境变量模板：`manual_trading_hub/.env.example`；四实例模板中已补充 `HUB_BRIDGE_TOKEN` 说明。

---

## 3. 启动顺序（Ubuntu + PM2）

**原则**：代码在 **`/opt/crypto_monitor`**，先四实例 Flask，再中控（一条 PM2 含 4 agent + hub）。环境见 **[docs/ubuntu-server.md](../docs/ubuntu-server.md)**。

```bash
# 四所 Flask（示例：币安；其余三所同理）
cd /opt/crypto_monitor/crypto_monitor_binance
pm2 start ecosystem.config.cjs

# 中控 + 子代理
cd /opt/crypto_monitor/manual_trading_hub
pm2 start ecosystem.config.cjs
pm2 save
```

浏览器（本机或反代）：

- 监控区：`http://127.0.0.1:5100/monitor`  
- 行情区：`http://127.0.0.1:5100/market`  
- 内照明心：`http://127.0.0.1:5100/archive`  
- 资金概况：`http://127.0.0.1:5100/funds`  
- 系统设置：`http://127.0.0.1:5100/settings`  

验收：

```bash
bash /opt/crypto_monitor/manual_trading_hub/scripts/verify_hub_deploy.sh
curl -s http://127.0.0.1:5100/api/ping
```

---

## 4. 页面操作说明

Chrome **桌面快捷方式**图标来自站点 `favicon` / `manifest`（已配置统一品牌图），说明见 **[docs/shortcut-icon.md](../docs/shortcut-icon.md)**。

### 4.1 监控区 `/monitor`

| 功能 | 说明 |
|------|------|
| **服务器状态** | 标题下方可折叠条（**默认收起**），摘要行显示 CPU/内存/硬盘；展开见四指标卡片（`GET /api/host/status`，每 5 秒刷新）。**CPU 或内存 ≥85%** 时浏览器弹窗告警（降至 85% 以下后再次超标会再提示）。依赖 `manual_trading_hub/.venv` 内 **psutil**（勿用系统 `pip`，见 [部署文档.md](./部署文档.md)）。可选 `HUB_HOST_DISK_PATH` 指定监控磁盘 |
| **2×2 主界面** | 四所信息**完整展示**：余额、持仓表、委托/平仓、折叠委托单、下单监控、关键位、趋势/加仓摘要 |
| **全屏放大** | **点击卡片标题栏**（非按钮区）→ 该所**全屏**：每币种一张实盘风格持仓卡（趋势持仓显示**来源: 趋势回调计划**、**风险%**、**程序监控·止盈价**、**盈亏比**，与实例策略页一致）；独立卡片：**关键位**、**下单监控**、**趋势回调**（单计划 **两列**：左=币种基本信息与 3×2 指标，右=**补仓计划明细**，底=**保本偏移%** 可编辑 + **保本移交** / **结束计划**（中控直接调实例，与 `/strategy` 一致）、快照可用/计划保证金/杠杆）、**顺势加仓** |
| **委托单折叠** | 仅「委托单」区块默认折叠；展开状态存浏览器本地，**5 秒刷新不重置** |
| **条件单 / 委托** | 每个持仓下方展示交易所 **条件单**（默认折叠）与 **普通委托**；数据来自子代理实时拉取（币安含 Algo 通道） |
| **撤单** | 条件单区内单笔「撤单」或「撤销全部」；经中控 `POST /api/orders/{id}/cancel`、`cancel-symbol` |
| **挂止盈止损** | 持仓行 **「委托」**：弹窗填止损/止盈价 → **先撤该合约全部条件单，再挂新 TP/SL**（币安 / OKX / Gate / Gate趋势 四所统一，逻辑与各实例 `.env` 参数一致） |
| **平仓** | 持仓行「平仓」：仅平该方向仓位（子代理市价减仓） |
| **机器人单** | 来自实例 `/api/hub/monitor` 的 `order_monitors`（active），为本地监控计划，**不等于**交易所条件单 |
| **关键位** | 仅 `capabilities` 含 `key` 的户；展示门控摘要（`/api/price_snapshot`） |
| **趋势计划** | 仅当该户勾选 **监控趋势计划** 时展示 `trend_pullback_plans`（active） |
| **实例 / 复盘** | 「实例」「策略交易」「复盘」经中控签发 **SSO 链接**（默认 2h、单次）打开，**免输**实例 `APP_USERNAME/PASSWORD`；直链实例 IP/域名仍走 `/login`。**云服务器**见 **[云服务器部署说明.md](./云服务器部署说明.md)**；局域网/反代见 **[局域网与反代部署说明.md](./局域网与反代部署说明.md)** |
| **关键位列表** | 来自 `/api/hub/monitor` + `/api/price_snapshot`；Flask 未连通时卡片提示原因；**Gate 趋势户**无关键位块 |
| **该户全平** | `POST` 子代理 `/emergency/close-all`，仅平该 API Key 仓位 |
| **全局紧急全平** | 对所有已启用户依次全平（不含 `HUB_DISABLED_IDS` 强制关闭的 id） |
| **自动刷新** | 默认每 5 秒请求 `/api/monitor/board` |

持仓数据以 **子代理 ccxt** 为准；关键位/趋势/机器人单以 **Flask 数据库** 为准。若 Flask 未启动，卡片仍会显示 agent 持仓，但下方策略信息可能为空或报错。

### 4.2 行情区 `/market`

| 功能 | 说明 |
|------|------|
| **K 线** | 选择已启用交易所 + 币种 + 周期；按需拉取，本地 `data/hub_kline.db` 缓存（默认保留 15 天） |
| **周期** | `1m` `5m` `15m` `1h` `2h` `4h` `12h` `1d` `1w` |
| **加载 / 强制刷新** | 普通加载优先缓存；强制刷新重拉并覆盖缓存 |
| **从监控跳转** | 点击持仓合约名带入品种，并显示入场/止损/止盈/委托与 K 线价格线 |
| **技术指标** | 可选 EMA 21/55、MACD、RSI |
| **快捷键** | **`F`** 全屏/退出；全屏时 **`Esc`** 退出；数字键切换周期（见 [行情区说明.md](./行情区说明.md)） |
| **自动刷新** | 约 5 秒更新最新 OHLCV |

数据经中控 → 各实例 `GET /api/hub/ohlcv`（`hub_ohlcv_lib`）。升级 hub 与四实例 Flask 后请 **强刷浏览器**；异常 K 线可点 **强制刷新**。

### 4.2.1 内照明心 `/archive`

| 功能 | 说明 |
|------|------|
| **复盘语录** | 左栏按日添加/编辑；最多 100 条 |
| **日期** | **本日 / 本周 / 本月 / 自选区间**（交易日 8:00 切日） |
| **区间统计** | 总开仓、犯病次数与占比、盈亏、剔除犯病盈亏、各交易所分项 |
| **筛选** | 盈利单、亏损单、犯病（仅过滤表格；统计栏不受此三项影响） |
| **交易记录** | 区间内开仓列表；犯病行红色字体；可编辑备注与犯病标签 |
| **K 线** | 默认折叠按需加载；独立库 `data/hub_symbol_archive.db`；仅存 **5m** 真源，**15m/1h/4h** 聚合 |
| **建档** | 最早开仓向前 **30 天** 5m 种子；之后每 **4h** 增量（Hub 后台 + 可点「同步」） |
| **视窗** | **持仓过程**（锚平仓）/ **进场决策**（锚开仓）；支持时间输入跳转 |

与行情区 `hub_kline.db`（15 天滚动）**分离**，建档起 **只增不删**。细则见 **[docs/hub-symbol-archive-kline.md](../docs/hub-symbol-archive-kline.md)**。

### 4.2.2 资金概况 `/funds`

| 功能 | 说明 |
|------|------|
| **总资金** | 已监控账户的 **资金户 + 交易户** 合计（不含浮盈） |
| **总曲线** | 自 **2026-06-09** 起、按北京时间交易日（默认 8:00 切日）每日一点，最多 **180** 天 |
| **最大回撤** | 基于总资金余额曲线（非平仓盈亏回撤） |
| **分户** | 每户资金/交易拆分、迷你曲线、分户回撤；**未监控** 不参与合计 |
| **快照** | 监控板聚合成功时写入 `hub_fund_history.json` |

细则见 **[资金概况说明.md](./资金概况说明.md)**。

### 4.2.3 数据看板 `/dashboard`

| 功能 | 说明 |
|------|------|
| **总览** | 交易日、平仓盈亏、笔数、浮盈亏、资金合计、持仓数 |
| **分户** | 四户资金/交易账户、今日盈亏、浮盈亏；单日亏损 ≥ 资金合计 **5%** 高亮预警 |
| **平仓明细** | 当日平仓流水表 |
| **刷新** | 后台每 60s 聚合 + **SSE** 推送版本号；页面无整页轮询闪烁 |
| **主题** | 跟随顶栏亮/暗主题，卡片柔光样式（非霓虹背景） |

细则见 **[数据看板说明.md](./数据看板说明.md)**。

### 4.3 AI 教练 `/ai`

| 功能 | 说明 |
|------|------|
| **交易教练** | 口语化陪聊；后台注入四户监控快照（不在页面展示今日总结） |
| **普通聊天** | 不绑交易数据 |
| **会话** | 多会话历史（切换/删除）、消息复制；点 **「新开对话」** 清空当前上下文 |
| **模型** | 与四实例相同 `.env`（默认 `AI_PROVIDER=openai` + `OPENAI_*`；改 `ollama` 走本机），见 [AI教练说明.md](./AI教练说明.md) |
| **与实例复盘** | 深度单笔 journal 复盘仍在各所 `/records`；中控不做重复 |

依赖四实例 `GET /api/hub/trades/today`（`hub_bridge`）；升级代码后需 **重启四所 Flask**。

### 4.4 系统设置 `/settings`

**可用**：打开 http://127.0.0.1:5100/settings ，修改表格后点 **保存设置** 即写入 `hub_settings.json`；**重新加载** 从磁盘/默认再读（会重新套用 `HUB_DISABLED_IDS`）。保存后监控区立即使用新 URL/启用状态，**无需重启 hub**。

**显示与导航**（`hub_settings.json` → `display`）：

| 开关 | 说明 |
|------|------|
| 监控区资金/浮盈 | 关闭后监控卡片不显示资金户、交易户、浮盈亏列 |
| 顶栏「资金概况」 | 关闭后隐藏导航；直接访问 `/funds` 会跳回监控区 |
| 顶栏「数据看板」 | 关闭后隐藏导航；直接访问 `/dashboard` 会跳回监控区 |

**下单、关键位、策略交易**：请在监控卡片点击 **「实例」** 或 **「策略交易」**（SSO），进入各 `crypto_monitor_*` 网页（`/trade`、`/key_monitor`、`/strategy`、`/strategy/records` 等）。中控 **不** 提供下单区；**策略交易记录** 仅在实例顶栏查看（见 [策略交易说明.md](../策略交易说明.md) §五）。

| 列 | 含义 |
|----|------|
| 启用 | 是否参与监控与全局全平；被 `HUB_DISABLED_IDS` 锁定的无法勾选 |
| 显示名 | 监控卡片标题 |
| Flask URL | 实例根地址，如 `http://127.0.0.1:5001` |
| Agent URL | 子代理根地址，如 `http://127.0.0.1:15200` |
| 复盘链接 | 一般为 `{Flask}/records` |
| **监控关键位** | 勾选后卡片展示 **关键位** 列表 + 门控价（读 Flask `/api/price_snapshot`） |
| **监控趋势计划** | 勾选后卡片展示 **趋势回调** 运行中计划（`trend_pullback_plans` active） |
| id | 与 `HUB_DISABLED_IDS`、全平 API 路径中的 id 对应；新增户勿与已有 id 重复 |

- **保存设置**：写入 `hub_settings.json`，重启 hub 后仍生效。
- **添加交易所**：见下文 §4.5（须先自建 Flask + agent，再在中控登记）。
- **删**：从列表移除（保存后生效）。

#### 能力与「策略交易」的关系（重要）

| 能力勾选 | 中控监控区 | 策略交易（趋势回调 / 顺势加仓） |
|----------|------------|----------------------------------|
| 监控关键位 | 显示关键位块 | **不控制**；在实例页 `/key_monitor` |
| 监控趋势计划 | 显示趋势计划块 | **不控制**；在实例页 `/strategy` 左栏操作 |
| 均未勾选 | 仅持仓、余额、机器人单 | 仍可在实例网页使用策略交易 |

四所 Flask 均已注册 `hub_bridge` 且 **`has_trend=true`**，勾选「监控趋势计划」后才会从 `/api/hub/monitor` 拉取趋势数据。修改勾选后 **保存即可**，须 **重启对应 Flask** 仅在你刚升级了 `hub_bridge` 相关代码时。

---

### 4.5 增加账户（例如再挂一个 Gate）

中控 **不会** 自动启动进程，也 **不** 保存交易所 API Key。新增一户 = **复制/新建一套实例目录 + 独立 `.env` + 新端口 Flask/agent + 在中控登记一行**。

#### 4.5.1 端口勿冲突（示例）

| 用途 | 目录（示例） | Flask `APP_PORT` | Agent `PORT` |
|------|----------------|------------------|--------------|
| Gate 训练（已有） | `crypto_monitor_gate` | 5000 | 15202 |
| Gate 趋势（已有） | `crypto_monitor_gate_bot` | 5002 | 15203 |
| **新增 Gate 子账户** | 复制为 `crypto_monitor_gate_2` 等 | **5005**（自定） | **15204**（自定） |

`agent` 的 `PORT` 与 Flask 的 `APP_PORT` **必须不同**；且不要与币安 5001、OKX 5004、中控 5100 等占用端口相同。

#### 4.5.2 新建实例目录

1. 复制整个 `crypto_monitor_gate` 到新目录（仓库内副本或 `/opt/` 下均可）。
2. 在新目录：`cp .env.example .env`，至少修改：
   - `APP_PORT` → 新 Flask 端口（如 5005）
   - `DB_PATH` → 独立库（如 `crypto_gate2.db`），**勿**与 5000/5002 共用 `crypto.db`
   - `GATE_API_KEY` / `GATE_API_SECRET` → **该子账户** 密钥
   - `HUB_BRIDGE_TOKEN` → 与中控、其它实例 **相同**
3. 安装 venv 与依赖（`bash /opt/crypto_monitor/deploy/setup_env.sh --only gate` 或按 Gate 部署文档），启动：

```bash
cd /opt/crypto_monitor/crypto_monitor_gate_2
pm2 start ecosystem.config.cjs
```

4. 在中控 `ecosystem.config.cjs` 增加对应 agent，或单独 `run_agent.sh` 配置后 `pm2 restart`（勿与已有 agent 端口冲突）。

验收：`curl http://127.0.0.1:5005/login` 能开页；`curl http://127.0.0.1:15204/status` 返回 `ok`。

#### 4.5.3 在中控登记

1. 打开 **系统设置** → **添加交易所**（或手改 `manual_trading_hub/hub_settings.json`）。
2. 填写 **Flask URL**、**Agent URL**、**id**（如 `4`）、**显示名**。
3. 能力建议：
   - 训练/关键位户：**监控关键位** + **监控趋势计划**（若也要在中控看趋势计划）；
   - 纯趋势户：只勾 **监控趋势计划**。
4. 勾选 **启用** → **保存设置**。
5. 在 **监控区** 应出现新卡片；点 **实例** 进入该户网页做下单与 **策略交易**。

PM2：仓库 `ecosystem.config.cjs` 默认只有四 agent；第五户需自行 `pm2 start` 或手工终端，与是否改 hub 源码无关。

---

## 5. 能力矩阵（监控展示，建议勾选）

| 账户 | 监控关键位 | 监控趋势计划 | 策略交易（实例页） |
|------|:----------:|:--------------:|:------------------:|
| 币安 | ✓ 建议 | ✓ 建议 | `/strategy` |
| OKX | ✓ 建议 | ✓ 建议 | `/strategy` |
| Gate 训练 | ✓ 建议 | ✓ 建议 | `/strategy` |
| Gate 趋势 | —（通常不勾） | ✓ | `/strategy` |

「建议」表示中控卡片展示对应块；**不勾** 仍可在该实例网页使用关键位或策略交易。

---

## 6. HTTP API 摘要（中控）

访问控制：

- **IP**：默认允许本机与 RFC1918 私网（`HUB_TRUST_LAN=true`）；公网 IP 直连返回 403。
- **登录**：设置 `HUB_PASSWORD` 后须用户名+密码登录（`HUB_USERNAME`，未设时默认 `admin`）；反代到公网时**务必设置**。

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/settings` | 读取配置 |
| POST | `/api/settings` | 保存配置 |
| GET | `/api/monitor/board` | 监控聚合 |
| POST | `/api/close/{id}` | 单户全平 |
| POST | `/api/close-all` | 全局全平，body 可选 `exclude_ids` |
| GET | `/api/auth/status` | 是否需登录、是否已登录 |
| POST | `/api/auth/login` | body `{"username":"...","password":"..."}` |
| POST | `/api/auth/logout` | 退出 |
| GET | `/api/ping` | 版本与健康检查（**免登录**） |
| GET | `/api/chart/meta` | 行情区：交易所、周期、limit |
| GET | `/api/chart/ohlcv` | 行情区 K 线（`exchange_key`、`symbol`、`timeframe`、可选 `refresh=1`） |
| GET | `/api/hub/fund-overview` | 资金概况：总/分户资金、180 日曲线、回撤 |
| GET | `/api/archive/meta` | 内照明心：周期、同步间隔 |
| GET | `/api/archive/daily-trades` | 内照明心：区间交易与统计（`period` / `date_from` / `date_to`） |
| GET | `/api/archive/quotes` | 内照明心：复盘语录 |
| GET | `/api/archive/list` | 币种列表（筛选 query） |
| GET | `/api/archive/detail` | 单币种交易时间线 |
| GET | `/api/archive/ohlcv` | 档案 K 线视窗 |
| PATCH | `/api/archive/trade/{exchange_key}/{trade_id}` | 犯病/情绪标签与备注 |
| POST | `/api/archive/sync` | 立即同步四所交易与 K 线 |

已移除的 `/api/trade/*` 若被旧缓存页面请求，返回 **410** 并提示前往各实例网页。

实例侧（中控只读；下单/关键位/趋势在实例网页）：

| 路径 | 说明 |
|------|------|
| `/api/hub/ping` | 连通与能力 |
| `/api/hub/monitor` | 关键位、机器人单、趋势计划 |
| `/api/hub/ohlcv` | 行情区 OHLCV（ccxt 拉取，供中控聚合缓存） |
| `/api/hub/trades/archive` | 内照明心：近 N 天已平仓（`days` / `limit`） |

---

## 7. 环境变量速查

### 中控 hub.py

| 变量 | 默认 | 说明 |
|------|------|------|
| `HUB_HOST` | `0.0.0.0` | 监听地址 |
| `HUB_PORT` | `5100` | 监听端口 |
| `HUB_BRIDGE_TOKEN` | 空 | Flask 桥接令牌；可同 `CONTROL_TOKEN` |
| `HUB_DISABLED_IDS` | `1` | 逗号分隔，强制关闭的账户 id |
| `HUB_TRUST_LAN` | `true` | `false` 时仅本机可访问中控页面 |
| `HUB_USERNAME` | `admin` | 登录用户名（仅当已设密码时生效） |
| `HUB_PASSWORD` | （空） | 非空即启用 Web 登录 |
| `HUB_SESSION_SECRET` | 用户名+密码 | 会话 Cookie 签名密钥 |
| `HUB_COOKIE_SECURE` | `false` | HTTPS 反代建议 `true`（仅 HTTPS 发 Secure Cookie，HTTP 内网 IP 仍可登） |
| `HUB_SESSION_DAYS` | `7` | 登录保持天数 |
| `HUB_KLINE_RETENTION_DAYS` | `15` | 行情区 K 线库保留天数 |
| `HUB_KLINE_DB_PATH` | `data/hub_kline.db` | K 线 SQLite 路径 |
| `HUB_ARCHIVE_DB_PATH` | `data/hub_symbol_archive.db` | 内照明心永久 K 线库 |
| `HUB_ARCHIVE_SYNC_INTERVAL_SEC` | `14400` | 档案 K 线后台同步间隔（秒） |
| `HUB_ARCHIVE_TRADE_DAYS` | `365` | 同步交易记录回看天数 |
| `HUB_ARCHIVE_TRADE_LIMIT` | `2000` | 单所同步交易条数上限 |

### 子代理 agent.py

| 变量 | 说明 |
|------|------|
| `EXCHANGE` | `binance` / `okx` / `gate` |
| `PORT` / `HOST` | 监听 |
| `CONTROL_TOKEN` | 与中控一致时必填头 `X-Control-Token` |

### 各实例 Flask

| 变量 | 说明 |
|------|------|
| `HUB_BRIDGE_TOKEN` | 与中控一致 |
| `APP_AUTH_DISABLED` | `true` 时跳过登录与令牌（仅建议本机调试） |

---

## 8. 安全与边界

1. **中控不下单**：开仓、关键位、趋势回调仅在各实例网页操作。
2. **全平为市价减仓**：监控区全平不可撤销，操作前二次确认。
3. **子代理建议只监听 127.0.0.1**，不要对局域网暴露 API Key 通道。
4. **公网暴露 hub**：必须设置 `HUB_USERNAME` + `HUB_PASSWORD`；HTTPS 反代建议 `HUB_COOKIE_SECURE=true`；亦可 `HUB_HOST=127.0.0.1` 仅本机监听 + 反代。
5. **复盘不在中控**：时间筛选、导出 CSV、编辑笔记仍在各实例 `/records`。
6. **OKX 默认关**：避免未部署 OKX 时监控卡片持续报错。

---

## 9. 故障排查（速查）

完整实录（含 `api_trade_key`、`multipart`、git 版本、PM2 等）见 **[常见问题.md](./常见问题.md)**。

| 现象 | 可能原因 | 处理 |
|------|----------|------|
| 监控卡片「子代理不可用」 | agent 未启动或端口错 | 检查 Agent URL；`pm2 restart` agent |
| 无关键位/趋势信息 | Flask 未起或 hub_bridge 未加载 | 启动 `crypto_*`；`curl .../api/hub/ping` |
| 全平 401 | `CONTROL_TOKEN` 与中控不一致 | 与 `HUB_BRIDGE_TOKEN` 对齐 |
| OKX 始终灰色 | `HUB_DISABLED_IDS=1` | 改掉环境变量并在设置页启用 |
| 打开即跳转登录 | 已设 `HUB_PASSWORD` | 正常；访问 `/login` |
| 域名能登、IP:5100 不能 | Secure Cookie + HTTP | 见常见问题 §2.1；或分别登录 |
| 添加关键位报错 / SyntaxError | 旧前端或旧 hub 代码 | 强刷浏览器；`git pull` + `verify_hub_deploy.sh` |
| `curl /api/ping` 非 JSON | hub 未启动 | `pm2 restart manual-trading-hub` |
| K 线只有约 300 根 | 旧版未分页 | `git pull` 四实例 + hub，强制刷新 |
| 12h 周期异常 | 无原生 12h 或旧缓存 | 强制刷新；见 [行情区说明.md](./行情区说明.md) |

**运维脚本**（在 `manual_trading_hub` 目录执行）：

| 脚本 | 作用 |
|------|------|
| `scripts/fix_hub_deps.sh` | 安装依赖（含 `python-multipart`） |
| `scripts/verify_hub_deploy.sh` | 检查代码版本与 ping |
| `scripts/fix_env_crlf.sh` | 修复 `.env` 的 CRLF 导致 agent 起不来 |

手动探测实例桥接：

```bash
curl -sS -H "X-Hub-Token: 你的令牌" http://127.0.0.1:5001/api/hub/ping
```

---

## 10. 与旧版 README 的差异

早期中控 **仅监控 + 全平**，使用环境变量 `HUB_AGENTS` 列表。当前版本改为：

- **hub_settings.json**（或内置默认）管理四所 URL 与能力；
- **三页 UI**：监控 / 行情 / 设置；
- 通过 **hub_bridge** 只读聚合监控数据。

子代理 `agent.py` 仍负责持仓与全平；`HUB_AGENTS` 环境变量在新版 hub 中 **不再使用**（以设置文件为准）。

**PM2 守护**：

```bash
cd /opt/crypto_monitor/manual_trading_hub
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
pm2 start ecosystem.config.cjs    # 一次启动 4 个 agent + manual-trading-hub
pm2 save && pm2 startup
```

快捷：`bash scripts/pm2_hub.sh start|restart|logs`（同样 hub+agent 一起）。

更细的安装顺序、反代、验收见 **《部署文档.md》**；PM2 见 **[scripts/后台运行-Ubuntu.md](./scripts/后台运行-Ubuntu.md)**。

---

## 11. 日常推荐流程

1. 启动四所 **agent** + **Flask**（OKX 按需）。
2. 启动 **hub.py**，打开监控区确认持仓与关键位门控正常。
3. 看 K 线 → **行情区** 或监控区点击合约名跳转；异常图表点 **强制刷新**。
4. 开仓、关键位、趋势 → 点击监控卡片「实例」进入对应 Flask。
5. 复盘、导出记录 → 点击「复盘」进入 `/records`。
6. 异常行情 → 单户全平或全局紧急全平。

增加账户步骤见 **§4.4**；无需改 `hub.py` 源码，但须该户 Flask 已 `git pull` 并 **重启**（`hub_bridge` + `has_trend` + `ohlcv`），且 agent 已部署。

---

## 12. 文档索引

| 文档 | 内容 |
|------|------|
| [使用说明.md](./使用说明.md) | 本文 |
| [行情区说明.md](./行情区说明.md) | K 线周期、缓存、快捷键、API |
| [开仓计划说明.md](./开仓计划说明.md) | 计划录入、归档、胜率统计 |
| [docs/hub-symbol-archive-kline.md](../docs/hub-symbol-archive-kline.md) | 内照明心、区间统计、永久 5m、建档与同步 |
| [部署文档.md](./部署文档.md) | Ubuntu / PM2 / 反代 |
| [常见问题.md](./常见问题.md) | 故障实录与排障 |
| [README.md](./README.md) | 速览 |
| [.env.example](./.env.example) | 环境变量模板 |
| [scripts/后台运行-Ubuntu.md](./scripts/后台运行-Ubuntu.md) | PM2 常驻 |
| [docs/ubuntu-server.md](../docs/ubuntu-server.md) | Ubuntu 环境总览 |
