arbitrage-engine/docs/BACKEND_RUNTIME.md

220 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Arbitrage Engine 后端运行说明Backend Runtime Guide
> 本文从“后端工程师 / 运维”的角度,描述项目的后端模块、进程拓扑和数据流。
> 详细字段与业务规则仍以 `docs/arbitrage-engine-full-spec.md` 为准。
---
## 1. 后端整体结构概览
后端主要由三类组件组成:
1. **FastAPI HTTP APIarb-api**
- 文件:`backend/main.py`
- 职责:
- 提供 `/api/...` 下的所有 HTTP 接口;
- 负责认证(集成 `auth.py` 的路由);
- 对数据库执行查询和聚合逻辑,为前端和脚本服务;
- 启动少量后台任务(如资金费率快照)。
2. **信号与交易引擎进程**
- `backend/signal_engine.py`:信号引擎(策略评估 + 模拟盘开仓);
- `backend/paper_monitor.py`模拟盘平仓TP/SL/timeout/signal_flip
- `backend/live_executor.py`(未来/暂定):连接实盘执行;
- `backend/risk_guard.py`:风控守护进程;
- `backend/position_sync.py`:实盘仓位同步。
3. **数据采集与维护进程**
- `backend/agg_trades_collector.py`:从币安 WebSocket 收集逐笔成交写入 `agg_trades`
- `backend/market_data_collector.py`收集资金费率、OI、多空比等写入 `market_indicators`
- `backend/liquidation_collector.py`:收集爆仓数据写入 `liquidations`
- `backend/backfill_agg_trades.py`:历史数据回补;
- `backend/fix_historical_pnl.py` 等维护脚本:用于修复历史统计。
这些组件通过 PostgreSQL 共享状态FastAPI 作为对外唯一 HTTP 入口,信号/模拟盘引擎作为“后端大脑”,采集进程负责填充数据湖。
---
## 2. FastAPI APIarb-api
入口文件:`backend/main.py`
运行方式:由 PM2 管理的 `arb-api` 进程(端口 4332
主要职责:
- 提供 `/api/...` REST 接口:
- 资金费率/历史数据(`/api/rates`、`/api/history`、`/api/kline`、`/api/snapshots`
- 信号相关接口(`/api/signals/*`
- 模拟盘接口(`/api/paper/*`
- 策略管理接口(`/api/strategies*`、`/api/strategy-plaza*`
- 实盘状态与控制接口(`/api/live/*`
- 服务器监控接口(`/api/server/status`)。
- 初始化数据库连接:
-`startup` 事件中调用 `init_schema()``ensure_auth_tables()`
- 初始化 asyncpg 连接池(`get_async_pool()`)。
- 启动后台任务:
- `background_snapshot_loop()`:每 2 秒从币安拉资金费率 + 标记价,写入 `rate_snapshots`
开发/调试提示:
- 本地如需仅调试 API 层,可以只启动 `main.py`(例如 `uvicorn main:app --reload`),连接已有 Cloud SQL
- 复杂查询(如 stats / strategy-plaza建议先查阅 `docs/API_CONTRACTS.md`,再看对应路由实现。
---
## 3. 信号与交易引擎进程
### 3.1 signal_engine.py — 信号引擎
文件:`backend/signal_engine.py`
PM2 名称:`signal-engine`
职责(结合 full-spec
- 定时循环(约每 15 秒):
1.`agg_trades` 滑动窗口计算 CVD、ATR、VWAP 等指标;
2.`market_indicators` / `liquidations` 读取宏观指标和爆仓数据;
3. 对每个策略(`strategies` 表中 `status=running` 的记录调用评估函数V5.3 之前 `_evaluate_v53`V5.4 起为 `evaluate_factory_strategy`
4. 生成评分与信号(`score`、`signal`),写入 `signal_indicators`
5. 在满足开仓条件时写入 `paper_trades`,通过 `paper_open_trade()` 等逻辑开模拟仓。
- 与前端/上层接口的关系:
- 前端 `/signals*` 页面只读 `signal_indicators` 和相关汇总接口,不直接调用 signal_engine
- `/paper`、`/strategy-plaza` 通过 `paper_trades``strategies`/`signal_indicators` 组合呈现结果。
注意:
- `signal_engine.py` 是最复杂的单体文件之一,对其进行修改前建议:
- 阅读 `arbitrage-engine-full-spec.md` 中“信号引擎”章节;
- 阅读 `docs/AI_HANDBOOK.md` 中关于“禁止/谨慎修改”的约束;
- 在未来可以为其单独增加 `GUIDE_SIGNAL_ENGINE.md` 做更细粒度说明。
### 3.2 paper_monitor.py — 模拟盘平仓
文件:`backend/paper_monitor.py`
PM2 名称:`paper-monitor`
职责:
- 通过币安 WebSocket 获取 mark price
- 监控所有 `paper_trades``status="active"``tp1_hit` 的持仓;
- 根据价格触发规则:
- 触及 TP1 → 将 status 改为 `tp1_hit`,移动 SL 到保本价;
- 触及 TP2 → status=`tp`,计算 `pnl_r`
- 触及 SL → status=`sl``pnl_r=-1`
- 超时(持仓超过 timeout_minutes→ status=`timeout`,按价差换算 R
- 被反向信号强平 → status=`signal_flip`。
信号引擎负责开仓逻辑paper_monitor 负责平仓逻辑,两者通过 `paper_trades` 协作。
### 3.3 其他进程(概要)
- `live_executor.py`
- 负责将信号转换为实盘订单(当前可能处于试验/非默认启用状态);
-`/api/live/*` 接口、`risk_guard.py` 共同控制实盘行为。
- `risk_guard.py`
- 独立风控守护进程,通过检查日内 R、连续亏损、API 状态等判断是否触发熔断;
-`/api/live/risk-status``/api/live/emergency-close` 等控制接口关联。
- `position_sync.py`
- 定期从交易所拉取真实仓位,对齐本地 `live_positions` 记录;
-`/api/live/reconciliation` 提供比对数据。
这些进程对模拟盘的影响有限,但对实盘 `/live` 页至关重要。
---
## 4. 数据采集与维护脚本
### 4.1 市场数据采集
- `agg_trades_collector.py`
- 订阅币安逐笔成交 WebSocket 流;
- 将成交写入 `agg_trades` 分区表;
- 为 CVD/ATR/VWAP 等指标计算提供原始成交数据。
- `market_data_collector.py`
- 定期从币安/其他来源拉取资金费率、未平仓合约OI、多空比、订单簿不平衡等
- 写入 `market_indicators`
- 供 signal_engine 的环境层/拥挤层/辅助层使用。
- `liquidation_collector.py`
- 拉取爆仓(强平)数据;
- 写入 `liquidations`
- 供 V5.2/V5.3 的 liquidation 层打分使用。
### 4.2 历史数据与修复
- `backfill_agg_trades.py`
- 用于历史数据回补;
- 配合 `/api/server/status``backfill_running` 标记监控运行状态。
- `fix_historical_pnl.py` 等修复脚本:
- 针对旧数据的 PnL 计算错误或结构变更进行一次性修复;
- 修改前请查阅 full-spec 中对应章节,并记录在决策/变更文档中。
---
## 5. 后端数据流(服务视角)
从“服务/进程”的角度看,主数据流可简化为:
1. **行情写入**
- 币安 WebSocket → `agg_trades_collector.py``agg_trades`
- 市场宏观指标 API → `market_data_collector.py``market_indicators`
- 强平数据 → `liquidation_collector.py``liquidations`
- 资金费率快照 → `main.py` 中后台任务 → `rate_snapshots`
2. **信号生成**
- `signal_engine.py` 周期性读取:
- `agg_trades` 滑动窗口;
- `market_indicators`
- `liquidations`
- `strategies` 配置;
- 计算指标与评分 → 写入 `signal_indicators`
- 满足条件时 → 写入 `paper_trades`(开仓记录)。
3. **模拟盘结算**
- `paper_monitor.py` 通过 WebSocket 获取 price
- 根据 `paper_trades` 的 SL/TP/timeout 规则更新 `paper_trades.status``pnl_r`
4. **API 展示与控制**
- `main.py` 通过 `/api/paper/*`、`/api/signals/*`、`/api/strategy-plaza*` 等接口对外提供:
- 信号历史和当前状态;
- 模拟盘持仓、交易历史、统计与权益曲线;
- 策略列表与管理操作。
- `/api/live/*` 接口与 `live_executor.py` / `risk_guard.py` 等进程协作控制实盘。
---
## 6. 本地开发与调试建议
1. **仅调试前端 + API不跑引擎**
- 使用现有 Cloud SQL 作为只读数据源:
- 启动 `backend/main.py`uvicorn 或 PM2
- 启动前端 `frontend`Next.js dev 模式);
- 适用于:
- 调整页面布局与数据展示;
- 优化 `/api/...` 查询逻辑;
- 编写/验证新接口契约。
2. **调试信号引擎/模拟盘**
- 启动 `signal_engine.py``paper_monitor.py` 所需的最小进程集合;
- 确保 `agg_trades` / `market_indicators` 至少有一部分历史数据(可以从线上复制或运行简化版 collector
- 使用日志和 `signal_indicators` / `paper_trades` 查询验证新策略。
3. **调试实盘页面 `/live`**
- 在本地/测试环境建议仅连接测试网账户;
- 启动相关进程:
- `live_executor.py`、`risk_guard.py`、`position_sync.py`(视具体实现和需求而定);
- 通过 `/api/live/*` 接口与 `/live` 页面观察状态变化,避免直接在生产环境实验未验证的逻辑。
4. **变更规则**
- 修改后端关键逻辑(尤其是 signal_engine、risk_guard建议遵守
- 先更新/确认 `arbitrage-engine-full-spec.md` 中对应章节;
- 再确保 `API_CONTRACTS.md` 与前端用法一致;
- 最后通过少量回测/模拟盘运行做 smoke test。
---
本文件的目标是提供一个“后端模块地图”和“进程视角的数据流”,让未来的你(以及 AI 助手)在需要修改/排障时,不必反复从头翻 full-spec 和代码,就能快速知道该看哪几个模块、查哪几张表、重启哪些进程。