9.4 KiB
Arbitrage Engine 后端运行说明(Backend Runtime Guide)
本文从“后端工程师 / 运维”的角度,描述项目的后端模块、进程拓扑和数据流。
详细字段与业务规则仍以docs/arbitrage-engine-full-spec.md为准。
1. 后端整体结构概览
后端主要由三类组件组成:
-
FastAPI HTTP API(arb-api)
- 文件:
backend/main.py - 职责:
- 提供
/api/...下的所有 HTTP 接口; - 负责认证(集成
auth.py的路由); - 对数据库执行查询和聚合逻辑,为前端和脚本服务;
- 启动少量后台任务(如资金费率快照)。
- 提供
- 文件:
-
信号与交易引擎进程
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:实盘仓位同步。
-
数据采集与维护进程
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 API(arb-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 秒):
- 从
agg_trades滑动窗口计算 CVD、ATR、VWAP 等指标; - 从
market_indicators/liquidations读取宏观指标和爆仓数据; - 对每个策略(
strategies表中status=running的记录)调用评估函数(V5.3 之前_evaluate_v53,V5.4 起为evaluate_factory_strategy); - 生成评分与信号(
score、signal),写入signal_indicators; - 在满足开仓条件时写入
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。
- 触及 TP1 → 将 status 改为
信号引擎负责开仓逻辑,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. 后端数据流(服务视角)
从“服务/进程”的角度看,主数据流可简化为:
-
行情写入
- 币安 WebSocket →
agg_trades_collector.py→agg_trades; - 市场宏观指标 API →
market_data_collector.py→market_indicators; - 强平数据 →
liquidation_collector.py→liquidations; - 资金费率快照 →
main.py中后台任务 →rate_snapshots。
- 币安 WebSocket →
-
信号生成
signal_engine.py周期性读取:agg_trades滑动窗口;market_indicators;liquidations;strategies配置;
- 计算指标与评分 → 写入
signal_indicators; - 满足条件时 → 写入
paper_trades(开仓记录)。
-
模拟盘结算
paper_monitor.py通过 WebSocket 获取 price;- 根据
paper_trades的 SL/TP/timeout 规则更新paper_trades.status和pnl_r。
-
API 展示与控制
main.py通过/api/paper/*、/api/signals/*、/api/strategy-plaza*等接口对外提供:- 信号历史和当前状态;
- 模拟盘持仓、交易历史、统计与权益曲线;
- 策略列表与管理操作。
/api/live/*接口与live_executor.py/risk_guard.py等进程协作控制实盘。
6. 本地开发与调试建议
-
仅调试前端 + API(不跑引擎)
- 使用现有 Cloud SQL 作为只读数据源:
- 启动
backend/main.py(uvicorn 或 PM2); - 启动前端
frontend(Next.js dev 模式);
- 启动
- 适用于:
- 调整页面布局与数据展示;
- 优化
/api/...查询逻辑; - 编写/验证新接口契约。
- 使用现有 Cloud SQL 作为只读数据源:
-
调试信号引擎/模拟盘
- 启动
signal_engine.py和paper_monitor.py所需的最小进程集合; - 确保
agg_trades/market_indicators至少有一部分历史数据(可以从线上复制或运行简化版 collector); - 使用日志和
signal_indicators/paper_trades查询验证新策略。
- 启动
-
调试实盘页面
/live- 在本地/测试环境建议仅连接测试网账户;
- 启动相关进程:
live_executor.py、risk_guard.py、position_sync.py(视具体实现和需求而定);
- 通过
/api/live/*接口与/live页面观察状态变化,避免直接在生产环境实验未验证的逻辑。
-
变更规则
- 修改后端关键逻辑(尤其是 signal_engine、risk_guard)时,建议遵守:
- 先更新/确认
arbitrage-engine-full-spec.md中对应章节; - 再确保
API_CONTRACTS.md与前端用法一致; - 最后通过少量回测/模拟盘运行做 smoke test。
- 先更新/确认
- 修改后端关键逻辑(尤其是 signal_engine、risk_guard)时,建议遵守:
本文件的目标是提供一个“后端模块地图”和“进程视角的数据流”,让未来的你(以及 AI 助手)在需要修改/排障时,不必反复从头翻 full-spec 和代码,就能快速知道该看哪几个模块、查哪几张表、重启哪些进程。