feat: 重构为三所价差异动监控系统

删除 HyperLiquid + 全部交易功能,构建自适应 surge 检测器。
- 新增 surge_detector.go: 每币独立滚动窗口基线,检测三所价差异常飙升
- 新增 SpreadCard/SurgeCard 前端组件
- 保留 momentum/trend/cumulative/trend_filter 扫描功能
- 更新文档和配置以反映新系统

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jackyu66git
2026-05-08 02:01:18 +08:00
co-authored by Claude Opus 4.6
parent 559d7bb870
commit d38782490c
36 changed files with 1201 additions and 6374 deletions
+56 -48
View File
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
Cross-exchange perpetual contract arbitrage system between Bitget and HyperLiquid. Scans ~150 coins for price spreads, executes automated arbitrage trades with scale-in/exit logic, and displays real-time data on a React dashboard.
3-exchange spread surge detection system using Binance, OKX, and Bitget. Scans ~150 coins for inter-exchange price spread anomalies, detects surge events with per-coin adaptive baselines, and displays real-time data on a React dashboard.
## Build & Run Commands
@@ -23,91 +23,99 @@ cd frontend && npm run dev
# Frontend production build
cd frontend && npm run build
# IPC commands (talk to running daemon via Unix socket)
./exchange-monitor status
./exchange-monitor close-all
./exchange-monitor close DOGE
./exchange-monitor stop
./exchange-monitor start
```
## Architecture
### Data Flow
```
Exchange WS (HL + BG) → PriceStore (in-memory) → scanner → Trader (entry/exit/scale)
dashboard (SSE hub, :8888)
React frontend (SSE events)
Exchange WS (Bitget + Binance + OKX) → PriceStore (in-memory)
scanner (Scan3Ex)
┌───────────────┼───────────────┐
↓ ↓ ↓
surge_detector momentum.go trend.go
cumulative.go trend_filter.go
↓ ↓ ↓
dashboard (SSE hub, :8888)
React frontend (SSE events)
```
### Main Loop (main.go:148-245)
Fixed 50ms tick: trader.Tick() → scan.scanBGHL() → TryEntry() for each opportunity. Every 30s: status log. Hourly: Telegram summary.
### Main Loop (main.go)
Fixed 50ms tick: reads snap from PriceStore → Scan3Ex() → surgeDetector.Tick() → momentum.Tick() etc. Every 30s: status log. Hourly: Telegram summary.
### Package Layout
| Package | Files | Responsibility |
|---------|-------|---------------|
| `main` (root) | `main.go`, `scanner.go`, `trader.go`, `dashboard.go`, `config.go`, `types.go`, `notifier.go`, `ipc.go` | All core logic in a single flat package |
| `exchange/` | `connector.go`, `bitget.go`, `hyperliquid.go`, `bitget_trade.go`, `hyperliquid_trade.go`, `helpers.go` | WS reconnector + exchange-specific REST/WS APIs |
| `db/` | `db.go`, `trade_repo.go` | SQLite persistence (trades, orders, system_orders, config_log) |
| `main` (root) | `main.go`, `scanner.go`, `dashboard.go`, `config.go`, `types.go`, `surge_detector.go`, `momentum.go`, `trend.go`, `cumulative.go`, `trend_filter.go` | All core logic in a single flat package |
| `exchange/` | `connector.go`, `bitget.go`, `binance.go`, `okx.go`, `helpers.go` | WS reconnector + exchange-specific REST/WS APIs |
| `db/` | `db.go`, `surge_event_repo.go` | SQLite persistence (surge_events, cm_events, trend_events, trend_signals) |
| `frontend/` | Vite + React | Real-time dashboard consuming SSE from backend |
### Key Types
- **PriceStore** — Thread-safe in-memory map of coin→exchange→price, with bid/ask spread tracking
- **ArbOpportunity** — Scanning result: coin, direction (BG→HL or HL→BG), prices, net profit %
- **ArbPosition** — Open position with long/short legs, scale-in tracking, entry prices array
- **Trader** — Manages positions, entry/exit logic, fund tracking, blacklist, DB persistence
- **ThreeExSpread** — 3-exchange scan result: coin, prices, spread %, max/min exchange
- **SurgeDetector** — Per-coin adaptive baseline surge detection with rolling window median
- **SurgeEvent** — Detected surge: coin, prices, spread, baseline, direction, leading exchange
- **MomentumTracker** — Multi-window (1s/5s/15s/60s) price change tracking per exchange
- **TrendDetector** — Cross-exchange trend state machine (idle→alert→confirmed→exhausting)
- **CumulativeTracker** — 1m/5m/1h consensus change tracking across exchanges
- **TrendFilter** — K-line based quiet detection + EMA52 trend filtering
### Exchange Connector
`PriceConnector` (exchange/connector.go) is a reusable WebSocket reconnector with exponential backoff (1s-30s), configurable ping interval, and read deadline. Bitget uses text ping frames; HyperLiquid uses standard ping/pong.
`PriceConnector` (exchange/connector.go) is a reusable WebSocket reconnector with exponential backoff (1s-30s), configurable ping interval, and read deadline. Bitget uses text ping frames; Binance and OKX use standard ping/pong.
### Trading Logic
### Surge Detection Logic
- **Entry (TryEntry → executeEntry)**: Checks threshold, margin, blacklist, cooldown, max positions. Places both legs asynchronously with 300ms delay. Persists DB record immediately on "entering" status for crash recovery.
- **Scale-in (checkScaleIn)**: Adds position when spread widens by ScaleStepPct per level. Posts additional orders on both legs.
- **Exit (checkExit)**: Take profit at threshold, converged spread ≤ 0.02%, or timeout. Retries failed closes up to 30 times.
- **Blacklist**: Force-closes position open >10min without convergence, prevents re-entry for BlacklistDuration.
### Net Profit Calculation
```go
netProfit(buyPrice, sellPrice, buyFee, sellFee) = (revenue/cost - 1)*100 - 2*(buyFee + sellFee)
```
Where cost = buyPrice * (1 + buyFee/100), revenue = sellPrice * (1 - sellFee/100). Four total fees (2 entry + 2 exit).
- **Adaptive baseline**: Per-coin rolling window (600 samples, ~30s at 50ms tick) of 3-exchange max spreads
- **Threshold**: median(spreads) × multiplier (default 3.0), with min floor (0.05%)
- **Trigger**: currentSpread > threshold AND cooldown (60s) passed
- **Direction**: Compare highest exchange deviation from median vs lowest exchange deviation
- **Leading exchange**: The exchange furthest from median price (first to reflect price move)
### Configuration Priority
`.env` vars > `config.json` > code defaults. Config struct in `config.go`.
Key env vars: `BITGET_API_KEY`, `BITGET_API_SECRET`, `BITGET_PASSPHRASE`, `HL_PRIVATE_KEY`, `HL_ADDRESS`, `HL_API_ADDRESS`, `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`, `TRADE_ENABLED`, `TEST_MODE`.
Key env vars: `BITGET_API_KEY`, `BITGET_API_SECRET`, `BITGET_PASSPHRASE`, `BINANCE_API_KEY`, `BINANCE_API_SECRET`, `HTTPS_PROXY`, `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`.
### Dashboard API
| Endpoint | Description |
|----------|-------------|
| `GET /` | Serves index.html (disk first, fallback embed) |
| `GET /api/status` | Prices, positions, stats, exchange funds |
| `GET /events` | SSE stream (prices, positions, arb, stats — 1s interval) |
| `GET /api/status` | Current prices snapshot |
| `GET /events` | SSE stream (prices, spread_3ex, momentum, trend, cumulative, trend_filter, surge, status) |
| `GET /api/history?coin=&exchange=` | Price history ring buffer (500 pts) |
| `GET /api/spread-history?coin=` | BG↔HL spread history |
| `GET /api/trades?page=&limit=&coin=` | Paginated trade history from DB |
| `GET /api/trade/{id}` | Trade detail + orders |
| `GET /api/spread-history?coin=` | 3-exchange spread history |
| `GET /api/surge-events?limit=` | Surge event history from DB or memory |
| `GET /api/cm-history` | Cumulative change event history |
| `GET /api/trend-signals` | Trend filter signal history |
| `GET /api/connections` | Exchange WS health (online/stale/offline) |
| `POST /api/stop` | Stop trading + force-close positions |
| `POST /api/start` | Resume trading |
### SSE Events
| Event | Data | Frequency |
|-------|------|-----------|
| `prices` | All coin prices + 3-ex spread | Every tick |
| `spread_3ex` | Top 3-ex spreads scan results | Every tick |
| `momentum` | Multi-window price change % | Every tick |
| `trend` | Trend state machine snapshots | Every tick |
| `cumulative` | Cumulative consensus changes | Every tick |
| `trend_filter` | K-line filter states | Every tick |
| `trend_signal` | Individual trend signal (enter/exit) | On event |
| `surge` | Current spread/baseline snapshots | Every tick |
| `surge_event` | New surge detection event | On detection |
| `status` | Connection health + coin count | Every tick |
### Database
SQLite at `~/Project/exchange-monitor-go/data/trades.db` (single-writer mode). Tables: `trades` (trade-level), `orders` (per-leg filled orders), `system_orders` (linked long+short order pairs), `config_log`.
SQLite at `~/Project/exchange-monitor-go/data/trades.db` (single-writer mode). Tables: `surge_events`, `cm_events`, `trend_events`, `trend_signals`.
### Coin Tracking
~150 coins in `TrackedCoins` slice (scanner.go). Each entry has Name, BN (Binance, currently unused), BG (Bitget symbol), HL (HyperLiquid symbol). Only BG+HL are actively connected.
### IPC (Unix Socket)
`/tmp/exchange-monitor.sock` — JSON commands from CLI to daemon. Actions: status, close-all, close {coin}, stop, start.
~150 coins in `TrackedCoins` slice (scanner.go). Each entry has Name, BN (Binance symbol), BG (Bitget symbol), OKX (OKX symbol). Active WebSocket connections: Bitget + Binance + OKX.