首次上传
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
# 多执行器与信号转发 · 设计归档
|
||||
|
||||
本文档归档 2026-05 前后关于 **onchain_scout_gate(扫描端)** 与 **gate_order_executor(执行器)** 联动的讨论结论与已实现能力,便于后期检阅。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **一套信号** | 扫描端在企微突破推送成功后,构造 **一份** 方案 A 止盈/止损 payload |
|
||||
| **多套账户** | 可向多个执行器进程广播,各绑不同 Gate API,用于盈亏比等规则的对照实验 |
|
||||
| **规则在执行器** | 最低盈亏比、仓位、移动保本等 **不在扫描端** 区分,由各执行器自行配置 |
|
||||
| **统一 Webhook** | 全系统使用 **同一个** `webhook_secret` |
|
||||
| **仅扫描端登记** | 执行器列表 **只能** 在扫描端 Web 面板(及对应 API)维护,**禁止执行器反向注册** |
|
||||
|
||||
---
|
||||
|
||||
## 2. 架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
scout[onchain_scout_gate :8088]
|
||||
scout -->|1 次| wecom[企业微信]
|
||||
scout -->|同一 payload| exA[执行器 A]
|
||||
scout -->|同一 payload| exB[执行器 B]
|
||||
exA --> gateA[Gate 账户 A]
|
||||
exB --> gateB[Gate 账户 B]
|
||||
```
|
||||
|
||||
- 转发 **不走** 扫描端 `proxy`,直连各 `base_url`(通常 `http://127.0.0.1:8090` 或内网 IP)。
|
||||
- 各执行器独立进程、独立 `config.yaml`、独立 SQLite;互不通信。
|
||||
|
||||
---
|
||||
|
||||
## 3. 扫描端实现要点(已实现)
|
||||
|
||||
### 3.1 持久化
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `runtime/order_executors.json` | 总开关、`webhook_secret`、`timeout_seconds`、执行器列表 |
|
||||
| `config.yaml` `order_executor` | **仅冷启动**:首次无 json 时从 `base_url` / `enabled` / `secret` 导入一条 |
|
||||
|
||||
之后以 **面板修改** 为准;改 `config.yaml` **不会** 覆盖已有 json。
|
||||
|
||||
### 3.2 执行器列表字段
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `id` | UUID |
|
||||
| `name` | 展示名(日志、面板) |
|
||||
| `base_url` | 如 `http://127.0.0.1:8090` |
|
||||
| `enabled` | 单条开关 |
|
||||
| `last_forward` | 最近一次转发结果(HTTP、exec_status) |
|
||||
|
||||
### 3.3 HTTP API(需登录)
|
||||
|
||||
| 方法 | 路径 | 作用 |
|
||||
|------|------|------|
|
||||
| GET | `/api/order-executors` | 读取完整配置 |
|
||||
| PUT | `/api/order-executors/settings` | 总开关、webhook_secret、timeout |
|
||||
| POST | `/api/order-executors` | 新增 |
|
||||
| PATCH | `/api/order-executors/{id}` | 改名称/URL/启用 |
|
||||
| DELETE | `/api/order-executors/{id}` | 删除 |
|
||||
|
||||
### 3.4 转发逻辑
|
||||
|
||||
1. `build_order_executor_payload()` 仍只构建 **一次**(与企微方案 A 一致)。
|
||||
2. 对 `enabled=true` 的列表项 **并行** `POST {base_url}/v1/signal`。
|
||||
3. **同一 `signal_id`** 发往所有目标。
|
||||
4. 部分失败只记日志,不阻断其他执行器。
|
||||
|
||||
### 3.5 Web 面板
|
||||
|
||||
路径:Dashboard → **「下单执行器 · 转发链」**
|
||||
|
||||
- 总开关、Webhook 密钥(可改)、超时
|
||||
- 添加 / 启用 / 停用 / 删除
|
||||
- 展示上次转发状态
|
||||
|
||||
### 3.6 代码模块
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `app/order_executors_store.py` | 读写 json、CRUD |
|
||||
| `app/order_executor_forward.py` | 构建 payload、多路 POST |
|
||||
| `app/monitor.py` | 企微成功后调用转发 |
|
||||
| `app/web.py` | API + 启动时 `ensure_store_initialized` |
|
||||
|
||||
---
|
||||
|
||||
## 4. 执行器侧(gate_order_executor)
|
||||
|
||||
本次 **未改** 执行器业务代码。多账户 = 多实例部署:
|
||||
|
||||
| 实例 | 典型差异 |
|
||||
|------|----------|
|
||||
| 目录/PM2 名 | 两份 `gate_order_executor` |
|
||||
| `app.port` | 8090 / 8091 |
|
||||
| `gate.api_key/secret` | 不同子账户 |
|
||||
| `security.webhook_secret` | 与扫描端面板 **相同** |
|
||||
| `risk.*`、移动保本 | 各实例自行实验 |
|
||||
|
||||
另见执行器仓库已实现的 **移动保本**(1R 拉至开仓价±0.2%、面板开关、`breakeven_prefs` 等),与多路转发正交。
|
||||
|
||||
---
|
||||
|
||||
## 5. 部署套数怎么选
|
||||
|
||||
| 场景 | 面板操作 |
|
||||
|------|----------|
|
||||
| 单账户 | 列表 **1 条** URL |
|
||||
| 双账户对照 | **2 条** URL,各指向不同端口/机器 |
|
||||
| 临时只跑一套 | 另一条 `enabled: false` 或关总开关 |
|
||||
| 完全停止自动下单 | 总开关 `enabled: false` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 盈亏比对照实验(用法)
|
||||
|
||||
1. 扫描端产生同一 `signal_id`、同一 TP/SL。
|
||||
2. 执行器 A:`min_reward_risk_ratio = 1.3` → 可能 `accepted`。
|
||||
3. 执行器 B:`min_reward_risk_ratio = 1.8` → 可能 `skipped` / `reward_risk_below_min`。
|
||||
4. 分别在两个执行器面板「信号流」与 Gate 平仓统计中对比结果。
|
||||
|
||||
---
|
||||
|
||||
## 7. 云服务器关闭代理
|
||||
|
||||
### 7.1 何时关闭
|
||||
|
||||
- **本机 + 本地 SOCKS**:`proxy.enabled: true`
|
||||
- **境外云、可直连 Gate**:`proxy.enabled: false`
|
||||
|
||||
### 7.2 扫描端
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
仅影响 **Gate 行情**;企微、转发执行器本就直连。
|
||||
|
||||
### 7.3 执行器(每个实例)
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
影响 Gate 下单/查仓及(若开启)企微出站。
|
||||
|
||||
### 7.4 自检
|
||||
|
||||
```bash
|
||||
curl -I --max-time 15 https://api.gateio.ws
|
||||
```
|
||||
|
||||
### 7.5 文档索引
|
||||
|
||||
- `onchain_scout_gate/交易系统部署说明.md` §7、§8
|
||||
- `onchain_scout_gate/docs/本地部署-SOCKS5代理.md`(本地 SOCKS)
|
||||
- `gate_order_executor/docs/部署说明.md` §6.1
|
||||
|
||||
---
|
||||
|
||||
## 8. 日志关键字
|
||||
|
||||
扫描端运行日志(面板「运行日志」或 `runtime/system.log`):
|
||||
|
||||
| 日志前缀 | 含义 |
|
||||
|----------|------|
|
||||
| `order_executor_ok name=...` | 该执行器 HTTP 成功 |
|
||||
| `order_executor_failed name=...` | HTTP 或业务失败 |
|
||||
| `order_executor_no_active_targets` | 总开关开但无启用条目 |
|
||||
| `webhook_secret is empty` | 未配置密钥 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 安全与约束
|
||||
|
||||
- **Webhook 密钥** 在面板修改后,须手动同步到 **每一个** 执行器 `security.webhook_secret`。
|
||||
- **勿** 将执行器 `8090/8091` 对公网裸奔;建议仅本机或内网 + 防火墙。
|
||||
- 执行器 **不会** 也 **不能** 向扫描端注册;避免运维混乱。
|
||||
|
||||
---
|
||||
|
||||
## 10. 变更记录
|
||||
|
||||
| 日期 | 内容 |
|
||||
|------|------|
|
||||
| 2026-05 | 多执行器运行时存储、面板 CRUD、并行广播、部署与代理文档 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 相关路径速查
|
||||
|
||||
```text
|
||||
onchain_scout_gate/
|
||||
runtime/order_executors.json # 执行器列表(面板写入)
|
||||
app/order_executors_store.py
|
||||
app/order_executor_forward.py
|
||||
templates/dashboard.html # 「下单执行器」区块
|
||||
static/app.js
|
||||
|
||||
gate_order_executor/ # 多实例部署,代码无需为多账户改动
|
||||
config.yaml # 每实例独立 API / risk / proxy
|
||||
```
|
||||
@@ -0,0 +1,233 @@
|
||||
# 本地部署说明(含 SOCKS5 代理 `socks5h://127.0.0.1:1080`)
|
||||
|
||||
> **云服务器部署**:若主机在境外且可直连 `api.gateio.ws`,请将 `config.yaml` 中 `proxy.enabled` 设为 **`false`**,无需 SOCKS。详见 [`交易系统部署说明.md`](../交易系统部署说明.md) §8 与 [`多执行器与信号转发归档.md`](./多执行器与信号转发归档.md) §7。
|
||||
|
||||
本文说明如何在**本机**部署 **onchain_scout_gate**(Gate USDT 永续监控 + 可选 Gemma 漏斗 + Web 看板),并在访问 Gate 行情、企业微信等外网接口时使用 **本地 SOCKS5 代理**。环境变量统一使用 `**socks5h://127.0.0.1:1080`**(**h** = 主机名在代理端解析,等同 curl 的 `socks5h`,推荐)。端口 `**1080`** 与 Clash / v2rayN / Sing-box 等本地 SOCKS 入站一致。
|
||||
|
||||
---
|
||||
|
||||
## 1. 前置条件
|
||||
|
||||
### 1.1 系统与软件
|
||||
|
||||
|
||||
| 项目 | 说明 |
|
||||
| ------ | ---------------------------------------------------------------------------- |
|
||||
| 操作系统 | Windows 10/11 或 Linux / macOS 均可 |
|
||||
| Python | **3.10+**(推荐 3.11 / 3.12) |
|
||||
| 代理客户端 | 本机已运行 **SOCKS5** 监听 `**127.0.0.1:1080`**(常见为 Clash / v2rayN 的「本地 SOCKS5 端口」) |
|
||||
| 浏览器 | 用于打开 `http://127.0.0.1:8088`(或你在 `config.yaml` 中配置的端口) |
|
||||
|
||||
|
||||
### 1.2 代理必须可用(自检)
|
||||
|
||||
在启动本服务前,请先确认 **1080 端口 SOCKS5 已连通外网**(否则 Gate 行情请求会超时或 TLS 失败)。
|
||||
|
||||
**Windows PowerShell**(若已安装 `curl` 且 curl 支持 socks5h):
|
||||
|
||||
```powershell
|
||||
curl -x socks5h://127.0.0.1:1080 -I "https://api.gateio.ws" --max-time 15
|
||||
```
|
||||
|
||||
期望看到 HTTP 状态行(如 `HTTP/1.1 200` 或 `HTTP/2 302` 等),而不是长时间卡住或 `Connection refused`。
|
||||
|
||||
**说明**:`socks5h` 表示把 **DNS 也走代理**(推荐,避免 DNS 污染)。Python 侧下文使用等价思路。
|
||||
|
||||
---
|
||||
|
||||
## 2. 获取代码与目录
|
||||
|
||||
将仓库(或 `onchain_scout` 目录)放到本机任意路径,例如:
|
||||
|
||||
- Windows:`C:\opt\onchain_scout`
|
||||
- Linux:`/opt/onchain_scout`
|
||||
|
||||
下文以 `**onchain_scout` 为项目根目录**(即包含 `config.yaml`、`requirements.txt`、`app/` 的那一层)。
|
||||
|
||||
---
|
||||
|
||||
## 3. Python 虚拟环境
|
||||
|
||||
### 3.1 Windows(PowerShell)
|
||||
|
||||
```powershell
|
||||
cd C:\opt\onchain_scout
|
||||
python -m venv .venv
|
||||
.\.venv\Scripts\Activate.ps1
|
||||
python -m pip install -U pip
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
若执行策略禁止激活脚本:
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
|
||||
```
|
||||
|
||||
### 3.2 Linux / macOS
|
||||
|
||||
```bash
|
||||
cd /opt/onchain_scout
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -U pip
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 3.3 SOCKS5 与 httpx
|
||||
|
||||
本项目通过 **httpx** 访问 Gate 行情(及按需的企业微信 Webhook)。走 **SOCKS5** 需要安装带 socks 依赖的 httpx。`requirements.txt` 中已使用:
|
||||
|
||||
```text
|
||||
httpx[socks]==0.27.2
|
||||
```
|
||||
|
||||
若你曾单独安装过无 extras 的 `httpx`,请在本虚拟环境中重新执行:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置文件 `config.yaml`
|
||||
|
||||
1. 若不存在,从示例复制:
|
||||
```bash
|
||||
copy config.example.yaml config.yaml
|
||||
```
|
||||
2. 至少修改:
|
||||
- `auth.username` / `auth.password`:登录 Web 看板用(生产环境请使用强密码)。
|
||||
- `wecom.webhook`:企业微信群机器人 Webhook(若暂不用推送,可先填占位,但**触发类推送**仍可能失败,可先关相关逻辑或接受报错日志)。
|
||||
- `monitor.min_24h_quote_volume_usdt`:成交额过滤(默认一千万量级,按 README 说明)。
|
||||
- `**gemma`**:若本机已装 Ollama 且要跑漏斗,将 `enabled: true` 并设置 `model`;否则保持 `enabled: false`。
|
||||
- `**proxy**`:访问 Gate 行情需走本机 SOCKS 时,设 `proxy.enabled: true`,`proxy.url` 一般为 `**socks5h://127.0.0.1:1080**`(与 Clash 等本地 SOCKS 端口一致)。**本机 Ollama 不会使用该代理**。
|
||||
3. **不要将** `config.yaml` **提交到公开仓库**(内含密钥与 Webhook)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 代理写入 `config.yaml`(推荐,无需环境变量)
|
||||
|
||||
在 `config.yaml` 根级增加或修改 `**proxy`** 段(与 `config.example.yaml` 一致):
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
enabled: true
|
||||
url: "socks5h://127.0.0.1:1080"
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `**socks5h://**`:配置里可继续写(与 curl 习惯一致)。程序在创建 httpx 客户端时会**自动改成 `socks5://`**,因部分环境下 httpx/socksio 不认 `socks5h` 会报 `Unknown scheme`;改为 `socks5` 后由**本机解析 DNS** 再走 SOCKS。若仍异常,可直接在配置里写 `**socks5://127.0.0.1:1080`**。
|
||||
- **作用范围**:**Gate 行情**相关 httpx 请求使用 `config.yaml` 中的 `proxy`;企业微信当前实现为直连。**不会**对 `gemma.ollama_base_url`(本机 Ollama)套代理。
|
||||
- `**proxy.enabled: false`**:Gate 客户端仍可使用系统环境变量中的 `HTTP_PROXY` / `ALL_PROXY`(`trust_env=True`);启用配置代理后则**固定走 `proxy.url`**,并 `trust_env=False`,避免与环境变量冲突。
|
||||
|
||||
---
|
||||
|
||||
## 6. PM2 守护进程(推荐)
|
||||
|
||||
### 6.1 安装 PM2
|
||||
|
||||
需已安装 **Node.js**,然后全局安装 PM2:
|
||||
|
||||
```bash
|
||||
npm install -g pm2
|
||||
```
|
||||
|
||||
### 6.2 准备虚拟环境与配置
|
||||
|
||||
1. 项目根目录已创建 `.venv` 且 `pip install -r requirements.txt` 完成。
|
||||
2. `config.yaml` 已按上文填写(含 `proxy`、`app.port` 等)。
|
||||
3. 确保存在目录 `**runtime/**`(用于日志与 SQLite;首次启动会自动创建亦可)。
|
||||
|
||||
### 6.3 使用仓库内 `ecosystem` 启动
|
||||
|
||||
仓库提供 `**deploy/ecosystem.config.cjs**`:
|
||||
|
||||
- `**cwd**`:自动设为项目根(`deploy` 的上一级)。
|
||||
- `**script**`:根据操作系统选择 `**.venv/Scripts/python.exe`(Windows)** 或 `**.venv/bin/python`(Linux/macOS)**。
|
||||
- `**args`**:`python -m app.main`,**监听地址与端口完全由 `config.yaml` 的 `app.host` / `app.port` 决定**,无需改 ecosystem 里的端口。
|
||||
|
||||
在项目根目录执行:
|
||||
|
||||
```bash
|
||||
cd /opt/onchain_scout # 或你的实际路径
|
||||
pm2 start deploy/ecosystem.config.cjs
|
||||
pm2 status
|
||||
pm2 logs onchain-scout
|
||||
```
|
||||
|
||||
常用维护命令:
|
||||
|
||||
|
||||
| 命令 | 说明 |
|
||||
| --------------------------- | --------------------------- |
|
||||
| `pm2 restart onchain-scout` | 热重启(改 `config.yaml` 后需重启生效) |
|
||||
| `pm2 stop onchain-scout` | 停止 |
|
||||
| `pm2 delete onchain-scout` | 从进程列表移除 |
|
||||
| `pm2 save` | 保存当前进程列表 |
|
||||
| `pm2 startup` | 生成开机自启脚本(按屏幕提示执行一次) |
|
||||
|
||||
|
||||
标准输出与错误会写入项目 `**runtime/pm2-out.log**`、`**runtime/pm2-error.log**`(见 ecosystem 内配置)。
|
||||
|
||||
### 6.4 Windows 说明
|
||||
|
||||
在 **PowerShell** 或 **cmd** 中同样可使用 `pm2 start deploy\ecosystem.config.cjs`。若 `python.exe` 路径不对,请确认虚拟环境目录名为 `.venv` 且位于项目根。
|
||||
|
||||
---
|
||||
|
||||
## 7. 前台启动(调试用)
|
||||
|
||||
不经过 PM2、仅本地调试时,**无需**再设置 `ALL_PROXY` 等环境变量(代理已由 `config.yaml` 的 `proxy` 段控制):
|
||||
|
||||
```powershell
|
||||
cd C:\opt\onchain_scout
|
||||
.\.venv\Scripts\Activate.ps1
|
||||
python -m app.main
|
||||
```
|
||||
|
||||
`app.host` / `app.port` 以 `config.yaml` 为准。
|
||||
|
||||
---
|
||||
|
||||
## 8. 验证
|
||||
|
||||
1. **代理**:本机 SOCKS 入站已监听;`config.yaml` 中 `proxy.enabled: true`。
|
||||
2. **Web**:浏览器访问 `http://127.0.0.1:<app.port>`,登录后「监控池配置」JSON 中应出现 `**proxy`** 字段(`enabled` / `url`)。
|
||||
3. **Gate**:等待一个 `poll_interval` 周期,看日志是否仍有 TLS/连接错误;若有,尝试 `socks5` 或检查端口。
|
||||
4. **Ollama**:`gemma.enabled: true` 时,访问 `127.0.0.1:11434` **不**走 `proxy.url`,一般无需 `NO_PROXY`。
|
||||
|
||||
---
|
||||
|
||||
## 9. 常见问题(FAQ)
|
||||
|
||||
### Q1:`Connection refused` 连 Gate / 代理
|
||||
|
||||
- 本机代理未开或端口不是 **1080**。
|
||||
- `proxy.enabled` 未设为 `true` 或 `proxy.url` 写错。
|
||||
|
||||
### Q2:改了 `config.yaml` 不生效
|
||||
|
||||
- PM2 下需执行 `**pm2 restart onchain-scout`** 重新加载进程与配置。
|
||||
|
||||
### Q3:企业微信推送失败
|
||||
|
||||
- 多为 Webhook 无效;若走代理仍失败,检查代理是否允许访问 `qyapi.weixin.qq.com`。
|
||||
|
||||
### Q4:pip / git 走代理
|
||||
|
||||
- 与应用程序无关;可在安装依赖的终端自行 `export HTTPS_PROXY=...`(**不必**写进应用 `config.yaml`)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 备忘
|
||||
|
||||
```bash
|
||||
cd /opt/onchain_scout
|
||||
pm2 start deploy/ecosystem.config.cjs && pm2 save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
文档版本:与仓库 `onchain_scout_gate` 当前结构对应;请以 `README.md`、`deploy/ecosystem.config.cjs`、`app/main.py` 为准。
|
||||
Reference in New Issue
Block a user