# Gate Api 模块 — 网格交易系统 ## 文件列表 | 文件 | 类型 | 说明 | |------|------|------| | [GateWebSocketClientManager](#gatewebsocketclientmanager) | `@Component` | Spring 启动入口,生命周期管理 | | [GateKlineWebSocketClient](#gateklinewebsocketclient) | WebSocket 连接管理 | 连接/心跳/重连/消息路由 | | [GateGridTradeService](#gategridtradeservice) | 交易服务 | 网格策略 + REST 下单 | | [GateWebSocketClientMain](#gatewebsocketclientmain) | main 入口 | 独立测试启动 | | [Example.java](#examplejava) | 示例 | Gate SDK 用法参考 | ### wsHandler 子包 | 文件 | 类型 | 说明 | |------|------|------| | `wsHandler/GateChannelHandler.java` | **接口** | `subscribe/unsubscribe/handleMessage/getChannelName` | | `wsHandler/AbstractPrivateChannelHandler.java` | **抽象类** | 私有频道基类:HMAC-SHA512 签名 + 认证请求 | | `wsHandler/handler/CandlestickChannelHandler.java` | 公开频道处理器 | K 线订阅/解析 → `onKline()` | | `wsHandler/handler/PositionsChannelHandler.java` | 私有频道处理器 | 仓位推送解析 → `onPositionUpdate()` | | `wsHandler/handler/PositionClosesChannelHandler.java` | 私有频道处理器 | 平仓推送解析 → `onPositionClose()` | --- ## 架构总览 ``` ┌──────────────────────────────────────────────────────────────────┐ │ GateWebSocketClientManager │ │ (Spring @Component) │ │ │ │ @PostConstruct init(): │ │ ┌──────────────────────┐ ┌───────────────────────────────┐ │ │ │ GateGridTradeService │ │ GateKlineWebSocketClient │ │ │ │ ▶ init() │ │ ▶ addChannelHandler(x3) │ │ │ │ ▶ startGrid() │ │ ▶ init() │ │ │ └──────┬───────────────┘ └──────────┬────────────────────┘ │ │ │ REST API │ WebSocket (委托路由) │ │ ▼ ▼ │ │ Gate Testnet API Gate Testnet WS │ │ (https://api-testnet...) (wss://ws-testnet.gate.com) │ │ ┌──────────────────────┐ │ │ │ CandlestickHandler │ → onKline │ │ │ PositionsHandler │ → onPos │ │ │ PositionClosesHandler │ → onClose │ │ └──────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ ``` --- ## 数据流 ``` WebSocket 推送 │ ├─ futures.candlesticks (update) [公开] │ └─ CandlestickChannelHandler.handleMessage() │ ├─ 解析: o/h/l/c/v/a/t/w │ ├─ 打印 K 线日志 │ └─ GateGridTradeService.onKline(closePx) │ ├─ 首次 → dualOpenPositions() → 开多 + 开空 + TP 单 │ └─ 后续 → 仅缓存 lastKlinePrice │ ├─ futures.positions (update) [私有,HMAC-SHA512] │ └─ PositionsChannelHandler.handleMessage() │ ├─ 解析: contract/mode/size/entry_price │ └─ GateGridTradeService.onPositionUpdate(...) │ ├─ size=0 && longActive → reopenLongPosition() │ ├─ size=0 && shortActive → reopenShortPosition() │ └─ size>0 → 确认仓位活跃 │ ├─ futures.position_closes (update) [私有,HMAC-SHA512] │ └─ PositionClosesChannelHandler.handleMessage() │ ├─ 解析: contract/side/pnl │ └─ GateGridTradeService.onPositionClose(pnl) │ └─ cumulativePnl += pnl → checkStopConditions() │ ├─ futures.pong │ └─ cancelPongTimeout() │ └─ subscribe/unsubscribe/error └─ 日志输出 ``` --- ## 策略时序 ### 阶段 1:启动与初始化 ``` Spring 启动 → GateWebSocketClientManager.init() → GateGridTradeService.init() → REST: 查用户ID → REST: 查账户 → 如需要切换持仓模式 (dual) → REST: 清除旧止盈止损条件单 → REST: 设杠杆 30x cross → REST: 打印账户余额 → GateKlineWebSocketClient → addChannelHandler: Candlestick + Positions + PositionCloses → init() → connect() → onOpen: 遍历 handlers.subscribe() + sendPing() → GateGridTradeService.startGrid() → strategyActive = true ``` ### 阶段 2:首次开仓 ``` K 线推送 closePrice=4711 → onKline(4711) → dualOpened = true → dualOpenPositions() → REST: 市价开多 10 张 → longEntryPrice=4711 → REST: 创建多头止盈单 TP=4711×1.0035=4727 (close-long-position) → REST: 市价开空 10 张 → shortEntryPrice=4711 → REST: 创建空头止盈单 TP=4711×0.9965=4694 (close-short-position) → longActive=true, shortActive=true ``` ### 阶段 3:止盈触发 → 补仓 ``` 仓位推送: mode=dual_long, size=0 (多头被服务器止盈平掉了) → longActive=true && size=0 → reopenLongPosition() → REST: 市价补开多 10 张 → REST: 创建新的多头止盈单 仓位推送: mode=dual_short, size=0 (空头被服务器止盈平掉了) → shortActive=true && size=0 → reopenShortPosition() → REST: 市价补开空 10 张 → REST: 创建新的空头止盈单 ``` > 注意:只补被平掉的方向(另一方向不受影响),不双方向重新开。补仓时检查 `longActive` / `shortActive` 防重复开仓。 ### 阶段 4:停止条件 ``` 平仓推送: pnl=+0.2 → cumulativePnl = 0.2, 未达阈值,继续 平仓推送: pnl=+0.4 → cumulativePnl = 0.6 ≥ 0.5 → strategyActive=false 平仓推送: pnl=-8 → cumulativePnl = -8 ≤ -7.5 → strategyActive=false ``` --- ## GateWebSocketClientManager **角色**: Spring Bean 入口,组装并管理所有 Gate 模块组件。 **关键方法**: - `init()`: 创建 `GateGridTradeService` → 初始化 → 创建 `GateKlineWebSocketClient` + 注册 3 个 Handler → 启动策略 - `destroy()`: 停止策略 → 关闭 WebSocket **当前参数**(硬编码在 `init()` 中): | 参数 | 值 | 说明 | |------|-----|------| | 合约 | XAUT_USDT | 黄金(测试网) | | 杠杆 | 30x | 全仓模式 | | 持仓模式 | dual | 双向持仓 | | 网格间距 | 0.0035 | 0.35% | | 整体止盈 | 0.5 USDT | | | 最大亏损 | 7.5 USDT | 本金 50×15% | | 下单量 | 10 张 | | --- ## GateKlineWebSocketClient **角色**: WebSocket 连接管理器。负责建立连接、心跳检测、指数退避重连。频道逻辑委托给 `GateChannelHandler` 实现类。 **Handler 路由**: | 频道 | Handler | 认证 | 回调 | |------|---------|------|------| | `futures.candlesticks` | `CandlestickChannelHandler` | 否 | `onKline(closePx)` | | `futures.positions` | `PositionsChannelHandler` | HMAC-SHA512 | `onPositionUpdate(mode, size, entryPrice)` | | `futures.position_closes` | `PositionClosesChannelHandler` | HMAC-SHA512 | `onPositionClose(side, pnl)` | **消息路由** (`handleMessage`): | channel | event | 处理 | |---------|-------|------| | `futures.pong` | — | `cancelPongTimeout()` | | — | `subscribe` | 打日志 | | — | `unsubscribe` | 打日志 | | — | `error` | 打错误日志 | | 任意 | `update`/`all` | 遍历 channelHandlers → `handler.handleMessage()` | **签名算法**: ``` message = "channel={channel}&event=subscribe&time={秒级时间戳}" SIGN = Hex(HmacSHA512(apiSecret.getBytes(UTF-8), message.getBytes(UTF-8))) ``` **连接管理**: - 心跳: 10 秒超时,每 25 秒检查,超时发 ping - 重连: 指数退避,最多 3 次,初始 5 秒 - 关闭: 遍历 `handler.unsubscribe()` → 等 500ms → `closeBlocking()` → `sharedExecutor.shutdown()` --- ## GateChannelHandler 接口体系 ``` GateChannelHandler (接口) ├── CandlestickChannelHandler (公开频道) └── AbstractPrivateChannelHandler (抽象类) (私有频道基类) ├── PositionsChannelHandler └── PositionClosesChannelHandler ``` | 方法 | 说明 | |------|------| | `getChannelName()` | 返回频道名(如 `"futures.candlesticks"`) | | `subscribe(ws)` | 发送订阅请求。私有频道自动附加 HMAC-SHA512 签名 | | `unsubscribe(ws)` | 发送取消订阅请求 | | `handleMessage(response)` | 解析推送数据并回调 `GateGridTradeService`,返回 `true` 表示已处理 | --- ## GateGridTradeService **角色**: 使用 Gate SDK (`io.gate:gate-api:7.2.71`) 通过 REST API 执行合约下单。 **状态机**: ``` strategyActive=false ──startGrid()──→ strategyActive=true (等待K线) │ onKline(price) │ dualOpened=true dualOpenPositions() │ ┌───────────┴───────────┐ ▼ ▼ longActive=true shortActive=true │ │ 仓位推送 size=0 仓位推送 size=0 (止盈触发平仓) (止盈触发平仓) │ │ ▼ ▼ reopenLong() reopenShort() │ │ └───────────┬───────────┘ │ 平仓推送 pnl (futures.position_closes) │ checkStopConditions() │ ┌───────────┴───────────┐ ▼ ▼ cumulativePnl≥0.5 cumulativePnl≤-7.5 strategyActive=false strategyActive=false ``` **止盈计算**: | 方向 | 公式 | 触发条件 | order_type | auto_size | |------|------|----------|------------|-----------| | 多头 TP | entryPrice × (1 + gridRate) | 最新价 ≥ 触发价 | `close-long-position` | `close_long` | | 空头 TP | entryPrice × (1 - gridRate) | 最新价 ≤ 触发价 | `close-short-position` | `close_short` | **REST API 调用**: | 操作 | API | 方法 | |------|-----|------| | 获取用户 ID | `GET /account/detail` | `AccountApi.getAccountDetail()` | | 切持仓模式 | `POST /futures/{settle}/set_position_mode` | `FuturesApi.setPositionMode()` | | 设杠杆 | `POST /futures/{settle}/positions/{contract}/leverage` | `FuturesApi.updateContractPositionLeverageCall()` | | 查账户 | `GET /futures/{settle}/accounts` | `FuturesApi.listFuturesAccounts()` | | 清除条件单 | `DELETE /futures/{settle}/price_orders` | `FuturesApi.cancelPriceTriggeredOrderList()` | | 市价下单 | `POST /futures/{settle}/orders` (price=0, tif=IOC) | `FuturesApi.createFuturesOrder()` | | 止盈条件单 | `POST /futures/{settle}/price_orders` | `FuturesApi.createPriceTriggeredOrder()` | **初始化顺序** (`init()`): ``` 1. 获取用户 ID 2. 查账户 → 如需要切持仓模式 3. 清除旧的止盈止损条件单 4. 设杠杆 5. 打印账户余额 ``` --- ## GateWebSocketClientMain **角色**: 独立的 `main()` 方法入口,通过 Spring XML 上下文启动。 --- ## Example.java Gate SDK 使用示例,展示 `FuturesApi` 的基本用法。仅作参考,不参与实际策略运行。