Files
exchange-monitor-go/README.md
T
jackyu66git 915b316ca7 fix: HL size floor, random scan jitter 50-250ms
- GetHLSize: change rounding from Sprintf (round-to-nearest)
  to math.Floor (floor), consistent with GetBitgetSize
- Scan interval: fixed 200ms → random 50-250ms to avoid
  lock-step with HyperLiquid's ~200ms allMids push cycle
- README: update architecture diagram, trading logic, config note
2026-05-03 22:25:01 +08:00

10 KiB

Exchange Monitor Go

Cross-exchange perpetual futures arbitrage scanner and automated trading system. Monitors real-time prices from 4 exchanges via WebSocket, identifies Bitget ↔ HyperLiquid arbitrage opportunities, executes maker-fee trades, and provides a real-time Web dashboard.

Architecture

                    ┌──────────────┐
     ┌──────────────┤   Binance    │◄──── bookTicker WS (price reference)
     │              └──────────────┘
     │              ┌──────────────┐
     │──────────────┤   Bitget     │◄──── ticker WS (trading exchange)
     │              └──────────────┘
PriceStore ─────────┼──────────────┤
     │              │ HyperLiquid  │◄──── webData2 WS (trading exchange)
     │              └──────────────┘
     │              ┌──────────────┐
     └──────────────┤    dYdX      │◄──── v4_markets WS (price reference)
                    └──────────────┘
                           │
                 ┌─────────▼─────────┐
                 │ ScanBGHL (50-250ms │
                 │   random jitter)   │
                 │ BG ↔ HL only       │
                 └─────────┬─────────┘
                           │
           ┌───────────────▼────────────────┐
           │   Trader (trading logic only)   │
           │  TryEntry / Tick / Exit        │
           │  Maker fees, scale-in, stop    │
           │  Synchronous entry (no goroutine)│
           │  NO display/stat calculations  │
           └───────────────┬────────────────┘
                           │
                 ┌─────────▼─────────┐
                 │ SpreadWindowTracker│
                 │ (opportunity life) │
                 └─────────┬─────────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
  ┌─────▼─────┐   ┌────────▼───────┐   ┌─────▼─────┐
  │ Notifier  │   │ Dashboard      │   │ DB        │
  │ TG        │   │ :8888          │   │ SQLite    │
  │           │   │ Stats calc     │   │ trades.db │
  │           │   │ (calcDetailed) │   │           │
  └───────────┘   └────────────────┘   └───────────┘

Tracked Coins

Coin Binance Bitget HyperLiquid dYdX
DOGE DOGEUSDT DOGEUSDT DOGE DOGE
LINK LINKUSDT LINKUSDT LINK LINK
ONDO ONDOUSDT ONDOUSDT ONDO ONDO
OP OPUSDT OPUSDT OP OP
WIF WIFUSDT WIFUSDT WIF WIF
ARB ARBUSDT ARBUSDT ARB ARB
  • Bitget / HyperLiquid — trading exchanges (limit orders with maker fees)
  • Binance / dYdX — price reference only

Requirements

  • Go 1.25+
  • WebSocket connectivity to all 4 exchanges

Quick Start

cd exchange-monitor-go
go build -o exchange-monitor .
# Edit .env to configure (token, threshold, etc.)
./exchange-monitor

Or use the startup script (auto-compiles if sources changed, cleans stale port):

./start.sh

Then open http://localhost:8888 for the Web dashboard.

Configuration (.env)

Variable Code Default Description
TELEGRAM_BOT_TOKEN Telegram bot token for notifications
TELEGRAM_CHAT_ID Target chat ID for notifications
TRADE_ENABLED false Enable real trading (1 to enable)
TRADE_THRESHOLD 0.15 Min net profit % to enter (after fees)
TRADE_AMOUNT_USD 10 USD per leg
TRADE_COOLDOWN_MS 30000 Cooldown between same-coin trades (ms)
TEST_MODE false Simulate orders with mock fills (no real API calls)
MOCK_SLIPPAGE_PCT 0.005 Simulated slippage per leg (%)
BITGET_API_KEY / BITGET_API_SECRET / BITGET_PASSPHRASE Bitget API credentials (test mode skips)
HL_PRIVATE_KEY / HL_ADDRESS HyperLiquid wallet credentials (test mode skips)

Note: Scan interval is fixed at 50-250ms random jitter (not configurable). This prevents lock-step with HyperLiquid's ~200ms push cycle.

Fee Model

All trades use maker (limit orders), no rebate. Only Bitget and HyperLiquid are used for trading:

