refactor: 移除 gate_bot,统一为三所架构并更新文档
删除 crypto_monitor_gate_bot 目录,中控与子代理改为 binance/okx/gate 三账户; 文档与 UI 文案「四所」改为「三所」;新增清库前一次性配置备份脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,7 +9,7 @@ HUB_HOST=0.0.0.0
|
||||
HUB_PORT=5100
|
||||
# 仅本机访问可改为 127.0.0.1,并设 HUB_TRUST_LAN=false
|
||||
|
||||
# 与四实例 .env 中 HUB_BRIDGE_TOKEN 相同的长随机串
|
||||
# 与三实例 .env 中 HUB_BRIDGE_TOKEN 相同的长随机串
|
||||
# 中控 → 各 Flask:请求头 X-Hub-Token
|
||||
# 中控 → 各子代理:请求头 X-Control-Token(可与子代理 CONTROL_TOKEN 同值,hub 会用 HUB_BRIDGE_TOKEN 转发)
|
||||
# 中控「打开实例」SSO 链接也复用此令牌签名(默认 2 小时内有效、单次使用)
|
||||
@@ -41,10 +41,10 @@ HUB_PASSWORD=admin123
|
||||
# 限制可嵌入的父页来源(逗号分隔);默认 * 不限制
|
||||
# HUB_EMBED_ORIGINS=http://192.168.8.6:5070,https://hub.example.com
|
||||
|
||||
# 四实例允许被中控 iframe 内嵌(各 crypto_monitor_*/.env,与 hub 同步部署)
|
||||
# 三实例允许被中控 iframe 内嵌(各 crypto_monitor_*/.env,与 hub 同步部署)
|
||||
# APP_ALLOW_HUB_EMBED=true
|
||||
# HUB_EMBED_PARENT_ORIGINS=https://hub.example.com
|
||||
# HTTPS 跨子域 iframe 时四实例还须 APP_COOKIE_SECURE=true(见 crypto_monitor_*/.env.example)
|
||||
# HTTPS 跨子域 iframe 时三实例还须 APP_COOKIE_SECURE=true(见 crypto_monitor_*/.env.example)
|
||||
|
||||
# 浏览器打开的实例/复盘链接(hub_settings 里 flask_url 为 127.0.0.1 时替换为对外地址)
|
||||
# 局域网:填内网 IP,见《局域网与反代部署说明.md》
|
||||
@@ -53,7 +53,7 @@ HUB_PASSWORD=admin123
|
||||
# HUB_PUBLIC_HOST=192.168.1.100
|
||||
# HUB_PUBLIC_SCHEME=http
|
||||
|
||||
# 四实例网页登录(直链反代/IP:端口 访问时输入;中控点「打开实例」免输)
|
||||
# 三实例网页登录(直链反代/IP:端口 访问时输入;中控点「打开实例」免输)
|
||||
# 各 crypto_monitor_*/.env 统一:APP_USERNAME=... APP_PASSWORD=...
|
||||
|
||||
# 监控区:hub 后台每 N 秒聚合一次,浏览器经 SSE 收版本号再拉快照(默认 5 秒)
|
||||
@@ -82,7 +82,7 @@ HUB_PASSWORD=admin123
|
||||
# HOST=127.0.0.1
|
||||
|
||||
# ---------- 中控 AI 教练(/ai,模块 hub_ai/,存 hub_ai_*.json)----------
|
||||
# 与四实例相同变量名;默认 OpenAI 兼容网关(改 AI_PROVIDER=ollama 可走本机 Ollama)
|
||||
# 与三实例相同变量名;默认 OpenAI 兼容网关(改 AI_PROVIDER=ollama 可走本机 Ollama)
|
||||
# 详见 manual_trading_hub/AI教练说明.md 与仓库根 AI复盘与模型配置说明.md
|
||||
AI_TIMEOUT_SECONDS=120
|
||||
# AI 教练聊天(默认:输出 8192 token、续写 4 次、快照约 2 万字符、历史单条 1500 字)
|
||||
@@ -102,7 +102,7 @@ OPENAI_MODEL=gemma4:e4b
|
||||
OLLAMA_API=http://127.0.0.1:11434/api/generate
|
||||
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
|
||||
|
||||
# 交易日切分(与四实例 TRADING_DAY_RESET_HOUR 一致,定义「今日总结」的日期)
|
||||
# 交易日切分(与三实例 TRADING_DAY_RESET_HOUR 一致,定义「今日总结」的日期)
|
||||
TRADING_DAY_RESET_HOUR=8
|
||||
# 资金概况 / AI 上下文:分户资金快照保留交易日数(默认 180)
|
||||
# HUB_FUND_HISTORY_DAYS=180
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
# 中控 AI 教练说明
|
||||
|
||||
中控 **AI 教练**(`/ai`)与四实例 `/records` 里的 **AI 复盘** 分离:模块在 `manual_trading_hub/hub_ai/`,数据存同目录 JSON。
|
||||
|
||||
## 能力
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| **交易教练** | 口语化陪聊;注入四户监控快照与今日总结摘要(后台自动生成,不在页面展示) |
|
||||
| **普通聊天** | 不绑交易数据,适合闲聊、答疑 |
|
||||
| **交易监管** | 今日长会话;手动/中控开平仓与新开仓自动推送 + 企业微信 + 可回聊(见 [交易监管说明.md](./交易监管说明.md)) |
|
||||
| **会话历史** | 右侧列表:切换、删除;消息一键复制 |
|
||||
|
||||
页面保留 **交易教练 / 普通聊天 / 交易监管** 与聊天区;**今日总结** 已移至 **数据看板**(`/dashboard`)纯数据展示,不再在 AI 页生成。
|
||||
|
||||
## 存储
|
||||
|
||||
与 `hub_settings.json` 同目录(`manual_trading_hub/`):
|
||||
|
||||
- `hub_ai_summaries.json` — 历史总结(供交易教练上下文,可选 API 仍保留)
|
||||
- `hub_ai_chat.json` — 聊天会话(`active_session_id`、多会话、`bot_mode`)
|
||||
|
||||
升级 / 迁移时请一并备份(见 [本地数据迁移到云端.md](./本地数据迁移到云端.md))。
|
||||
|
||||
## 模型配置
|
||||
|
||||
在 **`manual_trading_hub/.env`** 配置,**变量名与四实例完全相同**;中控 `hub_ai/client.py` 共用仓库根 `ai_client.py`,**默认也是 OpenAI 兼容网关**(`AI_PROVIDER=openai`),与你在四所 `.env` 里配的那套一致即可。
|
||||
|
||||
**推荐(与四实例默认一致):**
|
||||
|
||||
```env
|
||||
AI_PROVIDER=openai
|
||||
OPENAI_API_BASE=https://op.bz121.com/v1
|
||||
OPENAI_API_KEY=你的密钥
|
||||
OPENAI_MODEL=gemma4:e4b
|
||||
|
||||
# 本机 Ollama 备用(仅当 AI_PROVIDER=ollama 时生效)
|
||||
OLLAMA_API=http://127.0.0.1:11434/api/generate
|
||||
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
|
||||
```
|
||||
|
||||
改走本机无限制模型时,将 `AI_PROVIDER=ollama`,并填好 `OLLAMA_API` / `AI_MODEL`;`OPENAI_*` 可保留不动。
|
||||
|
||||
总结与聊天使用**同一模型**(同一套 `OPENAI_MODEL` 或 `AI_MODEL`);总结 temperature≈0.15,聊天≈0.5。
|
||||
|
||||
可选:`TRADING_DAY_RESET_HOUR=8`(与实例一致,定义「今日」交易日)。
|
||||
|
||||
## 依赖接口
|
||||
|
||||
中控通过 HTTP 拉取各实例:
|
||||
|
||||
- `GET /api/hub/monitor`(已有)
|
||||
- `GET /api/hub/trades/today?trading_day=YYYY-MM-DD`(`hub_bridge` 注册,需四实例更新代码并重启)
|
||||
|
||||
子代理 `GET /status` 提供持仓与余额。
|
||||
|
||||
## 与实例 AI 复盘的分工
|
||||
|
||||
| | 中控 AI 教练 | 实例 AI 复盘 |
|
||||
|--|-------------|-------------|
|
||||
| 入口 | `/ai` | 各所 `/records` |
|
||||
| 数据 | 四户聚合 | 单户 `journal_entries` |
|
||||
| 语气 | 聊天搭档 | 结构化教练报告 |
|
||||
| 代码 | `hub_ai/*` | `ai_review_lib` + 各 `app.py` |
|
||||
|
||||
详见仓库根 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)(实例侧)。
|
||||
# 中控 AI 教练说明
|
||||
|
||||
中控 **AI 教练**(`/ai`)与三实例 `/records` 里的 **AI 复盘** 分离:模块在 `manual_trading_hub/hub_ai/`,数据存同目录 JSON。
|
||||
|
||||
## 能力
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| **交易教练** | 口语化陪聊;注入三户监控快照与今日总结摘要(后台自动生成,不在页面展示) |
|
||||
| **普通聊天** | 不绑交易数据,适合闲聊、答疑 |
|
||||
| **交易监管** | 今日长会话;手动/中控开平仓与新开仓自动推送 + 企业微信 + 可回聊(见 [交易监管说明.md](./交易监管说明.md)) |
|
||||
| **会话历史** | 右侧列表:切换、删除;消息一键复制 |
|
||||
|
||||
页面保留 **交易教练 / 普通聊天 / 交易监管** 与聊天区;**今日总结** 已移至 **数据看板**(`/dashboard`)纯数据展示,不再在 AI 页生成。
|
||||
|
||||
## 存储
|
||||
|
||||
与 `hub_settings.json` 同目录(`manual_trading_hub/`):
|
||||
|
||||
- `hub_ai_summaries.json` — 历史总结(供交易教练上下文,可选 API 仍保留)
|
||||
- `hub_ai_chat.json` — 聊天会话(`active_session_id`、多会话、`bot_mode`)
|
||||
|
||||
升级 / 迁移时请一并备份(见 [本地数据迁移到云端.md](./本地数据迁移到云端.md))。
|
||||
|
||||
## 模型配置
|
||||
|
||||
在 **`manual_trading_hub/.env`** 配置,**变量名与三实例完全相同**;中控 `hub_ai/client.py` 共用仓库根 `ai_client.py`,**默认也是 OpenAI 兼容网关**(`AI_PROVIDER=openai`),与你在三所 `.env` 里配的那套一致即可。
|
||||
|
||||
**推荐(与三实例默认一致):**
|
||||
|
||||
```env
|
||||
AI_PROVIDER=openai
|
||||
OPENAI_API_BASE=https://op.bz121.com/v1
|
||||
OPENAI_API_KEY=你的密钥
|
||||
OPENAI_MODEL=gemma4:e4b
|
||||
|
||||
# 本机 Ollama 备用(仅当 AI_PROVIDER=ollama 时生效)
|
||||
OLLAMA_API=http://127.0.0.1:11434/api/generate
|
||||
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
|
||||
```
|
||||
|
||||
改走本机无限制模型时,将 `AI_PROVIDER=ollama`,并填好 `OLLAMA_API` / `AI_MODEL`;`OPENAI_*` 可保留不动。
|
||||
|
||||
总结与聊天使用**同一模型**(同一套 `OPENAI_MODEL` 或 `AI_MODEL`);总结 temperature≈0.15,聊天≈0.5。
|
||||
|
||||
可选:`TRADING_DAY_RESET_HOUR=8`(与实例一致,定义「今日」交易日)。
|
||||
|
||||
## 依赖接口
|
||||
|
||||
中控通过 HTTP 拉取各实例:
|
||||
|
||||
- `GET /api/hub/monitor`(已有)
|
||||
- `GET /api/hub/trades/today?trading_day=YYYY-MM-DD`(`hub_bridge` 注册,需三实例更新代码并重启)
|
||||
|
||||
子代理 `GET /status` 提供持仓与余额。
|
||||
|
||||
## 与实例 AI 复盘的分工
|
||||
|
||||
| | 中控 AI 教练 | 实例 AI 复盘 |
|
||||
|--|-------------|-------------|
|
||||
| 入口 | `/ai` | 各所 `/records` |
|
||||
| 数据 | 三户聚合 | 单户 `journal_entries` |
|
||||
| 语气 | 聊天搭档 | 结构化教练报告 |
|
||||
| 代码 | `hub_ai/*` | `ai_review_lib` + 各 `app.py` |
|
||||
|
||||
详见仓库根 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)(实例侧)。
|
||||
|
||||
+105
-106
@@ -1,106 +1,105 @@
|
||||
# 复盘系统中控(manual_trading_hub)
|
||||
|
||||
> **完整说明**:[使用说明.md](./使用说明.md) · **资金概况**:[资金概况说明.md](./资金概况说明.md) · **数据看板**:[数据看板说明.md](./数据看板说明.md) · **AI 教练**:[AI教练说明.md](./AI教练说明.md) · **行情区**:[行情区说明.md](./行情区说明.md) · **部署**:[部署文档.md](./部署文档.md) · **云服务器**:[云服务器部署说明.md](./云服务器部署说明.md) · **本地→云端迁移**:[本地数据迁移到云端.md](./本地数据迁移到云端.md) · **局域网/反代**:[局域网与反代部署说明.md](./局域网与反代部署说明.md) · **故障**:[常见问题.md](./常见问题.md)
|
||||
|
||||
多账户 **监控聚合 + 紧急全平**;**不在中控网页下单**。人工下单、关键位、**策略交易**(`/strategy`)、复盘请在各 `crypto_monitor_*` 实例网页操作(监控卡片 **「实例」** / **「复盘」**)。**增加子账户**见 [使用说明 §4.3](./使用说明.md#43-增加账户例如再挂一个-gate)。
|
||||
|
||||
---
|
||||
|
||||
## 当前能力
|
||||
|
||||
| 能力 | 说明 |
|
||||
|------|------|
|
||||
| 监控区 | 持仓、余额、关键位摘要、趋势计划、机器人单(只读) |
|
||||
| 资金概况 | 总/分户资金(资金户+交易户)、180 日曲线、最大回撤 |
|
||||
| **数据看板** | 四户当日总览/分户/平仓明细,SSE 推送(`/dashboard`;见 [数据看板说明.md](./数据看板说明.md)) |
|
||||
| 行情区 | K 线(多周期、本地缓存、技术指标、从监控跳转持仓线) |
|
||||
| **AI 教练** | 交易教练 + 普通聊天、会话历史(`/ai`;见 [AI教练说明.md](./AI教练说明.md)) |
|
||||
| 紧急全平 | 单户 / 全局市价减仓 |
|
||||
| 系统设置 | `hub_settings.json` 管理 URL、启用、**监控关键位 / 监控趋势计划**(不控制策略交易页) |
|
||||
| Web 登录 | `.env` 设 `HUB_PASSWORD` 后用户名+密码保护(反代公网**务必**配置) |
|
||||
| ~~下单区~~ | **已移除**(避免与实例重复、减少故障面) |
|
||||
|
||||
---
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
浏览器 → hub.py (:5100) 监控 / 资金概况 / **数据看板** / 行情 / **AI 教练** / 设置 / 登录
|
||||
├→ agent.py × N (:15200~15203) 持仓、全平
|
||||
└→ 各 Flask (:5000/5001/5002/5004) /api/hub/monitor 只读聚合
|
||||
```
|
||||
|
||||
- 账户列表:**系统设置** 或默认 `settings_store.py`(不再使用环境变量 `HUB_AGENTS`)。
|
||||
- 四实例须注册 **hub_bridge**(仓库根 `hub_bridge.py`);PM2 建议 `PYTHONPATH=..`。
|
||||
|
||||
---
|
||||
|
||||
## 快速启动(Linux / 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
|
||||
# 编辑 .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`(行情 `/market`;已设密码则先 `/login`)。
|
||||
|
||||
---
|
||||
|
||||
## 中控 `.env` 要点
|
||||
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `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.example](./.env.example)。
|
||||
|
||||
---
|
||||
|
||||
## 子代理(agent)
|
||||
|
||||
每所策略目录单独进程,`EXCHANGE` + `PORT`(15200~15203),密钥来自**该目录 `.env`**。PM2 经 `scripts/run_agent.sh` 启动(自动 `source .env`、去 CRLF)。
|
||||
|
||||
| PORT | 目录 |
|
||||
|------|------|
|
||||
| 15200 | crypto_monitor_binance |
|
||||
| 15201 | crypto_monitor_okx |
|
||||
| 15202 | crypto_monitor_gate |
|
||||
| 15203 | crypto_monitor_gate_bot |
|
||||
|
||||
---
|
||||
|
||||
## 运维脚本
|
||||
|
||||
| 脚本 | 作用 |
|
||||
|------|------|
|
||||
| [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) | PM2 常驻 |
|
||||
| [docs/ubuntu-server.md](../docs/ubuntu-server.md) | Ubuntu / Python / Node / PM2 |
|
||||
|
||||
---
|
||||
|
||||
## 文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 页面、API、环境变量、日常流程 |
|
||||
| [行情区说明.md](./行情区说明.md) | K 线周期、缓存、快捷键、拉取逻辑 |
|
||||
| [部署文档.md](./部署文档.md) | Ubuntu、PM2、反代、升级 |
|
||||
| [常见问题.md](./常见问题.md) | 已遇到问题与处理 |
|
||||
| [.env.example](./.env.example) | 环境变量模板 |
|
||||
# 复盘系统中控(manual_trading_hub)
|
||||
|
||||
> **完整说明**:[使用说明.md](./使用说明.md) · **资金概况**:[资金概况说明.md](./资金概况说明.md) · **数据看板**:[数据看板说明.md](./数据看板说明.md) · **AI 教练**:[AI教练说明.md](./AI教练说明.md) · **行情区**:[行情区说明.md](./行情区说明.md) · **部署**:[部署文档.md](./部署文档.md) · **云服务器**:[云服务器部署说明.md](./云服务器部署说明.md) · **本地→云端迁移**:[本地数据迁移到云端.md](./本地数据迁移到云端.md) · **局域网/反代**:[局域网与反代部署说明.md](./局域网与反代部署说明.md) · **故障**:[常见问题.md](./常见问题.md)
|
||||
|
||||
多账户 **监控聚合 + 紧急全平**;**不在中控网页下单**。人工下单、关键位、**策略交易**(`/strategy`)、复盘请在各 `crypto_monitor_*` 实例网页操作(监控卡片 **「实例」** / **「复盘」**)。**增加子账户**见 [使用说明 §4.3](./使用说明.md#43-增加账户例如再挂一个-gate)。
|
||||
|
||||
---
|
||||
|
||||
## 当前能力
|
||||
|
||||
| 能力 | 说明 |
|
||||
|------|------|
|
||||
| 监控区 | 持仓、余额、关键位摘要、趋势计划、机器人单(只读) |
|
||||
| 资金概况 | 总/分户资金(资金户+交易户)、180 日曲线、最大回撤 |
|
||||
| **数据看板** | 三户当日总览/分户/平仓明细,SSE 推送(`/dashboard`;见 [数据看板说明.md](./数据看板说明.md)) |
|
||||
| 行情区 | K 线(多周期、本地缓存、技术指标、从监控跳转持仓线) |
|
||||
| **AI 教练** | 交易教练 + 普通聊天、会话历史(`/ai`;见 [AI教练说明.md](./AI教练说明.md)) |
|
||||
| 紧急全平 | 单户 / 全局市价减仓 |
|
||||
| 系统设置 | `hub_settings.json` 管理 URL、启用、**监控关键位 / 监控趋势计划**(不控制策略交易页) |
|
||||
| Web 登录 | `.env` 设 `HUB_PASSWORD` 后用户名+密码保护(反代公网**务必**配置) |
|
||||
| ~~下单区~~ | **已移除**(避免与实例重复、减少故障面) |
|
||||
|
||||
---
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
浏览器 → hub.py (:5100) 监控 / 资金概况 / **数据看板** / 行情 / **AI 教练** / 设置 / 登录
|
||||
├→ agent.py × N (:15200~15202) 持仓、全平
|
||||
└→ 各 Flask (:5000/5001/5004) /api/hub/monitor 只读聚合
|
||||
```
|
||||
|
||||
- 账户列表:**系统设置** 或默认 `settings_store.py`(不再使用环境变量 `HUB_AGENTS`)。
|
||||
- 三实例须注册 **hub_bridge**(仓库根 `hub_bridge.py`);PM2 建议 `PYTHONPATH=..`。
|
||||
|
||||
---
|
||||
|
||||
## 快速启动(Linux / 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
|
||||
# 编辑 .env:HUB_PASSWORD、HUB_BRIDGE_TOKEN、HUB_PUBLIC_ORIGIN 等
|
||||
|
||||
pm2 start ecosystem.config.cjs # 3 agent + hub
|
||||
pm2 save
|
||||
|
||||
bash scripts/verify_hub_deploy.sh
|
||||
curl -s http://127.0.0.1:5100/api/ping
|
||||
```
|
||||
|
||||
浏览器:`http://<本机IP>:5100/monitor`(行情 `/market`;已设密码则先 `/login`)。
|
||||
|
||||
---
|
||||
|
||||
## 中控 `.env` 要点
|
||||
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `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.example](./.env.example)。
|
||||
|
||||
---
|
||||
|
||||
## 子代理(agent)
|
||||
|
||||
每所策略目录单独进程,`EXCHANGE` + `PORT`(15200~15202),密钥来自**该目录 `.env`**。PM2 经 `scripts/run_agent.sh` 启动(自动 `source .env`、去 CRLF)。
|
||||
|
||||
| PORT | 目录 |
|
||||
|------|------|
|
||||
| 15200 | crypto_monitor_binance |
|
||||
| 15201 | crypto_monitor_okx |
|
||||
| 15202 | crypto_monitor_gate |
|
||||
|
||||
---
|
||||
|
||||
## 运维脚本
|
||||
|
||||
| 脚本 | 作用 |
|
||||
|------|------|
|
||||
| [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) | PM2 常驻 |
|
||||
| [docs/ubuntu-server.md](../docs/ubuntu-server.md) | Ubuntu / Python / Node / PM2 |
|
||||
|
||||
---
|
||||
|
||||
## 文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 页面、API、环境变量、日常流程 |
|
||||
| [行情区说明.md](./行情区说明.md) | K 线周期、缓存、快捷键、拉取逻辑 |
|
||||
| [部署文档.md](./部署文档.md) | Ubuntu、PM2、反代、升级 |
|
||||
| [常见问题.md](./常见问题.md) | 已遇到问题与处理 |
|
||||
| [.env.example](./.env.example) | 环境变量模板 |
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# 更新前快照(行情区 + K 线库)
|
||||
|
||||
> 行情区使用说明见 [行情区说明.md](./行情区说明.md)。
|
||||
|
||||
更新前已打 Git 标签,回滚方式:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor # 或你的仓库路径
|
||||
git fetch --tags
|
||||
git checkout snapshot/pre-hub-market-20260528
|
||||
# 恢复后重启:
|
||||
pm2 restart manual-trading-hub crypto_okx crypto_binance crypto_gate crypto_gate_bot
|
||||
```
|
||||
|
||||
回到最新主线:
|
||||
|
||||
```bash
|
||||
git checkout main
|
||||
git pull
|
||||
```
|
||||
|
||||
K 线数据库(不纳入 Git):`manual_trading_hub/data/hub_kline.db`,回滚代码不会自动删除该文件。
|
||||
# 更新前快照(行情区 + K 线库)
|
||||
|
||||
> 行情区使用说明见 [行情区说明.md](./行情区说明.md)。
|
||||
|
||||
更新前已打 Git 标签,回滚方式:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor # 或你的仓库路径
|
||||
git fetch --tags
|
||||
git checkout snapshot/pre-hub-market-20260528
|
||||
# 恢复后重启:
|
||||
pm2 restart manual-trading-hub crypto_okx crypto_binance crypto_gate
|
||||
```
|
||||
|
||||
回到最新主线:
|
||||
|
||||
```bash
|
||||
git checkout main
|
||||
git pull
|
||||
```
|
||||
|
||||
K 线数据库(不纳入 Git):`manual_trading_hub/data/hub_kline.db`,回滚代码不会自动删除该文件。
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"""
|
||||
子账户极轻代理:GET /status、挂单/条件单查询与撤销、POST /emergency/close-all、POST /emergency/close-position,仅监听 127.0.0.1。
|
||||
|
||||
与仓库内四个策略/监控目录一一对应时,典型用法(各目录自己的 .env 里已有密钥;子代理用环境变量 PORT,勿与 Flask 的 APP_PORT 相同):
|
||||
与仓库内三个策略/监控目录一一对应时,典型用法(各目录自己的 .env 里已有密钥;子代理用环境变量 PORT,勿与 Flask 的 APP_PORT 相同):
|
||||
EXCHANGE=binance → crypto_monitor_binance(BINANCE_*)
|
||||
EXCHANGE=okx → crypto_monitor_okx(OKX_*)
|
||||
EXCHANGE=gate → crypto_monitor_gate / crypto_monitor_gate_bot(GATE_*)
|
||||
EXCHANGE=gate → crypto_monitor_gate(GATE_*)
|
||||
|
||||
环境变量:
|
||||
EXCHANGE binance(默认)| okx | gate
|
||||
PORT 默认 15200(与 crypto_monitor_* 的 Flask APP_PORT 错开;中控默认聚合 15200–15203)
|
||||
PORT 默认 15200(与 crypto_monitor_* 的 Flask APP_PORT 错开;中控默认聚合 15200–15202)
|
||||
HOST 默认 127.0.0.1
|
||||
CONTROL_TOKEN 可选;请求头 X-Control-Token
|
||||
|
||||
@@ -392,7 +392,7 @@ def _position_price_fmt(ex: Any, symbol: str, price: float | None) -> tuple[floa
|
||||
|
||||
|
||||
def _position_entry_price(p: dict[str, Any]) -> float | None:
|
||||
"""四所 ccxt 持仓统一解析开仓均价(Binance/OKX/Gate 字段名不一致)。"""
|
||||
"""三所 ccxt 持仓统一解析开仓均价(Binance/OKX/Gate 字段名不一致)。"""
|
||||
return parse_position_entry_price(p)
|
||||
|
||||
|
||||
@@ -406,7 +406,7 @@ def _position_contract_size(ex: Any, symbol: str) -> float:
|
||||
|
||||
|
||||
def _position_mark_price(p: dict[str, Any]) -> float | None:
|
||||
"""四所 ccxt 持仓统一解析标记价(与实例 parse_ccxt_position_metrics 一致)。"""
|
||||
"""三所 ccxt 持仓统一解析标记价(与实例 parse_ccxt_position_metrics 一致)。"""
|
||||
return parse_position_mark_price(p)
|
||||
|
||||
|
||||
@@ -740,7 +740,7 @@ def place_tpsl_orders(
|
||||
body: PlaceTpslBody,
|
||||
x_control_token: str | None = Header(default=None, alias="X-Control-Token"),
|
||||
):
|
||||
"""先撤该合约全部条件单,再挂止盈+止损(与四实例策略逻辑一致)。"""
|
||||
"""先撤该合约全部条件单,再挂止盈+止损(与三实例策略逻辑一致)。"""
|
||||
_check_token(x_control_token)
|
||||
sym = (body.symbol or "").strip()
|
||||
side = (body.side or "").strip().lower()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* PM2:中控 hub + 四路子代理 agent(一次启动全部)
|
||||
* PM2:中控 hub + 三路子代理 agent(一次启动全部)
|
||||
*
|
||||
* 前置:
|
||||
* cd manual_trading_hub
|
||||
@@ -49,7 +49,6 @@ module.exports = {
|
||||
agentApp("manual-agent-binance", "crypto_monitor_binance", "binance", 15200),
|
||||
agentApp("manual-agent-okx", "crypto_monitor_okx", "okx", 15201),
|
||||
agentApp("manual-agent-gate", "crypto_monitor_gate", "gate", 15202),
|
||||
agentApp("manual-agent-gate-bot", "crypto_monitor_gate_bot", "gate", 15203),
|
||||
{
|
||||
name: "manual-trading-hub",
|
||||
cwd: HUB_DIR,
|
||||
|
||||
@@ -805,7 +805,7 @@ def replace_position_tpsl(
|
||||
take_profit: float,
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
先撤销该合约全部条件单,再挂止盈+止损。与四实例策略页逻辑对齐(读各目录 .env 中 GATE_/BINANCE_/OKX_ 参数)。
|
||||
先撤销该合约全部条件单,再挂止盈+止损。与三实例策略页逻辑对齐(读各目录 .env 中 GATE_/BINANCE_/OKX_ 参数)。
|
||||
"""
|
||||
kind = (exchange_kind or "binance").lower()
|
||||
direction = (direction or "long").strip().lower()
|
||||
|
||||
@@ -353,7 +353,7 @@ async def _run_archive_sync_once() -> dict:
|
||||
if st == 404:
|
||||
msg = (
|
||||
"HTTP 404:该 Flask 未注册 /api/hub/trades/archive。"
|
||||
"请在仓库根目录 git pull 后 pm2 restart crypto_gate crypto_gate_bot"
|
||||
"请在仓库根目录 git pull 后 pm2 restart crypto_gate"
|
||||
)
|
||||
results.append(
|
||||
{
|
||||
@@ -619,7 +619,7 @@ _ACCOUNT_RISK_BADGE_JS = _REPO_STATIC / "account_risk_badge.js"
|
||||
|
||||
@app.get("/assets/account_risk_badge.css")
|
||||
def hub_account_risk_badge_css():
|
||||
"""与四所实例共用仓库根 static/account_risk_badge.css。"""
|
||||
"""与三所实例共用仓库根 static/account_risk_badge.css。"""
|
||||
if not _ACCOUNT_RISK_BADGE_CSS.is_file():
|
||||
raise HTTPException(status_code=404, detail="account_risk_badge.css not found")
|
||||
return FileResponse(
|
||||
@@ -630,7 +630,7 @@ def hub_account_risk_badge_css():
|
||||
|
||||
@app.get("/assets/account_risk_badge.js")
|
||||
def hub_account_risk_badge_js():
|
||||
"""与四所实例共用仓库根 static/account_risk_badge.js。"""
|
||||
"""与三所实例共用仓库根 static/account_risk_badge.js。"""
|
||||
if not _ACCOUNT_RISK_BADGE_JS.is_file():
|
||||
raise HTTPException(status_code=404, detail="account_risk_badge.js not found")
|
||||
return FileResponse(
|
||||
@@ -641,7 +641,7 @@ def hub_account_risk_badge_js():
|
||||
|
||||
@app.get("/assets/ai_review_render.js")
|
||||
def hub_ai_review_render_js():
|
||||
"""与四所实例共用仓库根 static/ai_review_render.js(须在 /assets mount 之前注册)。"""
|
||||
"""与三所实例共用仓库根 static/ai_review_render.js(须在 /assets mount 之前注册)。"""
|
||||
if not _AI_REVIEW_RENDER_JS.is_file():
|
||||
raise HTTPException(status_code=404, detail="ai_review_render.js not found")
|
||||
return FileResponse(
|
||||
@@ -1542,7 +1542,7 @@ def _flask_error_from_hub_mon(hub_mon: dict | None) -> str | None:
|
||||
if st == 404:
|
||||
return (
|
||||
"HTTP 404:该 Flask 未注册 /api/hub/*(hub_bridge 未加载)。"
|
||||
"请在仓库根目录 git pull 后 pm2 restart crypto_binance crypto_gate crypto_gate_bot,"
|
||||
"请在仓库根目录 git pull 后 pm2 restart crypto_binance crypto_gate,"
|
||||
"并查看启动日志是否含 [hub_bridge] ImportError"
|
||||
)
|
||||
return (
|
||||
@@ -2348,7 +2348,7 @@ async def api_close_position(exchange_id: str, body: ClosePositionBody):
|
||||
if out.get("ok"):
|
||||
ex_key = (ex.get("key") or "").strip().lower()
|
||||
async with httpx.AsyncClient() as flask_client:
|
||||
if ex_key in ("gate", "gate_bot"):
|
||||
if ex_key == "gate":
|
||||
order_sync = await _fetch_flask_json(
|
||||
flask_client,
|
||||
ex,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""中控 AI:四户数据聚合为结构化上下文。"""
|
||||
"""中控 AI:三户数据聚合为结构化上下文。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""中控数据看板:四户当日总览(无 AI,纯数据聚合)。"""
|
||||
"""中控数据看板:三户当日总览(无 AI,纯数据聚合)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# 检查四路子代理端口与 /status(在服务器上运行)
|
||||
# 检查三路子代理端口与 /status(在服务器上运行)
|
||||
set -e
|
||||
|
||||
check_one() {
|
||||
@@ -29,7 +29,6 @@ check_one() {
|
||||
check_one "binance" 15200
|
||||
check_one "okx" 15201
|
||||
check_one "gate" 15202
|
||||
check_one "gate_bot" 15203
|
||||
|
||||
echo "PM2 状态:"
|
||||
pm2 status 2>/dev/null | grep -E 'manual-agent|manual-trading' || true
|
||||
|
||||
@@ -10,7 +10,6 @@ dirs=(
|
||||
"${REPO}/crypto_monitor_binance"
|
||||
"${REPO}/crypto_monitor_okx"
|
||||
"${REPO}/crypto_monitor_gate"
|
||||
"${REPO}/crypto_monitor_gate_bot"
|
||||
)
|
||||
|
||||
fixed=0
|
||||
@@ -30,5 +29,5 @@ for d in "${dirs[@]}"; do
|
||||
done
|
||||
|
||||
echo "完成,共修复 ${fixed} 个 .env。"
|
||||
echo "请重启子代理: cd ${REPO}/manual_trading_hub && pm2 restart manual-agent-gate manual-agent-gate-bot manual-agent-binance manual-agent-okx"
|
||||
echo "请重启子代理: cd ${REPO}/manual_trading_hub && pm2 restart manual-agent-gate manual-agent-binance manual-agent-okx"
|
||||
echo "或: bash scripts/pm2_hub.sh restart"
|
||||
|
||||
@@ -12,7 +12,7 @@ usage() {
|
||||
|
||||
一般请用: bash scripts/pm2_hub.sh start (hub + agent 一起)
|
||||
|
||||
本脚本仅操作 4 路子代理(不含中控)
|
||||
本脚本仅操作 3 路子代理(不含中控)
|
||||
|
||||
仅启动币安: pm2 start ecosystem.agents.config.cjs --only manual-agent-binance
|
||||
EOF
|
||||
@@ -33,20 +33,20 @@ case "${cmd}" in
|
||||
pm2 save 2>/dev/null || true
|
||||
;;
|
||||
stop)
|
||||
pm2 stop manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot 2>/dev/null || true
|
||||
pm2 stop manual-agent-binance manual-agent-okx manual-agent-gate 2>/dev/null || true
|
||||
;;
|
||||
restart)
|
||||
pm2 restart manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot 2>/dev/null \
|
||||
pm2 restart manual-agent-binance manual-agent-okx manual-agent-gate 2>/dev/null \
|
||||
|| pm2 start "${ECO}"
|
||||
;;
|
||||
status)
|
||||
pm2 status
|
||||
;;
|
||||
logs)
|
||||
pm2 logs manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot --lines 100
|
||||
pm2 logs manual-agent-binance manual-agent-okx manual-agent-gate --lines 100
|
||||
;;
|
||||
delete)
|
||||
pm2 delete manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot 2>/dev/null || true
|
||||
pm2 delete manual-agent-binance manual-agent-okx manual-agent-gate 2>/dev/null || true
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
|
||||
@@ -11,7 +11,6 @@ PM2_NAMES=(
|
||||
manual-agent-binance
|
||||
manual-agent-okx
|
||||
manual-agent-gate
|
||||
manual-agent-gate-bot
|
||||
manual-trading-hub
|
||||
)
|
||||
|
||||
@@ -19,7 +18,7 @@ usage() {
|
||||
cat <<'EOF'
|
||||
用法: bash scripts/pm2_hub.sh <start|stop|restart|status|logs|delete>
|
||||
|
||||
start 启动 ecosystem.config.cjs(4 路子代理 + 中控,已存在则 restart 全部)
|
||||
start 启动 ecosystem.config.cjs(3 路子代理 + 中控,已存在则 restart 全部)
|
||||
stop 停止全部
|
||||
restart 重启全部
|
||||
status pm2 status
|
||||
|
||||
@@ -9,18 +9,15 @@ ECO="${HUB_DIR}/ecosystem.config.cjs"
|
||||
cd "${HUB_DIR}"
|
||||
chmod +x scripts/run_agent.sh scripts/run_hub.sh 2>/dev/null || true
|
||||
|
||||
AGENTS=(manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot)
|
||||
AGENTS=(manual-agent-binance manual-agent-okx manual-agent-gate)
|
||||
|
||||
for n in "${AGENTS[@]}"; do
|
||||
pm2 delete "${n}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
pm2 start "${ECO}" --only manual-agent-binance
|
||||
pm2 start "${ECO}" --only manual-agent-okx
|
||||
pm2 start "${ECO}" --only manual-agent-gate
|
||||
pm2 start "${ECO}" --only manual-agent-gate-bot
|
||||
|
||||
# OKX 若已 online 可跳过;若也挂了则:
|
||||
# pm2 start "${ECO}" --only manual-agent-okx
|
||||
|
||||
pm2 save 2>/dev/null || true
|
||||
echo "已重建 binance / gate / gate-bot 子代理,请执行: bash scripts/check_agents.sh"
|
||||
echo "已重建 binance / okx / gate 子代理,请执行: bash scripts/check_agents.sh"
|
||||
|
||||
@@ -39,4 +39,4 @@ bash scripts/verify_hub_deploy.sh
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [../部署文档.md](../部署文档.md) | 端口、反代、故障排查 |
|
||||
| [../../docs/ubuntu-server.md](../../docs/ubuntu-server.md) | Python / Node / PM2 版本与四所启动顺序 |
|
||||
| [../../docs/ubuntu-server.md](../../docs/ubuntu-server.md) | Python / Node / PM2 版本与三所启动顺序 |
|
||||
|
||||
@@ -54,23 +54,13 @@ DEFAULT_EXCHANGES = [
|
||||
{
|
||||
"id": "2",
|
||||
"key": "gate",
|
||||
"name": "Gate训练 · crypto_monitor_gate",
|
||||
"name": "Gate · crypto_monitor_gate",
|
||||
"agent_url": "http://127.0.0.1:15202",
|
||||
"flask_url": "http://127.0.0.1:5000",
|
||||
"review_url": "http://127.0.0.1:5000/records",
|
||||
"enabled": True,
|
||||
"capabilities": ["key", "trend"],
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"key": "gate_bot",
|
||||
"name": "Gate趋势 · crypto_monitor_gate_bot",
|
||||
"agent_url": "http://127.0.0.1:15203",
|
||||
"flask_url": "http://127.0.0.1:5002",
|
||||
"review_url": "http://127.0.0.1:5002/records",
|
||||
"enabled": True,
|
||||
"capabilities": ["key", "trend"],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
+7395
-7395
File diff suppressed because it is too large
Load Diff
+5030
-5030
File diff suppressed because it is too large
Load Diff
+3386
-3386
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"name": "复盘系统中控",
|
||||
"short_name": "中控",
|
||||
"description": "四所交易监控与行情中控",
|
||||
"start_url": "/monitor",
|
||||
"display": "standalone",
|
||||
"background_color": "#0b0e18",
|
||||
"theme_color": "#0b0e18",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/assets/icons/icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/assets/icons/icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"name": "复盘系统中控",
|
||||
"short_name": "中控",
|
||||
"description": "三所交易监控与行情中控",
|
||||
"start_url": "/monitor",
|
||||
"display": "standalone",
|
||||
"background_color": "#0b0e18",
|
||||
"theme_color": "#0b0e18",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/assets/icons/icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/assets/icons/icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1121
-1121
File diff suppressed because it is too large
Load Diff
+289
-293
@@ -1,293 +1,289 @@
|
||||
# 云服务器部署说明
|
||||
|
||||
本文说明在 **云服务器(VPS)** 上部署 `crypto_monitor` 中控与四实例的推荐配置:硬件、软件、防火墙、宝塔反代、环境变量、PM2 启动与验收。
|
||||
|
||||
云上标准做法:**域名 + 宝塔/Nginx 反代 + HTTPS**;业务端口(5100、5000~5004、15200~15203)**不对公网直连**。
|
||||
|
||||
相关文档:
|
||||
|
||||
- **[本地数据迁移到云端.md](./本地数据迁移到云端.md)** — 备份 `crypto.db`、图片、`hub_settings` 与恢复步骤
|
||||
- [局域网与反代部署说明.md](./局域网与反代部署说明.md) — 局域网 IP:端口 与反代域名对照、SSO 行为
|
||||
- [部署文档.md](./部署文档.md) — PM2、依赖安装、日常运维
|
||||
- [使用说明.md](./使用说明.md) — 中控功能说明
|
||||
- [常见问题.md](./常见问题.md) — 故障排查
|
||||
- 环境变量模板:[.env.example](./.env.example)
|
||||
|
||||
---
|
||||
|
||||
## 一、服务器硬件与系统
|
||||
|
||||
| 项目 | 建议 |
|
||||
|------|------|
|
||||
| 配置 | **2 核 4G** 起步;四实例 + 中控 + PM2 同时运行,**4G~8G 更稳** |
|
||||
| 系统 | **Ubuntu 22.04 / 24.04**(项目文档按 Linux 编写) |
|
||||
| 磁盘 | **20G+**;日志、SQLite、上传图片会占空间 |
|
||||
| 网络 | 需能访问各交易所 API;若走代理,在对应 `crypto_monitor_*/.env` 配置 `OKX_SOCKS_PROXY`、`BINANCE_SOCKS_PROXY` 等 |
|
||||
|
||||
---
|
||||
|
||||
## 二、软件环境
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y python3 python3-venv python3-pip git curl
|
||||
|
||||
# 进程守护(推荐)
|
||||
sudo npm i -g pm2
|
||||
```
|
||||
|
||||
**宝塔面板(可选但推荐)**:安装 **Nginx**,用于反向代理与 **SSL**(Let’s Encrypt)。
|
||||
|
||||
Python 虚拟环境(分开安装,互不替代):
|
||||
|
||||
| 目录 | 用途 |
|
||||
|------|------|
|
||||
| `manual_trading_hub/.venv` | 中控 `hub.py` + 子代理 `agent.py` |
|
||||
| `crypto_monitor_binance/.venv` | 币安 Flask |
|
||||
| `crypto_monitor_okx/.venv` | OKX Flask |
|
||||
| `crypto_monitor_gate/.venv` | Gate 训练 Flask |
|
||||
| `crypto_monitor_gate_bot/.venv` | Gate 趋势 Flask |
|
||||
|
||||
各实例 `ecosystem.config.cjs` 一般已设置 **`PYTHONPATH=..`**(仓库根),以便加载 `hub_bridge.py`、`hub_auth.py` 等。
|
||||
|
||||
---
|
||||
|
||||
## 三、网络与端口(云上最重要)
|
||||
|
||||
**原则:公网只暴露 Nginx 的 80/443;Flask 与 agent 只监听本机。**
|
||||
|
||||
| 服务 | 本机端口(示例) | 是否对公网开放 |
|
||||
|------|------------------|----------------|
|
||||
| 中控 hub | 5100 | **否** → 仅 `https://hub.你的域名` 反代 |
|
||||
| 币安 Flask | 5001 | **否** → `https://binance.你的域名` |
|
||||
| OKX Flask | 5004 | **否** → `https://okx.你的域名` |
|
||||
| Gate 训练 Flask | 5000 | **否** → `https://gate.你的域名` |
|
||||
| Gate 趋势 Flask | 5002 | **否** → `https://gate-bot.你的域名` |
|
||||
| 子代理 agent | 15200~15203 | **否**,必须 **127.0.0.1** |
|
||||
|
||||
### 云厂商安全组 / 系统防火墙
|
||||
|
||||
- **放行**:`80`、`443`(给宝塔/Nginx)
|
||||
- **不要放行**:`5100`、`5000`~`5004`、`15200`~`15203`(除非临时本机调试,用完即关)
|
||||
|
||||
---
|
||||
|
||||
## 四、域名与宝塔反代
|
||||
|
||||
为 **中控 + 每个要对外打开的实例** 各建一个站点(子域名示例):
|
||||
|
||||
| 站点(浏览器访问) | 反代目标 |
|
||||
|--------------------|----------|
|
||||
| `https://hub.example.com` | `http://127.0.0.1:5100` |
|
||||
| `https://okx.example.com` | `http://127.0.0.1:5004` |
|
||||
| `https://binance.example.com` | `http://127.0.0.1:5001` |
|
||||
| `https://gate.example.com` | `http://127.0.0.1:5000` |
|
||||
| `https://gate-bot.example.com` | `http://127.0.0.1:5002` |
|
||||
|
||||
### 宝塔操作要点
|
||||
|
||||
1. 每个域名 → **网站** → **反向代理** → 目标 `http://127.0.0.1:对应端口`。
|
||||
2. 申请 **SSL**(Let’s Encrypt),强制 HTTPS。
|
||||
3. **不要**再给实例站加一层宝塔「访问密码」(会与 Flask `/login` 重复);直链鉴权用下文 **`APP_USERNAME` / `APP_PASSWORD`**。
|
||||
4. Nginx 建议保留常见代理头(宝塔默认通常已带):
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
```
|
||||
|
||||
中控请求实例 `/api/hub/*` 时会带 **`X-Hub-Token`**,一般无需额外配置。
|
||||
|
||||
---
|
||||
|
||||
## 五、环境变量(必配)
|
||||
|
||||
### 5.1 中控 `manual_trading_hub/.env`
|
||||
|
||||
```env
|
||||
HUB_HOST=0.0.0.0
|
||||
HUB_PORT=5100
|
||||
|
||||
# 与四实例 .env 完全相同(API + SSO 签名)
|
||||
HUB_BRIDGE_TOKEN=请填一长串随机字符
|
||||
|
||||
# 中控网页登录(公网务必设置)
|
||||
HUB_USERNAME=admin
|
||||
HUB_PASSWORD=强密码
|
||||
HUB_SESSION_SECRET=另一串随机字符
|
||||
|
||||
# 中控为 HTTPS 时建议 true
|
||||
HUB_COOKIE_SECURE=true
|
||||
|
||||
# 公网用域名访问中控(宝塔反代)时必设其一:
|
||||
# HUB_ALLOW_PUBLIC=true (推荐:反代 + 中控密码)
|
||||
# 或反代目标必须是 http://127.0.0.1:5100 且可保持 HUB_TRUST_LAN=false
|
||||
HUB_ALLOW_PUBLIC=true
|
||||
HUB_TRUST_LAN=false
|
||||
|
||||
# 从中控打开实例的 SSO 链接有效期(秒),默认 7200 = 2 小时
|
||||
HUB_SSO_TTL_SEC=7200
|
||||
|
||||
# 各实例 hub_settings 里 flask_url 已写 https 域名时,一般可不设
|
||||
# HUB_PUBLIC_ORIGIN=https://hub.example.com
|
||||
```
|
||||
|
||||
完整项见 [`.env.example`](./.env.example)。
|
||||
|
||||
### 5.2 四个实例 `crypto_monitor_*/.env`
|
||||
|
||||
每个目录都要有(**直链** `https://okx.域名` 时用这套登录网页):
|
||||
|
||||
```env
|
||||
# 各所 API 密钥(按交易所填写)
|
||||
# APP_PORT=5004
|
||||
|
||||
# 与中控 manual_trading_hub/.env 中 HUB_BRIDGE_TOKEN 完全一致
|
||||
HUB_BRIDGE_TOKEN=与中控相同
|
||||
|
||||
# 四实例建议统一(直链登录用)
|
||||
APP_USERNAME=统一用户名
|
||||
APP_PASSWORD=统一强密码
|
||||
|
||||
# 云服务器切勿开启(会跳过网页登录):
|
||||
# APP_AUTH_DISABLED=true
|
||||
```
|
||||
|
||||
### 5.3 子代理
|
||||
|
||||
- `CONTROL_TOKEN` 可与 `HUB_BRIDGE_TOKEN` 相同。
|
||||
- 由 PM2 在对应 `crypto_monitor_*` 目录启动,`run_agent.sh` 加载该目录 `.env`。
|
||||
- 只监听 **127.0.0.1:1520x**,不映射到公网。
|
||||
|
||||
---
|
||||
|
||||
## 六、中控「系统设置」`hub_settings.json`
|
||||
|
||||
在网页 **系统设置** 保存,或编辑 `manual_trading_hub/hub_settings.json`。
|
||||
|
||||
云上 **`flask_url` 必须写浏览器能打开的 HTTPS 域名**(不要写 `127.0.0.1`,除非配合 `HUB_PUBLIC_ORIGIN` 做替换):
|
||||
|
||||
| 字段 | 云上填法 | 说明 |
|
||||
|------|----------|------|
|
||||
| `flask_url` | `https://okx.example.com` | 用户浏览器、SSO 打开实例 |
|
||||
| `agent_url` | `http://127.0.0.1:15201` | 仅中控本机访问子代理 |
|
||||
| `enabled` | 按需 | 不参与监控的户可关 |
|
||||
| `capabilities` | 按需 | `key` / `trend` 等 |
|
||||
|
||||
**同机部署的两种写法(二选一):**
|
||||
|
||||
1. **推荐**:每个实例 `flask_url` 直接写该实例的 `https://子域名`。
|
||||
2. **备选**:`flask_url` 写 `http://127.0.0.1:5004`,中控 `.env` 设 `HUB_PUBLIC_ORIGIN=https://okx.example.com`(适合共用一个 IP、靠端口区分时)。
|
||||
|
||||
`agent_url` 始终用 **`http://127.0.0.1:1520x`**。
|
||||
|
||||
---
|
||||
|
||||
## 七、PM2 启动顺序
|
||||
|
||||
代码路径示例:`/opt/crypto_monitor/`(按实际替换)。
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
|
||||
# 1)四个实例 Flask(各目录 ecosystem.config.cjs,进程名以你机器为准)
|
||||
cd crypto_monitor_okx && pm2 start ecosystem.config.cjs
|
||||
cd ../crypto_monitor_binance && pm2 start ecosystem.config.cjs
|
||||
cd ../crypto_monitor_gate && pm2 start ecosystem.config.cjs
|
||||
cd ../crypto_monitor_gate_bot && pm2 start ecosystem.config.cjs
|
||||
|
||||
# 2)中控 + 四个子代理(一条拉起 5 个进程)
|
||||
cd ../manual_trading_hub
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # 编辑填入真实值
|
||||
chmod +x scripts/run_hub.sh scripts/run_agent.sh
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 save
|
||||
pm2 startup # 按提示执行 sudo 命令后再 pm2 save
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor/manual_trading_hub
|
||||
bash scripts/pm2_hub.sh start
|
||||
```
|
||||
|
||||
### PM2 进程一览
|
||||
|
||||
| 进程名 | 说明 |
|
||||
|--------|------|
|
||||
| `manual-trading-hub` | 中控 :5100 |
|
||||
| `manual-agent-binance` | :15200 |
|
||||
| `manual-agent-okx` | :15201 |
|
||||
| `manual-agent-gate` | :15202 |
|
||||
| `manual-agent-gate-bot` | :15203 |
|
||||
| `crypto_*`(各目录自定) | 各 Flask `APP_PORT` |
|
||||
|
||||
不用 OKX 时可在 `.env` 设 `HUB_DISABLED_IDS=1`,或 `pm2 stop manual-agent-okx`。
|
||||
|
||||
---
|
||||
|
||||
## 八、访问与登录(云上行为)
|
||||
|
||||
| 访问方式 | 地址示例 | 需要什么 |
|
||||
|----------|----------|----------|
|
||||
| 中控监控 | `https://hub.example.com/monitor` | **中控** `HUB_USERNAME` / `HUB_PASSWORD` |
|
||||
| 中控点「实例 / 策略交易 / 复盘」 | 自动打开 `https://okx.example.com/hub-sso?...` | 已登中控即可;**2 小时内、单次** SSO,**免输**实例密码 |
|
||||
| 浏览器直链实例 | `https://okx.example.com` | 实例 **`APP_USERNAME` / `APP_PASSWORD`**(`/login`) |
|
||||
|
||||
SSO 复用 **`HUB_BRIDGE_TOKEN`** 签名,详见 [局域网与反代部署说明.md §五](./局域网与反代部署说明.md)。
|
||||
|
||||
---
|
||||
|
||||
## 九、安全建议(云服务器必看)
|
||||
|
||||
1. **SSH**:密钥登录,关闭密码登录;必要时改 SSH 端口。
|
||||
2. **`HUB_BRIDGE_TOKEN`**:足够长、随机;勿提交 Git、勿写进前端页面。
|
||||
3. **交易所 API Key**:仅放在各实例 `.env`;权限尽量最小化(勿随意开提币)。
|
||||
4. **中控**:公网必须设 `HUB_PASSWORD`;`HUB_TRUST_LAN=false`。
|
||||
5. **实例**:云上 **`APP_AUTH_DISABLED` 必须为 false**(或未设置)。
|
||||
6. **备份**:定期备份各实例数据库 / SQLite 与 `hub_settings.json`。
|
||||
7. **`.env` 换行**:Linux 上勿用 Windows CRLF;可用 `bash scripts/fix_env_crlf.sh`。
|
||||
|
||||
---
|
||||
|
||||
## 十、部署后验收清单
|
||||
|
||||
- [ ] `https://hub.你的域名` 能打开并登录中控
|
||||
- [ ] 监控卡片有持仓/余额(子代理在线)
|
||||
- [ ] 已登录中控 → 点「实例」→ **无**实例登录页,直接进入
|
||||
- [ ] 隐身窗口直开 `https://okx.你的域名` → 出现 **`/login`**,统一账号密码可进
|
||||
- [ ] `pm2 status`:hub、4×agent、用到的 `crypto_*` 均为 online
|
||||
- [ ] 云安全组 **未** 对公网开放 5100、5000~5004、15200~15203
|
||||
- [ ] 四实例 `.env` 与中控 `HUB_BRIDGE_TOKEN` 一致
|
||||
- [ ] 实例启动日志无长期 `[hub_bridge] ImportError`
|
||||
|
||||
---
|
||||
|
||||
## 十一、常见问题速查
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 从中控打开仍要实例密码 | 见 [常见问题.md §4.3](./常见问题.md);检查 token、重启 Flask、`hub_settings` 的 `key` |
|
||||
| 监控无持仓 / 子代理不可用 | `curl http://127.0.0.1:15201/status`;查 `.env` CRLF、API 密钥 |
|
||||
| 复盘/实例链接是 127.0.0.1 | `flask_url` 改为 https 域名,或设 `HUB_PUBLIC_ORIGIN` |
|
||||
| 仅 Gate 子代理反复重启 | `.env` CRLF:`bash manual_trading_hub/scripts/fix_env_crlf.sh` |
|
||||
|
||||
---
|
||||
|
||||
## 十二、与局域网部署的区别(简要)
|
||||
|
||||
| 项目 | 云服务器 | 局域网 |
|
||||
|------|----------|--------|
|
||||
| 对外地址 | `https://子域名` | `http://内网IP:端口` |
|
||||
| `flask_url` | 写 **域名** | 写 **内网 IP:端口** |
|
||||
| 防火墙 | 只开 80/443 | 内网可开 5100、500x |
|
||||
| SSL | 必须(宝塔证书) | 通常 HTTP 即可 |
|
||||
| `HUB_COOKIE_SECURE` | 建议 `true` | HTTP 时用 `false` |
|
||||
|
||||
局域网详细步骤见 [局域网与反代部署说明.md §三](./局域网与反代部署说明.md)。
|
||||
# 云服务器部署说明
|
||||
|
||||
本文说明在 **云服务器(VPS)** 上部署 `crypto_monitor` 中控与三实例的推荐配置:硬件、软件、防火墙、宝塔反代、环境变量、PM2 启动与验收。
|
||||
|
||||
云上标准做法:**域名 + 宝塔/Nginx 反代 + HTTPS**;业务端口(5100、5000~5004、15200~15202)**不对公网直连**。
|
||||
|
||||
相关文档:
|
||||
|
||||
- **[本地数据迁移到云端.md](./本地数据迁移到云端.md)** — 备份 `crypto.db`、图片、`hub_settings` 与恢复步骤
|
||||
- [局域网与反代部署说明.md](./局域网与反代部署说明.md) — 局域网 IP:端口 与反代域名对照、SSO 行为
|
||||
- [部署文档.md](./部署文档.md) — PM2、依赖安装、日常运维
|
||||
- [使用说明.md](./使用说明.md) — 中控功能说明
|
||||
- [常见问题.md](./常见问题.md) — 故障排查
|
||||
- 环境变量模板:[.env.example](./.env.example)
|
||||
|
||||
---
|
||||
|
||||
## 一、服务器硬件与系统
|
||||
|
||||
| 项目 | 建议 |
|
||||
|------|------|
|
||||
| 配置 | **2 核 4G** 起步;三实例 + 中控 + PM2 同时运行,**4G~8G 更稳** |
|
||||
| 系统 | **Ubuntu 22.04 / 24.04**(项目文档按 Linux 编写) |
|
||||
| 磁盘 | **20G+**;日志、SQLite、上传图片会占空间 |
|
||||
| 网络 | 需能访问各交易所 API;若走代理,在对应 `crypto_monitor_*/.env` 配置 `OKX_SOCKS_PROXY`、`BINANCE_SOCKS_PROXY` 等 |
|
||||
|
||||
---
|
||||
|
||||
## 二、软件环境
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y python3 python3-venv python3-pip git curl
|
||||
|
||||
# 进程守护(推荐)
|
||||
sudo npm i -g pm2
|
||||
```
|
||||
|
||||
**宝塔面板(可选但推荐)**:安装 **Nginx**,用于反向代理与 **SSL**(Let’s Encrypt)。
|
||||
|
||||
Python 虚拟环境(分开安装,互不替代):
|
||||
|
||||
| 目录 | 用途 |
|
||||
|------|------|
|
||||
| `manual_trading_hub/.venv` | 中控 `hub.py` + 子代理 `agent.py` |
|
||||
| `crypto_monitor_binance/.venv` | 币安 Flask |
|
||||
| `crypto_monitor_okx/.venv` | OKX Flask |
|
||||
| `crypto_monitor_gate/.venv` | Gate Flask |
|
||||
| `crypto_monitor_gate/.venv` | Gate Flask |
|
||||
|
||||
各实例 `ecosystem.config.cjs` 一般已设置 **`PYTHONPATH=..`**(仓库根),以便加载 `hub_bridge.py`、`hub_auth.py` 等。
|
||||
|
||||
---
|
||||
|
||||
## 三、网络与端口(云上最重要)
|
||||
|
||||
**原则:公网只暴露 Nginx 的 80/443;Flask 与 agent 只监听本机。**
|
||||
|
||||
| 服务 | 本机端口(示例) | 是否对公网开放 |
|
||||
|------|------------------|----------------|
|
||||
| 中控 hub | 5100 | **否** → 仅 `https://hub.你的域名` 反代 |
|
||||
| 币安 Flask | 5001 | **否** → `https://binance.你的域名` |
|
||||
| OKX Flask | 5004 | **否** → `https://okx.你的域名` |
|
||||
| Gate Flask | 5000 | **否** → `https://gate.你的域名` |
|
||||
| 子代理 agent | 15200~15202 | **否**,必须 **127.0.0.1** |
|
||||
|
||||
### 云厂商安全组 / 系统防火墙
|
||||
|
||||
- **放行**:`80`、`443`(给宝塔/Nginx)
|
||||
- **不要放行**:`5100`、`5000`~`5004`、`15200`~`15202`(除非临时本机调试,用完即关)
|
||||
|
||||
---
|
||||
|
||||
## 四、域名与宝塔反代
|
||||
|
||||
为 **中控 + 每个要对外打开的实例** 各建一个站点(子域名示例):
|
||||
|
||||
| 站点(浏览器访问) | 反代目标 |
|
||||
|--------------------|----------|
|
||||
| `https://hub.example.com` | `http://127.0.0.1:5100` |
|
||||
| `https://okx.example.com` | `http://127.0.0.1:5004` |
|
||||
| `https://binance.example.com` | `http://127.0.0.1:5001` |
|
||||
| `https://gate.example.com` | `http://127.0.0.1:5000` |
|
||||
|
||||
### 宝塔操作要点
|
||||
|
||||
1. 每个域名 → **网站** → **反向代理** → 目标 `http://127.0.0.1:对应端口`。
|
||||
2. 申请 **SSL**(Let’s Encrypt),强制 HTTPS。
|
||||
3. **不要**再给实例站加一层宝塔「访问密码」(会与 Flask `/login` 重复);直链鉴权用下文 **`APP_USERNAME` / `APP_PASSWORD`**。
|
||||
4. Nginx 建议保留常见代理头(宝塔默认通常已带):
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
```
|
||||
|
||||
中控请求实例 `/api/hub/*` 时会带 **`X-Hub-Token`**,一般无需额外配置。
|
||||
|
||||
---
|
||||
|
||||
## 五、环境变量(必配)
|
||||
|
||||
### 5.1 中控 `manual_trading_hub/.env`
|
||||
|
||||
```env
|
||||
HUB_HOST=0.0.0.0
|
||||
HUB_PORT=5100
|
||||
|
||||
# 与三实例 .env 完全相同(API + SSO 签名)
|
||||
HUB_BRIDGE_TOKEN=请填一长串随机字符
|
||||
|
||||
# 中控网页登录(公网务必设置)
|
||||
HUB_USERNAME=admin
|
||||
HUB_PASSWORD=强密码
|
||||
HUB_SESSION_SECRET=另一串随机字符
|
||||
|
||||
# 中控为 HTTPS 时建议 true
|
||||
HUB_COOKIE_SECURE=true
|
||||
|
||||
# 公网用域名访问中控(宝塔反代)时必设其一:
|
||||
# HUB_ALLOW_PUBLIC=true (推荐:反代 + 中控密码)
|
||||
# 或反代目标必须是 http://127.0.0.1:5100 且可保持 HUB_TRUST_LAN=false
|
||||
HUB_ALLOW_PUBLIC=true
|
||||
HUB_TRUST_LAN=false
|
||||
|
||||
# 从中控打开实例的 SSO 链接有效期(秒),默认 7200 = 2 小时
|
||||
HUB_SSO_TTL_SEC=7200
|
||||
|
||||
# 各实例 hub_settings 里 flask_url 已写 https 域名时,一般可不设
|
||||
# HUB_PUBLIC_ORIGIN=https://hub.example.com
|
||||
```
|
||||
|
||||
完整项见 [`.env.example`](./.env.example)。
|
||||
|
||||
### 5.2 三个实例 `crypto_monitor_*/.env`
|
||||
|
||||
每个目录都要有(**直链** `https://okx.域名` 时用这套登录网页):
|
||||
|
||||
```env
|
||||
# 各所 API 密钥(按交易所填写)
|
||||
# APP_PORT=5004
|
||||
|
||||
# 与中控 manual_trading_hub/.env 中 HUB_BRIDGE_TOKEN 完全一致
|
||||
HUB_BRIDGE_TOKEN=与中控相同
|
||||
|
||||
# 三实例建议统一(直链登录用)
|
||||
APP_USERNAME=统一用户名
|
||||
APP_PASSWORD=统一强密码
|
||||
|
||||
# 云服务器切勿开启(会跳过网页登录):
|
||||
# APP_AUTH_DISABLED=true
|
||||
```
|
||||
|
||||
### 5.3 子代理
|
||||
|
||||
- `CONTROL_TOKEN` 可与 `HUB_BRIDGE_TOKEN` 相同。
|
||||
- 由 PM2 在对应 `crypto_monitor_*` 目录启动,`run_agent.sh` 加载该目录 `.env`。
|
||||
- 只监听 **127.0.0.1:1520x**,不映射到公网。
|
||||
|
||||
---
|
||||
|
||||
## 六、中控「系统设置」`hub_settings.json`
|
||||
|
||||
在网页 **系统设置** 保存,或编辑 `manual_trading_hub/hub_settings.json`。
|
||||
|
||||
云上 **`flask_url` 必须写浏览器能打开的 HTTPS 域名**(不要写 `127.0.0.1`,除非配合 `HUB_PUBLIC_ORIGIN` 做替换):
|
||||
|
||||
| 字段 | 云上填法 | 说明 |
|
||||
|------|----------|------|
|
||||
| `flask_url` | `https://okx.example.com` | 用户浏览器、SSO 打开实例 |
|
||||
| `agent_url` | `http://127.0.0.1:15201` | 仅中控本机访问子代理 |
|
||||
| `enabled` | 按需 | 不参与监控的户可关 |
|
||||
| `capabilities` | 按需 | `key` / `trend` 等 |
|
||||
|
||||
**同机部署的两种写法(二选一):**
|
||||
|
||||
1. **推荐**:每个实例 `flask_url` 直接写该实例的 `https://子域名`。
|
||||
2. **备选**:`flask_url` 写 `http://127.0.0.1:5004`,中控 `.env` 设 `HUB_PUBLIC_ORIGIN=https://okx.example.com`(适合共用一个 IP、靠端口区分时)。
|
||||
|
||||
`agent_url` 始终用 **`http://127.0.0.1:1520x`**。
|
||||
|
||||
---
|
||||
|
||||
## 七、PM2 启动顺序
|
||||
|
||||
代码路径示例:`/opt/crypto_monitor/`(按实际替换)。
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
|
||||
# 1)三个实例 Flask(各目录 ecosystem.config.cjs,进程名以你机器为准)
|
||||
cd crypto_monitor_okx && pm2 start ecosystem.config.cjs
|
||||
cd ../crypto_monitor_binance && pm2 start ecosystem.config.cjs
|
||||
cd ../crypto_monitor_gate && pm2 start ecosystem.config.cjs
|
||||
|
||||
# 2)中控 + 三个子代理(一条拉起 4 个进程:hub + 3 agent)
|
||||
cd ../manual_trading_hub
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # 编辑填入真实值
|
||||
chmod +x scripts/run_hub.sh scripts/run_agent.sh
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 save
|
||||
pm2 startup # 按提示执行 sudo 命令后再 pm2 save
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor/manual_trading_hub
|
||||
bash scripts/pm2_hub.sh start
|
||||
```
|
||||
|
||||
### PM2 进程一览
|
||||
|
||||
| 进程名 | 说明 |
|
||||
|--------|------|
|
||||
| `manual-trading-hub` | 中控 :5100 |
|
||||
| `manual-agent-binance` | :15200 |
|
||||
| `manual-agent-okx` | :15201 |
|
||||
| `manual-agent-gate` | :15202 |
|
||||
| `crypto_*`(各目录自定) | 各 Flask `APP_PORT` |
|
||||
|
||||
不用 OKX 时可在 `.env` 设 `HUB_DISABLED_IDS=1`,或 `pm2 stop manual-agent-okx`。
|
||||
|
||||
---
|
||||
|
||||
## 八、访问与登录(云上行为)
|
||||
|
||||
| 访问方式 | 地址示例 | 需要什么 |
|
||||
|----------|----------|----------|
|
||||
| 中控监控 | `https://hub.example.com/monitor` | **中控** `HUB_USERNAME` / `HUB_PASSWORD` |
|
||||
| 中控点「实例 / 策略交易 / 复盘」 | 自动打开 `https://okx.example.com/hub-sso?...` | 已登中控即可;**2 小时内、单次** SSO,**免输**实例密码 |
|
||||
| 浏览器直链实例 | `https://okx.example.com` | 实例 **`APP_USERNAME` / `APP_PASSWORD`**(`/login`) |
|
||||
|
||||
SSO 复用 **`HUB_BRIDGE_TOKEN`** 签名,详见 [局域网与反代部署说明.md §五](./局域网与反代部署说明.md)。
|
||||
|
||||
---
|
||||
|
||||
## 九、安全建议(云服务器必看)
|
||||
|
||||
1. **SSH**:密钥登录,关闭密码登录;必要时改 SSH 端口。
|
||||
2. **`HUB_BRIDGE_TOKEN`**:足够长、随机;勿提交 Git、勿写进前端页面。
|
||||
3. **交易所 API Key**:仅放在各实例 `.env`;权限尽量最小化(勿随意开提币)。
|
||||
4. **中控**:公网必须设 `HUB_PASSWORD`;`HUB_TRUST_LAN=false`。
|
||||
5. **实例**:云上 **`APP_AUTH_DISABLED` 必须为 false**(或未设置)。
|
||||
6. **备份**:定期备份各实例数据库 / SQLite 与 `hub_settings.json`。
|
||||
7. **`.env` 换行**:Linux 上勿用 Windows CRLF;可用 `bash scripts/fix_env_crlf.sh`。
|
||||
|
||||
---
|
||||
|
||||
## 十、部署后验收清单
|
||||
|
||||
- [ ] `https://hub.你的域名` 能打开并登录中控
|
||||
- [ ] 监控卡片有持仓/余额(子代理在线)
|
||||
- [ ] 已登录中控 → 点「实例」→ **无**实例登录页,直接进入
|
||||
- [ ] 隐身窗口直开 `https://okx.你的域名` → 出现 **`/login`**,统一账号密码可进
|
||||
- [ ] `pm2 status`:hub、4×agent、用到的 `crypto_*` 均为 online
|
||||
- [ ] 云安全组 **未** 对公网开放 5100、5000~5004、15200~15202
|
||||
- [ ] 三实例 `.env` 与中控 `HUB_BRIDGE_TOKEN` 一致
|
||||
- [ ] 实例启动日志无长期 `[hub_bridge] ImportError`
|
||||
|
||||
---
|
||||
|
||||
## 十一、常见问题速查
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 从中控打开仍要实例密码 | 见 [常见问题.md §4.3](./常见问题.md);检查 token、重启 Flask、`hub_settings` 的 `key` |
|
||||
| 监控无持仓 / 子代理不可用 | `curl http://127.0.0.1:15201/status`;查 `.env` CRLF、API 密钥 |
|
||||
| 复盘/实例链接是 127.0.0.1 | `flask_url` 改为 https 域名,或设 `HUB_PUBLIC_ORIGIN` |
|
||||
| 仅 Gate 子代理反复重启 | `.env` CRLF:`bash manual_trading_hub/scripts/fix_env_crlf.sh` |
|
||||
|
||||
---
|
||||
|
||||
## 十二、与局域网部署的区别(简要)
|
||||
|
||||
| 项目 | 云服务器 | 局域网 |
|
||||
|------|----------|--------|
|
||||
| 对外地址 | `https://子域名` | `http://内网IP:端口` |
|
||||
| `flask_url` | 写 **域名** | 写 **内网 IP:端口** |
|
||||
| 防火墙 | 只开 80/443 | 内网可开 5100、500x |
|
||||
| SSL | 必须(宝塔证书) | 通常 HTTP 即可 |
|
||||
| `HUB_COOKIE_SECURE` | 建议 `true` | HTTP 时用 `false` |
|
||||
|
||||
局域网详细步骤见 [局域网与反代部署说明.md §三](./局域网与反代部署说明.md)。
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
# 交易监管(AI 教练)
|
||||
|
||||
中控 **交易监管** 用于防止过度交易与频繁手动操作:在 **手动/中控开平仓** 与 **新开仓** 时自动推送至 **今日监管长会话**,并可选 **企业微信** 提醒;程序止盈/止损按「正常执行」鼓励,不计入频繁交易统计。
|
||||
|
||||
入口:**AI 教练**(`/ai`)→ Tab **交易监管**,或微信链接(在系统设置中配置)。
|
||||
|
||||
## 监管范围
|
||||
|
||||
| 类型 | 识别 | 页内推送 | 微信(P0) | 频率统计 |
|
||||
|------|------|----------|------------|----------|
|
||||
| 实例手动平仓 | `result = 手动平仓` | ✓ | ✓ | ✓ |
|
||||
| 中控平仓 | `result = 强制清仓` 等 | ✓ | ✓ | ✓ |
|
||||
| 新开仓 | 监控板持仓 diff(0→有仓 / 新合约) | ✓ | ✓ | ✓ |
|
||||
| 程序止盈 | 止盈 / 保本止盈 / 移动止盈 | ✓ | 可选 | ✗ |
|
||||
| 程序止损 | 止损 | ✓ | 可选 | ✗ |
|
||||
| 外部平仓 | 外部平仓、时间平仓 | ✗ | ✗ | ✗ |
|
||||
|
||||
频率规则(间隔过短、30 分钟笔数、日笔数、连亏、平后快开)**只对手动/中控开平** 叠加 `[监管·频率]` 警告。
|
||||
|
||||
## 会话
|
||||
|
||||
- 每个交易日 **一条长会话**(`bot_mode: supervisor`,标题 `今日监管 YYYY-MM-DD`)。
|
||||
- 系统消息(`role: system`)+ AI 短评(`assistant`)+ 用户回复(`user`)同线程。
|
||||
- 与 **交易教练 / 普通聊天** 分离;监管会话不支持「新开对话」。
|
||||
|
||||
## 系统设置
|
||||
|
||||
路径:**系统设置** → **交易监管 · 企业微信**(写入 `hub_settings.json` → `supervisor`)。
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `enabled` | 总开关 |
|
||||
| `wechat_webhook` | **监管专用** 企业微信机器人(与四所实例 `.env` 的 `WECHAT_WEBHOOK` 独立) |
|
||||
| `wechat_link_base` | 微信消息末尾跳转链接(**可单独修改**,如 `https://域名/ai?mode=supervisor`) |
|
||||
| `wechat_prefix` | 消息前缀,默认 `【交易监管】` |
|
||||
| `wechat_on_program_tp_sl` | 程序止盈/止损是否也发微信 |
|
||||
| `manual_close_daily_warn` | 日手动平警告阈值(默认 2) |
|
||||
| `interval_warn_minutes` | 两笔手动/中控平最短间隔(默认 15 分钟) |
|
||||
| `freq_30m_count` | 30 分钟内笔数阈值(默认 2) |
|
||||
| `reopen_after_close_minutes` | 手动平后再开仓警告间隔(默认 30 分钟) |
|
||||
|
||||
`.env` 兜底(设置页保存优先):
|
||||
|
||||
```env
|
||||
SUPERVISOR_WECHAT_WEBHOOK=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...
|
||||
SUPERVISOR_WECHAT_LINK=https://你的域名/ai?mode=supervisor
|
||||
SUPERVISOR_POLL_INTERVAL_SEC=30
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/ai/supervisor/session` | 今日监管会话 |
|
||||
| GET | `/api/ai/supervisor/stream` | SSE 版本推送 |
|
||||
| POST | `/api/ai/supervisor/chat/send` | 用户回聊(JSON `{ "message": "..." }`) |
|
||||
| GET | `/api/ai/supervisor/rules` | 当前阈值 |
|
||||
| POST | `/api/ai/supervisor/refresh` | 立即扫描 |
|
||||
|
||||
## 存储
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `hub_supervisor_state.json` | 已处理事件、持仓快照、频率统计 |
|
||||
| `hub_ai_chat.json` | 监管会话(`bot_mode: supervisor`) |
|
||||
| `hub_settings.json` | `supervisor` 配置节 |
|
||||
|
||||
**首次启用** 会对当前交易日已有平仓做 **种子同步**(不补发历史推送),避免部署瞬间刷屏。
|
||||
|
||||
## 与实例风控
|
||||
|
||||
实例 `account_risk_lib`(冷静期 / 日冻结)为 **硬拦截**;监管为 **软提醒 + 陪聊**,不绕过实例开仓限制。
|
||||
|
||||
## 代码位置
|
||||
|
||||
| 模块 | 路径 |
|
||||
|------|------|
|
||||
| 规则与推送 | `hub_supervisor_lib.py` |
|
||||
| 后台扫描 | `hub_supervisor_cache.py` |
|
||||
| 会话 | `hub_ai/supervisor_store.py` |
|
||||
| AI 评语/回聊 | `hub_ai/supervisor.py` |
|
||||
| 提示词 | `hub_ai/prompts.py` → `SUPERVISOR_SYSTEM` |
|
||||
|
||||
部署后重启中控:`pm2 restart manual-trading-hub`(或你的 hub 进程名)。
|
||||
# 交易监管(AI 教练)
|
||||
|
||||
中控 **交易监管** 用于防止过度交易与频繁手动操作:在 **手动/中控开平仓** 与 **新开仓** 时自动推送至 **今日监管长会话**,并可选 **企业微信** 提醒;程序止盈/止损按「正常执行」鼓励,不计入频繁交易统计。
|
||||
|
||||
入口:**AI 教练**(`/ai`)→ Tab **交易监管**,或微信链接(在系统设置中配置)。
|
||||
|
||||
## 监管范围
|
||||
|
||||
| 类型 | 识别 | 页内推送 | 微信(P0) | 频率统计 |
|
||||
|------|------|----------|------------|----------|
|
||||
| 实例手动平仓 | `result = 手动平仓` | ✓ | ✓ | ✓ |
|
||||
| 中控平仓 | `result = 强制清仓` 等 | ✓ | ✓ | ✓ |
|
||||
| 新开仓 | 监控板持仓 diff(0→有仓 / 新合约) | ✓ | ✓ | ✓ |
|
||||
| 程序止盈 | 止盈 / 保本止盈 / 移动止盈 | ✓ | 可选 | ✗ |
|
||||
| 程序止损 | 止损 | ✓ | 可选 | ✗ |
|
||||
| 外部平仓 | 外部平仓、时间平仓 | ✗ | ✗ | ✗ |
|
||||
|
||||
频率规则(间隔过短、30 分钟笔数、日笔数、连亏、平后快开)**只对手动/中控开平** 叠加 `[监管·频率]` 警告。
|
||||
|
||||
## 会话
|
||||
|
||||
- 每个交易日 **一条长会话**(`bot_mode: supervisor`,标题 `今日监管 YYYY-MM-DD`)。
|
||||
- 系统消息(`role: system`)+ AI 短评(`assistant`)+ 用户回复(`user`)同线程。
|
||||
- 与 **交易教练 / 普通聊天** 分离;监管会话不支持「新开对话」。
|
||||
|
||||
## 系统设置
|
||||
|
||||
路径:**系统设置** → **交易监管 · 企业微信**(写入 `hub_settings.json` → `supervisor`)。
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `enabled` | 总开关 |
|
||||
| `wechat_webhook` | **监管专用** 企业微信机器人(与三所实例 `.env` 的 `WECHAT_WEBHOOK` 独立) |
|
||||
| `wechat_link_base` | 微信消息末尾跳转链接(**可单独修改**,如 `https://域名/ai?mode=supervisor`) |
|
||||
| `wechat_prefix` | 消息前缀,默认 `【交易监管】` |
|
||||
| `wechat_on_program_tp_sl` | 程序止盈/止损是否也发微信 |
|
||||
| `manual_close_daily_warn` | 日手动平警告阈值(默认 2) |
|
||||
| `interval_warn_minutes` | 两笔手动/中控平最短间隔(默认 15 分钟) |
|
||||
| `freq_30m_count` | 30 分钟内笔数阈值(默认 2) |
|
||||
| `reopen_after_close_minutes` | 手动平后再开仓警告间隔(默认 30 分钟) |
|
||||
|
||||
`.env` 兜底(设置页保存优先):
|
||||
|
||||
```env
|
||||
SUPERVISOR_WECHAT_WEBHOOK=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...
|
||||
SUPERVISOR_WECHAT_LINK=https://你的域名/ai?mode=supervisor
|
||||
SUPERVISOR_POLL_INTERVAL_SEC=30
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/ai/supervisor/session` | 今日监管会话 |
|
||||
| GET | `/api/ai/supervisor/stream` | SSE 版本推送 |
|
||||
| POST | `/api/ai/supervisor/chat/send` | 用户回聊(JSON `{ "message": "..." }`) |
|
||||
| GET | `/api/ai/supervisor/rules` | 当前阈值 |
|
||||
| POST | `/api/ai/supervisor/refresh` | 立即扫描 |
|
||||
|
||||
## 存储
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `hub_supervisor_state.json` | 已处理事件、持仓快照、频率统计 |
|
||||
| `hub_ai_chat.json` | 监管会话(`bot_mode: supervisor`) |
|
||||
| `hub_settings.json` | `supervisor` 配置节 |
|
||||
|
||||
**首次启用** 会对当前交易日已有平仓做 **种子同步**(不补发历史推送),避免部署瞬间刷屏。
|
||||
|
||||
## 与实例风控
|
||||
|
||||
实例 `account_risk_lib`(冷静期 / 日冻结)为 **硬拦截**;监管为 **软提醒 + 陪聊**,不绕过实例开仓限制。
|
||||
|
||||
## 代码位置
|
||||
|
||||
| 模块 | 路径 |
|
||||
|------|------|
|
||||
| 规则与推送 | `hub_supervisor_lib.py` |
|
||||
| 后台扫描 | `hub_supervisor_cache.py` |
|
||||
| 会话 | `hub_ai/supervisor_store.py` |
|
||||
| AI 评语/回聊 | `hub_ai/supervisor.py` |
|
||||
| 提示词 | `hub_ai/prompts.py` → `SUPERVISOR_SYSTEM` |
|
||||
|
||||
部署后重启中控:`pm2 restart manual-trading-hub`(或你的 hub 进程名)。
|
||||
|
||||
+518
-522
File diff suppressed because it is too large
Load Diff
+226
-228
@@ -1,228 +1,226 @@
|
||||
# 中控 · 局域网与反代部署说明
|
||||
|
||||
本文说明在 **局域网(IP + 端口)** 与 **宝塔/Nginx 反代(域名)** 两种场景下,如何配置中控与各实例,并实现:
|
||||
|
||||
- **从中控** 点「实例 / 策略交易 / 复盘」→ **免输入** 实例网页密码(SSO 临时链接,默认 **2 小时** 内有效、**单次使用**)
|
||||
- **浏览器直链** 实例地址(反代域名或 `http://IP:端口`)→ 进入 **`/login`**,输入统一 **`APP_USERNAME` / `APP_PASSWORD`**
|
||||
|
||||
SSO 签名复用 **`HUB_BRIDGE_TOKEN`**(与中控调实例 API 相同,四所 `.env` 与 `manual_trading_hub/.env` 保持一致)。
|
||||
|
||||
**云服务器(VPS)** 的硬件、安全组、宝塔、环境变量与验收清单见 **[云服务器部署说明.md](./云服务器部署说明.md)**。
|
||||
|
||||
---
|
||||
|
||||
## 一、两种访问方式对照
|
||||
|
||||
| 项目 | 局域网 | 反代(域名) |
|
||||
|------|--------|----------------|
|
||||
| 中控地址 | `http://内网IP:5100` | `https://hub.你的域名.com` |
|
||||
| 实例地址(浏览器) | `http://内网IP:5004` 等 | `https://okx.你的域名.com` 等 |
|
||||
| `hub_settings` 里 `flask_url` | 建议写 **`http://内网IP:端口`** | 建议写 **`https://该实例域名`**(与浏览器一致) |
|
||||
| 中控本机调实例 API | 可与浏览器相同;同机也可用 `http://127.0.0.1:端口` + `HUB_PUBLIC_ORIGIN` | 同机可用 `127.0.0.1:端口` 或域名(需 Nginx 转发 `X-Hub-Token`) |
|
||||
| `HUB_PUBLIC_ORIGIN` | 若 `flask_url` 填 `127.0.0.1`,**必填** `http://内网IP` | 若 `flask_url` 已是完整域名,**可不设** |
|
||||
| 宝塔 | 可不装反代,直连端口 | 每实例一个站点 + SSL;中控单独站点 |
|
||||
| 直链登录 | 实例 `/login` | 实例 `/login` |
|
||||
| 从中控打开 | `/hub-sso?token=...` 自动登录 | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## 二、共用环境变量(必配)
|
||||
|
||||
### 2.1 中控 `manual_trading_hub/.env`
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=请填一长串随机字符
|
||||
HUB_USERNAME=admin # 中控登录(建议设置)
|
||||
HUB_PASSWORD=你的中控密码
|
||||
HUB_SSO_TTL_SEC=7200 # 可选,默认 7200 = 2 小时
|
||||
```
|
||||
|
||||
### 2.2 四个实例 `crypto_monitor_*/.env`
|
||||
|
||||
每个目录相同(**直链**时用这套登录实例网页):
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=与中控完全相同
|
||||
APP_USERNAME=统一用户名
|
||||
APP_PASSWORD=统一密码
|
||||
# 云上切勿 APP_AUTH_DISABLED=true
|
||||
```
|
||||
|
||||
### 2.3 子代理
|
||||
|
||||
`CONTROL_TOKEN` 可与 `HUB_BRIDGE_TOKEN` 相同;子代理只监听 `127.0.0.1`,**不要**对公网暴露 `15200`~`15203`。
|
||||
|
||||
---
|
||||
|
||||
## 三、局域网部署(IP + 端口)
|
||||
|
||||
适用:家里/办公室内网,例如服务器 `192.168.8.6`。
|
||||
|
||||
### 3.1 端口约定(示例,以你实际为准)
|
||||
|
||||
| 服务 | 端口 |
|
||||
|------|------|
|
||||
| 中控 hub | 5100 |
|
||||
| OKX Flask | 5004 |
|
||||
| 币安 Flask | 5001 |
|
||||
| Gate 训练 | 5000 |
|
||||
| Gate 趋势 | 5002 |
|
||||
| agent | 15200~15203(仅本机) |
|
||||
|
||||
### 3.2 系统设置 `hub_settings.json`(网页「系统设置」保存)
|
||||
|
||||
浏览器里你会打开的地址,应使用 **内网 IP**,不要用 `127.0.0.1`(否则别的电脑上的浏览器会连到你本机):
|
||||
|
||||
```json
|
||||
{
|
||||
"flask_url": "http://192.168.8.6:5004",
|
||||
"agent_url": "http://127.0.0.1:15201"
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- **`flask_url`**:给浏览器用的实例页地址 → 写 **`http://192.168.8.6:端口`**
|
||||
- **`agent_url`**:仅中控服务器访问 → 写 **`http://127.0.0.1:1520x`**
|
||||
|
||||
各账户按上表改端口即可。
|
||||
|
||||
### 3.3 可选:`flask_url` 仍写 127.0.0.1 时
|
||||
|
||||
若坚持 `flask_url` 为 `http://127.0.0.1:5004`(仅 hub 与本机 Flask 同机),在中控 `.env` 增加:
|
||||
|
||||
```bash
|
||||
HUB_PUBLIC_ORIGIN=http://192.168.8.6
|
||||
```
|
||||
|
||||
中控会把返回给前端的链接从 `127.0.0.1` 替换为 `192.168.8.6`(端口保留)。
|
||||
|
||||
### 3.4 访问方式
|
||||
|
||||
1. 中控:`http://192.168.8.6:5100` → 登录中控 → 点「实例」→ 新标签进入 OKX,**无需**再输实例密码。
|
||||
2. 直链:`http://192.168.8.6:5004` → 出现登录页 → 输入 `APP_USERNAME` / `APP_PASSWORD`。
|
||||
|
||||
### 3.5 防火墙
|
||||
|
||||
内网自用:放行 `5100`、各 `APP_PORT`;**不要**对公网开放 agent 端口。
|
||||
|
||||
---
|
||||
|
||||
## 四、反代部署(域名 + 宝塔)
|
||||
|
||||
适用:云服务器,对外用 HTTPS 域名。
|
||||
|
||||
### 4.1 域名规划(示例)
|
||||
|
||||
| 站点 | 反代到 |
|
||||
|------|--------|
|
||||
| `hub.example.com` | `127.0.0.1:5100` |
|
||||
| `okx.example.com` | `127.0.0.1:5004` |
|
||||
| `binance.example.com` | `127.0.0.1:5001` |
|
||||
| `gate.example.com` | `127.0.0.1:5000` |
|
||||
| `gate-bot.example.com` | `127.0.0.1:5002` |
|
||||
|
||||
Flask / hub 进程仍只监听 **127.0.0.1** 或 `0.0.0.0` 本机端口,由 Nginx 对外提供 HTTPS。
|
||||
|
||||
### 4.2 宝塔操作要点
|
||||
|
||||
1. 每个域名 → **反向代理** → 目标 `http://127.0.0.1:对应端口`。
|
||||
2. 申请 **SSL**(Let’s Encrypt)。
|
||||
3. **不要**再给实例站加一层宝塔「访问密码」(避免与 Flask `/login` 重复);直链鉴权用 **`APP_USERNAME` / `APP_PASSWORD`** 即可。
|
||||
4. 自定义 Nginx 配置中保留 WebSocket/大 body 如需;确保代理头:
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
```
|
||||
|
||||
中控请求实例 API 时会带 **`X-Hub-Token`**,Nginx 默认会转发请求头,一般无需额外配置。
|
||||
|
||||
### 4.3 `hub_settings` 示例(反代)
|
||||
|
||||
```json
|
||||
{
|
||||
"flask_url": "https://okx.example.com",
|
||||
"agent_url": "http://127.0.0.1:15201"
|
||||
}
|
||||
```
|
||||
|
||||
- 浏览器与 SSO 链接使用 **`https://okx.example.com`**。
|
||||
- 中控服务器拉 `/api/hub/*` 仍走本机 `agent_url`;`flask_url` 用域名时,hub 会请求 `https://okx.example.com/api/...`(同机可通即可)。
|
||||
|
||||
同机部署时也可:
|
||||
|
||||
- `flask_url`: `http://127.0.0.1:5004`
|
||||
- `HUB_PUBLIC_ORIGIN`: `https://okx.example.com`
|
||||
|
||||
仅当**所有实例共用一个对外 IP、靠端口区分**时才适合用 `HUB_PUBLIC_ORIGIN`;**每实例独立域名**时,请直接在 `flask_url` 写该实例域名。
|
||||
|
||||
### 4.4 中控 `.env`(反代建议)
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=...
|
||||
HUB_USERNAME=...
|
||||
HUB_PASSWORD=...
|
||||
HUB_COOKIE_SECURE=true # 中控为 HTTPS 时建议开启
|
||||
```
|
||||
|
||||
### 4.5 访问方式
|
||||
|
||||
1. `https://hub.example.com` 登录中控 → 点「打开实例」→ `https://okx.example.com/hub-sso?...` → 进入系统。
|
||||
2. 地址栏直接输入 `https://okx.example.com` → `/login` → 实例账号密码。
|
||||
|
||||
---
|
||||
|
||||
## 五、SSO 行为说明(2 小时)
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| 有效期 | 默认 **7200 秒(2 小时)**,`HUB_SSO_TTL_SEC` 可改 |
|
||||
| 单次使用 | 同一链接成功登录后 **不能再用**;需在中控重新点「打开实例」 |
|
||||
| 密钥 | 复用 **`HUB_BRIDGE_TOKEN`** |
|
||||
| 直链 | 无 token → 正常 **`/login`** |
|
||||
|
||||
---
|
||||
|
||||
## 六、部署与重启顺序
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
# 各实例
|
||||
pm2 restart crypto_okx crypto_binance crypto_gate crypto_gate_bot # 名称以你为准
|
||||
|
||||
cd manual_trading_hub
|
||||
pm2 restart manual-trading-hub manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot
|
||||
```
|
||||
|
||||
改 `hub_settings` 或 `.env` 后重启 **hub + 对应实例 Flask**(`hub_bridge` 与 `/hub-sso` 在实例进程内)。
|
||||
|
||||
---
|
||||
|
||||
## 七、验收清单
|
||||
|
||||
- [ ] 四实例 `.env` 与中控 `HUB_BRIDGE_TOKEN` 一致
|
||||
- [ ] 四实例 `APP_USERNAME` / `APP_PASSWORD` 一致
|
||||
- [ ] 局域网:`flask_url` 为 `http://IP:端口`;反代:`flask_url` 为 `https://域名`
|
||||
- [ ] 已登录中控 → 点「实例」→ **无**实例登录页
|
||||
- [ ] 隐身窗口直链实例域名/IP → **有** `/login`
|
||||
- [ ] 复制「打开实例」完整 URL,用过一次后再开 → 失效并回到登录页
|
||||
|
||||
---
|
||||
|
||||
## 八、常见问题
|
||||
|
||||
**Q:从中控打开仍要登录?**
|
||||
- 检查实例是否已 `git pull` 并重启(需有 `/hub-sso`)。
|
||||
- `HUB_BRIDGE_TOKEN` 是否四所一致。
|
||||
- `hub_settings` 里该账户 `key` 是否与 `install_on_app(exchange=...)` 一致(如 `okx`、`binance`、`gate`、`gate_bot`)。
|
||||
|
||||
**Q:直链也要登录中控?**
|
||||
- 不应。直链只走实例 `/login`。若跳到中控,检查是否点错链接或 Nginx 配错站点。
|
||||
|
||||
**Q:链接多久失效?**
|
||||
- 签发后 **2 小时**内且 **未使用过**;过期或已用需在中控重新点打开。
|
||||
|
||||
更多故障见 [常见问题.md](./常见问题.md)、[部署文档.md](./部署文档.md)。
|
||||
# 中控 · 局域网与反代部署说明
|
||||
|
||||
本文说明在 **局域网(IP + 端口)** 与 **宝塔/Nginx 反代(域名)** 两种场景下,如何配置中控与各实例,并实现:
|
||||
|
||||
- **从中控** 点「实例 / 策略交易 / 复盘」→ **免输入** 实例网页密码(SSO 临时链接,默认 **2 小时** 内有效、**单次使用**)
|
||||
- **浏览器直链** 实例地址(反代域名或 `http://IP:端口`)→ 进入 **`/login`**,输入统一 **`APP_USERNAME` / `APP_PASSWORD`**
|
||||
|
||||
SSO 签名复用 **`HUB_BRIDGE_TOKEN`**(与中控调实例 API 相同,三所 `.env` 与 `manual_trading_hub/.env` 保持一致)。
|
||||
|
||||
**云服务器(VPS)** 的硬件、安全组、宝塔、环境变量与验收清单见 **[云服务器部署说明.md](./云服务器部署说明.md)**。
|
||||
|
||||
---
|
||||
|
||||
## 一、两种访问方式对照
|
||||
|
||||
| 项目 | 局域网 | 反代(域名) |
|
||||
|------|--------|----------------|
|
||||
| 中控地址 | `http://内网IP:5100` | `https://hub.你的域名.com` |
|
||||
| 实例地址(浏览器) | `http://内网IP:5004` 等 | `https://okx.你的域名.com` 等 |
|
||||
| `hub_settings` 里 `flask_url` | 建议写 **`http://内网IP:端口`** | 建议写 **`https://该实例域名`**(与浏览器一致) |
|
||||
| 中控本机调实例 API | 可与浏览器相同;同机也可用 `http://127.0.0.1:端口` + `HUB_PUBLIC_ORIGIN` | 同机可用 `127.0.0.1:端口` 或域名(需 Nginx 转发 `X-Hub-Token`) |
|
||||
| `HUB_PUBLIC_ORIGIN` | 若 `flask_url` 填 `127.0.0.1`,**必填** `http://内网IP` | 若 `flask_url` 已是完整域名,**可不设** |
|
||||
| 宝塔 | 可不装反代,直连端口 | 每实例一个站点 + SSL;中控单独站点 |
|
||||
| 直链登录 | 实例 `/login` | 实例 `/login` |
|
||||
| 从中控打开 | `/hub-sso?token=...` 自动登录 | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## 二、共用环境变量(必配)
|
||||
|
||||
### 2.1 中控 `manual_trading_hub/.env`
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=请填一长串随机字符
|
||||
HUB_USERNAME=admin # 中控登录(建议设置)
|
||||
HUB_PASSWORD=你的中控密码
|
||||
HUB_SSO_TTL_SEC=7200 # 可选,默认 7200 = 2 小时
|
||||
```
|
||||
|
||||
### 2.2 三个实例 `crypto_monitor_*/.env`
|
||||
|
||||
每个目录相同(**直链**时用这套登录实例网页):
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=与中控完全相同
|
||||
APP_USERNAME=统一用户名
|
||||
APP_PASSWORD=统一密码
|
||||
# 云上切勿 APP_AUTH_DISABLED=true
|
||||
```
|
||||
|
||||
### 2.3 子代理
|
||||
|
||||
`CONTROL_TOKEN` 可与 `HUB_BRIDGE_TOKEN` 相同;子代理只监听 `127.0.0.1`,**不要**对公网暴露 `15200`~`15202`。
|
||||
|
||||
---
|
||||
|
||||
## 三、局域网部署(IP + 端口)
|
||||
|
||||
适用:家里/办公室内网,例如服务器 `192.168.8.6`。
|
||||
|
||||
### 3.1 端口约定(示例,以你实际为准)
|
||||
|
||||
| 服务 | 端口 |
|
||||
|------|------|
|
||||
| 中控 hub | 5100 |
|
||||
| OKX Flask | 5004 |
|
||||
| 币安 Flask | 5001 |
|
||||
| Gate | 5000 |
|
||||
| agent | 15200~15202(仅本机) |
|
||||
|
||||
### 3.2 系统设置 `hub_settings.json`(网页「系统设置」保存)
|
||||
|
||||
浏览器里你会打开的地址,应使用 **内网 IP**,不要用 `127.0.0.1`(否则别的电脑上的浏览器会连到你本机):
|
||||
|
||||
```json
|
||||
{
|
||||
"flask_url": "http://192.168.8.6:5004",
|
||||
"agent_url": "http://127.0.0.1:15201"
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- **`flask_url`**:给浏览器用的实例页地址 → 写 **`http://192.168.8.6:端口`**
|
||||
- **`agent_url`**:仅中控服务器访问 → 写 **`http://127.0.0.1:1520x`**
|
||||
|
||||
各账户按上表改端口即可。
|
||||
|
||||
### 3.3 可选:`flask_url` 仍写 127.0.0.1 时
|
||||
|
||||
若坚持 `flask_url` 为 `http://127.0.0.1:5004`(仅 hub 与本机 Flask 同机),在中控 `.env` 增加:
|
||||
|
||||
```bash
|
||||
HUB_PUBLIC_ORIGIN=http://192.168.8.6
|
||||
```
|
||||
|
||||
中控会把返回给前端的链接从 `127.0.0.1` 替换为 `192.168.8.6`(端口保留)。
|
||||
|
||||
### 3.4 访问方式
|
||||
|
||||
1. 中控:`http://192.168.8.6:5100` → 登录中控 → 点「实例」→ 新标签进入 OKX,**无需**再输实例密码。
|
||||
2. 直链:`http://192.168.8.6:5004` → 出现登录页 → 输入 `APP_USERNAME` / `APP_PASSWORD`。
|
||||
|
||||
### 3.5 防火墙
|
||||
|
||||
内网自用:放行 `5100`、各 `APP_PORT`;**不要**对公网开放 agent 端口。
|
||||
|
||||
---
|
||||
|
||||
## 四、反代部署(域名 + 宝塔)
|
||||
|
||||
适用:云服务器,对外用 HTTPS 域名。
|
||||
|
||||
### 4.1 域名规划(示例)
|
||||
|
||||
| 站点 | 反代到 |
|
||||
|------|--------|
|
||||
| `hub.example.com` | `127.0.0.1:5100` |
|
||||
| `okx.example.com` | `127.0.0.1:5004` |
|
||||
| `binance.example.com` | `127.0.0.1:5001` |
|
||||
| `gate.example.com` | `127.0.0.1:5000` |
|
||||
|
||||
Flask / hub 进程仍只监听 **127.0.0.1** 或 `0.0.0.0` 本机端口,由 Nginx 对外提供 HTTPS。
|
||||
|
||||
### 4.2 宝塔操作要点
|
||||
|
||||
1. 每个域名 → **反向代理** → 目标 `http://127.0.0.1:对应端口`。
|
||||
2. 申请 **SSL**(Let’s Encrypt)。
|
||||
3. **不要**再给实例站加一层宝塔「访问密码」(避免与 Flask `/login` 重复);直链鉴权用 **`APP_USERNAME` / `APP_PASSWORD`** 即可。
|
||||
4. 自定义 Nginx 配置中保留 WebSocket/大 body 如需;确保代理头:
|
||||
|
||||
```nginx
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
```
|
||||
|
||||
中控请求实例 API 时会带 **`X-Hub-Token`**,Nginx 默认会转发请求头,一般无需额外配置。
|
||||
|
||||
### 4.3 `hub_settings` 示例(反代)
|
||||
|
||||
```json
|
||||
{
|
||||
"flask_url": "https://okx.example.com",
|
||||
"agent_url": "http://127.0.0.1:15201"
|
||||
}
|
||||
```
|
||||
|
||||
- 浏览器与 SSO 链接使用 **`https://okx.example.com`**。
|
||||
- 中控服务器拉 `/api/hub/*` 仍走本机 `agent_url`;`flask_url` 用域名时,hub 会请求 `https://okx.example.com/api/...`(同机可通即可)。
|
||||
|
||||
同机部署时也可:
|
||||
|
||||
- `flask_url`: `http://127.0.0.1:5004`
|
||||
- `HUB_PUBLIC_ORIGIN`: `https://okx.example.com`
|
||||
|
||||
仅当**所有实例共用一个对外 IP、靠端口区分**时才适合用 `HUB_PUBLIC_ORIGIN`;**每实例独立域名**时,请直接在 `flask_url` 写该实例域名。
|
||||
|
||||
### 4.4 中控 `.env`(反代建议)
|
||||
|
||||
```bash
|
||||
HUB_BRIDGE_TOKEN=...
|
||||
HUB_USERNAME=...
|
||||
HUB_PASSWORD=...
|
||||
HUB_COOKIE_SECURE=true # 中控为 HTTPS 时建议开启
|
||||
```
|
||||
|
||||
### 4.5 访问方式
|
||||
|
||||
1. `https://hub.example.com` 登录中控 → 点「打开实例」→ `https://okx.example.com/hub-sso?...` → 进入系统。
|
||||
2. 地址栏直接输入 `https://okx.example.com` → `/login` → 实例账号密码。
|
||||
|
||||
---
|
||||
|
||||
## 五、SSO 行为说明(2 小时)
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| 有效期 | 默认 **7200 秒(2 小时)**,`HUB_SSO_TTL_SEC` 可改 |
|
||||
| 单次使用 | 同一链接成功登录后 **不能再用**;需在中控重新点「打开实例」 |
|
||||
| 密钥 | 复用 **`HUB_BRIDGE_TOKEN`** |
|
||||
| 直链 | 无 token → 正常 **`/login`** |
|
||||
|
||||
---
|
||||
|
||||
## 六、部署与重启顺序
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
# 各实例
|
||||
pm2 restart crypto_okx crypto_binance crypto_gate # 名称以你为准
|
||||
|
||||
cd manual_trading_hub
|
||||
pm2 restart manual-trading-hub manual-agent-binance manual-agent-okx manual-agent-gate
|
||||
```
|
||||
|
||||
改 `hub_settings` 或 `.env` 后重启 **hub + 对应实例 Flask**(`hub_bridge` 与 `/hub-sso` 在实例进程内)。
|
||||
|
||||
---
|
||||
|
||||
## 七、验收清单
|
||||
|
||||
- [ ] 三实例 `.env` 与中控 `HUB_BRIDGE_TOKEN` 一致
|
||||
- [ ] 三实例 `APP_USERNAME` / `APP_PASSWORD` 一致
|
||||
- [ ] 局域网:`flask_url` 为 `http://IP:端口`;反代:`flask_url` 为 `https://域名`
|
||||
- [ ] 已登录中控 → 点「实例」→ **无**实例登录页
|
||||
- [ ] 隐身窗口直链实例域名/IP → **有** `/login`
|
||||
- [ ] 复制「打开实例」完整 URL,用过一次后再开 → 失效并回到登录页
|
||||
|
||||
---
|
||||
|
||||
## 八、常见问题
|
||||
|
||||
**Q:从中控打开仍要登录?**
|
||||
- 检查实例是否已 `git pull` 并重启(需有 `/hub-sso`)。
|
||||
- `HUB_BRIDGE_TOKEN` 是否三所一致。
|
||||
- `hub_settings` 里该账户 `key` 是否与 `install_on_app(exchange=...)` 一致(如 `okx`、`binance`、`gate`、`gate`)。
|
||||
|
||||
**Q:直链也要登录中控?**
|
||||
- 不应。直链只走实例 `/login`。若跳到中控,检查是否点错链接或 Nginx 配错站点。
|
||||
|
||||
**Q:链接多久失效?**
|
||||
- 签发后 **2 小时**内且 **未使用过**;过期或已用需在中控重新点打开。
|
||||
|
||||
更多故障见 [常见问题.md](./常见问题.md)、[部署文档.md](./部署文档.md)。
|
||||
|
||||
+354
-354
@@ -1,354 +1,354 @@
|
||||
# 中控与四实例 — 常见问题实录
|
||||
|
||||
本文档整理部署与运行 **manual_trading_hub**(复盘系统中控)及四所 `crypto_monitor_*` 时**实际遇到过**的问题与处理办法。操作步骤仍以 [使用说明.md](./使用说明.md)、[部署文档.md](./部署文档.md) 为准。
|
||||
|
||||
---
|
||||
|
||||
## 一、中控进程与代码版本
|
||||
|
||||
### 1.1 PM2 日志仍出现 `api_trade_key`、`python-multipart` 断言
|
||||
|
||||
**现象**:`pm2 logs` 里报错 `File "hub.py", line 324, in api_trade_key` 或 `The python-multipart library must be installed`。
|
||||
|
||||
**原因**:
|
||||
|
||||
- 服务器上的 `hub.py` 仍是**旧版**(含已移除的「下单区」接口),或 pull 后**未重启** PM2,日志是历史残留。
|
||||
- 旧版「添加关键位」会 `request.form()`,未装 `python-multipart` 时直接 500。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
git pull
|
||||
|
||||
cd manual_trading_hub
|
||||
bash scripts/fix_hub_deps.sh # 安装 python-multipart 等
|
||||
bash scripts/verify_hub_deploy.sh # 应显示无 api_trade_key、含 HUB_BUILD
|
||||
|
||||
pm2 restart manual-trading-hub
|
||||
curl -s http://127.0.0.1:5100/api/ping
|
||||
```
|
||||
|
||||
**正常 ping**(无需登录)应含 `"build":"20260521-no-trade-ui"`、`"trade_ui":false`。
|
||||
|
||||
**说明**:当前版本**已移除中控下单区**;添加关键位、人工下单、趋势回调请在监控卡片点 **「实例」** 进入各 Flask 网页。浏览器请 **Ctrl+F5** 强刷,避免旧前端缓存仍请求 `/api/trade/key`。
|
||||
|
||||
---
|
||||
|
||||
### 1.2 `curl /api/ping` 返回 `{"detail":"未登录"}`
|
||||
|
||||
**原因**:早期版本未把 `/api/ping` 列入免登录白名单(已修复)。
|
||||
|
||||
**处理**:`git pull` 后 `pm2 restart manual-trading-hub`;再测应直接返回 JSON,无需 Cookie。
|
||||
|
||||
---
|
||||
|
||||
### 1.3 `verify_hub_deploy.sh` 报 `Expecting value: line 1 column 1`
|
||||
|
||||
**原因**:5100 端口无进程监听(hub 未启动或已崩溃),`curl` 拿到空响应。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
pm2 restart manual-trading-hub
|
||||
sleep 2
|
||||
pm2 logs manual-trading-hub --lines 30 --nostream
|
||||
ss -ltn | grep 5100
|
||||
bash scripts/verify_hub_deploy.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 1.4 `bash scripts/fix_hub_deps.sh` 在仓库根目录找不到
|
||||
|
||||
**原因**:脚本在 `manual_trading_hub/scripts/` 下,不在 `/opt/crypto_monitor/scripts/`。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor/manual_trading_hub
|
||||
bash scripts/fix_hub_deps.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、登录与 Cookie(反代 / 域名 / 内网 IP)
|
||||
|
||||
### 2.1 设了密码后,域名能登录,`http://内网IP:5100` 不能
|
||||
|
||||
**原因**(最常见):
|
||||
|
||||
- `.env` 中 `HUB_COOKIE_SECURE=true`,且用 **HTTP** 访问 IP:5100 → 浏览器**不保存**带 `Secure` 的 Cookie,表现为登录成功后又跳回登录页。
|
||||
- **域名(HTTPS)** 与 **IP:5100(HTTP)** 是不同站点,Cookie **不共用**,需在 IP 上再登一次。
|
||||
|
||||
**处理**:
|
||||
|
||||
- 已支持:仅在实际 **HTTPS** 请求时发 `Secure` Cookie(读 `X-Forwarded-Proto`),HTTP 内网 IP 可正常登录。
|
||||
- 反代 Nginx 需传:`proxy_set_header X-Forwarded-Proto $scheme;`
|
||||
- 若仍异常:HTTPS 域名与 HTTP IP **分别登录**;或内网仅用 IP 时可注释 `HUB_COOKIE_SECURE`。
|
||||
|
||||
### 2.2 登录后接口仍 401
|
||||
|
||||
| 检查项 | 说明 |
|
||||
|--------|------|
|
||||
| 用户名密码 | `.env` 中 `HUB_USERNAME`(未设默认为 `admin`)、`HUB_PASSWORD` |
|
||||
| 改密后 | 需重新登录;旧 Cookie 失效 |
|
||||
| 混用地址 | 不要用 A 浏览器标签登域名、B 标签指望 IP 已登录 |
|
||||
|
||||
### 2.3 本地导航 iframe 嵌入:登录成功但一直「跳转中」/ 进不去
|
||||
|
||||
**原因**:父页(如 `http://192.168.8.6:5070`)跨域 `fetch` 中控 `/api/auth/login` 时,浏览器**不会**把 `Set-Cookie` 写进 iframe 里的中控站点,表现为接口 200、弹窗「登录成功」,但 iframe 仍无会话。
|
||||
|
||||
**处理**(中控 `git pull` 并重启 hub 后):
|
||||
|
||||
1. 登录接口会返回 `session_token`;父页应把 iframe 指向:
|
||||
`http://中控地址/embed-auth?token=会话token&next=/monitor`
|
||||
2. 若直接在 iframe 内打开中控 `/login` 登录,页面会自动走 `/embed-auth` 写入 Cookie。
|
||||
3. 父页也可监听 `postMessage`,事件类型 `hub:login-ok`,字段含 `embed_auth_url`。
|
||||
|
||||
`.env` 可选:
|
||||
|
||||
```env
|
||||
HUB_ALLOW_EMBED=true
|
||||
HUB_EMBED_ORIGINS=http://192.168.8.6:5070
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、监控区无数据 / 子代理异常
|
||||
|
||||
### 3.1 卡片「子代理不可用」或余额为 —
|
||||
|
||||
| 原因 | 处理 |
|
||||
|------|------|
|
||||
| agent 未启动 | `pm2 restart ecosystem.config.cjs` 或 `pm2 restart manual-agent-*` |
|
||||
| Agent URL 与端口不符 | 系统设置里应为 `http://127.0.0.1:15200` 等 |
|
||||
| PM2 未加载策略 `.env` | 须用 `run_agent.sh` 启动(会 `source` 各目录 `.env`),勿裸跑 `agent.py` |
|
||||
| `.env` 为 Windows CRLF | 日志 `$'\r': command not found` → `bash scripts/fix_env_crlf.sh` 后重启 |
|
||||
|
||||
验证:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:15202/status | head -c 300
|
||||
```
|
||||
|
||||
应 `ok: true` 且有 `balance_usdt`。
|
||||
|
||||
### 3.3 Gate 子代理「一会正常、一会连不上」(仅 Gate 两户)
|
||||
|
||||
| 现象 | 说明 |
|
||||
|------|------|
|
||||
| 中控 LINK 2/4,仅 Gate 红 | 本机 `15202`/`15203` 在 PM2 重启间隙连不上 |
|
||||
| 日志 `$'\r': command not found` | `crypto_monitor_gate*` 的 `.env` 为 Windows CRLF |
|
||||
| `curl` 有时通有时不通 | 与 Gate 外网无关,先修 CRLF 并重建 agent |
|
||||
|
||||
**修复**(服务器):
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
sed -i 's/\r$//' crypto_monitor_gate/.env crypto_monitor_gate_bot/.env
|
||||
bash manual_trading_hub/scripts/fix_env_crlf.sh
|
||||
cd manual_trading_hub && pm2 restart manual-agent-gate manual-agent-gate-bot
|
||||
# 仍反复重启时:pm2 delete 后按 ecosystem.config.cjs 重新 start(见部署文档 §5.6)
|
||||
```
|
||||
|
||||
修好后 `pm2 describe manual-agent-gate` 的 **restarts** 应不再疯涨;`pm2 flush manual-agent-gate` 可清掉旧 CRLF 日志。
|
||||
|
||||
**若子代理已绿但挂委托失败**:再查 `GATE_SOCKS_PROXY`、API 权限、止损止盈价格是否合理(与各实例策略页相同 `.env` 参数)。
|
||||
|
||||
### 3.2 有持仓但无关键位 / 趋势,或提示 Flask 404
|
||||
|
||||
| 原因 | 处理 |
|
||||
|------|------|
|
||||
| 对应 `crypto_*` Flask 未启动 | `pm2 restart crypto_gate` 等 |
|
||||
| 未注册 `hub_bridge` | 启动日志勿含 `[hub_bridge] ImportError`;仓库根需在 `PYTHONPATH`(各实例 `ecosystem.config.cjs` 已配 `PYTHONPATH=..`) |
|
||||
| 中控 `ModuleNotFoundError: hub_auth` | 确认仓库根存在 `/opt/crypto_monitor/hub_auth.py`(`git pull`);`run_hub.sh` / PM2 已设 `PYTHONPATH=仓库根`;`pm2 restart manual-trading-hub` |
|
||||
| `HUB_BRIDGE_TOKEN` 不一致 | 中控 `.env` 与四实例 `.env` 设相同令牌,或实例 `APP_AUTH_DISABLED=true`(仅建议本机) |
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Hub-Token:你的令牌" http://127.0.0.1:5000/api/hub/ping
|
||||
```
|
||||
|
||||
### 3.3 中控监控区打开慢、一直转圈
|
||||
|
||||
**原因(常见)**:
|
||||
|
||||
1. 首屏要等 **`/api/monitor/board`**:向 4 个子代理拉持仓/余额,并向 4 个 Flask 拉监控与(默认)关键位行情;任一实例慢或超时都会拖住整页。
|
||||
2. 旧版 hub 对每所 Flask **串行**请求,4 所 × 3 接口容易累计到十几秒;新版已改为**并行**(`git pull` 后 `pm2 restart manual-trading-hub`)。
|
||||
3. 各实例 **`/api/price_snapshot`** 会调交易所接口(含全量持仓),最耗时;内网访问 Google 字体也会拖首屏渲染。
|
||||
4. 子代理 `/status` 里 `fetch_balance` / `fetch_positions` / 挂单列表走交易所 API,网络差时单次可达数秒。
|
||||
|
||||
**加快办法**:
|
||||
|
||||
```env
|
||||
# manual_trading_hub/.env
|
||||
HUB_BOARD_KEY_PRICES=false # 不拉 price_snapshot,关键位门控显示为「-」,首屏明显更快
|
||||
HUB_AGENT_TIMEOUT=6
|
||||
HUB_FLASK_TIMEOUT=8
|
||||
```
|
||||
|
||||
并确认四所 `crypto_*` 与 `manual-agent-*` 均为 **online**,避免等满超时。浏览器 **Ctrl+F5** 强刷静态资源(版本号含 `20260525-perf`)。
|
||||
|
||||
---
|
||||
|
||||
## 四、云服务器 / 公网反代
|
||||
|
||||
**云服务器完整配置(安全组、宝塔、环境变量、PM2、验收)** 见 **[云服务器部署说明.md](./云服务器部署说明.md)**。
|
||||
|
||||
---
|
||||
|
||||
## 五、复盘链接与公网反代
|
||||
|
||||
### 4.1 监控里点「复盘」打开的是本机 127.0.0.1
|
||||
|
||||
**原因**:未设 `HUB_PUBLIC_ORIGIN`,浏览器拿到的链接仍是 Flask 本机地址。
|
||||
|
||||
**处理**:`manual_trading_hub/.env` 增加(示例):
|
||||
|
||||
```env
|
||||
HUB_PUBLIC_ORIGIN=http://192.168.8.6
|
||||
```
|
||||
|
||||
或 `HUB_PUBLIC_HOST=192.168.8.6`。改后 `pm2 restart manual-trading-hub`。
|
||||
|
||||
**说明**:仅反代中控、四实例 Flask 仍只监听 127.0.0.1 时,其它电脑要能打开复盘,还须能访问各实例端口或单独反代。
|
||||
|
||||
### 4.2 只反代中控、不反代四实例
|
||||
|
||||
**可以**。中控聚合监控与全平;复盘、下单、关键位维护进各实例网页。实例 Flask/agent 建议 `127.0.0.1` + 与中控相同的 `HUB_BRIDGE_TOKEN`。
|
||||
|
||||
### 4.3 从中控「打开实例」仍要输密码
|
||||
|
||||
**完整说明**:[局域网与反代部署说明.md](./局域网与反代部署说明.md)
|
||||
|
||||
**常见原因**:
|
||||
|
||||
1. 四实例未重启,`/hub-sso` 未加载(启动日志勿长期 `[hub_bridge] ImportError`)。
|
||||
2. `HUB_BRIDGE_TOKEN` 与四实例 `.env` 不一致。
|
||||
3. `hub_settings` 里该户 `key` 与实例 `install_on_app(exchange=...)` 不一致(如 `okx`、`gate_bot`)。
|
||||
4. **HTTPS 跨域 iframe**:中控与实例不同域名时,四实例须 `APP_COOKIE_SECURE=true`(使 session Cookie 为 `SameSite=None`),否则 SSO 成功仍跳 `/login`。
|
||||
5. **经本地导航打开中控**(LocalNav → 中控 iframe → 点实例):旧版会在中控内再嵌一层实例 iframe,Cookie 易失效。请升级 **LocalNav + 中控** 最新代码:点实例后由导航页直接打开实例,工具栏有「← 中控」;须配置 `NAV_HUB_USERNAME` / `NAV_HUB_PASSWORD`,四实例 `HUB_EMBED_PARENT_ORIGINS` 含本地导航地址(如 `http://192.168.8.6:5070`)。
|
||||
6. 浏览器仍用旧书签直链首页,未从中控点「实例」(直链本来就要登录)。
|
||||
|
||||
**直链**:`http://IP:端口` 或 `https://实例域名` → 使用各实例 **`APP_USERNAME` / `APP_PASSWORD`**(四所建议统一)。
|
||||
|
||||
---
|
||||
|
||||
## 六、Gate 趋势 / 复盘相关(实例侧)
|
||||
|
||||
### 5.1 Gate 趋势 `/records` 或预览 500(`preview_created_at`)
|
||||
|
||||
**原因**:数据库缺列或查询未兼容旧库。
|
||||
|
||||
**处理**:`git pull` 后重启 `crypto_gate_bot`;必要时在实例目录执行一次带 `init_db` 的启动或按该目录更新文档迁移。
|
||||
|
||||
### 5.2 中控监控区 Gate 趋势户「无关键位」
|
||||
|
||||
**设计如此**:Gate 趋势户通常只勾 **监控趋势计划**,不勾关键位;关键位在 Gate 训练户。四所 **策略交易** 均在各实例 `/strategy`,与中控勾选无关。增加 Gate 子账户见 [使用说明.md](./使用说明.md) **§4.3**。
|
||||
|
||||
---
|
||||
|
||||
## 七、环境与配置
|
||||
|
||||
### 6.1 OKX 默认不显示
|
||||
|
||||
`HUB_DISABLED_IDS=1`(默认关 OKX)。要用 OKX:清空或改掉该变量,并在系统设置启用 id=1。
|
||||
|
||||
### 6.2 公网 IP 直连中控 403
|
||||
|
||||
`HUB_TRUST_LAN=true` 时仅允许本机 + RFC1918 私网(10/172.16/192.168)。公网 IP 直连 5100 会被拒;应走 **Nginx 反代到 127.0.0.1:5100**。
|
||||
|
||||
### 4.4 浏览器显示 `{"detail":"forbidden"}`
|
||||
|
||||
**原因**:中控 `local_only` 中间件认为访问来源 IP 不允许(常见于云上 `HUB_TRUST_LAN=false` 且反代未指向 `127.0.0.1:5100`)。
|
||||
|
||||
**处理**(二选一):
|
||||
|
||||
1. `manual_trading_hub/.env` 增加 **`HUB_ALLOW_PUBLIC=true`**(已设 `HUB_PASSWORD` 时推荐),`pm2 restart manual-trading-hub`。
|
||||
2. 宝塔反代目标改为 **`http://127.0.0.1:5100`**(不要用公网 IP:5100 作 upstream)。
|
||||
|
||||
改后强刷浏览器再开 `/login`。
|
||||
|
||||
### 6.3 `.env` 修改不生效
|
||||
|
||||
PM2 须重启:`pm2 restart manual-trading-hub`(`run_hub.sh` 每次启动会重读 `.env`)。
|
||||
|
||||
### 6.4 `hub_settings.json` 与 Git
|
||||
|
||||
网页「系统设置」保存生成,**一般不提交 Git**。`git pull` **不会覆盖** 该文件与 `.env`。
|
||||
|
||||
---
|
||||
|
||||
## 八、功能边界(避免误用)
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| 中控下单区 | **已移除**;勿再在中控添加关键位/人工单/趋势预览 |
|
||||
| 中控能力 | 监控聚合、单户/全局紧急全平、系统设置、登录保护 |
|
||||
| 下单与关键位 | 各 `crypto_monitor_*` 原网页 |
|
||||
| 复盘 | 各实例 `/records`;中控仅「复盘」外链 |
|
||||
| 全平 | 市价减仓,不可撤销,操作前确认 |
|
||||
|
||||
---
|
||||
|
||||
## 九、推荐排障顺序
|
||||
|
||||
1. `git pull` → `manual_trading_hub` 下 `bash scripts/fix_hub_deps.sh` → `bash scripts/verify_hub_deploy.sh`
|
||||
2. `pm2 restart manual-trading-hub`(及 `ecosystem.config.cjs` 若 agent/Flask 也有问题)
|
||||
3. `curl http://127.0.0.1:5100/api/ping` → 确认 `build` 与 `trade_ui:false`
|
||||
4. 浏览器打开 `/login` 登录 → `/monitor` 强刷
|
||||
5. 逐项 `curl` 子代理 `/status`、Flask `/api/hub/ping`
|
||||
6. 仍不行则查 `pm2 logs manual-trading-hub`、`pm2 logs crypto_gate` 最近 50 行
|
||||
|
||||
---
|
||||
|
||||
## 十、行情区 K 线
|
||||
|
||||
### 10.1 只加载约 300 根(目标 1000)
|
||||
|
||||
**原因**:旧版 `hub_ohlcv_lib` 无 `since` 分页时,OKX/Gate 单次 API 常只返回 ~300 根。
|
||||
|
||||
**处理**:`git pull` 后重启 **hub + 四实例 Flask**,行情区点 **强制刷新**;浏览器强刷(`chart.js` 带版本号)。
|
||||
|
||||
### 10.2 6h / 8h 周期错乱(已移除)
|
||||
|
||||
中控行情区 **已不再提供** `6h`、`8h`(以及 `3m`/`10m`/`20m`/`30m`)。若 URL 或旧缓存仍带这些周期,会回退为 `5m`。请改用 `4h` / `12h` 等当前列表,见 [行情区说明.md](./行情区说明.md)。
|
||||
|
||||
### 10.3 12h 数据异常
|
||||
|
||||
**原因**:部分交易所无原生 12h;或本地 `hub_kline.db` 存有升级前的错误缓存。
|
||||
|
||||
**处理**:强制刷新;仍异常可停 hub 后备份并删除 `manual_trading_hub/data/hub_kline.db` 再拉取。
|
||||
|
||||
### 10.4 快捷键无效
|
||||
|
||||
- 全屏请用 **`F`**(Win 下 Ctrl+空格常被输入法占用,已不作为全屏键)。
|
||||
- 须在 **行情区** 页面且焦点不在币种输入框。
|
||||
- 升级后确认加载 `chart.js?v=...` 新版本。
|
||||
|
||||
---
|
||||
|
||||
## 十一、相关脚本
|
||||
|
||||
| 脚本 | 作用 |
|
||||
|------|------|
|
||||
| `scripts/fix_hub_deps.sh` | 安装/更新中控 venv 依赖(含 python-multipart) |
|
||||
| `scripts/verify_hub_deploy.sh` | 检查代码版本、multipart、ping、PM2 状态 |
|
||||
| `scripts/fix_env_crlf.sh` | 去除各目录 `.env` 的 Windows 换行 |
|
||||
| `scripts/run_hub.sh` | PM2 启动 hub(加载 `.env`) |
|
||||
| `scripts/run_agent.sh` | PM2 启动 agent(加载策略目录 `.env`) |
|
||||
| `scripts/pm2_hub.sh` | 启停/日志 hub+agent 一体 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 架构、页面、环境变量、API |
|
||||
| [行情区说明.md](./行情区说明.md) | K 线周期、缓存、快捷键 |
|
||||
| [部署文档.md](./部署文档.md) | Ubuntu/PM2 安装与运维 |
|
||||
| [云服务器部署说明.md](./云服务器部署说明.md) | VPS 配置、安全组、宝塔、env、验收 |
|
||||
| [局域网与反代部署说明.md](./局域网与反代部署说明.md) | 内网 IP:端口 / 域名反代、SSO |
|
||||
| [README.md](./README.md) | 速览与快速启动 |
|
||||
| [.env.example](./.env.example) | 中控环境变量模板 |
|
||||
# 中控与三实例 — 常见问题实录
|
||||
|
||||
本文档整理部署与运行 **manual_trading_hub**(复盘系统中控)及三所 `crypto_monitor_*` 时**实际遇到过**的问题与处理办法。操作步骤仍以 [使用说明.md](./使用说明.md)、[部署文档.md](./部署文档.md) 为准。
|
||||
|
||||
---
|
||||
|
||||
## 一、中控进程与代码版本
|
||||
|
||||
### 1.1 PM2 日志仍出现 `api_trade_key`、`python-multipart` 断言
|
||||
|
||||
**现象**:`pm2 logs` 里报错 `File "hub.py", line 324, in api_trade_key` 或 `The python-multipart library must be installed`。
|
||||
|
||||
**原因**:
|
||||
|
||||
- 服务器上的 `hub.py` 仍是**旧版**(含已移除的「下单区」接口),或 pull 后**未重启** PM2,日志是历史残留。
|
||||
- 旧版「添加关键位」会 `request.form()`,未装 `python-multipart` 时直接 500。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
git pull
|
||||
|
||||
cd manual_trading_hub
|
||||
bash scripts/fix_hub_deps.sh # 安装 python-multipart 等
|
||||
bash scripts/verify_hub_deploy.sh # 应显示无 api_trade_key、含 HUB_BUILD
|
||||
|
||||
pm2 restart manual-trading-hub
|
||||
curl -s http://127.0.0.1:5100/api/ping
|
||||
```
|
||||
|
||||
**正常 ping**(无需登录)应含 `"build":"20260521-no-trade-ui"`、`"trade_ui":false`。
|
||||
|
||||
**说明**:当前版本**已移除中控下单区**;添加关键位、人工下单、趋势回调请在监控卡片点 **「实例」** 进入各 Flask 网页。浏览器请 **Ctrl+F5** 强刷,避免旧前端缓存仍请求 `/api/trade/key`。
|
||||
|
||||
---
|
||||
|
||||
### 1.2 `curl /api/ping` 返回 `{"detail":"未登录"}`
|
||||
|
||||
**原因**:早期版本未把 `/api/ping` 列入免登录白名单(已修复)。
|
||||
|
||||
**处理**:`git pull` 后 `pm2 restart manual-trading-hub`;再测应直接返回 JSON,无需 Cookie。
|
||||
|
||||
---
|
||||
|
||||
### 1.3 `verify_hub_deploy.sh` 报 `Expecting value: line 1 column 1`
|
||||
|
||||
**原因**:5100 端口无进程监听(hub 未启动或已崩溃),`curl` 拿到空响应。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
pm2 restart manual-trading-hub
|
||||
sleep 2
|
||||
pm2 logs manual-trading-hub --lines 30 --nostream
|
||||
ss -ltn | grep 5100
|
||||
bash scripts/verify_hub_deploy.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 1.4 `bash scripts/fix_hub_deps.sh` 在仓库根目录找不到
|
||||
|
||||
**原因**:脚本在 `manual_trading_hub/scripts/` 下,不在 `/opt/crypto_monitor/scripts/`。
|
||||
|
||||
**处理**:
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor/manual_trading_hub
|
||||
bash scripts/fix_hub_deps.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、登录与 Cookie(反代 / 域名 / 内网 IP)
|
||||
|
||||
### 2.1 设了密码后,域名能登录,`http://内网IP:5100` 不能
|
||||
|
||||
**原因**(最常见):
|
||||
|
||||
- `.env` 中 `HUB_COOKIE_SECURE=true`,且用 **HTTP** 访问 IP:5100 → 浏览器**不保存**带 `Secure` 的 Cookie,表现为登录成功后又跳回登录页。
|
||||
- **域名(HTTPS)** 与 **IP:5100(HTTP)** 是不同站点,Cookie **不共用**,需在 IP 上再登一次。
|
||||
|
||||
**处理**:
|
||||
|
||||
- 已支持:仅在实际 **HTTPS** 请求时发 `Secure` Cookie(读 `X-Forwarded-Proto`),HTTP 内网 IP 可正常登录。
|
||||
- 反代 Nginx 需传:`proxy_set_header X-Forwarded-Proto $scheme;`
|
||||
- 若仍异常:HTTPS 域名与 HTTP IP **分别登录**;或内网仅用 IP 时可注释 `HUB_COOKIE_SECURE`。
|
||||
|
||||
### 2.2 登录后接口仍 401
|
||||
|
||||
| 检查项 | 说明 |
|
||||
|--------|------|
|
||||
| 用户名密码 | `.env` 中 `HUB_USERNAME`(未设默认为 `admin`)、`HUB_PASSWORD` |
|
||||
| 改密后 | 需重新登录;旧 Cookie 失效 |
|
||||
| 混用地址 | 不要用 A 浏览器标签登域名、B 标签指望 IP 已登录 |
|
||||
|
||||
### 2.3 本地导航 iframe 嵌入:登录成功但一直「跳转中」/ 进不去
|
||||
|
||||
**原因**:父页(如 `http://192.168.8.6:5070`)跨域 `fetch` 中控 `/api/auth/login` 时,浏览器**不会**把 `Set-Cookie` 写进 iframe 里的中控站点,表现为接口 200、弹窗「登录成功」,但 iframe 仍无会话。
|
||||
|
||||
**处理**(中控 `git pull` 并重启 hub 后):
|
||||
|
||||
1. 登录接口会返回 `session_token`;父页应把 iframe 指向:
|
||||
`http://中控地址/embed-auth?token=会话token&next=/monitor`
|
||||
2. 若直接在 iframe 内打开中控 `/login` 登录,页面会自动走 `/embed-auth` 写入 Cookie。
|
||||
3. 父页也可监听 `postMessage`,事件类型 `hub:login-ok`,字段含 `embed_auth_url`。
|
||||
|
||||
`.env` 可选:
|
||||
|
||||
```env
|
||||
HUB_ALLOW_EMBED=true
|
||||
HUB_EMBED_ORIGINS=http://192.168.8.6:5070
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、监控区无数据 / 子代理异常
|
||||
|
||||
### 3.1 卡片「子代理不可用」或余额为 —
|
||||
|
||||
| 原因 | 处理 |
|
||||
|------|------|
|
||||
| agent 未启动 | `pm2 restart ecosystem.config.cjs` 或 `pm2 restart manual-agent-*` |
|
||||
| Agent URL 与端口不符 | 系统设置里应为 `http://127.0.0.1:15200` 等 |
|
||||
| PM2 未加载策略 `.env` | 须用 `run_agent.sh` 启动(会 `source` 各目录 `.env`),勿裸跑 `agent.py` |
|
||||
| `.env` 为 Windows CRLF | 日志 `$'\r': command not found` → `bash scripts/fix_env_crlf.sh` 后重启 |
|
||||
|
||||
验证:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:15202/status | head -c 300
|
||||
```
|
||||
|
||||
应 `ok: true` 且有 `balance_usdt`。
|
||||
|
||||
### 3.3 Gate 子代理「一会正常、一会连不上」(仅 Gate 两户)
|
||||
|
||||
| 现象 | 说明 |
|
||||
|------|------|
|
||||
| 中控某所子代理红 | 本机对应 agent 端口在 PM2 重启间隙连不上 |
|
||||
| 日志 `$'\r': command not found` | `crypto_monitor_gate*` 的 `.env` 为 Windows CRLF |
|
||||
| `curl` 有时通有时不通 | 与 Gate 外网无关,先修 CRLF 并重建 agent |
|
||||
|
||||
**修复**(服务器):
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
sed -i 's/\r$//' crypto_monitor_gate/.env crypto_monitor_gate/.env
|
||||
bash manual_trading_hub/scripts/fix_env_crlf.sh
|
||||
cd manual_trading_hub && pm2 restart manual-agent-gate
|
||||
# 仍反复重启时:pm2 delete 后按 ecosystem.config.cjs 重新 start(见部署文档 §5.6)
|
||||
```
|
||||
|
||||
修好后 `pm2 describe manual-agent-gate` 的 **restarts** 应不再疯涨;`pm2 flush manual-agent-gate` 可清掉旧 CRLF 日志。
|
||||
|
||||
**若子代理已绿但挂委托失败**:再查 `GATE_SOCKS_PROXY`、API 权限、止损止盈价格是否合理(与各实例策略页相同 `.env` 参数)。
|
||||
|
||||
### 3.2 有持仓但无关键位 / 趋势,或提示 Flask 404
|
||||
|
||||
| 原因 | 处理 |
|
||||
|------|------|
|
||||
| 对应 `crypto_*` Flask 未启动 | `pm2 restart crypto_gate` 等 |
|
||||
| 未注册 `hub_bridge` | 启动日志勿含 `[hub_bridge] ImportError`;仓库根需在 `PYTHONPATH`(各实例 `ecosystem.config.cjs` 已配 `PYTHONPATH=..`) |
|
||||
| 中控 `ModuleNotFoundError: hub_auth` | 确认仓库根存在 `/opt/crypto_monitor/hub_auth.py`(`git pull`);`run_hub.sh` / PM2 已设 `PYTHONPATH=仓库根`;`pm2 restart manual-trading-hub` |
|
||||
| `HUB_BRIDGE_TOKEN` 不一致 | 中控 `.env` 与三实例 `.env` 设相同令牌,或实例 `APP_AUTH_DISABLED=true`(仅建议本机) |
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Hub-Token:你的令牌" http://127.0.0.1:5000/api/hub/ping
|
||||
```
|
||||
|
||||
### 3.3 中控监控区打开慢、一直转圈
|
||||
|
||||
**原因(常见)**:
|
||||
|
||||
1. 首屏要等 **`/api/monitor/board`**:向 4 个子代理拉持仓/余额,并向 4 个 Flask 拉监控与(默认)关键位行情;任一实例慢或超时都会拖住整页。
|
||||
2. 旧版 hub 对每所 Flask **串行**请求,3 所 × 3 接口容易累计到十几秒;新版已改为**并行**(`git pull` 后 `pm2 restart manual-trading-hub`)。
|
||||
3. 各实例 **`/api/price_snapshot`** 会调交易所接口(含全量持仓),最耗时;内网访问 Google 字体也会拖首屏渲染。
|
||||
4. 子代理 `/status` 里 `fetch_balance` / `fetch_positions` / 挂单列表走交易所 API,网络差时单次可达数秒。
|
||||
|
||||
**加快办法**:
|
||||
|
||||
```env
|
||||
# manual_trading_hub/.env
|
||||
HUB_BOARD_KEY_PRICES=false # 不拉 price_snapshot,关键位门控显示为「-」,首屏明显更快
|
||||
HUB_AGENT_TIMEOUT=6
|
||||
HUB_FLASK_TIMEOUT=8
|
||||
```
|
||||
|
||||
并确认三所 `crypto_*` 与 `manual-agent-*` 均为 **online**,避免等满超时。浏览器 **Ctrl+F5** 强刷静态资源(版本号含 `20260525-perf`)。
|
||||
|
||||
---
|
||||
|
||||
## 四、云服务器 / 公网反代
|
||||
|
||||
**云服务器完整配置(安全组、宝塔、环境变量、PM2、验收)** 见 **[云服务器部署说明.md](./云服务器部署说明.md)**。
|
||||
|
||||
---
|
||||
|
||||
## 五、复盘链接与公网反代
|
||||
|
||||
### 4.1 监控里点「复盘」打开的是本机 127.0.0.1
|
||||
|
||||
**原因**:未设 `HUB_PUBLIC_ORIGIN`,浏览器拿到的链接仍是 Flask 本机地址。
|
||||
|
||||
**处理**:`manual_trading_hub/.env` 增加(示例):
|
||||
|
||||
```env
|
||||
HUB_PUBLIC_ORIGIN=http://192.168.8.6
|
||||
```
|
||||
|
||||
或 `HUB_PUBLIC_HOST=192.168.8.6`。改后 `pm2 restart manual-trading-hub`。
|
||||
|
||||
**说明**:仅反代中控、三实例 Flask 仍只监听 127.0.0.1 时,其它电脑要能打开复盘,还须能访问各实例端口或单独反代。
|
||||
|
||||
### 4.2 只反代中控、不反代三实例
|
||||
|
||||
**可以**。中控聚合监控与全平;复盘、下单、关键位维护进各实例网页。实例 Flask/agent 建议 `127.0.0.1` + 与中控相同的 `HUB_BRIDGE_TOKEN`。
|
||||
|
||||
### 4.3 从中控「打开实例」仍要输密码
|
||||
|
||||
**完整说明**:[局域网与反代部署说明.md](./局域网与反代部署说明.md)
|
||||
|
||||
**常见原因**:
|
||||
|
||||
1. 三实例未重启,`/hub-sso` 未加载(启动日志勿长期 `[hub_bridge] ImportError`)。
|
||||
2. `HUB_BRIDGE_TOKEN` 与三实例 `.env` 不一致。
|
||||
3. `hub_settings` 里该户 `key` 与实例 `install_on_app(exchange=...)` 不一致(如 `okx`、`gate`)。
|
||||
4. **HTTPS 跨域 iframe**:中控与实例不同域名时,三实例须 `APP_COOKIE_SECURE=true`(使 session Cookie 为 `SameSite=None`),否则 SSO 成功仍跳 `/login`。
|
||||
5. **经本地导航打开中控**(LocalNav → 中控 iframe → 点实例):旧版会在中控内再嵌一层实例 iframe,Cookie 易失效。请升级 **LocalNav + 中控** 最新代码:点实例后由导航页直接打开实例,工具栏有「← 中控」;须配置 `NAV_HUB_USERNAME` / `NAV_HUB_PASSWORD`,三实例 `HUB_EMBED_PARENT_ORIGINS` 含本地导航地址(如 `http://192.168.8.6:5070`)。
|
||||
6. 浏览器仍用旧书签直链首页,未从中控点「实例」(直链本来就要登录)。
|
||||
|
||||
**直链**:`http://IP:端口` 或 `https://实例域名` → 使用各实例 **`APP_USERNAME` / `APP_PASSWORD`**(三所建议统一)。
|
||||
|
||||
---
|
||||
|
||||
## 六、Gate / 复盘相关(实例侧)
|
||||
|
||||
### 5.1 Gate `/records` 或预览 500(`preview_created_at`)
|
||||
|
||||
**原因**:数据库缺列或查询未兼容旧库。
|
||||
|
||||
**处理**:`git pull` 后重启 `crypto_gate`;必要时在实例目录执行一次带 `init_db` 的启动或按该目录更新文档迁移。
|
||||
|
||||
### 5.2 中控监控区 Gate「无关键位」
|
||||
|
||||
**说明**:若系统设置未勾选「监控关键位」,中控不会展示关键位区块;策略交易仍在各实例 `/strategy` 操作。
|
||||
|
||||
---
|
||||
|
||||
## 七、环境与配置
|
||||
|
||||
### 6.1 OKX 默认不显示
|
||||
|
||||
`HUB_DISABLED_IDS=1`(默认关 OKX)。要用 OKX:清空或改掉该变量,并在系统设置启用 id=1。
|
||||
|
||||
### 6.2 公网 IP 直连中控 403
|
||||
|
||||
`HUB_TRUST_LAN=true` 时仅允许本机 + RFC1918 私网(10/172.16/192.168)。公网 IP 直连 5100 会被拒;应走 **Nginx 反代到 127.0.0.1:5100**。
|
||||
|
||||
### 4.4 浏览器显示 `{"detail":"forbidden"}`
|
||||
|
||||
**原因**:中控 `local_only` 中间件认为访问来源 IP 不允许(常见于云上 `HUB_TRUST_LAN=false` 且反代未指向 `127.0.0.1:5100`)。
|
||||
|
||||
**处理**(二选一):
|
||||
|
||||
1. `manual_trading_hub/.env` 增加 **`HUB_ALLOW_PUBLIC=true`**(已设 `HUB_PASSWORD` 时推荐),`pm2 restart manual-trading-hub`。
|
||||
2. 宝塔反代目标改为 **`http://127.0.0.1:5100`**(不要用公网 IP:5100 作 upstream)。
|
||||
|
||||
改后强刷浏览器再开 `/login`。
|
||||
|
||||
### 6.3 `.env` 修改不生效
|
||||
|
||||
PM2 须重启:`pm2 restart manual-trading-hub`(`run_hub.sh` 每次启动会重读 `.env`)。
|
||||
|
||||
### 6.4 `hub_settings.json` 与 Git
|
||||
|
||||
网页「系统设置」保存生成,**一般不提交 Git**。`git pull` **不会覆盖** 该文件与 `.env`。
|
||||
|
||||
---
|
||||
|
||||
## 八、功能边界(避免误用)
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| 中控下单区 | **已移除**;勿再在中控添加关键位/人工单/趋势预览 |
|
||||
| 中控能力 | 监控聚合、单户/全局紧急全平、系统设置、登录保护 |
|
||||
| 下单与关键位 | 各 `crypto_monitor_*` 原网页 |
|
||||
| 复盘 | 各实例 `/records`;中控仅「复盘」外链 |
|
||||
| 全平 | 市价减仓,不可撤销,操作前确认 |
|
||||
|
||||
---
|
||||
|
||||
## 九、推荐排障顺序
|
||||
|
||||
1. `git pull` → `manual_trading_hub` 下 `bash scripts/fix_hub_deps.sh` → `bash scripts/verify_hub_deploy.sh`
|
||||
2. `pm2 restart manual-trading-hub`(及 `ecosystem.config.cjs` 若 agent/Flask 也有问题)
|
||||
3. `curl http://127.0.0.1:5100/api/ping` → 确认 `build` 与 `trade_ui:false`
|
||||
4. 浏览器打开 `/login` 登录 → `/monitor` 强刷
|
||||
5. 逐项 `curl` 子代理 `/status`、Flask `/api/hub/ping`
|
||||
6. 仍不行则查 `pm2 logs manual-trading-hub`、`pm2 logs crypto_gate` 最近 50 行
|
||||
|
||||
---
|
||||
|
||||
## 十、行情区 K 线
|
||||
|
||||
### 10.1 只加载约 300 根(目标 1000)
|
||||
|
||||
**原因**:旧版 `hub_ohlcv_lib` 无 `since` 分页时,OKX/Gate 单次 API 常只返回 ~300 根。
|
||||
|
||||
**处理**:`git pull` 后重启 **hub + 三实例 Flask**,行情区点 **强制刷新**;浏览器强刷(`chart.js` 带版本号)。
|
||||
|
||||
### 10.2 6h / 8h 周期错乱(已移除)
|
||||
|
||||
中控行情区 **已不再提供** `6h`、`8h`(以及 `3m`/`10m`/`20m`/`30m`)。若 URL 或旧缓存仍带这些周期,会回退为 `5m`。请改用 `4h` / `12h` 等当前列表,见 [行情区说明.md](./行情区说明.md)。
|
||||
|
||||
### 10.3 12h 数据异常
|
||||
|
||||
**原因**:部分交易所无原生 12h;或本地 `hub_kline.db` 存有升级前的错误缓存。
|
||||
|
||||
**处理**:强制刷新;仍异常可停 hub 后备份并删除 `manual_trading_hub/data/hub_kline.db` 再拉取。
|
||||
|
||||
### 10.4 快捷键无效
|
||||
|
||||
- 全屏请用 **`F`**(Win 下 Ctrl+空格常被输入法占用,已不作为全屏键)。
|
||||
- 须在 **行情区** 页面且焦点不在币种输入框。
|
||||
- 升级后确认加载 `chart.js?v=...` 新版本。
|
||||
|
||||
---
|
||||
|
||||
## 十一、相关脚本
|
||||
|
||||
| 脚本 | 作用 |
|
||||
|------|------|
|
||||
| `scripts/fix_hub_deps.sh` | 安装/更新中控 venv 依赖(含 python-multipart) |
|
||||
| `scripts/verify_hub_deploy.sh` | 检查代码版本、multipart、ping、PM2 状态 |
|
||||
| `scripts/fix_env_crlf.sh` | 去除各目录 `.env` 的 Windows 换行 |
|
||||
| `scripts/run_hub.sh` | PM2 启动 hub(加载 `.env`) |
|
||||
| `scripts/run_agent.sh` | PM2 启动 agent(加载策略目录 `.env`) |
|
||||
| `scripts/pm2_hub.sh` | 启停/日志 hub+agent 一体 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 架构、页面、环境变量、API |
|
||||
| [行情区说明.md](./行情区说明.md) | K 线周期、缓存、快捷键 |
|
||||
| [部署文档.md](./部署文档.md) | Ubuntu/PM2 安装与运维 |
|
||||
| [云服务器部署说明.md](./云服务器部署说明.md) | VPS 配置、安全组、宝塔、env、验收 |
|
||||
| [局域网与反代部署说明.md](./局域网与反代部署说明.md) | 内网 IP:端口 / 域名反代、SSO |
|
||||
| [README.md](./README.md) | 速览与快速启动 |
|
||||
| [.env.example](./.env.example) | 中控环境变量模板 |
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| 日期 | 计划日期(日期选择器,可手输 `YYYY-MM-DD`) |
|
||||
| 交易所 | 四所:binance / okx / gate / gate_bot(来自 hub 已启用账户) |
|
||||
| 交易所 | 三所:binance / okx / gate(来自 hub 已启用账户) |
|
||||
| 币种 | 输入 `BTC` 或 `BTC/USDT`,自动规范为 `XXX/USDT` |
|
||||
| 类型 | 趋势单 / 波段单 / 日内短线 |
|
||||
| 趋势周期 | 5m / 15m / 30m / 1h / 4h / 1d |
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
# 中控数据看板说明
|
||||
|
||||
入口:**`/dashboard`**(顶栏「数据看板」)。
|
||||
|
||||
## 能力
|
||||
|
||||
| 区块 | 说明 |
|
||||
|------|------|
|
||||
| **总览 KPI** | 交易日、平仓盈亏、笔数、浮盈亏、资金合计、实盘持仓 |
|
||||
| **分户明细** | 四户资金/交易账户、今日盈亏、浮盈亏、备注;未启用显示「未监控」 |
|
||||
| **平仓明细** | 当日平仓流水(合约、方向、结果、盈亏、时间) |
|
||||
| **风险预警** | 单户单日平仓亏损 ≥ 资金合计 **5%** 时横幅 + 卡片高亮 |
|
||||
|
||||
纯数据聚合,**不调用 AI**。交易日口径与实例一致(`TRADING_DAY_RESET_HOUR`,默认 8 点)。
|
||||
|
||||
## 刷新机制(SSE)
|
||||
|
||||
与监控区 board 类似,采用 **后台聚合 + SSE 推送版本号**:
|
||||
|
||||
1. `hub.py` 启动后 `dashboard_store` 每 **60s**(`DASHBOARD_POLL_INTERVAL_SEC`)聚合四户数据到内存快照。
|
||||
2. 浏览器打开看板页后连接 `GET /api/dashboard/stream`(`event: dashboard`)。
|
||||
3. 收到新版本号后拉取 `GET /api/dashboard/daily` 快照并局部渲染,**无整页轮询闪烁**。
|
||||
4. 监控区触发 board 刷新(全平、撤单等)时,会一并 `request_refresh` 看板,尽量与实盘同步。
|
||||
5. 「立即刷新」→ `POST /api/dashboard/refresh` 触发下一轮聚合。
|
||||
|
||||
可选环境变量:`HUB_DASHBOARD_SSE_HEARTBEAT_SEC`(默认 25,SSE 心跳间隔)。
|
||||
|
||||
## 主题与样式
|
||||
|
||||
- 跟随中控顶栏 **亮/暗主题**(`theme.js`),使用 `--panel` / `--border` / `--accent` 等变量。
|
||||
- 卡片采用 **柔光阴影**(非霓虹渐变背景);亮色主题下为浅灰投影,暗色主题为轻微内高光。
|
||||
- 盈亏仍用绿/红语义色,与全局一致。
|
||||
|
||||
## API
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/dashboard/daily` | 当前交易日快照(含 `dashboard_version`) |
|
||||
| GET | `/api/dashboard/stream` | SSE 版本推送 |
|
||||
| POST | `/api/dashboard/refresh` | 请求立即重聚合 |
|
||||
|
||||
`GET /api/ping` 含 `dashboard_version`、`dashboard_poll_interval_sec` 等字段。
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `hub_dashboard.py` — 聚合逻辑
|
||||
- `hub_dashboard_cache.py` — 后台轮询 + SSE
|
||||
- `static/dashboard.js` / `dashboard.css` — 前端
|
||||
|
||||
部署后 `git pull` 并 `pm2 restart manual-trading-hub`。
|
||||
# 中控数据看板说明
|
||||
|
||||
入口:**`/dashboard`**(顶栏「数据看板」)。
|
||||
|
||||
## 能力
|
||||
|
||||
| 区块 | 说明 |
|
||||
|------|------|
|
||||
| **总览 KPI** | 交易日、平仓盈亏、笔数、浮盈亏、资金合计、实盘持仓 |
|
||||
| **分户明细** | 三户资金/交易账户、今日盈亏、浮盈亏、备注;未启用显示「未监控」 |
|
||||
| **平仓明细** | 当日平仓流水(合约、方向、结果、盈亏、时间) |
|
||||
| **风险预警** | 单户单日平仓亏损 ≥ 资金合计 **5%** 时横幅 + 卡片高亮 |
|
||||
|
||||
纯数据聚合,**不调用 AI**。交易日口径与实例一致(`TRADING_DAY_RESET_HOUR`,默认 8 点)。
|
||||
|
||||
## 刷新机制(SSE)
|
||||
|
||||
与监控区 board 类似,采用 **后台聚合 + SSE 推送版本号**:
|
||||
|
||||
1. `hub.py` 启动后 `dashboard_store` 每 **60s**(`DASHBOARD_POLL_INTERVAL_SEC`)聚合三户数据到内存快照。
|
||||
2. 浏览器打开看板页后连接 `GET /api/dashboard/stream`(`event: dashboard`)。
|
||||
3. 收到新版本号后拉取 `GET /api/dashboard/daily` 快照并局部渲染,**无整页轮询闪烁**。
|
||||
4. 监控区触发 board 刷新(全平、撤单等)时,会一并 `request_refresh` 看板,尽量与实盘同步。
|
||||
5. 「立即刷新」→ `POST /api/dashboard/refresh` 触发下一轮聚合。
|
||||
|
||||
可选环境变量:`HUB_DASHBOARD_SSE_HEARTBEAT_SEC`(默认 25,SSE 心跳间隔)。
|
||||
|
||||
## 主题与样式
|
||||
|
||||
- 跟随中控顶栏 **亮/暗主题**(`theme.js`),使用 `--panel` / `--border` / `--accent` 等变量。
|
||||
- 卡片采用 **柔光阴影**(非霓虹渐变背景);亮色主题下为浅灰投影,暗色主题为轻微内高光。
|
||||
- 盈亏仍用绿/红语义色,与全局一致。
|
||||
|
||||
## API
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/dashboard/daily` | 当前交易日快照(含 `dashboard_version`) |
|
||||
| GET | `/api/dashboard/stream` | SSE 版本推送 |
|
||||
| POST | `/api/dashboard/refresh` | 请求立即重聚合 |
|
||||
|
||||
`GET /api/ping` 含 `dashboard_version`、`dashboard_poll_interval_sec` 等字段。
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `hub_dashboard.py` — 聚合逻辑
|
||||
- `hub_dashboard_cache.py` — 后台轮询 + SSE
|
||||
- `static/dashboard.js` / `dashboard.css` — 前端
|
||||
|
||||
部署后 `git pull` 并 `pm2 restart manual-trading-hub`。
|
||||
|
||||
+268
-268
@@ -1,268 +1,268 @@
|
||||
# 本地数据备份与迁移到云服务器
|
||||
|
||||
本文说明如何把 **本机** 上运行的 `crypto_monitor`(四实例 + 中控)的**业务数据**迁到 **云 VPS**,并正确改配置。
|
||||
**不迁移** 本机 Python 虚拟环境(`.venv`),云上重新 `pip install` 即可。
|
||||
|
||||
相关:[云服务器部署说明.md](./云服务器部署说明.md) · [部署文档.md](./部署文档.md)
|
||||
|
||||
---
|
||||
|
||||
## 一、要迁什么、不迁什么
|
||||
|
||||
### 必须迁移(业务数据)
|
||||
|
||||
| 路径(每个实例目录下) | 内容 |
|
||||
|------------------------|------|
|
||||
| `crypto.db`(或 `.env` 里 `DB_PATH` 指向的文件) | 监控单、关键位、交易记录、复盘、运行时开关等 **SQLite 全库** |
|
||||
| `static/images/`(或 `UPLOAD_DIR`) | 上传图、复盘截图等 |
|
||||
| `static/images/order_charts/`(或 `ORDER_CHART_DIR`) | 订单 K 线图(若开启) |
|
||||
|
||||
四个实例 **各有一份独立库**:
|
||||
|
||||
- `crypto_monitor_binance/crypto.db`
|
||||
- `crypto_monitor_okx/crypto.db`
|
||||
- `crypto_monitor_gate/crypto.db`
|
||||
- `crypto_monitor_gate_bot/crypto.db`
|
||||
|
||||
### 中控额外迁移
|
||||
|
||||
| 路径 | 内容 |
|
||||
|------|------|
|
||||
| `manual_trading_hub/hub_settings.json` | 账户 URL、启用状态、能力勾选(网页「系统设置」保存的文件) |
|
||||
| `manual_trading_hub/hub_ai_summaries.json` | 中控 AI 今日总结(`/ai`) |
|
||||
| `manual_trading_hub/hub_ai_chat.json` | 中控 AI 聊天会话 |
|
||||
|
||||
### 不要直接覆盖拷贝(需在云上重写)
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| 各目录 `.env` | 含 API 密钥:可在云上**手工新建**,从本机抄密钥,但须改 **`flask_url`、代理、公网相关项**(见下文) |
|
||||
| `.venv/`、`__pycache__/` | 云上重建 |
|
||||
| PM2 日志 | 无需迁 |
|
||||
|
||||
### 可选
|
||||
|
||||
- 本机 `manual_trading_hub/.env` 里的 `HUB_BRIDGE_TOKEN`、`HUB_PASSWORD` 等:记下后在云上填入,**不要**把含密钥的 `.env` 发到公开网盘。
|
||||
|
||||
---
|
||||
|
||||
## 二、迁移前准备(本地)
|
||||
|
||||
### 1. 停服务(避免数据库半写入)
|
||||
|
||||
```bash
|
||||
# 本机:停中控与子代理
|
||||
cd manual_trading_hub
|
||||
pm2 stop manual-trading-hub manual-agent-binance manual-agent-okx manual-agent-gate manual-agent-gate-bot
|
||||
|
||||
# 本机:停四个 Flask(进程名以你 pm2 list 为准)
|
||||
pm2 stop crypto_okx crypto_binance crypto_gate crypto_gate_bot
|
||||
# 或各目录 ecosystem 里的名字
|
||||
```
|
||||
|
||||
未用 PM2 时,结束对应 Python/Flask 进程后再备份。
|
||||
|
||||
### 2. 确认数据库文件位置
|
||||
|
||||
各实例目录下查看 `.env` 中 `DB_PATH`(默认 `crypto.db`)。若存在 `crypto.db-wal`、`crypto.db-shm`,**必须先停服务** 再备份。
|
||||
|
||||
---
|
||||
|
||||
## 三、本地备份(推荐用自带脚本)
|
||||
|
||||
每个实例目录执行(会备份 **库 + static/images**):
|
||||
|
||||
```bash
|
||||
cd crypto_monitor_okx
|
||||
bash scripts/backup_data.sh
|
||||
# 默认输出到 /root/backups/crypto_monitor_okx/YYYY-MM-DD/
|
||||
# 本机可改环境变量:BACKUP_ROOT=~/crypto_backups bash scripts/backup_data.sh
|
||||
```
|
||||
|
||||
对 `crypto_monitor_binance`、`crypto_monitor_gate`、`crypto_monitor_gate_bot` **各执行一次**。
|
||||
|
||||
脚本产物示例:
|
||||
|
||||
```text
|
||||
~/crypto_backups/crypto_monitor_okx/2026-05-21/
|
||||
crypto.db
|
||||
static_images.tar.gz
|
||||
manifest.txt
|
||||
```
|
||||
|
||||
### 手工打包(不用脚本时)
|
||||
|
||||
在仓库根目录示例:
|
||||
|
||||
```bash
|
||||
BACKUP=~/crypto_migrate_$(date +%Y%m%d)
|
||||
mkdir -p "$BACKUP"
|
||||
|
||||
for dir in crypto_monitor_okx crypto_monitor_binance crypto_monitor_gate crypto_monitor_gate_bot; do
|
||||
tar -czf "$BACKUP/${dir}.tar.gz" \
|
||||
-C "$dir" crypto.db static/images 2>/dev/null || \
|
||||
tar -czf "$BACKUP/${dir}.tar.gz" -C "$dir" crypto.db
|
||||
done
|
||||
|
||||
cp manual_trading_hub/hub_settings.json "$BACKUP/" 2>/dev/null || true
|
||||
cp manual_trading_hub/hub_ai_summaries.json "$BACKUP/" 2>/dev/null || true
|
||||
cp manual_trading_hub/hub_ai_chat.json "$BACKUP/" 2>/dev/null || true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、上传到云服务器
|
||||
|
||||
在**你电脑**上(把 `USER`、`云IP` 换成实际值):
|
||||
|
||||
```bash
|
||||
# 打包整个备份目录
|
||||
tar -czf crypto_migrate.tar.gz -C ~ crypto_backups # 或你的 BACKUP 路径
|
||||
|
||||
scp crypto_migrate.tar.gz USER@云IP:/tmp/
|
||||
scp manual_trading_hub/hub_settings.json USER@云IP:/tmp/ # 若单独备份
|
||||
```
|
||||
|
||||
大文件可用 **rsync**(支持断点续传):
|
||||
|
||||
```bash
|
||||
rsync -avz --progress ~/crypto_backups/ USER@云IP:/tmp/crypto_backups/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、云上恢复数据
|
||||
|
||||
假设代码已在 `/opt/crypto_monitor`(`git clone` 或 `rsync` 代码均可,**代码与数据分开**)。
|
||||
|
||||
```bash
|
||||
ssh USER@云IP
|
||||
cd /opt/crypto_monitor
|
||||
|
||||
# 解压(若用 scp 单包)
|
||||
tar -xzf /tmp/crypto_migrate.tar.gz -C /tmp
|
||||
|
||||
# 按实例恢复(示例:OKX)
|
||||
pm2 stop crypto_okx 2>/dev/null || true
|
||||
cp /tmp/crypto_backups/crypto_monitor_okx/2026-05-21/crypto.db crypto_monitor_okx/crypto.db
|
||||
tar -xzf /tmp/crypto_backups/crypto_monitor_okx/2026-05-21/static_images.tar.gz -C crypto_monitor_okx/
|
||||
# 若 tar 里是 static/images 目录结构,确认解压后路径为 crypto_monitor_okx/static/images
|
||||
|
||||
# 对其余三所重复同样步骤
|
||||
```
|
||||
|
||||
恢复中控设置:
|
||||
|
||||
```bash
|
||||
cp /tmp/hub_settings.json manual_trading_hub/hub_settings.json
|
||||
# 或解压备份里带的 hub_settings.json
|
||||
```
|
||||
|
||||
**权限**(避免 Flask 写库失败):
|
||||
|
||||
```bash
|
||||
sudo chown -R 运行用户:运行用户 /opt/crypto_monitor/crypto_monitor_*/crypto.db
|
||||
sudo chown -R 运行用户:运行用户 /opt/crypto_monitor/crypto_monitor_*/static/images
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、云上必须改的配置(比迁移本身更重要)
|
||||
|
||||
数据文件原样拷过去不够,**.env 与 hub_settings 要按云环境改**。
|
||||
|
||||
### 1. 各实例 `crypto_monitor_*/.env`
|
||||
|
||||
从本机**抄写** API 密钥等,并调整:
|
||||
|
||||
| 项 | 本地常见 | 云上建议 |
|
||||
|----|----------|----------|
|
||||
| `OKX_SOCKS_PROXY` 等 | `socks5h://127.0.0.1:1080` | **留空**(直连),除非云上仍访问不了交易所 |
|
||||
| `APP_AUTH_DISABLED` | 可能为 true(本机) | **false** 或未设置 |
|
||||
| `APP_USERNAME` / `APP_PASSWORD` | 可有 | 设统一强密码(直链登录) |
|
||||
| `HUB_BRIDGE_TOKEN` | 有 | 与中控 **完全一致** |
|
||||
|
||||
### 2. `manual_trading_hub/.env`
|
||||
|
||||
见 [云服务器部署说明.md](./云服务器部署说明.md):`HUB_PASSWORD`、`HUB_BRIDGE_TOKEN`、`HUB_COOKIE_SECURE=true` 等。
|
||||
|
||||
### 3. `hub_settings.json` 里的 URL
|
||||
|
||||
**必须**改成浏览器能打开的地址:
|
||||
|
||||
| 字段 | 云上 |
|
||||
|------|------|
|
||||
| `flask_url` | `https://okx.你的域名.com`(每实例不同子域) |
|
||||
| `agent_url` | `http://127.0.0.1:15201`(保持本机,勿写公网 IP) |
|
||||
|
||||
本机若是 `http://192.168.x.x:5004` 或 `http://127.0.0.1:5004`,上云后**一定要改**,否则「打开实例」会指错地址。
|
||||
|
||||
---
|
||||
|
||||
## 七、云上启动与验收
|
||||
|
||||
```bash
|
||||
# 依赖(各目录 venv + manual_trading_hub)
|
||||
# 见 云服务器部署说明.md、部署文档.md
|
||||
|
||||
cd /opt/crypto_monitor
|
||||
# 先四实例 Flask,再 manual_trading_hub ecosystem
|
||||
pm2 start ...
|
||||
pm2 save
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
- [ ] 各实例网页能登录,**交易记录 / 关键位 / 监控单** 与本地一致
|
||||
- [ ] 复盘图片能显示(`static/images` 路径正确)
|
||||
- [ ] 中控监控卡片能读到持仓;`hub_settings` 账户 URL 正确
|
||||
- [ ] 本机已 **停止** 或不再用同一 API Key 同时跑两套(避免重复下单)
|
||||
|
||||
---
|
||||
|
||||
## 八、迁移策略建议
|
||||
|
||||
### 方案 A:一次性切换(简单)
|
||||
|
||||
1. 本地停 PM2 → 备份 → 上传 → 云上恢复 → 改配置 → 只跑云端。
|
||||
2. 适合能接受 **短暂停机**(几十分钟)。
|
||||
|
||||
### 方案 B:先云后停本地(稳一点)
|
||||
|
||||
1. 云上先部署代码、空库跑通;
|
||||
2. 临近切换时再备份本地**最新**库覆盖云上;
|
||||
3. 切换时刻停本地、启云上。
|
||||
4. 减少「备份到上线」之间的数据空窗。
|
||||
|
||||
### 注意
|
||||
|
||||
- **同一交易所 API Key 不要本地和云上同时自动交易**,以免重复挂单。
|
||||
- 迁移后第一次在云上打开,建议先看监控单、持仓是否与预期一致,再放开自动逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 九、常见问题
|
||||
|
||||
**Q:只拷 `crypto.db` 不够吗?**
|
||||
- 复盘、上传相关功能还依赖 `static/images`;建议库 + 图片一起迁。
|
||||
|
||||
**Q:迁移后 OKX 监控单没了?**
|
||||
- 查是否拷错目录(四所各一个库)、或恢复后用了空库路径(`DB_PATH` 不一致)。
|
||||
|
||||
**Q:图片 404?**
|
||||
- 检查 `static/images` 是否解压到实例目录下;数据库里路径若为相对路径,一般与目录结构一致即可。
|
||||
|
||||
**Q:本地还用 SOCKS,云上要不要?**
|
||||
- 云上通常 **不需要** SSH 隧道;见 [云服务器部署说明.md](./云服务器部署说明.md) 与此前说明:直连稳定后去掉 `*_SOCKS_PROXY`。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关脚本
|
||||
|
||||
各实例目录:
|
||||
|
||||
```bash
|
||||
bash scripts/backup_data.sh
|
||||
```
|
||||
|
||||
环境变量:`BACKUP_ROOT`、`BACKUP_RETENTION_DAYS`、`BACKUP_INSTANCE`(见脚本内注释)。
|
||||
# 本地数据备份与迁移到云服务器
|
||||
|
||||
本文说明如何把 **本机** 上运行的 `crypto_monitor`(三实例 + 中控)的**业务数据**迁到 **云 VPS**,并正确改配置。
|
||||
**不迁移** 本机 Python 虚拟环境(`.venv`),云上重新 `pip install` 即可。
|
||||
|
||||
相关:[云服务器部署说明.md](./云服务器部署说明.md) · [部署文档.md](./部署文档.md)
|
||||
|
||||
---
|
||||
|
||||
## 一、要迁什么、不迁什么
|
||||
|
||||
### 必须迁移(业务数据)
|
||||
|
||||
| 路径(每个实例目录下) | 内容 |
|
||||
|------------------------|------|
|
||||
| `crypto.db`(或 `.env` 里 `DB_PATH` 指向的文件) | 监控单、关键位、交易记录、复盘、运行时开关等 **SQLite 全库** |
|
||||
| `static/images/`(或 `UPLOAD_DIR`) | 上传图、复盘截图等 |
|
||||
| `static/images/order_charts/`(或 `ORDER_CHART_DIR`) | 订单 K 线图(若开启) |
|
||||
|
||||
三个实例 **各有一份独立库**:
|
||||
|
||||
- `crypto_monitor_binance/crypto.db`
|
||||
- `crypto_monitor_okx/crypto.db`
|
||||
- `crypto_monitor_gate/crypto.db`
|
||||
- `crypto_monitor_gate/crypto.db`
|
||||
|
||||
### 中控额外迁移
|
||||
|
||||
| 路径 | 内容 |
|
||||
|------|------|
|
||||
| `manual_trading_hub/hub_settings.json` | 账户 URL、启用状态、能力勾选(网页「系统设置」保存的文件) |
|
||||
| `manual_trading_hub/hub_ai_summaries.json` | 中控 AI 今日总结(`/ai`) |
|
||||
| `manual_trading_hub/hub_ai_chat.json` | 中控 AI 聊天会话 |
|
||||
|
||||
### 不要直接覆盖拷贝(需在云上重写)
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| 各目录 `.env` | 含 API 密钥:可在云上**手工新建**,从本机抄密钥,但须改 **`flask_url`、代理、公网相关项**(见下文) |
|
||||
| `.venv/`、`__pycache__/` | 云上重建 |
|
||||
| PM2 日志 | 无需迁 |
|
||||
|
||||
### 可选
|
||||
|
||||
- 本机 `manual_trading_hub/.env` 里的 `HUB_BRIDGE_TOKEN`、`HUB_PASSWORD` 等:记下后在云上填入,**不要**把含密钥的 `.env` 发到公开网盘。
|
||||
|
||||
---
|
||||
|
||||
## 二、迁移前准备(本地)
|
||||
|
||||
### 1. 停服务(避免数据库半写入)
|
||||
|
||||
```bash
|
||||
# 本机:停中控与子代理
|
||||
cd manual_trading_hub
|
||||
pm2 stop manual-trading-hub manual-agent-binance manual-agent-okx manual-agent-gate
|
||||
|
||||
# 本机:停三个 Flask(进程名以你 pm2 list 为准)
|
||||
pm2 stop crypto_okx crypto_binance crypto_gate
|
||||
# 或各目录 ecosystem 里的名字
|
||||
```
|
||||
|
||||
未用 PM2 时,结束对应 Python/Flask 进程后再备份。
|
||||
|
||||
### 2. 确认数据库文件位置
|
||||
|
||||
各实例目录下查看 `.env` 中 `DB_PATH`(默认 `crypto.db`)。若存在 `crypto.db-wal`、`crypto.db-shm`,**必须先停服务** 再备份。
|
||||
|
||||
---
|
||||
|
||||
## 三、本地备份(推荐用自带脚本)
|
||||
|
||||
每个实例目录执行(会备份 **库 + static/images**):
|
||||
|
||||
```bash
|
||||
cd crypto_monitor_okx
|
||||
bash scripts/backup_data.sh
|
||||
# 默认输出到 /root/backups/crypto_monitor_okx/YYYY-MM-DD/
|
||||
# 本机可改环境变量:BACKUP_ROOT=~/crypto_backups bash scripts/backup_data.sh
|
||||
```
|
||||
|
||||
对 `crypto_monitor_binance`、`crypto_monitor_gate`、`crypto_monitor_gate` **各执行一次**。
|
||||
|
||||
脚本产物示例:
|
||||
|
||||
```text
|
||||
~/crypto_backups/crypto_monitor_okx/2026-05-21/
|
||||
crypto.db
|
||||
static_images.tar.gz
|
||||
manifest.txt
|
||||
```
|
||||
|
||||
### 手工打包(不用脚本时)
|
||||
|
||||
在仓库根目录示例:
|
||||
|
||||
```bash
|
||||
BACKUP=~/crypto_migrate_$(date +%Y%m%d)
|
||||
mkdir -p "$BACKUP"
|
||||
|
||||
for dir in crypto_monitor_okx crypto_monitor_binance crypto_monitor_gate crypto_monitor_gate; do
|
||||
tar -czf "$BACKUP/${dir}.tar.gz" \
|
||||
-C "$dir" crypto.db static/images 2>/dev/null || \
|
||||
tar -czf "$BACKUP/${dir}.tar.gz" -C "$dir" crypto.db
|
||||
done
|
||||
|
||||
cp manual_trading_hub/hub_settings.json "$BACKUP/" 2>/dev/null || true
|
||||
cp manual_trading_hub/hub_ai_summaries.json "$BACKUP/" 2>/dev/null || true
|
||||
cp manual_trading_hub/hub_ai_chat.json "$BACKUP/" 2>/dev/null || true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、上传到云服务器
|
||||
|
||||
在**你电脑**上(把 `USER`、`云IP` 换成实际值):
|
||||
|
||||
```bash
|
||||
# 打包整个备份目录
|
||||
tar -czf crypto_migrate.tar.gz -C ~ crypto_backups # 或你的 BACKUP 路径
|
||||
|
||||
scp crypto_migrate.tar.gz USER@云IP:/tmp/
|
||||
scp manual_trading_hub/hub_settings.json USER@云IP:/tmp/ # 若单独备份
|
||||
```
|
||||
|
||||
大文件可用 **rsync**(支持断点续传):
|
||||
|
||||
```bash
|
||||
rsync -avz --progress ~/crypto_backups/ USER@云IP:/tmp/crypto_backups/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、云上恢复数据
|
||||
|
||||
假设代码已在 `/opt/crypto_monitor`(`git clone` 或 `rsync` 代码均可,**代码与数据分开**)。
|
||||
|
||||
```bash
|
||||
ssh USER@云IP
|
||||
cd /opt/crypto_monitor
|
||||
|
||||
# 解压(若用 scp 单包)
|
||||
tar -xzf /tmp/crypto_migrate.tar.gz -C /tmp
|
||||
|
||||
# 按实例恢复(示例:OKX)
|
||||
pm2 stop crypto_okx 2>/dev/null || true
|
||||
cp /tmp/crypto_backups/crypto_monitor_okx/2026-05-21/crypto.db crypto_monitor_okx/crypto.db
|
||||
tar -xzf /tmp/crypto_backups/crypto_monitor_okx/2026-05-21/static_images.tar.gz -C crypto_monitor_okx/
|
||||
# 若 tar 里是 static/images 目录结构,确认解压后路径为 crypto_monitor_okx/static/images
|
||||
|
||||
# 对其余三所重复同样步骤
|
||||
```
|
||||
|
||||
恢复中控设置:
|
||||
|
||||
```bash
|
||||
cp /tmp/hub_settings.json manual_trading_hub/hub_settings.json
|
||||
# 或解压备份里带的 hub_settings.json
|
||||
```
|
||||
|
||||
**权限**(避免 Flask 写库失败):
|
||||
|
||||
```bash
|
||||
sudo chown -R 运行用户:运行用户 /opt/crypto_monitor/crypto_monitor_*/crypto.db
|
||||
sudo chown -R 运行用户:运行用户 /opt/crypto_monitor/crypto_monitor_*/static/images
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、云上必须改的配置(比迁移本身更重要)
|
||||
|
||||
数据文件原样拷过去不够,**.env 与 hub_settings 要按云环境改**。
|
||||
|
||||
### 1. 各实例 `crypto_monitor_*/.env`
|
||||
|
||||
从本机**抄写** API 密钥等,并调整:
|
||||
|
||||
| 项 | 本地常见 | 云上建议 |
|
||||
|----|----------|----------|
|
||||
| `OKX_SOCKS_PROXY` 等 | `socks5h://127.0.0.1:1080` | **留空**(直连),除非云上仍访问不了交易所 |
|
||||
| `APP_AUTH_DISABLED` | 可能为 true(本机) | **false** 或未设置 |
|
||||
| `APP_USERNAME` / `APP_PASSWORD` | 可有 | 设统一强密码(直链登录) |
|
||||
| `HUB_BRIDGE_TOKEN` | 有 | 与中控 **完全一致** |
|
||||
|
||||
### 2. `manual_trading_hub/.env`
|
||||
|
||||
见 [云服务器部署说明.md](./云服务器部署说明.md):`HUB_PASSWORD`、`HUB_BRIDGE_TOKEN`、`HUB_COOKIE_SECURE=true` 等。
|
||||
|
||||
### 3. `hub_settings.json` 里的 URL
|
||||
|
||||
**必须**改成浏览器能打开的地址:
|
||||
|
||||
| 字段 | 云上 |
|
||||
|------|------|
|
||||
| `flask_url` | `https://okx.你的域名.com`(每实例不同子域) |
|
||||
| `agent_url` | `http://127.0.0.1:15201`(保持本机,勿写公网 IP) |
|
||||
|
||||
本机若是 `http://192.168.x.x:5004` 或 `http://127.0.0.1:5004`,上云后**一定要改**,否则「打开实例」会指错地址。
|
||||
|
||||
---
|
||||
|
||||
## 七、云上启动与验收
|
||||
|
||||
```bash
|
||||
# 依赖(各目录 venv + manual_trading_hub)
|
||||
# 见 云服务器部署说明.md、部署文档.md
|
||||
|
||||
cd /opt/crypto_monitor
|
||||
# 先三实例 Flask,再 manual_trading_hub ecosystem
|
||||
pm2 start ...
|
||||
pm2 save
|
||||
```
|
||||
|
||||
验收:
|
||||
|
||||
- [ ] 各实例网页能登录,**交易记录 / 关键位 / 监控单** 与本地一致
|
||||
- [ ] 复盘图片能显示(`static/images` 路径正确)
|
||||
- [ ] 中控监控卡片能读到持仓;`hub_settings` 账户 URL 正确
|
||||
- [ ] 本机已 **停止** 或不再用同一 API Key 同时跑两套(避免重复下单)
|
||||
|
||||
---
|
||||
|
||||
## 八、迁移策略建议
|
||||
|
||||
### 方案 A:一次性切换(简单)
|
||||
|
||||
1. 本地停 PM2 → 备份 → 上传 → 云上恢复 → 改配置 → 只跑云端。
|
||||
2. 适合能接受 **短暂停机**(几十分钟)。
|
||||
|
||||
### 方案 B:先云后停本地(稳一点)
|
||||
|
||||
1. 云上先部署代码、空库跑通;
|
||||
2. 临近切换时再备份本地**最新**库覆盖云上;
|
||||
3. 切换时刻停本地、启云上。
|
||||
4. 减少「备份到上线」之间的数据空窗。
|
||||
|
||||
### 注意
|
||||
|
||||
- **同一交易所 API Key 不要本地和云上同时自动交易**,以免重复挂单。
|
||||
- 迁移后第一次在云上打开,建议先看监控单、持仓是否与预期一致,再放开自动逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 九、常见问题
|
||||
|
||||
**Q:只拷 `crypto.db` 不够吗?**
|
||||
- 复盘、上传相关功能还依赖 `static/images`;建议库 + 图片一起迁。
|
||||
|
||||
**Q:迁移后 OKX 监控单没了?**
|
||||
- 查是否拷错目录(三所各一个库)、或恢复后用了空库路径(`DB_PATH` 不一致)。
|
||||
|
||||
**Q:图片 404?**
|
||||
- 检查 `static/images` 是否解压到实例目录下;数据库里路径若为相对路径,一般与目录结构一致即可。
|
||||
|
||||
**Q:本地还用 SOCKS,云上要不要?**
|
||||
- 云上通常 **不需要** SSH 隧道;见 [云服务器部署说明.md](./云服务器部署说明.md) 与此前说明:直连稳定后去掉 `*_SOCKS_PROXY`。
|
||||
|
||||
---
|
||||
|
||||
## 十、相关脚本
|
||||
|
||||
各实例目录:
|
||||
|
||||
```bash
|
||||
bash scripts/backup_data.sh
|
||||
```
|
||||
|
||||
环境变量:`BACKUP_ROOT`、`BACKUP_RETENTION_DAYS`、`BACKUP_INSTANCE`(见脚本内注释)。
|
||||
|
||||
+130
-130
@@ -1,130 +1,130 @@
|
||||
# 行情区(K 线)说明
|
||||
|
||||
中控 **行情区** `/market` 提供多交易所 K 线查看:按需拉取、本地 SQLite 缓存、可选技术指标与持仓价格线。数据经各实例 Flask 的 `/api/hub/ohlcv`(底层 `hub_ohlcv_lib` + ccxt)获取。
|
||||
|
||||
相关代码:`manual_trading_hub/static/chart.js`、`hub_kline_store.py`(仓库根目录)、`hub.py` 的 `/api/chart/*`。
|
||||
|
||||
---
|
||||
|
||||
## 1. 入口与导航
|
||||
|
||||
| 方式 | 说明 |
|
||||
|------|------|
|
||||
| 顶栏 **行情区** | 打开 `/market` |
|
||||
| 监控区持仓 | 点击合约名(**打开行情区**)→ 跳转 `/market?exchange_key=...&symbol=...`,并带入入场/止损/止盈等标记(`sessionStorage`) |
|
||||
| 全屏工具条 | K 线全屏时可在顶部切换交易所、币种、周期并 **加载** |
|
||||
|
||||
---
|
||||
|
||||
## 2. 支持的周期
|
||||
|
||||
下拉框与后端 `CHART_TIMEFRAMES` 一致:
|
||||
|
||||
| 周期 | 数字快捷键(分钟) |
|
||||
|------|-------------------|
|
||||
| 1m | `1`(稍停或 Enter 确认;连按 `1`→`5` 为 15m) |
|
||||
| 5m | `5` |
|
||||
| 15m | `15` |
|
||||
| 1h | `60` |
|
||||
| 2h | `120` |
|
||||
| 4h | `240` |
|
||||
| 12h | `720` |
|
||||
| 1d | `1440` |
|
||||
| 1w | `10080` |
|
||||
|
||||
- 快捷键仅在行情页、且焦点不在输入框/下拉框时生效。
|
||||
- **全屏**:按 **`F`** 切换;全屏时 **`Esc`** 退出。
|
||||
- 无效或已移除的周期(如 URL 带 `6h`)会回退为默认 **5m**。
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据拉取与本地库
|
||||
|
||||
| 项 | 说明 |
|
||||
|------|------|
|
||||
| **策略** | 先读本地库,不足或过期则向对应实例拉取并写入库;Hub **后台轮询** 增量更新尾部 K 线 |
|
||||
| **库文件** | 默认 `manual_trading_hub/data/hub_kline.db`(不纳入 Git) |
|
||||
| **保留** | 默认 **15 天**(`HUB_KLINE_RETENTION_DAYS`),每次请求顺带清理更早数据 |
|
||||
| **根数** | 日内周期约 **1000** 根;`1d` / `1w` 约 **500** 根 |
|
||||
| **刷新** | Hub 约 **5 秒** 轮询:① 监控区**有持仓**的合约(默认周期 `5m`)② 行情页 **watch** 的交易所+币种+周期(页面打开时每 25s 续期)。浏览器经 **SSE** 收 `chart_version` 后拉 `/api/chart/ohlcv`。**加载** 读库;**强制刷新** 全量重拉 |
|
||||
| **分页** | OKX/Gate 等单次常限 ~300 根,中控会自动分页补全 |
|
||||
| **12h** | 若交易所无原生 12h 或 K 线间隔异常,会从 **1h** 聚合生成 |
|
||||
|
||||
环境变量(`manual_trading_hub/.env`):
|
||||
|
||||
```bash
|
||||
# HUB_KLINE_RETENTION_DAYS=15
|
||||
# HUB_KLINE_DB_PATH=/opt/crypto_monitor/manual_trading_hub/data/hub_kline.db
|
||||
# HUB_CHART_POLL_INTERVAL=5
|
||||
# HUB_CHART_POSITION_TIMEFRAME=5m
|
||||
# HUB_CHART_WATCH_TTL_SEC=45
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 图表功能
|
||||
|
||||
- **主图**:K 线 + 成交量(Lightweight Charts)。
|
||||
- **价格轴**:「自动」切换是否跟随最新价缩放。
|
||||
- **技术指标**(可选勾选):EMA 21/55、MACD、RSI(含 30/70 参考线);副图自上而下为 MACD、RSI。
|
||||
- **持仓标记**(从监控跳转时):展示入场、止损、止盈、张数、**浮盈亏**(约 5 秒随监控快照刷新)、委托摘要;K 线上绘制对应价格线。趋势回调若止盈为程序监控,止盈栏显示「程序监控」且不与止损同价误显。
|
||||
- **趋势保本移交**:移交到下单监控后,持仓卡止盈/止损与「交易所止盈止损」与实例 **下单监控** 计划价一致(不再清空为程序监控占位);交易所仅市价只减仓单时也会按价格推断展示。
|
||||
- **拖动止损线**:鼠标靠近红色止损线(⟷)可上下拖动;松手确认后调用与监控区相同的 **挂止盈/止损** API(先撤全部条件单再挂新止损+止盈)。须已有有效止盈价(交易所条件单或计划止盈);仅改止损、不改止盈时止盈价沿用当前上下文。
|
||||
- **背离**:MACD/RSI 与价格简易背离标注(箭头 + 图例说明)。
|
||||
|
||||
---
|
||||
|
||||
## 5. HTTP API(中控)
|
||||
|
||||
须登录(与监控区相同,`/api/ping` 等白名单除外)。
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/chart/meta` | 已启用交易所列表、周期列表、各周期 limit、保留天数 |
|
||||
| GET | `/api/chart/ohlcv` | 查询参数:`exchange_key`、`symbol`、`timeframe`、可选 `refresh=1` 强制刷新 |
|
||||
| POST | `/api/chart/watch` | 行情页订阅(JSON:`exchange_key`、`symbol`、`timeframe`),45s 内需续期 |
|
||||
| POST | `/api/chart/unwatch` | 离开行情页取消订阅 |
|
||||
| GET | `/api/chart/stream` | SSE:`event: chart`,含 `chart_version` 与各 `series` 版本 |
|
||||
| GET | `/api/chart/poll/meta` | 当前轮询状态与各 series 版本 |
|
||||
|
||||
实例侧(中控转发):
|
||||
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| GET | `/api/hub/ohlcv` | 各 `crypto_monitor_*` 经 `hub_bridge` 注册;参数 `symbol`、`timeframe`、`since_ms`、`limit` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 部署与升级注意
|
||||
|
||||
1. **hub** 与 **四实例 Flask** 均需 `git pull` 到含 `hub_ohlcv_lib.py`、`hub_kline_store.py` 的版本。
|
||||
2. 重启:`pm2 restart manual-trading-hub` 及 `crypto_binance`、`crypto_okx`、`crypto_gate`、`crypto_gate_bot`(名称以你环境为准)。
|
||||
3. 浏览器 **强刷**(`chart.js` 带版本 query,避免旧前端缓存)。
|
||||
4. 周期或拉取逻辑升级后,对异常图表点一次 **强制刷新**,必要时可删 `data/hub_kline.db` 后重拉(会丢失本地缓存,不影响策略库)。
|
||||
|
||||
回滚标签说明见 [SNAPSHOT_ROLLBACK.md](./SNAPSHOT_ROLLBACK.md)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 常见问题
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 只显示约 300 根 | `git pull` 实例与 hub,强制刷新;确认 `hub_ohlcv_lib` 已含分页逻辑 |
|
||||
| 12h 错乱或过少 | 强制刷新;Gate 等无原生 12h 时依赖 1h 聚合,需实例 OHLCV 正常 |
|
||||
| 周期下拉无某项 | 以当前 `CHART_TIMEFRAMES` 为准;已移除 3m/10m/20m/30m/6h/8h 等 |
|
||||
| 快捷键无效 | 确认在行情页;全屏用 **F**;数字键勿在币种输入框内按 |
|
||||
| 持仓线不显示 | 须从监控区点击合约进入;或清除标记后重新跳转 |
|
||||
|
||||
更多中控共性问题见 [常见问题.md](./常见问题.md)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 中控总览(含行情区摘要) |
|
||||
| [行情区说明.md](./行情区说明.md) | 本文 |
|
||||
| [部署文档.md](./部署文档.md) | PM2 / 反代 / 验收 |
|
||||
| [.env.example](./.env.example) | `HUB_KLINE_*` 等变量 |
|
||||
# 行情区(K 线)说明
|
||||
|
||||
中控 **行情区** `/market` 提供多交易所 K 线查看:按需拉取、本地 SQLite 缓存、可选技术指标与持仓价格线。数据经各实例 Flask 的 `/api/hub/ohlcv`(底层 `hub_ohlcv_lib` + ccxt)获取。
|
||||
|
||||
相关代码:`manual_trading_hub/static/chart.js`、`hub_kline_store.py`(仓库根目录)、`hub.py` 的 `/api/chart/*`。
|
||||
|
||||
---
|
||||
|
||||
## 1. 入口与导航
|
||||
|
||||
| 方式 | 说明 |
|
||||
|------|------|
|
||||
| 顶栏 **行情区** | 打开 `/market` |
|
||||
| 监控区持仓 | 点击合约名(**打开行情区**)→ 跳转 `/market?exchange_key=...&symbol=...`,并带入入场/止损/止盈等标记(`sessionStorage`) |
|
||||
| 全屏工具条 | K 线全屏时可在顶部切换交易所、币种、周期并 **加载** |
|
||||
|
||||
---
|
||||
|
||||
## 2. 支持的周期
|
||||
|
||||
下拉框与后端 `CHART_TIMEFRAMES` 一致:
|
||||
|
||||
| 周期 | 数字快捷键(分钟) |
|
||||
|------|-------------------|
|
||||
| 1m | `1`(稍停或 Enter 确认;连按 `1`→`5` 为 15m) |
|
||||
| 5m | `5` |
|
||||
| 15m | `15` |
|
||||
| 1h | `60` |
|
||||
| 2h | `120` |
|
||||
| 4h | `240` |
|
||||
| 12h | `720` |
|
||||
| 1d | `1440` |
|
||||
| 1w | `10080` |
|
||||
|
||||
- 快捷键仅在行情页、且焦点不在输入框/下拉框时生效。
|
||||
- **全屏**:按 **`F`** 切换;全屏时 **`Esc`** 退出。
|
||||
- 无效或已移除的周期(如 URL 带 `6h`)会回退为默认 **5m**。
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据拉取与本地库
|
||||
|
||||
| 项 | 说明 |
|
||||
|------|------|
|
||||
| **策略** | 先读本地库,不足或过期则向对应实例拉取并写入库;Hub **后台轮询** 增量更新尾部 K 线 |
|
||||
| **库文件** | 默认 `manual_trading_hub/data/hub_kline.db`(不纳入 Git) |
|
||||
| **保留** | 默认 **15 天**(`HUB_KLINE_RETENTION_DAYS`),每次请求顺带清理更早数据 |
|
||||
| **根数** | 日内周期约 **1000** 根;`1d` / `1w` 约 **500** 根 |
|
||||
| **刷新** | Hub 约 **5 秒** 轮询:① 监控区**有持仓**的合约(默认周期 `5m`)② 行情页 **watch** 的交易所+币种+周期(页面打开时每 25s 续期)。浏览器经 **SSE** 收 `chart_version` 后拉 `/api/chart/ohlcv`。**加载** 读库;**强制刷新** 全量重拉 |
|
||||
| **分页** | OKX/Gate 等单次常限 ~300 根,中控会自动分页补全 |
|
||||
| **12h** | 若交易所无原生 12h 或 K 线间隔异常,会从 **1h** 聚合生成 |
|
||||
|
||||
环境变量(`manual_trading_hub/.env`):
|
||||
|
||||
```bash
|
||||
# HUB_KLINE_RETENTION_DAYS=15
|
||||
# HUB_KLINE_DB_PATH=/opt/crypto_monitor/manual_trading_hub/data/hub_kline.db
|
||||
# HUB_CHART_POLL_INTERVAL=5
|
||||
# HUB_CHART_POSITION_TIMEFRAME=5m
|
||||
# HUB_CHART_WATCH_TTL_SEC=45
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 图表功能
|
||||
|
||||
- **主图**:K 线 + 成交量(Lightweight Charts)。
|
||||
- **价格轴**:「自动」切换是否跟随最新价缩放。
|
||||
- **技术指标**(可选勾选):EMA 21/55、MACD、RSI(含 30/70 参考线);副图自上而下为 MACD、RSI。
|
||||
- **持仓标记**(从监控跳转时):展示入场、止损、止盈、张数、**浮盈亏**(约 5 秒随监控快照刷新)、委托摘要;K 线上绘制对应价格线。趋势回调若止盈为程序监控,止盈栏显示「程序监控」且不与止损同价误显。
|
||||
- **趋势保本移交**:移交到下单监控后,持仓卡止盈/止损与「交易所止盈止损」与实例 **下单监控** 计划价一致(不再清空为程序监控占位);交易所仅市价只减仓单时也会按价格推断展示。
|
||||
- **拖动止损线**:鼠标靠近红色止损线(⟷)可上下拖动;松手确认后调用与监控区相同的 **挂止盈/止损** API(先撤全部条件单再挂新止损+止盈)。须已有有效止盈价(交易所条件单或计划止盈);仅改止损、不改止盈时止盈价沿用当前上下文。
|
||||
- **背离**:MACD/RSI 与价格简易背离标注(箭头 + 图例说明)。
|
||||
|
||||
---
|
||||
|
||||
## 5. HTTP API(中控)
|
||||
|
||||
须登录(与监控区相同,`/api/ping` 等白名单除外)。
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/chart/meta` | 已启用交易所列表、周期列表、各周期 limit、保留天数 |
|
||||
| GET | `/api/chart/ohlcv` | 查询参数:`exchange_key`、`symbol`、`timeframe`、可选 `refresh=1` 强制刷新 |
|
||||
| POST | `/api/chart/watch` | 行情页订阅(JSON:`exchange_key`、`symbol`、`timeframe`),45s 内需续期 |
|
||||
| POST | `/api/chart/unwatch` | 离开行情页取消订阅 |
|
||||
| GET | `/api/chart/stream` | SSE:`event: chart`,含 `chart_version` 与各 `series` 版本 |
|
||||
| GET | `/api/chart/poll/meta` | 当前轮询状态与各 series 版本 |
|
||||
|
||||
实例侧(中控转发):
|
||||
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| GET | `/api/hub/ohlcv` | 各 `crypto_monitor_*` 经 `hub_bridge` 注册;参数 `symbol`、`timeframe`、`since_ms`、`limit` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 部署与升级注意
|
||||
|
||||
1. **hub** 与 **三实例 Flask** 均需 `git pull` 到含 `hub_ohlcv_lib.py`、`hub_kline_store.py` 的版本。
|
||||
2. 重启:`pm2 restart manual-trading-hub` 及 `crypto_binance`、`crypto_okx`、`crypto_gate`、``(名称以你环境为准)。
|
||||
3. 浏览器 **强刷**(`chart.js` 带版本 query,避免旧前端缓存)。
|
||||
4. 周期或拉取逻辑升级后,对异常图表点一次 **强制刷新**,必要时可删 `data/hub_kline.db` 后重拉(会丢失本地缓存,不影响策略库)。
|
||||
|
||||
回滚标签说明见 [SNAPSHOT_ROLLBACK.md](./SNAPSHOT_ROLLBACK.md)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 常见问题
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 只显示约 300 根 | `git pull` 实例与 hub,强制刷新;确认 `hub_ohlcv_lib` 已含分页逻辑 |
|
||||
| 12h 错乱或过少 | 强制刷新;Gate 等无原生 12h 时依赖 1h 聚合,需实例 OHLCV 正常 |
|
||||
| 周期下拉无某项 | 以当前 `CHART_TIMEFRAMES` 为准;已移除 3m/10m/20m/30m/6h/8h 等 |
|
||||
| 快捷键无效 | 确认在行情页;全屏用 **F**;数字键勿在币种输入框内按 |
|
||||
| 持仓线不显示 | 须从监控区点击合约进入;或清除标记后重新跳转 |
|
||||
|
||||
更多中控共性问题见 [常见问题.md](./常见问题.md)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 文档索引
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [使用说明.md](./使用说明.md) | 中控总览(含行情区摘要) |
|
||||
| [行情区说明.md](./行情区说明.md) | 本文 |
|
||||
| [部署文档.md](./部署文档.md) | PM2 / 反代 / 验收 |
|
||||
| [.env.example](./.env.example) | `HUB_KLINE_*` 等变量 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 资金概况 — 使用说明
|
||||
|
||||
中控顶栏 **资金概况**(`/funds`)汇总四所账户的 **资金账户 + 交易账户** 余额,不含浮盈亏;未监控账户不参与合计,但仍会在分户列表中灰显展示。
|
||||
中控顶栏 **资金概况**(`/funds`)汇总三所账户的 **资金账户 + 交易账户** 余额,不含浮盈亏;未监控账户不参与合计,但仍会在分户列表中灰显展示。
|
||||
|
||||
---
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
| **总资金** | 所有 **已启用且未被环境强制关闭** 的账户之和 |
|
||||
| **未监控** | 设置页未勾选「启用」或 `HUB_DISABLED_IDS` 强制关闭 → **跳过合计** |
|
||||
| **缺数据** | 资金户、交易户任一侧缺失 → 该户当日快照 **跳过**(不估、不补 0) |
|
||||
| **交易日** | 北京时间 `TRADING_DAY_RESET_HOUR`(默认 **8:00**)切日,与四所统计一致 |
|
||||
| **交易日** | 北京时间 `TRADING_DAY_RESET_HOUR`(默认 **8:00**)切日,与三所统计一致 |
|
||||
| **曲线粒度** | 每个交易日 **1 个点** |
|
||||
| **统计起点** | 默认 **2026-06-09**(`HUB_FUND_HISTORY_START_DAY`);此前不记、不展示 |
|
||||
| **历史保留** | 自起点起最多 **180** 个交易日(`HUB_FUND_HISTORY_DAYS`) |
|
||||
@@ -66,7 +66,7 @@
|
||||
|------|------|------|
|
||||
| `HUB_FUND_HISTORY_DAYS` | `180` | 资金快照保留交易日数(与起点取较晚边界) |
|
||||
| `HUB_FUND_HISTORY_START_DAY` | `2026-06-09` | 曲线/回撤统计起始交易日 |
|
||||
| `TRADING_DAY_RESET_HOUR` | `8` | 切日整点(北京),与四所 `.env` 建议一致 |
|
||||
| `TRADING_DAY_RESET_HOUR` | `8` | 切日整点(北京),与三所 `.env` 建议一致 |
|
||||
| `HUB_BOARD_POLL_INTERVAL` | `5` | 监控聚合间隔(秒),影响快照刷新频率 |
|
||||
|
||||
---
|
||||
|
||||
+18
-20
@@ -16,11 +16,11 @@
|
||||
| 组件 | 作用 | 默认监听 |
|
||||
|------|------|----------|
|
||||
| **hub.py** | 中控 Web + API | `0.0.0.0:5100` |
|
||||
| **agent.py × N** | 各账户持仓 / 紧急全平 | `127.0.0.1:15200`~`15203` |
|
||||
| **agent.py × N** | 各账户持仓 / 紧急全平 | `127.0.0.1:15200`~`15202` |
|
||||
| **crypto_monitor_*.app** | 策略、关键位、下单逻辑 | 各目录 `.env` 的 `APP_PORT` |
|
||||
|
||||
- 账户列表与 URL 由 **`hub_settings.json`**(网页「系统设置」保存)或内置默认维护;**不再使用** `HUB_AGENTS`。
|
||||
- 四实例 Flask **无需为中控改业务代码**(已注册 `hub_bridge`);与中控并行运行。
|
||||
- 三实例 Flask **无需为中控改业务代码**(已注册 `hub_bridge`);与中控并行运行。
|
||||
|
||||
---
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
1. **Python 3.10+**、`python3-venv`、`pip`。
|
||||
2. **Node.js + npm**(用于安装 PM2):`sudo npm i -g pm2`。
|
||||
3. 各 `crypto_monitor_*` 目录已 **`cp .env.example .env`** 并填好 API 密钥。
|
||||
4. 端口无冲突:`5100`、`15200`~`15203`、各实例 `APP_PORT`(5000/5001/5002/5004)。
|
||||
4. 端口无冲突:`5100`、`15200`~`15202`、各实例 `APP_PORT`(5000/5001/5004)。
|
||||
5. 建议代码路径:`/opt/crypto_monitor/`(下文用此示例,请按实际路径替换)。
|
||||
|
||||
---
|
||||
@@ -64,10 +64,10 @@ deactivate # 可选;交给 PM2 时不必保持激活
|
||||
|
||||
```
|
||||
1. 各实例 Flask(APP_PORT) ← 各 crypto_monitor_* 目录 ecosystem.config.cjs
|
||||
2. 中控 + 子代理(5100 + 15200~15203) ← 本目录一条 PM2 命令同时启动
|
||||
2. 中控 + 子代理(5100 + 15200~15202) ← 本目录一条 PM2 命令同时启动
|
||||
```
|
||||
|
||||
**`ecosystem.config.cjs` 会一次拉起 4 个 agent + 1 个 hub**,无需再单独 `pm2 start` 子代理。
|
||||
**`ecosystem.config.cjs` 会一次拉起 3 个 agent + 1 个 hub**,无需再单独 `pm2 start` 子代理。
|
||||
|
||||
仅反代中控到公网时:Flask / agent 仍只监听 **127.0.0.1**;系统设置里 URL 填 `http://127.0.0.1:端口`。
|
||||
|
||||
@@ -79,7 +79,7 @@ deactivate # 可选;交给 PM2 时不必保持激活
|
||||
|
||||
| 文件 | 包含进程 |
|
||||
|------|----------|
|
||||
| `ecosystem.config.cjs` | `manual-agent-binance` / `okx` / `gate` / `gate-bot` + **`manual-trading-hub`** |
|
||||
| `ecosystem.config.cjs` | `manual-agent-binance` / `okx` / `gate` + **`manual-trading-hub`** |
|
||||
|
||||
`run_hub.sh` 加载 **`manual_trading_hub/.env`** 后执行 `hub.py`;各 agent 经 **`run_agent.sh`** 在对应策略目录加载 **`.env`**(含 API 密钥),再执行 `agent.py`。
|
||||
|
||||
@@ -89,7 +89,7 @@ source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env
|
||||
|
||||
pm2 start ecosystem.config.cjs # 5 个进程一起起
|
||||
pm2 start ecosystem.config.cjs # 4 个进程一起起
|
||||
pm2 save
|
||||
|
||||
# 或
|
||||
@@ -103,17 +103,16 @@ bash scripts/pm2_hub.sh start
|
||||
| manual-agent-binance | crypto_monitor_binance | agent `15200` |
|
||||
| manual-agent-okx | crypto_monitor_okx | agent `15201` |
|
||||
| manual-agent-gate | crypto_monitor_gate | agent `15202` |
|
||||
| manual-agent-gate-bot | crypto_monitor_gate_bot | agent `15203` |
|
||||
| manual-trading-hub | manual_trading_hub | hub `5100` |
|
||||
|
||||
OKX 子代理会启动,但中控默认 `HUB_DISABLED_IDS=1` 不参与监控;不用 OKX 可 `pm2 stop manual-agent-okx`。
|
||||
OKX 子代理会启动;不用 OKX 可 `pm2 stop manual-agent-okx`。
|
||||
|
||||
### 5.3 常用运维命令
|
||||
|
||||
```bash
|
||||
pm2 status
|
||||
pm2 logs manual-trading-hub --lines 200
|
||||
pm2 restart ecosystem.config.cjs # 重启 hub + 全部 agent
|
||||
pm2 restart ecosystem.config.cjs # 重启 hub + 全部 agent
|
||||
|
||||
bash scripts/pm2_hub.sh restart # 同上
|
||||
bash scripts/pm2_hub.sh stop
|
||||
@@ -129,7 +128,7 @@ pm2 restart manual-trading-hub
|
||||
仅重启子代理:
|
||||
|
||||
```bash
|
||||
pm2 restart manual-agent-binance manual-agent-gate manual-agent-gate-bot
|
||||
pm2 restart manual-agent-binance manual-agent-gate manual-agent-okx
|
||||
# 或
|
||||
bash scripts/pm2_agents.sh restart
|
||||
```
|
||||
@@ -153,25 +152,24 @@ pm2 status
|
||||
|
||||
### 5.6 Gate 子代理「一会能连、一会子代理不可用」(Windows `.env` 换行)
|
||||
|
||||
**现象**:仅 Gate 训练 / Gate 趋势卡片红字「子代理不可用」;`pm2 logs manual-agent-gate` 反复出现:
|
||||
**现象**:Gate 卡片红字「子代理不可用」;`pm2 logs manual-agent-gate` 反复出现:
|
||||
|
||||
```text
|
||||
./.env: line 22: $'\r': command not found
|
||||
agent start: exchange=gate port=15202 ...
|
||||
```
|
||||
|
||||
**原因**:在 Windows 编辑的 `crypto_monitor_gate/.env`、`crypto_monitor_gate_bot/.env` 为 **CRLF**,Linux 上 `source` 失败;PM2 反复重启,中控轮询时偶发连不上(**不是外网问题**)。
|
||||
**原因**:在 Windows 编辑的 `crypto_monitor_gate/.env` 为 **CRLF**,Linux 上 `source` 失败;PM2 反复重启,中控轮询时偶发连不上(**不是外网问题**)。
|
||||
|
||||
**处理**(在服务器仓库根执行):
|
||||
|
||||
```bash
|
||||
cd /opt/crypto_monitor
|
||||
sed -i 's/\r$//' crypto_monitor_gate/.env crypto_monitor_gate_bot/.env
|
||||
sed -i 's/\r$//' crypto_monitor_gate/.env
|
||||
bash manual_trading_hub/scripts/fix_env_crlf.sh
|
||||
cd manual_trading_hub
|
||||
pm2 delete manual-agent-gate manual-agent-gate-bot 2>/dev/null || true
|
||||
pm2 delete manual-agent-gate 2>/dev/null || true
|
||||
pm2 start ecosystem.config.cjs --only manual-agent-gate
|
||||
pm2 start ecosystem.config.cjs --only manual-agent-gate-bot
|
||||
pm2 save
|
||||
curl -s http://127.0.0.1:15202/status | head -c 200 # 应 ok:true
|
||||
```
|
||||
@@ -200,7 +198,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/market** — 行情区可选交易所与周期拉 K 线;升级后强刷浏览器,详见 [行情区说明.md](./行情区说明.md)。
|
||||
4. **http://127.0.0.1:5100/ai** — AI 教练(四户今日总结 + 聊天);`manual_trading_hub/.env` 配与四实例相同的 `AI_*` 变量,见 [AI教练说明.md](./AI教练说明.md)。
|
||||
4. **http://127.0.0.1:5100/ai** — AI 教练(三户今日总结 + 聊天);`manual_trading_hub/.env` 配与三实例相同的 `AI_*` 变量,见 [AI教练说明.md](./AI教练说明.md)。
|
||||
5. **http://127.0.0.1:5100/settings** — 保存后生成 `hub_settings.json`(增加第五户、Gate 子账户等见 [使用说明.md §4.5](./使用说明.md#45-增加账户例如再挂一个-gate))。
|
||||
5. 监控卡片 **「实例」** — 在各 `crypto_monitor_*` 网页做下单、关键位、趋势;中控**不提供**下单表单。
|
||||
|
||||
@@ -237,8 +235,8 @@ curl -s http://127.0.0.1:15200/status | head -c 200
|
||||
HUB_COOKIE_SECURE=true
|
||||
```
|
||||
4. `hub_settings.json` 中 Flask/Agent 保持 **`http://127.0.0.1:...`**(中控本机调 API)。
|
||||
5. 四实例 **`APP_AUTH_DISABLED=false`** + 与中控相同 **`HUB_BRIDGE_TOKEN`**。
|
||||
6. 子代理 **`HOST=127.0.0.1`**;防火墙勿对公网开放 `15200`~`15203`、各 `APP_PORT`。
|
||||
5. 三实例 **`APP_AUTH_DISABLED=false`** + 与中控相同 **`HUB_BRIDGE_TOKEN`**。
|
||||
6. 子代理 **`HOST=127.0.0.1`**;防火墙勿对公网开放 `15200`~`15202`、各 `APP_PORT`。
|
||||
7. **复盘/实例外链**:`HUB_PUBLIC_ORIGIN=https://你的域名` 或内网 IP;否则其它设备点「复盘」会跳到 `127.0.0.1`。
|
||||
|
||||
**说明**:HTTPS 域名与 HTTP `内网IP:5100` Cookie **不共用**;内网访问 IP 需在 IP 地址再登录一次(见 [常见问题.md](./常见问题.md) §2.1)。
|
||||
@@ -254,7 +252,7 @@ curl -s http://127.0.0.1:15200/status | head -c 200
|
||||
| `HUB_DISABLED_IDS` | `1` | 强制关闭的账户 id(OKX) |
|
||||
| `HUB_TRUST_LAN` | `true` | 私网可访问;仅本机可 `false` |
|
||||
| `HUB_PUBLIC_ORIGIN` | 空 | 浏览器用复盘链接;如 `http://192.168.1.100`(**内网其它电脑访问中控时建议设置**) |
|
||||
| `HUB_BRIDGE_TOKEN` | 空 | 与四实例一致;公网建议配置 |
|
||||
| `HUB_BRIDGE_TOKEN` | 空 | 与三实例一致;公网建议配置 |
|
||||
| `HUB_USERNAME` | `admin` | Web 登录用户名 |
|
||||
| `HUB_PASSWORD` | 空 | 非空即启用登录 |
|
||||
| `HUB_SESSION_SECRET` | — | 会话签名 |
|
||||
|
||||
Reference in New Issue
Block a user