首次上传

This commit is contained in:
dekun
2026-05-16 22:25:48 +08:00
commit 2b8f902548
88 changed files with 16386 additions and 0 deletions
@@ -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 WindowsPowerShell
```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`。
### Q4pip / 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` 为准。