Exchange Maker Taker
Bitget 0.020% 0.040%
HyperLiquid 0.015% 0.035%

Round trip (2 legs entry + 2 legs exit): 0.07% total fees.

Trading Logic

  1. Scanner runs every 50-250ms (random jitter to avoid lock-step with exchange push cycles), checks all 6 coins for BG ↔ HL spread
  2. Entry when net profit ≥ TRADE_THRESHOLD (after full round-trip fees)
    • Uses scan-time prices directly (no re-read from store to avoid WS jitter)
    • Synchronous execution in the scanner tick (no goroutine delay)
    • Direction sanity check (0.1% tolerance) prevents entry on reversed spreads
  3. Scale-in adds another leg-worth when spread widens another 0.10%
  4. Exit conditions (whichever hits first):
    • Spread converges to ≤ 0.02% → 价差收敛,止盈平仓
    • Spread reverses below -0.02% → 价差反转,止盈平仓
    • Position held over 30 minutes → 超时平仓
  5. Direction: BG → HL (buy BG, sell HL) or HL → BG (buy HL, sell BG)

Spread Window Monitoring

SpreadWindowTracker runs every scan tick and measures how long each coin's spread stays above the trade threshold:

  • Records window start time when netProfit first hits threshold
  • Tracks real peak netProfit during the window
  • Logs window duration + peak when spread converges below threshold (sub-100ms windows filtered as noise)
  • Covers both directions (BG→HL and HL→BG) independently
  • Uses the same netProfit() fee model as the scanner for exact consistency

Log output example:

[SpreadWindow] ONDO BG->HL exceeded threshold for 1.4s (peak net=+0.1520%)
[SpreadWindow] OP HL->BG exceeded threshold for 3.2s (peak net=+0.1310%)

Notifications

All notifications sent to Telegram (via TELEGRAM_BOT_TOKEN):

  • 开仓 — entry notification with prices, direction, spread, amount
  • 平仓 — exit notification with PnL breakdown, fees, convergence analysis
  • 每小时 — summary of open positions (duration, amount)
  • Uses HTML parse mode for bold formatting

Web Dashboard

Built-in HTTP server at :8888 with real-time SSE push (1-second refresh):

  • Price table — live prices from all exchanges with bid-ask spread
  • BG↔HL spread — per-coin arbitrage spread with chart
  • Open positions — live PnL estimate, scaling level, duration
  • Arb scan results — current arbitrage opportunities
  • Trade history — past trades with detail view
  • Connection status — exchange health (online / stale / offline)
  • Charts rendered via Chart.js (loaded from CDN)

DB & Persistence

  • SQLite at data/trades.db
  • Tracks open positions across restarts
  • Stores all closed trades with full PnL details
  • Historical stats merged with in-memory session stats on startup

Signals

Signal Action
Ctrl+C / SIGINT Graceful shutdown (closes all WS connections)
SIGUSR1 Dump convergence statistics to trade_stats.txt

Project Structure

exchange-monitor-go/
├── main.go                   # Entry point, WS startup, main loop
├── config.go                 # .env + config.json hierarchical config
├── types.go                  # PriceStore, TrackedCoin, ArbOpportunity
├── scanner.go                # ScanBGHL — arbitrage scanner
├── trader.go                 # Position management, entry/exit/scale-in (pure trading logic)
├── dashboard.go              # Web server + SSE + stats calc (display layer)
├── toaster.go                # Telegram notifications
├── static.go                 # Embedded web static files
├── start.sh                  # Startup script (port check + build + run)
├── .env                      # Local configuration (TELEGRAM, API keys, thresholds)
├── exchange/
│   ├── connector.go          # Generic WS connector with reconnect
│   ├── binance.go            # Binance bookTicker WS
│   ├── hyperliquid.go        # HyperLiquid webData2 WS
│   ├── hyperliquid_trade.go  # HL REST trade API
│   ├── bitget.go             # Bitget ticker WS
│   ├── bitget_trade.go       # Bitget REST trade API
│   ├── dydx.go               # dYdX v4_markets WS
│   ├── helpers.go            # Package helpers
│   └── ping.go               # Accessibility check tools
├── db/
│   ├── db.go                 # SQLite open/migrate
│   └── trade_repo.go         # Trade record queries
└── web/static/
    ├── index.html            # Dashboard HTML
    ├── app.js                # SSE client + UI logic
    └── style.css             # Dashboard CSS

Disclaimer

This software is for educational/research purposes. Use at your own risk. Cryptocurrency trading involves substantial risk of loss.