Commit Graph
18 Commits
Author SHA1 Message Date
jackyu66git 9163d7fd30 切换到实盘环境
- HL: WS/REST 从 testnet 切换到 mainnet
- BG: 删除 paptrading header(实盘 key 不以 bg_ 前缀区分)
- config: 调整交易参数
- scanner: 更新跟踪币种列表
2026-05-04 22:24:30 +08:00
jackyu66git 19443c132a cleanup: remove 6 coins unsupported on Bitget testnet (OP, WIF, PYTH, SAND, IOTA, MOVE)
These coins return 40034 error on Bitget testnet (Parameter does not exist).
Keeping only 14 confirmed-working coins. Update memory with correct list.
2026-05-04 19:18:58 +08:00
jackyu66git 0aa9923067 fix: full arb table + net profit columns in price view
- ArbTable: removed slice(0,10) cap, shows all 42 opps (21x2)
- PriceTable: added net_bg_to_hl and net_hl_to_bg columns
- Backend SSE: sends net profit for both directions per coin
2026-05-04 18:26:49 +08:00
jackyu66git 5f6578c179 feat: add 17 new cross-exchange pairs (BG↔HL)
Added: ALGO, PYTH, SAND, ADA, HBAR, IOTA, MINA, FET, WLD,
       SUI, APT, NEAR, FIL, DYDX, JUP, TIA, MOVE

Removed: pixel and VET (fake 195% spreads on testnet)

Also updated GetHLSize() to handle szDecimals for all new coins.
2026-05-04 18:05:53 +08:00
jackyu66git 49da6fd35b fix: HL balance now reads spot USDC via SpotUserState
HL testnet USDC lives in the spot account, not the perp clearinghouse.
GetBalance() was calling UserState() (perp clearinghouseState), which
returned /usr/bin/bash. Switched to SpotUserState() and parse USDC.total - USDC.hold.

Also cleaned up .gitignore to exclude .env, binary, logs, data/.
2026-05-04 17:48:14 +08:00
jackyu66git e5ea78ffd2 feat: real trading mode, auto-stop after 5 trades, HL testnet support
- config.json: test_mode=false, ready for sim/testnet trading
- trader.go: auto-stop after 5 real trades, exchange response logging,
  Stop()/Start() API, shuttingDown flag for graceful stop
- dashboard.go: POST /api/stop + POST /api/start endpoints,
  trading status in SSE stats
- exchange/hyperliquid.go: switch HL WS to testnet endpoint
- exchange/hyperliquid_trade.go: switch REST to testnet endpoint,
  support base64 + 32-byte EVM private keys
- main.go: listen on trader.StopCh (graceful, no process exit)
- scanner.go: trim TrackedCoins to only 6 core coins (DOGE/LINK/ONDO/OP/WIF/ARB)
- .gitignore: ignore main binary
2026-05-04 14:31:52 +08:00
jackyu66git ccfa27b1a6 fix: scanner netProfit 漏算exit fees + 孤儿仓位标记failed
- scanner.go: netProfit 扣费改为 2*(buyFee+sellFee) 匹配 calcArbPnL
- trader.go: 第二腿失败时设 pos.Status=failed,避免语义混淆
2026-05-04 06:39:24 +08:00
jackyu66git 2f4d03f9b1 优化: 共用一次 store.GetAll() 快照,消除每 tick 两次 map 分配 2026-05-04 06:10:37 +08:00
jackyu66git 21a3f9a962 feat: 所有参数移至config.json, 重构退出逻辑, 清理遗留接口
- 将所有硬编码参数迁移到 config.json (手续费率、止盈/止损阈值、
  超时、腿间隔、加仓步进等)
- 退出条件: 净利 >= take_profit_pct 止盈, 价差 <= 0 平仓
- 删除 Binance/dYdX 遗留代码
- 更新 README 文档
- Dashboard: 双交易所价格表、黑名单UI、按币名排序持仓
- Bitget WS: 文本ping保活
- 数据库: 重置, 无历史仓位
2026-05-04 01:46:17 +08:00
jackyu66git 2ed6ffc747 fix: Bitget WS keepalive — send text ping, not WebSocket PingMessage
Bitget v2 WS requires a text message "ping" every 30s, not a WebSocket
PingMessage control frame (opcode 0x9). Using the wrong ping type caused
a silent failure: connection stays up and subscription succeeds, but NO
ticker data is pushed — zero errors, zero reconnection logs.

