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:
co-authored by
Claude Opus 4.6
parent
559d7bb870
commit
d38782490c
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user