diff --git a/README.md b/README.md
index 8db7949..8c602f5 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ cd crypto_monitor
- **中控** `hub.py`(`:5100`):多账户 **监控聚合**、**紧急全平**、系统设置;可选 **用户名+密码** 登录(反代公网时务必配置)。
- **子代理** `agent.py`:每账户一进程,默认 **`15200`~`15203`**,与四所 Flask **`APP_PORT`**(5000/5001/5002/5004)**必须错开**。
-- **下单、关键位、趋势、复盘**:在各 `crypto_monitor_*` 原网页操作(中控监控卡片 **「实例」** / **「复盘」**);中控**已移除下单区**。
+- **下单、关键位、策略交易、复盘**:在各 `crypto_monitor_*` 原网页操作(中控 **「实例」** / **「复盘」**);中控**已移除下单区**。增加子账户见 [manual_trading_hub/使用说明.md §4.3](./manual_trading_hub/使用说明.md#43-增加账户例如再挂一个-gate)。
- 账户列表由 **`hub_settings.json`**(网页「系统设置」)维护,**不再使用** `HUB_AGENTS`。
- 部署与排障:[manual_trading_hub/README.md](./manual_trading_hub/README.md)、[常见问题.md](./manual_trading_hub/常见问题.md)。
diff --git a/crypto_monitor_binance/app.py b/crypto_monitor_binance/app.py
index 44e1354..2b7254c 100644
--- a/crypto_monitor_binance/app.py
+++ b/crypto_monitor_binance/app.py
@@ -7665,7 +7665,7 @@ try:
app,
exchange="binance",
capabilities=["order", "key"],
- has_trend=False,
+ has_trend=True,
get_db=get_db,
row_to_dict=row_to_dict,
meta_fn=_hub_meta_bundle,
diff --git a/crypto_monitor_gate/app.py b/crypto_monitor_gate/app.py
index 02999e6..96cf117 100644
--- a/crypto_monitor_gate/app.py
+++ b/crypto_monitor_gate/app.py
@@ -7752,7 +7752,7 @@ try:
app,
exchange="gate",
capabilities=["order", "key"],
- has_trend=False,
+ has_trend=True,
get_db=get_db,
row_to_dict=row_to_dict,
meta_fn=_hub_meta_bundle,
diff --git a/crypto_monitor_okx/app.py b/crypto_monitor_okx/app.py
index 3535c41..1be28da 100644
--- a/crypto_monitor_okx/app.py
+++ b/crypto_monitor_okx/app.py
@@ -5942,7 +5942,7 @@ try:
app,
exchange="okx",
capabilities=["order", "key"],
- has_trend=False,
+ has_trend=True,
get_db=get_db,
row_to_dict=row_to_dict,
meta_fn=_hub_meta_bundle,
diff --git a/manual_trading_hub/README.md b/manual_trading_hub/README.md
index e17e551..c46bfd6 100644
--- a/manual_trading_hub/README.md
+++ b/manual_trading_hub/README.md
@@ -2,7 +2,7 @@
> **完整说明**:[使用说明.md](./使用说明.md) · **部署**:[部署文档.md](./部署文档.md) · **故障实录**:[常见问题.md](./常见问题.md)
-多账户 **监控聚合 + 紧急全平**;**不在中控网页下单**。人工下单、关键位、趋势回调、复盘请在各 `crypto_monitor_*` 实例原网页操作(监控卡片 **「实例」** / **「复盘」** 跳转)。
+多账户 **监控聚合 + 紧急全平**;**不在中控网页下单**。人工下单、关键位、**策略交易**(`/strategy`)、复盘请在各 `crypto_monitor_*` 实例网页操作(监控卡片 **「实例」** / **「复盘」**)。**增加子账户**见 [使用说明 §4.3](./使用说明.md#43-增加账户例如再挂一个-gate)。
---
@@ -12,7 +12,7 @@
|------|------|
| 监控区 | 持仓、余额、关键位摘要、趋势计划、机器人单(只读) |
| 紧急全平 | 单户 / 全局市价减仓 |
-| 系统设置 | `hub_settings.json` 管理四所 URL、启用状态、监控能力 |
+| 系统设置 | `hub_settings.json` 管理 URL、启用、**监控关键位 / 监控趋势计划**(不控制策略交易页) |
| Web 登录 | `.env` 设 `HUB_PASSWORD` 后用户名+密码保护(反代公网**务必**配置) |
| ~~下单区~~ | **已移除**(避免与实例重复、减少故障面) |
diff --git a/manual_trading_hub/settings_store.py b/manual_trading_hub/settings_store.py
index 4564ac3..a124808 100644
--- a/manual_trading_hub/settings_store.py
+++ b/manual_trading_hub/settings_store.py
@@ -18,7 +18,7 @@ DEFAULT_EXCHANGES = [
"flask_url": "http://127.0.0.1:5001",
"review_url": "http://127.0.0.1:5001/records",
"enabled": True,
- "capabilities": ["order", "key"],
+ "capabilities": ["key", "trend"],
},
{
"id": "1",
@@ -28,7 +28,7 @@ DEFAULT_EXCHANGES = [
"flask_url": "http://127.0.0.1:5004",
"review_url": "http://127.0.0.1:5004/records",
"enabled": False,
- "capabilities": ["order", "key"],
+ "capabilities": ["key", "trend"],
},
{
"id": "2",
@@ -38,7 +38,7 @@ DEFAULT_EXCHANGES = [
"flask_url": "http://127.0.0.1:5000",
"review_url": "http://127.0.0.1:5000/records",
"enabled": True,
- "capabilities": ["order", "key"],
+ "capabilities": ["key", "trend"],
},
{
"id": "3",
@@ -48,7 +48,7 @@ DEFAULT_EXCHANGES = [
"flask_url": "http://127.0.0.1:5002",
"review_url": "http://127.0.0.1:5002/records",
"enabled": True,
- "capabilities": ["order", "trend"],
+ "capabilities": ["trend"],
},
]
diff --git a/manual_trading_hub/static/app.js b/manual_trading_hub/static/app.js
index b369c0c..549ceab 100644
--- a/manual_trading_hub/static/app.js
+++ b/manual_trading_hub/static/app.js
@@ -192,7 +192,7 @@
});
}
}
- if (trends.length) {
+ if ((row.capabilities || []).includes("trend") && trends.length) {
inner += `
趋势计划 · ${trends.length}
`;
trends.forEach((t) => {
inner += `#${t.id} ${esc(t.symbol)} ${t.direction} · SL ${t.stop_loss} · TP ${t.take_profit}
`;
@@ -276,21 +276,26 @@
} catch (_) {}
}
+ function renderSettingsList(data) {
+ const list = document.getElementById("settings-list");
+ if (!list) return;
+ list.innerHTML = (data.exchanges || [])
+ .map((ex, idx) => renderSettingsCard(ex, idx))
+ .join("");
+ list.querySelectorAll(".btn-del-ex").forEach((btn) => {
+ btn.onclick = () => {
+ const i = Number(btn.dataset.idx);
+ data.exchanges.splice(i, 1);
+ settingsCache = data;
+ renderSettingsList(data);
+ };
+ });
+ }
+
function loadSettingsUI() {
loadSettingsMetaLine();
loadSettings().then((data) => {
- const list = document.getElementById("settings-list");
- document.getElementById("settings-list").innerHTML = (data.exchanges || [])
- .map((ex, idx) => renderSettingsCard(ex, idx))
- .join("");
- list.querySelectorAll(".btn-del-ex").forEach((btn) => {
- btn.onclick = () => {
- const i = Number(btn.dataset.idx);
- data.exchanges.splice(i, 1);
- settingsCache = data;
- loadSettingsUI();
- };
- });
+ renderSettingsList(data);
});
}
@@ -389,7 +394,7 @@
capabilities: ["key"],
});
settingsCache = data;
- loadSettingsUI();
+ renderSettingsList(data);
};
initAuth().then((ok) => {
diff --git a/manual_trading_hub/使用说明.md b/manual_trading_hub/使用说明.md
index 72dd73b..c885043 100644
--- a/manual_trading_hub/使用说明.md
+++ b/manual_trading_hub/使用说明.md
@@ -1,6 +1,6 @@
# 多账户交易中控 — 使用说明
-本文档说明 **manual_trading_hub** 的架构、启动方式、界面操作与故障排查。中控聚合四所 **持仓/余额/关键位/趋势计划监控 + 紧急全平**;**人工下单、添加关键位、趋势回调、交易复盘** 均在各实例网页操作。
+本文档说明 **manual_trading_hub** 的架构、启动方式、界面操作与故障排查。中控聚合四所 **持仓/余额/关键位/趋势计划监控 + 紧急全平**;**人工下单、关键位、策略交易(趋势回调 / 顺势加仓)、交易复盘** 均在各实例网页操作(点监控卡片 **「实例」**)。
---
@@ -29,9 +29,10 @@
| 0 | 币安 | :5001 | :15200 | 关键位 | 是 |
| 1 | OKX | :5004 | :15201 | 关键位 | **否**(`HUB_DISABLED_IDS=1`) |
| 2 | Gate 训练 | :5000 | :15202 | 关键位 | 是 |
-| 3 | Gate 趋势 | :5002 | :15203 | 趋势计划 | 是 |
+| 3 | Gate 趋势 | :5002 | :15203 | 趋势计划(默认不勾关键位) | 是 |
-- **Gate 趋势户**:监控区展示**趋势计划**;**不展示关键位**(capabilities 无 `key`)。人工下单、趋势回调、关键位均在各实例网页操作。
+- **Gate 趋势户**:默认只勾 **监控趋势计划**;一般不勾关键位(该户多用于趋势回调)。策略操作在实例 **`/strategy`**。
+- **币安 / Gate 训练 / OKX**:四所均已支持 **策略交易**;中控可同时勾 **监控关键位** + **监控趋势计划**(见 §4.2、§5)。
- **OKX**:默认关闭;需要时在「系统设置」勾选启用,并去掉环境变量 `HUB_DISABLED_IDS` 中的 `1`。
### 1.2 实例侧改动(最小)
@@ -178,8 +179,8 @@ curl -s http://127.0.0.1:5100/api/ping
| **2×2 卡片** | 仅显示「已启用」账户;每卡含子代理持仓、浮盈、余额 |
| **机器人持仓** | 来自实例 `/api/hub/monitor` 的 `order_monitors`(active) |
| **关键位** | 仅 `capabilities` 含 `key` 的户;展示门控摘要(`/api/price_snapshot`) |
-| **趋势计划** | 仅 Gate 趋势户;`trend_pullback_plans` active |
-| **实例 / 复盘** | 「实例」→ 该户 Flask(**下单、关键位、趋势**均在此操作);「复盘」→ `/records`。若配置 **`HUB_PUBLIC_ORIGIN`**,外链替换 `127.0.0.1` |
+| **趋势计划** | 仅当该户勾选 **监控趋势计划** 时展示 `trend_pullback_plans`(active) |
+| **实例 / 复盘** | 「实例」→ 该户 Flask(**实盘下单、关键位、策略交易 `/strategy`、复盘**);「复盘」→ `/records`。若配置 **`HUB_PUBLIC_ORIGIN`**,外链替换 `127.0.0.1` |
| **关键位列表** | 来自 `/api/hub/monitor` + `/api/price_snapshot`;Flask 未连通时卡片提示原因;**Gate 趋势户**无关键位块 |
| **该户全平** | `POST` 子代理 `/emergency/close-all`,仅平该 API Key 仓位 |
| **全局紧急全平** | 对所有已启用户依次全平(不含 `HUB_DISABLED_IDS` 强制关闭的 id) |
@@ -191,7 +192,7 @@ curl -s http://127.0.0.1:5100/api/ping
**可用**:打开 http://127.0.0.1:5100/settings ,修改表格后点 **保存设置** 即写入 `hub_settings.json`;**重新加载** 从磁盘/默认再读(会重新套用 `HUB_DISABLED_IDS`)。保存后监控区立即使用新 URL/启用状态,**无需重启 hub**。
-**下单与关键位**:请在监控卡片点击「实例」,进入各 `crypto_monitor_*` 网页操作(与中控上线前相同)。
+**下单、关键位、策略交易**:请在监控卡片点击 **「实例」**,进入各 `crypto_monitor_*` 网页(`/trade`、`/key_monitor`、`/strategy` 等)。中控 **不** 提供下单区。
| 列 | 含义 |
|----|------|
@@ -200,23 +201,91 @@ curl -s http://127.0.0.1:5100/api/ping
| Flask URL | 实例根地址,如 `http://127.0.0.1:5001` |
| Agent URL | 子代理根地址,如 `http://127.0.0.1:15200` |
| 复盘链接 | 一般为 `{Flask}/records` |
-| 能力 | 勾选「监控关键位」「监控趋势计划」,控制监控卡片展示块 |
-| id | 与 `HUB_DISABLED_IDS`、全平 API 路径中的 id 对应 |
+| **监控关键位** | 勾选后卡片展示 **关键位** 列表 + 门控价(读 Flask `/api/price_snapshot`) |
+| **监控趋势计划** | 勾选后卡片展示 **趋势回调** 运行中计划(`trend_pullback_plans` active) |
+| id | 与 `HUB_DISABLED_IDS`、全平 API 路径中的 id 对应;新增户勿与已有 id 重复 |
- **保存设置**:写入 `hub_settings.json`,重启 hub 后仍生效。
-- **添加交易所**:可增第五所等,需自行启动对应 Flask + agent 并填写 URL。
+- **添加交易所**:见下文 §4.3(须先自建 Flask + agent,再在中控登记)。
- **删**:从列表移除(保存后生效)。
+#### 能力与「策略交易」的关系(重要)
+
+| 能力勾选 | 中控监控区 | 策略交易(趋势回调 / 顺势加仓) |
+|----------|------------|----------------------------------|
+| 监控关键位 | 显示关键位块 | **不控制**;在实例页 `/key_monitor` |
+| 监控趋势计划 | 显示趋势计划块 | **不控制**;在实例页 `/strategy` 左栏操作 |
+| 均未勾选 | 仅持仓、余额、机器人单 | 仍可在实例网页使用策略交易 |
+
+四所 Flask 均已注册 `hub_bridge` 且 **`has_trend=true`**,勾选「监控趋势计划」后才会从 `/api/hub/monitor` 拉取趋势数据。修改勾选后 **保存即可**,须 **重启对应 Flask** 仅在你刚升级了 `hub_bridge` 相关代码时。
+
---
-## 5. 能力矩阵(监控展示)
+### 4.3 增加账户(例如再挂一个 Gate)
-| 账户 | 监控关键位 | 监控趋势计划 |
-|------|:----------:|:--------------:|
-| 币安 | ✓ | — |
-| OKX | ✓ | — |
-| Gate 训练 | ✓ | — |
-| Gate 趋势 | — | ✓ |
+中控 **不会** 自动启动进程,也 **不** 保存交易所 API Key。新增一户 = **复制/新建一套实例目录 + 独立 `.env` + 新端口 Flask/agent + 在中控登记一行**。
+
+#### 4.3.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.3.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 与依赖(与 Gate 部署文档相同),启动:
+
+```powershell
+cd crypto_monitor_gate_2
+$env:PYTHONPATH=".."
+python app.py
+```
+
+4. 另开终端,**cwd 必须为新目录**,启动子代理:
+
+```powershell
+cd crypto_monitor_gate_2
+$env:EXCHANGE="gate"
+$env:PORT="15204"
+python ..\manual_trading_hub\agent.py
+```
+
+验收:`curl http://127.0.0.1:5005/login` 能开页;`curl http://127.0.0.1:15204/status` 返回 `ok`。
+
+#### 4.3.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` |
+
+「建议」表示中控卡片展示对应块;**不勾** 仍可在该实例网页使用关键位或策略交易。
---
@@ -363,7 +432,7 @@ pm2 save && pm2 startup
4. 复盘、导出记录 → 点击「复盘」进入 `/records`。
5. 异常行情 → 单户全平或全局紧急全平。
-如有新交易所,在 **系统设置** 添加一行并勾选能力,无需修改 hub.py 源码(需该所有 Flask 注册 `hub_bridge` 且 agent 已部署)。
+增加账户步骤见 **§4.3**;无需改 `hub.py` 源码,但须该户 Flask 已 `git pull` 并 **重启**(`hub_bridge` + `has_trend`),且 agent 已部署。
---
diff --git a/manual_trading_hub/常见问题.md b/manual_trading_hub/常见问题.md
index 1197230..676a11d 100644
--- a/manual_trading_hub/常见问题.md
+++ b/manual_trading_hub/常见问题.md
@@ -162,7 +162,7 @@ HUB_PUBLIC_ORIGIN=http://192.168.8.6
### 5.2 中控监控区 Gate 趋势户「无关键位」
-**设计如此**:Gate 趋势户 capabilities 为趋势,不含 `key`;关键位在 Gate 训练户(`crypto_monitor_gate`)。
+**设计如此**:Gate 趋势户通常只勾 **监控趋势计划**,不勾关键位;关键位在 Gate 训练户。四所 **策略交易** 均在各实例 `/strategy`,与中控勾选无关。增加 Gate 子账户见 [使用说明.md](./使用说明.md) **§4.3**。
---
diff --git a/manual_trading_hub/部署文档.md b/manual_trading_hub/部署文档.md
index 7229d80..9f5e851 100644
--- a/manual_trading_hub/部署文档.md
+++ b/manual_trading_hub/部署文档.md
@@ -166,7 +166,7 @@ bash scripts/run_hub.sh
1. **http://127.0.0.1:5100/login** — 若 `.env` 已设 `HUB_PASSWORD`,用 `HUB_USERNAME` / `HUB_PASSWORD` 登录。
2. **http://127.0.0.1:5100/monitor** — 已启用账户显示持仓;Flask 已起时有关键位/趋势信息。
-3. **http://127.0.0.1:5100/settings** — 保存后生成 `hub_settings.json`。
+3. **http://127.0.0.1:5100/settings** — 保存后生成 `hub_settings.json`(增加第五户、Gate 子账户等见 [使用说明.md §4.3](./使用说明.md#43-增加账户例如再挂一个-gate))。
4. 监控卡片 **「实例」** — 在各 `crypto_monitor_*` 网页做下单、关键位、趋势;中控**不提供**下单表单。
**命令行验收**(推荐):