Commit Graph
70 Commits
Author SHA1 Message Date
jackyu66git 8b8d4140f9 refactor: HL EVM signing via sonirico/go-hyperliquid SDK 2026-05-04 16:15:51 +08:00
jackyu66git c5c4c7394f fix: HL testnet - add API wallet address to signed orders, 3-param constructor 2026-05-04 15:39:31 +08:00
jackyu66git 30436bbe75 fix: BG paper trading API - tradeSide param, correct host, marginMode 2026-05-04 15:28:08 +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 5fa3e1bac8 docs: update README for v1.3 — fund management, position click detail, slippage 2026-05-04 13:59:21 +08:00
jackyu66git f29e78a435 fix: db migration tab char corrupted, restore historical trades 2026-05-04 13:50:49 +08:00
jackyu66git e74fd084ce config: raise trade_threshold to 0.20%, mock_slippage to 0.05% 2026-05-04 13:10:22 +08:00
jackyu66git 9eaa4597db chore: 删除未使用的 SpreadReverseExitPct 配置字段 2026-05-04 06:41:49 +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 ddaa5badd2 fix: 重启后总PnL回到0的问题 + 前端PnL图表公式统一
- trader.go: NewTrader 启动时从DB GetAllClosedTrades() 加载所有已平仓交易到 closedTrades
- trader.go: 新增 safeFloat/safeStr 辅助函数处理DB空指针
- db/trade_repo.go: 新增 GetAllClosedTrades() 方法
- frontend: PnL图表标题和曲线改用 2*AmountUSD*NetPnl/100 公式,与后端Stats一致
2026-05-04 06:23:35 +08:00
jackyu66git 2f4d03f9b1 优化: 共用一次 store.GetAll() 快照,消除每 tick 两次 map 分配 2026-05-04 06:10:37 +08:00
jackyu66git 5aedcb6566 修复 scale-in 后 leg.EntryPrice 不更新 + 重启恢复时加载 scale prices
- trader.go: scale-in 后用 weightedAvgPrice 更新 LongLeg/ShortLeg.EntryPrice
- trader.go: restoreOpenPositions 从 orders 表加载 scale prices 重建完整价格切片
- db/trade_repo.go: 新增 GetScalePrices(tradeID) 方法
- README: v1.2.1 版本记录
2026-05-04 06:06:37 +08:00
jackyu66git 7b8ad6abc8 feat: 交易详情净收益总计加美元金额 2026-05-04 05:43:11 +08:00
jackyu66git af44e14f39 feat: 交易详情订单按交易所+时间排序, 加仓位列, 多空Pnl显示USD金额 2026-05-04 05:38:08 +08:00
jackyu66git a9a21de5a2 refactor: 逐批次实时写入DB,删除persistTrade 2026-05-04 05:29:04 +08:00
jackyu66git ec725ed11a fix: PnL计算改为美元归一化,加仓不再虚增手续费 (calcArbPnL) 2026-05-04 05:03:16 +08:00
jackyu66git c44d763ab0 fix: 持仓面板 pnl_est 显示改为美元符号(后台已改为USD) 2026-05-04 04:38:52 +08:00
jackyu66git 0288dc8284 feat: 手续费改为逐笔USD累算 + Vite React前端 + system_orders表 + README 2026-05-04 04:34:27 +08:00
jackyu66git 15a4684208 chore: 增强start.sh, 支持--clean清库/--rebuild强制编译 2026-05-04 02:03:17 +08:00
jackyu66git d1e6c965cb fix: blacklistCoin 计算退出PnL字段, 避免DB写入零值
blacklistCoin 之前只设 Status=close_failed 就跑了, 没给
ExitDiffPct/ExitNetPnl/ExitLongPnl/ExitTotalFees 等字段赋值。
retryClose 写 TradeRecord 时全为零, 导致DB出现 PnL=0 的假记录。