Changes:
- connector.go: Add TextPing bool flag, send text 'ping' when set
- bitget.go: Set TextPing=true, handle text 'pong', add debug logging
- scanner.go: Expand to 179 overlapping Bitget+HL coins
2026-05-04 00:33:03 +08:00
jackyu66git b8c73852be fix: BG taker fee 0.06% → 0.03% 2026-05-04 00:04:14 +08:00
jackyu66git 5d6d9352f3 fix: use taker fees (BG 0.06%, HL 0.045%) + threshold 0.25%
All IOC market orders incur taker fees, not maker fees. Previous
makerFees (BG 0.02%, HL 0.015%) caused 0.10% threshold trades to
actually lose 0.11% per round trip.

Changes:
- scanner.go: makerFees → takerFees (BG 0.060, HL 0.045)
- dashboard.go: makerFees → takerFees
- types.go: makerFees → takerFees
- trader.go: makerFees → takerFees
- config.json: trade_threshold 0.1 → 0.25
2026-05-03 23:34:01 +08:00
jackyu66git 931855e1f5 Cleanup: remove dead code after P3 refactor 2026-05-03 18:13:11 +08:00
jackyu66git beb3611778 Phase 3: Real-time enhancements
P3-1: Scan optimization — only BG↔HL (50+ pair combos → 2)
P3-2: Real-time spread chart — spreadHistory ring buffer +
      /api/spread-history endpoint + Chart.js spread chart
P3-3: Live position PnL — positions SSE now includes
      estimated current profit/loss + current spread
P3-4: Real-time trade events — trader.OnTradeEvent callback
      fires SSE 'trade_open' / 'trade_close' immediately
P3-5: Connection status monitoring — tracks last update time
      per exchange, broadcast via stats.connections + /api/connections

Frontend: spread chart card, PnL column in positions,
          connection status dots in stats bar,
          green/red border flash on trade events
2026-05-03 18:05:19 +08:00
jackyu66git da561325d7 Revert B#6: netProfit must NOT delegate to CalcNetProfit
CalcNetProfit (helpers.go) has internal price-swap logic — when
price2 < price1 it swaps buy/sell sides. ScanArbWithFees relies
on netProfit being a pure strict-direction calculation (callers
try both directions via addPair). Delegation caused double-swap:
both netProfit calls in addPair returned positive profit, but
direction1's struct reported wrong exchange pair, leading to
potential loss-making trades.

Keep both formulas as independent implementations with explicit
comments warning against future merging attempts.
2026-05-03 17:55:39 +08:00
jackyu66git 277c34c3bd Remove Aevo exchange (retired)
- Delete exchange/aevo.go (AevoWS, aevoTickerMsg, aevoTickerData, etc.)
- scanner.go: remove ExAevo constant, fee rates, scan pair entries, shortName mapping
- main.go: remove aevoSymbols collection loop and TrackedSymbol usage
2026-05-03 17:50:42 +08:00
jackyu66git eb74495470 Fix 8 bugs from code review
B#1 — sigCh shared across goroutines, SIGINT unreliable
  → context.WithCancel: main loop cancels ctx on SIGINT,
    4 WS goroutines select on ctx.Done() instead of shared sigCh

B#3 — restoreOpenPositions missing LastScaleAt
  → Set LastScaleAt = tr.OpenedAt on restore so scale-in cooldown works

B#4 — dYdX heartbeat goroutine leaks on reconnect
  → Added stopHeartbeat chan + heartbeatMu mutex; close old channel
    before spawning new heartbeat goroutine

B#5 — GetBitgetSize fmt.Sprintf rounds up, may exceed amountUSD
  → Added math.Floor(sz*multiplier)/multiplier before format to round
    DOWN to nearest valid step size for every coin

B#6 — netProfit and CalcNetProfit duplicate formula
  → scanner.go netProfit now delegates to exchange.CalcNetProfit

B#7 — Aevo Run callback only 2 params, incompatible with startExchange
  → Changed to 4-arg callback func(coin, price, bid, ask) with bid=ask=0

B#8 — parseFloat uses fmt.Sscanf (slow, locale-sensitive)
  → Replaced with strconv.ParseFloat

B#9 — dYdX receives hlSymbols instead of its own symbol list
  → Added dydxSymbols var, built from c.HL like other exchanges
2026-05-03 17:48:06 +08:00
jackyu66git 719f0a061d Initial commit 2026-05-03 16:54:36 +08:00