- 新增OKX WebSocket行情连接器,扩展4交易所价格监控 - 新增z-score趋势检测引擎(TrendDetector),识别价格异动/趋势启动 - 新增累积变动跟踪(CumulativeTracker),基于1min/5min多交易所共识 - 趋势事件和累积变动事件持久化到SQLite - 新增Binance/OKX动量检测字段,扩展前端动量卡片至15列 - 迁移至macOS(darwin-arm64),更新前端依赖 - Dashboard网格重构:非交易卡片置顶,交易卡片置底 - TrackedCoin添加OK字段,添加ExBinance/ExOKX常量 - 前端新增趋势检测卡片、趋势历史卡片、累积变动卡片 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
Build & Run Commands
# Build Go binary
go build -o exchange-monitor .
# Start (kills old process + builds if needed + runs)
bash start.sh
# Options: --clean (delete DB), --rebuild (force recompile)
bash start.sh --clean --rebuild
# Frontend dev (hot reload on :5173, proxies /api to :8888)
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)
Main Loop (main.go:148-245)
Fixed 50ms tick: trader.Tick() → scan.scanBGHL() → TryEntry() for each opportunity. 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) |
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
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.
Trading 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
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).
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.
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/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/connections |
Exchange WS health (online/stale/offline) |
POST /api/stop |
Stop trading + force-close positions |
POST /api/start |
Resume trading |
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.
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.