修复: blacklistCoin 现在接收当前价格, 用 checkExit 相同方式
计算 PnL/价差收敛标签并存入 pos 字段。
2026-05-04 02:00:04 +08:00
jackyu66git dd15c6fe43 fix: 移除多余的netPnl和反转检查, 收敛即退出(0.02%) 2026-05-04 01:57:56 +08:00
jackyu66git 1c0618583c fix: 收敛退出放宽到0.02%+净利为正, 恢复到0.02%即退不亏钱 2026-05-04 01:55:22 +08:00
jackyu66git 51b8ee0c8a chore: 添加.gitignore, 移除日志文件跟踪 2026-05-04 01:51:17 +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 e04a165d69 fix: start.sh detects embedded web file changes; rebuild on JS/CSS change 2026-05-04 00:09:49 +08:00
jackyu66git 004ff50325 web: spread highlight threshold 0.1% → 0.2% 2026-05-04 00:07:32 +08:00
jackyu66git b8c73852be fix: BG taker fee 0.06% → 0.03% 2026-05-04 00:04:14 +08:00
jackyu66git 02ca8e248c fix: trade_threshold 0.25 → 0.05 (net profit %) 2026-05-03 23:55:40 +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 68c0a342a6 fix: retryClose saves trade record and persists to DB on success 2026-05-03 23:19:15 +08:00
jackyu66git cf6548c37f fix: 4 bugfixes for production readiness
1. GetHLSize: add minimum size checks (prevent size=0 when price > amount)
2. executeEntry: orphan position warning when leg1 close also fails after leg2
3. checkExit: keep position as close_failed on failure, retryClose on each Tick
4. persistTrade: sync instead of goroutine (prevent data loss on exit)
2026-05-03 23:13:44 +08:00
jackyu66git cdcf0acea6 docs: update README for async entry, entering status, 50ms scan
- Architecture diagram: async goroutine entry path
- Trading Logic: async entry, entering status protection
- Config note: floor rounding on both exchanges
2026-05-03 23:00:18 +08:00
jackyu66git b55ff111a4 perf: scan interval 50ms fixed
HL allMids pushes ~200ms, scan at 50ms catches every update
within 1 tick. Async entry goroutine means no blocking.
2026-05-03 22:47:44 +08:00
jackyu66git 721abc02a9 fix: async entry race condition — 'entering' status prevents premature exit
During async executeEntry goroutine, the 300ms sleep between legs
left the position vulnerable to checkExit() from the main loop.
Added intermediate Status='entering' that checkExit/checkScaleIn
skip ('entering' != 'open'), switched to 'open' only after both
legs are placed.
2026-05-03 22:40:48 +08:00
jackyu66git 29f2072e90 feat: async TryEntry with goroutine, non-blocking main loop
- TryEntry now spawns a goroutine for order placement
- Main loop continues at 50-250ms even during entry
- 'entering' map prevents duplicate entries on same coin
- Async cleanup of entering state on completion
2026-05-03 22:32:09 +08:00
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
jackyu66git 6a4b046742 config.json: add trade_enabled=true 2026-05-03 21:19:07 +08:00
jackyu66git e301c5aa4c fix config.json boolean fields (test_mode, trade_enabled) not applying
loadJSONConfig only checked != 0 for floats, missing bool overrides.
Added def.X = cfg.X || def.X for both booleans.
2026-05-03 21:16:45 +08:00
jackyu66git 327f2505dd sync README: update arch diagram and structure for stats separation 2026-05-03 21:14:49 +08:00
jackyu66git 32f06b57d6 move DetailedStats calc out of trader.go into dashboard.go
- Remove DetailedStats struct and GetDetailedStats() method from trader.go
- Add calcDetailedStats() standalone pure function in dashboard.go
- Dashboard calls d.trader.GetClosedTrades() + calcDetailedStats()
- Trading logic now has zero display-oriented calculations
2026-05-03 21:13:11 +08:00
jackyu66git 1e4a3f3b37 Add detailed PnL and duration stats to dashboard 2026-05-03 21:03:40 +08:00
jackyu66git a89a1f6cd8 Configurable scan interval via SCAN_INTERVAL_MS env var
- Add SCAN_INTERVAL_MS env var support in config.go (code default 500ms)
- Set to 200ms in .env for tighter opportunity detection
2026-05-03 20:55:09 +08:00
jackyu66git de6463530d Update README: add start.sh, fix Quick Start
- Add start.sh to Quick Start section and project file tree
- Remove broken cp .env.example reference (no such file)
- Annotate .env with config categories
2026-05-03 20:31:19 +08:00
jackyu66git 35d9f7661b Update README: spread window monitoring, synchronous entry
- Add SpreadWindowTracker to architecture diagram
- Document synchronous entry logic (no goroutine, scan-time prices)
- Add Spread Window Monitoring section with log example
2026-05-03 20:30:47 +08:00
jackyu66git 5cfb6afa55 Fix SpreadWindow: use netProfit() for fee accuracy, track real peak
- Replace manual spread-fee calc with netProfit() call — matches
  scanner's exact fee model (round-trip 0.07%)
- Each direction gets correct buy/sell fee pairing
- Add PeakNet field to record true max during window, not close-time value
- Log peak net with +/- sign instead of approx symbol
2026-05-03 20:28:27 +08:00
jackyu66git 8ae85750b5 Add SpreadWindowTracker to measure opportunity duration
- New SpreadWindowTracker in types.go watches BG↔HL spread for all
  tracked coins, both directions
- Logs duration when spread stays above trade threshold then converges
- Wired into main loop after each scan tick
- Filters sub-100ms windows as noise
2026-05-03 20:24:36 +08:00
jackyu66git 89d92b6672 Fix entry latency: synchronous execution with scan-time prices
- Remove goroutine in TryEntry (executeEntry now synchronous)
- Use opp.BuyPrice/SellPrice directly instead of re-reading from store
- Keep lightweight direction sanity check (0.1% tolerance)
- executeEntry returns bool for call chain consistency
2026-05-03 20:17:35 +08:00
jackyu66git 02fac78c59 Update README to reflect current architecture and features
- Fix architecture diagram (ScanBGHL, correct data flow)
- Add configuration table with all env vars
- Document exit logic (convergence, reversal, timeout)
- Add Web Dashboard, Notifications, DB, Signals sections
- Add project file tree
2026-05-03 19:56:35 +08:00
jackyu66git c89a3b7333 fix: loadTrades before chart init + try-catch for CDN failure
- Reorder init(): loadTrades() runs first, charts second
- Wrap chart init in try-catch so UI survives CDN issues
- Update start.sh to detect changes in embedded .html/.js/.css
2026-05-03 19:42:06 +08:00