From 176f004c60a239fd4fde775e88c2a88af6d6e5da Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 07 May 2026 12:50:04 +0800
Subject: [PATCH] fix(okxWs): 修复OKX生产环境配置的调试模式设置

---
 src/main/java/com/xcong/excoin/modules/gateApi/Example.java                    |   75 
 src/main/java/com/xcong/excoin/modules/gateApi/gate-websocket.txt              | 5011 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientMain.java    |   19 
 src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientManager.java |   83 
 src/main/java/com/xcong/excoin/modules/gateApi/GateKlineWebSocketClient.java   |  583 ++++++
 src/main/resources/application-test.yml                                        |   22 
 pom.xml                                                                        |    8 
 7 files changed, 5,790 insertions(+), 11 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2c27f4e..885db64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,6 +35,14 @@
     </properties>
 
     <dependencies>
+
+        <!-- Source: https://mvnrepository.com/artifact/io.gate/gate-api -->
+        <dependency>
+            <groupId>io.gate</groupId>
+            <artifactId>gate-api</artifactId>
+            <version>7.2.71</version>
+            <scope>compile</scope>
+        </dependency>
     
         <dependency>
             <groupId>ripple</groupId>
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/Example.java b/src/main/java/com/xcong/excoin/modules/gateApi/Example.java
new file mode 100644
index 0000000..b041e48
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/Example.java
@@ -0,0 +1,75 @@
+package com.xcong.excoin.modules.gateApi;
+
+// Import classes:
+import io.gate.gateapi.ApiClient;
+import io.gate.gateapi.ApiException;
+import io.gate.gateapi.Configuration;
+import io.gate.gateapi.GateApiException;
+import io.gate.gateapi.api.FuturesApi;
+import io.gate.gateapi.auth.*;
+import io.gate.gateapi.models.*;
+import io.gate.gateapi.api.AccountApi;
+
+public class Example {
+    public static void main(String[] args) {
+        ApiClient defaultClient = Configuration.getDefaultApiClient();
+        defaultClient.setBasePath("https://api-testnet.gateapi.io/api/v4");
+//        defaultClient.setBasePath("https://api.gateio.ws/api/v4");
+
+        // Configure APIv4 authorization: apiv4
+        defaultClient.setApiKeySecret("d90ca272391992b8e74f8f92cedb21ec", "1861e4f52de4bb53369ea3208d9ede38ece4777368030f96c77d27934c46c274");
+
+        try {
+
+            String contract = "ETH_USDT";
+            String settle = "usdt";
+            //保证金模式 isolated/cross
+            String marginMode = "cross";
+            AccountApi accountApi = new AccountApi(defaultClient);
+            AccountDetail accountDetail = accountApi.getAccountDetail();
+            System.out.println(accountDetail.toString());
+
+
+            /**
+             * 获取账户余额
+             */
+            FuturesApi futuresApi = new FuturesApi(defaultClient);
+            FuturesAccount futuresAccount = futuresApi.listFuturesAccounts(settle);
+            String available = futuresAccount.getAvailable();
+            String result = "可用余额:" + available;
+            System.out.println(result);
+
+            /**
+             * 设置仓位模式
+             * 可选值:single, dual, dual_plus,分别表示单向、双向、分仓
+             */
+
+            String position_mode = "dual";
+            String positionMode = futuresAccount.getPositionMode();
+            if (!position_mode.equals(positionMode)){
+                futuresApi.setPositionMode(settle, position_mode);
+            }
+
+            /**
+             * 设置杠杆倍数
+             * 设置合理的杠杆倍数,不能为0
+             */
+            String leverage = "25";
+            futuresApi.updateContractPositionLeverageCall(
+                    settle,
+                    contract,
+                    leverage,
+                    marginMode,
+                    position_mode,
+                    null);
+        } catch (GateApiException e) {
+            System.err.println(String.format("Gate api exception, label: %s, message: %s", e.getErrorLabel(), e.getMessage()));
+            e.printStackTrace();
+        } catch (ApiException e) {
+            System.err.println("Exception when calling AccountApi#getAccountDetail");
+            System.err.println("Status code: " + e.getCode());
+            System.err.println("Response headers: " + e.getResponseHeaders());
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateKlineWebSocketClient.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateKlineWebSocketClient.java
new file mode 100644
index 0000000..42f639f
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateKlineWebSocketClient.java
@@ -0,0 +1,583 @@
+package com.xcong.excoin.modules.gateApi;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.json.JSONException;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.xcong.excoin.modules.blackchain.service.DateUtil;
+import com.xcong.excoin.modules.okxNewPrice.celue.CaoZuoService;
+import com.xcong.excoin.modules.okxNewPrice.indicator.macdAndMatrategy.MacdEmaStrategy;
+import com.xcong.excoin.modules.okxNewPrice.indicator.macdAndMatrategy.MacdMaStrategy;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.InstrumentsWs;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.TradeOrderWs;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.Kline;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListService;
+import com.xcong.excoin.modules.okxNewPrice.okxpi.config.ExchangeInfoEnum;
+import com.xcong.excoin.modules.okxNewPrice.okxpi.config.ExchangeLoginService;
+import com.xcong.excoin.modules.okxNewPrice.utils.SSLConfig;
+import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild;
+import lombok.extern.slf4j.Slf4j;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+/**
+ * Gate K线 WebSocket 客户端类,用于连接 Gate 的 WebSocket 接口,
+ * 实时获取并处理 K线(candlestick)数据。
+ * 同时支持心跳检测、自动重连以及异常恢复机制。
+ * @author Administrator
+ */
+@Slf4j
+public class GateKlineWebSocketClient {
+    private final CaoZuoService caoZuoService;
+    private final GateWebSocketClientManager clientManager;
+    private final WangGeListService wangGeListService;
+
+    private WebSocketClient webSocketClient;
+    private ScheduledExecutorService heartbeatExecutor;
+    private volatile ScheduledFuture<?> pongTimeoutFuture;
+    private final AtomicReference<Long> lastMessageTime = new AtomicReference<>(System.currentTimeMillis());
+
+    // 连接状态标志
+    private final AtomicBoolean isConnected = new AtomicBoolean(false);
+    private final AtomicBoolean isConnecting = new AtomicBoolean(false);
+    private final AtomicBoolean isInitialized = new AtomicBoolean(false);
+
+    private static final String CHANNEL = "futures.candlesticks";
+    private static final String FUTURES_PING = "futures.ping";
+    private static final String FUTURES_PONG = "futures.pong";
+    private static final String GATE_INTERVAL = "1m";
+    private static final String GATE_CONTRACT = "BTC_USDT";
+
+    // 心跳超时时间(秒),小于30秒
+    private static final int HEARTBEAT_TIMEOUT = 10;
+
+    // 共享线程池用于重连等异步任务
+    private final ExecutorService sharedExecutor = Executors.newCachedThreadPool(r -> {
+        Thread t = new Thread(r, "gate-kline-worker");
+        t.setDaemon(true);
+        return t;
+    });
+
+    public GateKlineWebSocketClient(CaoZuoService caoZuoService,
+                                    GateWebSocketClientManager clientManager,
+                                    WangGeListService wangGeListService
+    ) {
+        this.caoZuoService = caoZuoService;
+        this.clientManager = clientManager;
+        this.wangGeListService = wangGeListService;
+    }
+
+    /**
+     * 初始化方法,创建并初始化WebSocket客户端实例
+     */
+    public void init() {
+        if (!isInitialized.compareAndSet(false, true)) {
+            log.warn("GateKlineWebSocketClient 已经初始化过,跳过重复初始化");
+            return;
+        }
+        connect();
+        startHeartbeat();
+    }
+
+    /**
+     * 销毁方法,关闭WebSocket连接和相关资源
+     */
+    public void destroy() {
+        log.info("开始销毁GateKlineWebSocketClient");
+
+        if (webSocketClient != null && webSocketClient.isOpen()) {
+            unsubscribeKlineChannels();
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                log.warn("取消订阅等待被中断");
+            }
+        }
+
+        if (sharedExecutor != null && !sharedExecutor.isShutdown()) {
+            sharedExecutor.shutdown();
+        }
+
+        if (webSocketClient != null && webSocketClient.isOpen()) {
+            try {
+                webSocketClient.closeBlocking();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                log.warn("关闭WebSocket连接时被中断");
+            }
+        }
+
+        shutdownExecutorGracefully(heartbeatExecutor);
+        if (pongTimeoutFuture != null) {
+            pongTimeoutFuture.cancel(true);
+        }
+        shutdownExecutorGracefully(sharedExecutor);
+
+        log.info("GateKlineWebSocketClient销毁完成");
+    }
+
+    private static final String WS_URL_MONIPAN = "wss://ws-testnet.gate.com/v4/ws/futures/usdt";
+    private static final String WS_URL_SHIPAN = "wss://fx-ws.gateio.ws/v4/ws/usdt";
+    private static final boolean isAccountType = false;
+
+    /**
+     * 建立与 Gate WebSocket 服务器的连接。
+     * 设置回调函数以监听连接打开、接收消息、关闭和错误事件。
+     */
+    private void connect() {
+        // 避免重复连接
+        if (isConnecting.get()) {
+            log.info("连接已在进行中,跳过重复连接请求");
+            return;
+        }
+        
+        if (!isConnecting.compareAndSet(false, true)) {
+            log.info("连接已在进行中,跳过重复连接请求");
+            return;
+        }
+        
+        try {
+            SSLConfig.configureSSL();
+            System.setProperty("https.protocols", "TLSv1.2,TLSv1.3");
+            String WS_URL = WS_URL_MONIPAN;
+            if (isAccountType){
+                WS_URL = WS_URL_SHIPAN;
+            }
+            URI uri = new URI(WS_URL);
+            
+            // 关闭之前的连接(如果存在)
+            if (webSocketClient != null) {
+                try {
+                    webSocketClient.closeBlocking();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    log.warn("关闭之前连接时被中断");
+                }
+            }
+            
+            webSocketClient = new WebSocketClient(uri) {
+                @Override
+                public void onOpen(ServerHandshake handshake) {
+                    log.info("Gate Kline WebSocket连接成功");
+                    isConnected.set(true);
+                    isConnecting.set(false);
+                    
+                    // 检查应用是否正在关闭
+                    if (sharedExecutor != null && !sharedExecutor.isShutdown()) {
+                        resetHeartbeatTimer();
+                        subscribeKlineChannels();
+                        subscribePingChannels();
+                    } else {
+                        log.warn("应用正在关闭,忽略WebSocket连接成功回调");
+                    }
+                }
+
+                @Override
+                public void onMessage(String message) {
+                    lastMessageTime.set(System.currentTimeMillis());
+                    handleWebSocketMessage(message);
+                    resetHeartbeatTimer();
+                }
+
+                @Override
+                public void onClose(int code, String reason, boolean remote) {
+                    log.warn("Gate Kline WebSocket连接关闭: code={}, reason={}", code, reason);
+                    isConnected.set(false);
+                    isConnecting.set(false);
+                    cancelPongTimeout();
+
+                    if (sharedExecutor != null && !sharedExecutor.isShutdown() && !sharedExecutor.isTerminated()) {
+                        sharedExecutor.execute(() -> {
+                            try {
+                                reconnectWithBackoff();
+                            } catch (InterruptedException e) {
+                                Thread.currentThread().interrupt();
+                                log.error("重连线程被中断", e);
+                            } catch (Exception e) {
+                                log.error("重连失败", e);
+                            }
+                        });
+                    } else {
+                        log.warn("共享线程池已关闭,无法执行重连任务");
+                    }
+                }
+
+                @Override
+                public void onError(Exception ex) {
+                    log.error("Gate Kline WebSocket发生错误", ex);
+                    isConnected.set(false);
+                }
+            };
+
+            webSocketClient.connect();
+        } catch (URISyntaxException e) {
+            log.error("WebSocket URI格式错误", e);
+            isConnecting.set(false);
+        }
+    }
+
+    /**
+     * 订阅K线频道。
+     * 构造 Gate 格式的订阅请求并发送给服务端。
+     * payload: ["1m", "BTC_USDT"] (间隔, 合约名)
+     */
+    private void subscribeKlineChannels() {
+        JSONObject subscribeMsg = new JSONObject();
+        subscribeMsg.put("time", System.currentTimeMillis() / 1000);
+        subscribeMsg.put("channel", CHANNEL);
+        subscribeMsg.put("event", "subscribe");
+
+        JSONArray payload = new JSONArray();
+        payload.add(GATE_INTERVAL);
+        payload.add(GATE_CONTRACT);
+        subscribeMsg.put("payload", payload);
+
+        webSocketClient.send(subscribeMsg.toJSONString());
+        log.info("已发送 K线频道订阅请求,合约: {}, 周期: {}", GATE_CONTRACT, GATE_INTERVAL);
+    }
+    private void subscribePingChannels() {
+        JSONObject subscribeMsg = new JSONObject();
+        subscribeMsg.put("time", System.currentTimeMillis() / 1000);
+        subscribeMsg.put("channel", FUTURES_PING);
+        webSocketClient.send(subscribeMsg.toJSONString());
+        log.info("已发送 futures.ping");
+    }
+
+    private void unsubscribeKlineChannels() {
+        JSONObject unsubscribeMsg = new JSONObject();
+        unsubscribeMsg.put("time", System.currentTimeMillis() / 1000);
+        unsubscribeMsg.put("channel", CHANNEL);
+        unsubscribeMsg.put("event", "unsubscribe");
+        JSONArray payload = new JSONArray();
+        payload.add(GATE_INTERVAL);
+        payload.add(GATE_CONTRACT);
+        unsubscribeMsg.put("payload", payload);
+        webSocketClient.send(unsubscribeMsg.toJSONString());
+        log.info("已发送 K线频道取消订阅请求,合约: {}, 周期: {}", GATE_CONTRACT, GATE_INTERVAL);
+    }
+
+    /**
+     * 处理从 WebSocket 收到的消息。
+     * 包括订阅确认、错误响应、心跳响应以及实际的数据推送。
+     *
+     * @param message 来自 WebSocket 的原始字符串消息
+     */
+    private void handleWebSocketMessage(String message) {
+        try {
+            JSONObject response = JSON.parseObject(message);
+            String channel = response.getString("channel");
+            String event = response.getString("event");
+
+            if (FUTURES_PONG.equals(channel)) {
+                log.debug("收到futures.pong响应");
+                cancelPongTimeout();
+            } else if ("subscribe".equals(event)) {
+                log.info("{} 频道订阅成功: {}", channel, response.getJSONObject("result"));
+            } else if ("unsubscribe".equals(event)) {
+                log.info("{} 频道取消订阅成功", channel);
+            } else if ("error".equals(event)) {
+                JSONObject error = response.getJSONObject("error");
+                log.error("{} 频道错误: code={}, msg={}",
+                        channel,
+                        error != null ? error.getInteger("code") : "N/A",
+                        error != null ? error.getString("message") : response.getString("msg"));
+            } else if ("update".equals(event) || "all".equals(event)) {
+                processPushDataV2(response);
+            }
+        } catch (Exception e) {
+            log.error("处理WebSocket消息失败: {}", message, e);
+        }
+    }
+
+    /**
+     * 解析并处理K线推送数据。
+     * 控制台输出K线数据,并在K线完结时触发策略和量化操作。
+     *
+     * @param response 包含K线数据的 JSON 对象
+     */
+    private void processPushDataV2(JSONObject response) {
+        try {
+            /**
+             * Gate K线推送格式:
+             * {
+             *   "time": 1542162490,
+             *   "time_ms": 1542162490123,
+             *   "channel": "futures.candlesticks",
+             *   "event": "update",
+             *   "result": [
+             *     {
+             *       "t": 1545129300,
+             *       "v": "27525555",
+             *       "c": "95.4",
+             *       "h": "96.9",
+             *       "l": "89.5",
+             *       "o": "94.3",
+             *       "n": "1m_BTC_USD",
+             *       "a": "314732.87412",
+             *       "w": false
+             *     }
+             *   ]
+             * }
+             */
+            String channel = response.getString("channel");
+            if (!CHANNEL.equals(channel)) {
+                return;
+            }
+
+            JSONArray resultArray = response.getJSONArray("result");
+            if (resultArray == null || resultArray.isEmpty()) {
+                log.warn("K线频道数据为空");
+                return;
+            }
+
+            JSONObject data = resultArray.getJSONObject(0);
+            BigDecimal openPx = new BigDecimal(data.getString("o"));
+            BigDecimal highPx = new BigDecimal(data.getString("h"));
+            BigDecimal lowPx = new BigDecimal(data.getString("l"));
+            BigDecimal closePx = new BigDecimal(data.getString("c"));
+            BigDecimal vol = new BigDecimal(data.getString("v"));
+            BigDecimal baseVol = new BigDecimal(data.getString("a"));
+            String name = data.getString("n");
+            long tsSeconds = data.getLong("t");
+            boolean windowClosed = data.getBooleanValue("w");
+            String time = DateUtil.TimeStampToDateTime(tsSeconds * 1000);
+
+            System.out.println("========== Gate K线数据 ==========");
+            System.out.println("名称(n): " + name);
+            System.out.println("时间  : " + time);
+            System.out.println("开盘(o): " + openPx);
+            System.out.println("最高(h): " + highPx);
+            System.out.println("最低(l): " + lowPx);
+            System.out.println("收盘(c): " + closePx);
+            System.out.println("成交量(v): " + vol);
+            System.out.println("成交额(a): " + baseVol);
+            System.out.println("K线完结(w): " + windowClosed);
+            System.out.println("==================================");
+
+            if (windowClosed) {
+                MacdEmaStrategy strategy = new MacdEmaStrategy();
+
+                List<Kline> kline1MinuteData = getKlineDataByInstIdAndBar(CoinEnums.HE_YUE.getCode(), "1m");
+                List<BigDecimal> historicalPrices1M = kline1MinuteData.stream()
+                        .map(Kline::getC)
+                        .collect(Collectors.toList());
+
+                MacdEmaStrategy.TradingOrder tradingOrderOpenOpen = strategy.generateTradingOrder(historicalPrices1M, MacdMaStrategy.OperationType.open.name());
+                if (tradingOrderOpenOpen == null) {
+                    return;
+                }
+
+            }
+        } catch (Exception e) {
+            log.error("处理 K线频道推送数据失败", e);
+        }
+    }
+
+    private void doOpen(WebSocketClient webSocketClient, String accountName, MacdEmaStrategy.TradingOrder tradingOrderOpenOpen, BigDecimal closePx) {
+        // 根据信号执行交易操作
+        TradeRequestParam tradeRequestParam = new TradeRequestParam();
+
+        String posSide = tradingOrderOpenOpen.getPosSide();
+        tradeRequestParam.setPosSide(posSide);
+        String currentPrice = String.valueOf(closePx);
+        tradeRequestParam = caoZuoService.caoZuoStrategy(accountName, currentPrice, posSide);
+
+        String side = tradingOrderOpenOpen.getSide();
+        tradeRequestParam.setSide(side);
+
+        String clOrdId = WsParamBuild.getOrderNum(side);
+        tradeRequestParam.setClOrdId(clOrdId);
+
+        String sz = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
+        tradeRequestParam.setSz(sz);
+        TradeOrderWs.orderEvent(webSocketClient, tradeRequestParam);
+    }
+
+    private List<Kline> getKlineDataByInstIdAndBar(String instId, String bar) {
+        List<Kline> klineList = new ArrayList<>();
+        try {
+            LinkedHashMap<String, Object> requestParam = new LinkedHashMap<>();
+            requestParam.put("instId", instId);
+            requestParam.put("bar", bar);
+            requestParam.put("limit", "200");
+            String result = ExchangeLoginService.getInstance(ExchangeInfoEnum.OKX_UAT.name()).lineHistory(requestParam);
+            JSONObject json = JSON.parseObject(result);
+            String data = json.getString("data");
+            
+            if (data != null) {
+                List<String[]> klinesList = JSON.parseArray(data, String[].class);
+                if (!CollUtil.isEmpty(klinesList)) {
+                    for (String[] s : klinesList) {
+                        // 确保数组有足够的元素
+                        if (s != null && s.length >= 9) {
+                            String s1 = s[8];
+                            try {
+                                if ("1".equals(s1)){
+                                    Kline kline = new Kline();
+                                    kline.setTs(s[0]);
+                                    kline.setO(new BigDecimal(s[1]));
+                                    kline.setH(new BigDecimal(s[2]));
+                                    kline.setL(new BigDecimal(s[3]));
+                                    kline.setC(new BigDecimal(s[4]));
+                                    kline.setVol(new BigDecimal(s[5]));
+                                    kline.setConfirm(s[8]);
+                                    klineList.add(kline);
+                                }
+                            } catch (NumberFormatException e) {
+                                log.error("K线数据转换为BigDecimal失败: {}", Arrays.toString(s), e);
+                            }
+                        } else {
+                            log.warn("K线数据数组长度不足: {}", Arrays.toString(s));
+                        }
+                    }
+                }
+            } else {
+                log.warn("K线数据为空");
+            }
+        } catch (JSONException e) {
+            log.error("K线数据解析失败", e);
+        } catch (Exception e) {
+            log.error("获取K线数据异常", e);
+        }
+        return klineList;
+    }
+
+    /**
+     * 构建 Redis Key
+     */
+    private String buildRedisKey(String instId) {
+        return "PRICE_" + instId.replace("-", "");
+    }
+
+    /**
+     * 启动心跳检测任务。
+     * 使用 ScheduledExecutorService 定期检查是否需要发送 ping 请求来维持连接。
+     */
+    private void startHeartbeat() {
+        if (heartbeatExecutor != null && !heartbeatExecutor.isTerminated()) {
+            heartbeatExecutor.shutdownNow();
+        }
+
+        heartbeatExecutor = Executors.newSingleThreadScheduledExecutor(r -> {
+            Thread t = new Thread(r, "gate-kline-heartbeat");
+            t.setDaemon(true);
+            return t;
+        });
+
+        heartbeatExecutor.scheduleWithFixedDelay(this::checkHeartbeatTimeout, 25, 25, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 重置心跳计时器。
+     * 当收到新消息或发送 ping 后取消当前超时任务并重新安排下一次超时检查。
+     */
+    private synchronized void resetHeartbeatTimer() {
+        cancelPongTimeout();
+
+        if (heartbeatExecutor != null && !heartbeatExecutor.isShutdown()) {
+            pongTimeoutFuture = heartbeatExecutor.schedule(this::checkHeartbeatTimeout,
+                    HEARTBEAT_TIMEOUT, TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 检查心跳超时情况。
+     * 若长时间未收到任何消息则主动发送 ping 请求保持连接活跃。
+     */
+    private void checkHeartbeatTimeout() {
+        // 只有在连接状态下才检查心跳
+        if (!isConnected.get()) {
+            return;
+        }
+        
+        long currentTime = System.currentTimeMillis();
+        long lastTime = lastMessageTime.get();
+
+        if (currentTime - lastTime >= HEARTBEAT_TIMEOUT * 1000L) {
+            sendPing();
+        }
+    }
+
+    /**
+     * 发送 ping 请求至 WebSocket 服务端。
+     * 用于维持长连接有效性。
+     */
+    private void sendPing() {
+        try {
+            if (webSocketClient != null && webSocketClient.isOpen()) {
+                JSONObject pingMsg = new JSONObject();
+                pingMsg.put("time", System.currentTimeMillis() / 1000);
+                pingMsg.put("channel", FUTURES_PING);
+                webSocketClient.send(pingMsg.toJSONString());
+                log.debug("发送futures.ping请求");
+            }
+        } catch (Exception e) {
+            log.warn("发送ping失败", e);
+        }
+    }
+
+    /**
+     * 取消当前的心跳超时任务。
+     * 在收到 pong 或其他有效消息时调用此方法避免不必要的断开重连。
+     */
+    private synchronized void cancelPongTimeout() {
+        if (pongTimeoutFuture != null && !pongTimeoutFuture.isDone()) {
+            pongTimeoutFuture.cancel(true);
+        }
+    }
+
+    /**
+     * 执行 WebSocket 重连操作。
+     * 在连接意外中断后尝试重新建立连接。
+     */
+    private void reconnectWithBackoff() throws InterruptedException {
+        int attempt = 0;
+        int maxAttempts = 3;
+        long delayMs = 5000;
+
+        while (attempt < maxAttempts) {
+            try {
+                Thread.sleep(delayMs);
+                connect();
+                return;
+            } catch (Exception e) {
+                log.warn("第{}次重连失败", attempt + 1, e);
+                delayMs *= 2;
+                attempt++;
+            }
+        }
+
+        log.error("超过最大重试次数({})仍未连接成功", maxAttempts);
+    }
+
+    /**
+     * 优雅关闭线程池
+     */
+    private void shutdownExecutorGracefully(ExecutorService executor) {
+        if (executor == null || executor.isTerminated()) {
+            return;
+        }
+        try {
+            executor.shutdown();
+            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+                executor.shutdownNow();
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            executor.shutdownNow();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientMain.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientMain.java
new file mode 100644
index 0000000..604f2bc
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientMain.java
@@ -0,0 +1,19 @@
+package com.xcong.excoin.modules.gateApi;
+
+import com.xcong.excoin.modules.okxNewPrice.OkxWebSocketClientManager;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class GateWebSocketClientMain {
+    public static void main(String[] args) throws InterruptedException {
+        // 使用Spring上下文初始化管理器
+        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
+        GateWebSocketClientManager manager = context.getBean(GateWebSocketClientManager.class);
+
+        // 运行一段时间以观察结果
+        Thread.sleep(1200000000L); // 运行一小时
+        
+        // 关闭连接
+        manager.destroy();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientManager.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientManager.java
new file mode 100644
index 0000000..f020544
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateWebSocketClientManager.java
@@ -0,0 +1,83 @@
+package com.xcong.excoin.modules.gateApi;
+
+import com.xcong.excoin.modules.okxNewPrice.OkxKlineWebSocketClient;
+import com.xcong.excoin.modules.okxNewPrice.OkxQuantWebSocketClient;
+import com.xcong.excoin.modules.okxNewPrice.celue.CaoZuoService;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.ExchangeInfoEnum;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListService;
+import com.xcong.excoin.utils.RedisUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 管理多个OKX WebSocket客户端实例,每个实例对应一个账号
+ */
+@Slf4j
+@Component
+public class GateWebSocketClientManager {
+    @Autowired
+    private CaoZuoService caoZuoService;
+    @Autowired
+    private RedisUtils redisUtils;
+    @Autowired
+    private WangGeListService wangGeListService;
+
+    private GateKlineWebSocketClient klinePriceClient;
+
+
+    /**
+     * 初始化方法,在Spring Bean构造完成后执行
+     * 创建并初始化所有账号的WebSocket客户端实例
+     */
+    @PostConstruct
+    public void init() {
+        log.info("开始初始化OkxWebSocketClientManager");
+        
+        // 初始化价格WebSocket客户端
+        try {
+            klinePriceClient = new GateKlineWebSocketClient(caoZuoService, this, wangGeListService);
+            klinePriceClient.init();
+            log.info("已初始化OkxNewPriceWebSocketClient");
+        } catch (Exception e) {
+            log.error("初始化OkxNewPriceWebSocketClient失败", e);
+        }
+        
+    }
+
+    /**
+     * 销毁方法,在Spring Bean销毁前执行
+     * 关闭所有WebSocket客户端连接和相关资源
+     */
+    @PreDestroy
+    public void destroy() {
+        log.info("开始销毁OkxWebSocketClientManager");
+        
+        // 关闭价格WebSocket客户端
+        if (klinePriceClient != null) {
+            try {
+                klinePriceClient.destroy();
+                log.info("已销毁OkxNewPriceWebSocketClient");
+            } catch (Exception e) {
+                log.error("销毁OkxNewPriceWebSocketClient失败", e);
+            }
+        }
+        
+        log.info("OkxWebSocketClientManager销毁完成");
+    }
+
+    /**
+     * 获取OkxNewPriceWebSocketClient实例
+     * @return 价格WebSocket客户端实例
+     */
+    public GateKlineWebSocketClient getKlineWebSocketClient() {
+        return klinePriceClient;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/gate-websocket.txt b/src/main/java/com/xcong/excoin/modules/gateApi/gate-websocket.txt
new file mode 100644
index 0000000..d763d63
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/gate-websocket.txt
@@ -0,0 +1,5011 @@
+v4.0.0 · Stable
+#Gate Futures WebSocket v4.0.0
+Gate 提供简单而强大的 Websocket API,将 Gate BTCUSDT 永续合约交易状态集成到您的业务或应用程序中。
+
+我们在 Python 和 Golang 中有语言绑定,将来还会有更多!您可以在右侧的深色区域中查看代码示例,并且可以通过右上角的选项卡切换示例的编程语言
+
+#服务地址
+我们提供 BTC/USDT 结算永续合约交易服务器地址,您可以根据自己的情况选择其中之一
+
+#BTC Contract
+地址列表:
+
+线上交易: wss://fx-ws.gateio.ws/v4/ws/btc
+模拟盘交易: wss://fx-ws-testnet.gateio.ws/v4/ws/btc
+#USDT Contract
+地址列表:
+
+线上交易: wss://fx-ws.gateio.ws/v4/ws/usdt
+线上SBE: wss://fx-ws.gateio.ws/v4/ws/usdt/sbe
+模拟盘交易: wss://ws-testnet.gate.com/v4/ws/futures/usdt
+建议使用SBE以获取更快的行情和更小的带宽成本
+
+如果你使用老的服务地址(wss://fx-ws.gateio.ws/v4/ws 或 wss://fx-ws-testnet.gateio.ws/v4/ws), 将默认是 BTC 结算的 websocket 服务.
+
+#变更日志
+2026-04-14
+
+部分频道支持SBE数据推送: futures.trades、futures.obu、futures.book_ticker、futures.tickers、futures.candlesticks、futures.order_book、futures.order_book_update、futures.usertrades、futures.positions、futures.orders。
+具体的使用查看SBE 数据推送章节
+2026-03-30
+
+futures.order_place 下单请求:iceberg 字段说明修正为类型 string(原文档为 int64)、可选(原文档为必填)
+2026-02-09
+
+模拟盘部分频道支持SBE数据推送
+正式环境实装另行同步
+2026-02-04
+
+futures.obu 模拟盘新增立即的首次快照推送,该次快照推送将会在订阅请求的响应之前推送。此行为与之前快照在订阅请求的响应之后推送不同,请注意该行为变更。
+正式环境实装另行同步
+2026-01-07
+
+futures.orders 新增字段 market_order_slip_ratio (市价单的预设滑点比例)
+futures.order_place futures.order_batch_place 入参新增字段market_order_slip_ratio (允许自定义市价单的最大滑点)
+2025-12-09
+
+合约的张数支持小数,所有的推送的张数、成交量等均改为字符串(可能是小数)。
+
+如何对接websocket的小数支持:
+
+在请求链接websocket时,加入:"X-Gate-Size-Decimal": "1" 的header即可,推送的张数、成交量等将会是字符串(可能是小数)。
+如果在链接websocket时,不加入:"X-Gate-Size-Decimal": "1" 的header,推送将保持原始的字段类型(整形)。
+请尽快切换到字符串的推送支持,后续整形的推送将会下线(下线时间会另行通知)。
+如果出现小数的size,用户如果还是在使用整形的推送,那么推送出来的size将会是向下取整,例如1.1、1.5、1.7的size推送出去都将会是1。
+将影响到以下的推送频道,和对应的字段。
+
+频道	字段
+futures.trades	size
+futures.tickers	total_size
+futures.book_ticker	A B
+futures.order_book_update	a.s、b.s
+futures.order_book	a.s、b.s
+futures.obu	size 会有小数
+futures.candlesticks	v
+futures.liquidates	left、size、 order_size
+futures.public_liquidates	size
+futures.contract_stats	long_liq_size、short_liq_size、open_interest
+futures.orders	iceberg、left、size
+futures.usertrades	size
+futures.auto_deleverages	position_size、trade_size
+futures.positions	size
+futures.autoorders	position_size、 trade_size
+将影响到以下的API请求频道,主要涉及张数,成交量等字段。
+
+频道	字段
+futures.order_place	size、left
+futures.order_batch_place	size
+futures.order_cancel	size、left
+futures.order_cancel_cp	size、left
+futures.order_amend	size、left
+futures.order_list	size、left
+futures.order_status	size、left
+2025-09-25
+
+新增 仓位 Adl 排名频道 文档
+2025-05-22
+
+新增深度频道V2文档说明
+futures.order_book_update 新增字段 full
+2025-04-25
+
+账户交易API新增通道 futures.order_cancel_ids
+futures.order_book 和 futures.order_book_update 新增深度档位字段 l
+2025-04-18
+
+补充文档代码示例
+2025-03-24
+
+修复了深度频道部分文档的错误描述
+修复了订单频道部分文档的错误描述
+2025-03-21
+
+更新了频道 futures.orders 文档, 新增了 update_id, update_time, biz_info, stop_profit_price 和 stop_loss_price 等字段的说明
+2025-03-12
+
+合约统计信息频道增加 contract 字段
+更新账户交易 API,新增了 x-gate-exptime 字段
+修复了账户交易 API 部分文档描述性错误
+2025-02-19
+
+新增频道 futures.public_liquidates 用于推送合约强平订单的快照信息
+2025-02-10
+
+更新账户交易 API,新增了 x_in_time, x_out_time, conn_trace_id, trace_id 字段
+futures.order_place, futures.order_batch_place, futures.order_cancel, futures.order_cancel_cp 和 futures.order_amend 新增了 x_gate_ratelimit_requests_remain, x_gate_ratelimit_limit 和 x_gat_ratelimit_reset_timestamp 字段
+2024-11-18
+
+在频道 futures.order_book_update 移除 10 档位 1000ms 推送间隔支持
+2023-09-21
+
+在频道futures.trades推送参数中新增is_internal字段
+2023-08-18
+
+添加 WebSocket API 操作
+WebSocket API 允许通过 WebSocket 连接创建、取消、修改、查询订单。
+2023-07-07
+
+在频道futures.order_book_update中添加新的间隔“20ms”,请注意,20ms 的间隔仅支持 20 档位
+2023-06-20
+
+在频道 futures.positions 增加update_id 字段
+2022-12-22
+
+在频道 futures.autoorders 初始结构中添加新字段 auto_size,将字段详细信息添加到 http api
+2022-11-22
+
+在通用的返回结果中添加新字段“time_ms”,以表示创建消息的时间
+2022-08-11
+
+在频道futures.autoorders通知中添加新字段text
+在频道futures.tickers通知中添加新字段low_24h和high_24h
+2022-04-15
+
+在频道futures.balances通知中添加新字段 currency
+2021-03-31
+
+在频道futures.book_ticker和futures.order_book推送中添加毫秒字段t
+2021-03-10
+
+添加新的订单簿频道 futures.book_ticker 以实时推送最佳卖价/买价
+添加新的订单簿频道 futures.order_book_update 以与用户推送订单簿更改 指定更新频率
+添加本地订单簿维护文档
+2021-03-01
+
+在通用的返回结果中添加以_ms结尾的新毫秒精度时间戳
+在futures.book all通知中添加新字段id
+2020-8-08
+
+添加完整代码 demo(golang, python)
+2020-8-07
+
+添加futures.autoorders频道
+2020-7-07
+
+添加futures.order_book频道
+2020-4-30
+
+添加futures.position频道
+2019-11-06
+
+新增 USDT 结算永续合约的 websocket 推送
+为futures.tickers添加volume_24h_base字段、volume_24h_settle字段、volume_24h_quote字段
+删除旧服务器地址(wss://fx-ws.gateio.ws/v4/ws 或 wss://fx-ws-testnet.gateio.ws/v4/ws)
+如果您使用旧的服务器地址(wss://fx-ws.gateio.ws/v4/ws 或 wss://fx-ws-testnet.gateio.ws/v4/ws),我们 将为您使用 BTC 结算永续合约的 websocket 推送
+
+2019-10-22
+
+添加应用层 ping/pong 消息
+2019-04-30
+
+添加index和mark futures.candlesticks 订阅
+为futures.tickers添加funding_rate_indicative字段
+为futures.orders添加 is_reduce_only 和状态字段
+2019-02-13
+
+更改 webSocket 基本 url
+为futures.tickers添加volume_24h_usd字段和volume_24h_btc字段
+2019-01-11
+
+添加futures.position_closes 和 futures.balance 订阅
+删除频道 futures.auto_deleverages 和futures.liquidates的 finish_time 字段
+为频道 futures.auto_deleverages 和futures.liquidates 添加 time字段
+WebSocket 应用示例
+
+# !/usr/bin/env python
+# coding: utf-8
+
+import hashlib
+import hmac
+import json
+import logging
+import time
+import threading
+
+from websocket import WebSocketApp
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+event = threading.Event()
+
+class GateWebSocketApp(WebSocketApp):
+
+  def __init__(self, url, api_key, api_secret, **kwargs):
+    super(GateWebSocketApp, self).__init__(url, **kwargs)
+    self._api_key = api_key
+    self._api_secret = api_secret
+
+  def _send_ping(self):
+    while not event.wait(10):
+      self.last_ping_tm = time.time()
+      if self.sock:
+        try:
+          self.sock.ping()
+        except Exception as ex:
+          logger.warning("send_ping routine terminated: {}".format(ex))
+          break
+        try:
+          self._request("futures.ping", auth_required=False)
+        except Exception as e:
+          raise e
+
+  def _request(self, channel, event=None, payload=None, auth_required=True):
+    current_time = int(time.time())
+    data = {
+      "time": current_time,
+      "channel": channel,
+      "event": event,
+      "payload": payload,
+    }
+    if auth_required:
+      message = 'channel=%s&event=%s&time=%d' % (channel, event, current_time)
+      data['auth'] = {
+        "method": "api_key",
+        "KEY": self._api_key,
+        "SIGN": self.get_sign(message),
+      }
+    data = json.dumps(data)
+    logger.info('request: %s', data)
+    self.send(data)
+
+  def get_sign(self, message):
+    h = hmac.new(self._api_secret.encode("utf8"), message.encode("utf8"), hashlib.sha512)
+    return h.hexdigest()
+
+  def subscribe(self, channel, payload=None, auth_required=True):
+    self._request(channel, "subscribe", payload, auth_required)
+
+  def unsubscribe(self, channel, payload=None, auth_required=True):
+    self._request(channel, "unsubscribe", payload, auth_required)
+
+
+def on_message(ws, message):
+  # type: (GateWebSocketApp, str) -> None
+  # handle message received
+  logger.info("message received from server: {}".format(message))
+
+
+def on_open(ws):
+  # type: (GateWebSocketApp) -> None
+  # subscribe to channels interested
+  logger.info('websocket connected')
+  ws.subscribe("futures.tickers", ['BTC_USDT'], False)
+
+# custom header
+custom_headers = {
+    "X-Gate-Size-Decimal": "1"
+}
+
+if __name__ == "__main__":
+  logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.DEBUG)
+  app = GateWebSocketApp("wss://fx-ws.gateio.ws/v4/ws/usdt",
+                         "YOUR_API_KEY",
+                         "YOUR_API_SECRET",
+                         on_open=on_open,
+                         on_message=on_message,
+                         header=custom_headers)
+  app.run_forever(ping_interval=5)
+Copy
+#Websocket API 概述
+#事件
+每个通用 订阅频道/channel(例如ticker、order_book等)都支持一些不同的事件消息,它们是:
+
+subscribe (推荐使用)
+
+订阅,接受服务器的新数据通知。
+
+unsubscribe
+
+如果取消订阅,服务器将不会发送新数据通知。
+
+update
+
+服务器将向客户端发送新的订阅数据(增量数据)。
+
+all
+
+如果有新订阅的数据(所有数据)可用,服务器将向客户端发送通知。
+
+#请求
+每个请求都遵循通用格式,其中包含time、channel、event和payload。
+
+请求
+名称	类型	必选	描述
+id	Integer	否	可选的请求 ID,将由服务器发回,以帮助您识别服务器响应哪个请求
+time	Integer	是	请求时间
+channel	String	是	请求 subscribe/unsubscribe 频道
+auth	String	否	请求身份验证信息,请参阅身份验证部分了解详细信息
+event	String	是	请求event (subscribe/unsubscribe/update/all/api)
+payload	Array	是	请求详细参数
+#响应
+与请求类似,响应遵循以下通用格式,其中包含: time, channel, event , error 和 result.
+
+响应
+名称	类型	必选	描述
+time	Integer	是	响应时间
+time_ms	Integer	是	毫秒响应时间
+channel	String	是	响应频道
+event	String	是	响应频道事件 (update/all)
+error	Object	是	响应错误
+result	Any	是	返回来自服务端的新数据通知 或 对客户端请求的响应。如果有错误返回则error 不为空,没有错误则此字段为空。
+注意:如果它是服务端发起的数据更新通知 那么 result 的类型是基于 channel 的,不同 channel 的 result 类型有所不同。
+
+但如果是对客户端订阅请求的响应,那么 result 为固定的 {"status": "success"}。 验证订阅请求是否成功,您只需要检查 error 字段是否为空即可,不需要再解析 result 字段。
+
+为了简单起见,下面的频道(channel)描述只给出对应频道的 payload 格式。
+
+#错误
+如果出现错误,您会收到error字段,其中包含错误代码和错误的类型。
+
+错误
+Code	Message
+1	invalid argument struct
+2	invalid argument
+3	service error
+4	authentication fail
+#鉴权
+如果频道是私有的,则请求体需要携带认证信息, 例如futures.usertrades
+
+WebSocket 认证使用与 HTTP API 相同的签名计算方法,但具有 以下差异:
+
+签名字符串拼接方式:channel=<channel>&event=<event>&time=<time>, 其中<channel>、<event>、<time>是对应的请求信息
+身份验证信息在请求正文中的auth字段中发送。
+您可以登录账户获取永续合约账户的 api_key 和 secret。
+
+名称	类型	描述
+method	String	验证方式:api_key
+KEY	String	apiKey 的值
+SIGN	String	签名结果
+代码示例
+
+# example WebSocket signature calculation implementation in Python
+import hmac, hashlib, json, time
+
+
+def gen_sign(channel, event, timestamp):
+    # GateAPIv4 key pair
+    api_key = 'YOUR_API_KEY'
+    api_secret = 'YOUR_API_SECRET'
+
+    s = 'channel=%s&event=%s&time=%d' % (channel, event, timestamp)
+    sign = hmac.new(api_secret.encode('utf-8'), s.encode('utf-8'), hashlib.sha512).hexdigest()
+    return {'method': 'api_key', 'KEY': api_key, 'SIGN': sign}
+
+
+request = {
+    'id': int(time.time() * 1e6),
+    'time': int(time.time()),
+    'channel': 'futures.orders',
+    'event': 'subscribe',
+    'payload': ["20011", "BTC_USD"]
+}
+request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
+print(json.dumps(request))
+Copy
+#SBE 数据推送
+#对接SBE
+使用地址,在现有的地址后添加/sbe:
+prod: wss://fx-ws.gateio.ws/v4/ws/usdt/sbe
+testnet: wss://ws-testnet.gate.com/v4/ws/futures/usdt/sbe
+schema地址:
+prod: gate_fex_ws_prod_latest.xml(opens new window)
+testnet: gate_fex_ws_testnet_latest.xml(opens new window)
+如果需要指定sbe_schema_id,则通过query的形式传入sbe_schema_id的参数,例如:wss://fx-ws.gateio.ws/v4/ws/usdt/sbe?sbe_schema_id=1
+目前支持的sbe_schema_id为0和1;sbe_schema_id为0用于客户端测试sbe schema不兼容升级的逻辑
+不传入sbe_schema_id则默认使用最新的schema版本
+传入不合法的sbe_schema_id在连接之后会返回系统通知,并将sbe_schema_id调整为最新的schema版本
+传入旧版本的sbe_schema_id在连接之后会返回系统通知,提醒更新新版本的SBE schema,依旧使用客户端指定的旧版本schema
+无效的sbe_schema_id的系统通知
+
+{
+  "time": 1770600979,
+  "time_ms": 1770600979609,
+  "channel": "futures.system",
+  "event": "update",
+  "result": {
+    "type": "invalid_sbe_schema_id",
+    "msg": "Your sbe_schema_id '011' does not exist, it has been adjusted to the default sbe_schema_id '1'."
+  }
+}
+Copy
+过时的sbe_schema_id的系统通知
+
+{
+  "time": 1770601096,
+  "time_ms": 1770601096665,
+  "channel": "futures.system",
+  "event": "update",
+  "result": {
+    "type": "outdated_sbe_schema_id",
+    "msg": "Your sbe_schema_id '0' is outdated, please upgrade to the latest version '1'."
+  }
+}
+Copy
+#SBE使用说明
+使用JSON进行请求和首次响应;使用SBE作为数据推送;
+同一条连接上同时存在JSON和SBE的消息,请使用opcode来区分数据:opcode为1代表JSON,opcode为2代表SBE。
+SBE 的解码:
+MessageHeader:每条 SBE 二进制帧均为「MessageHeader + 消息体」。Header 中包含 blockLength、templateId、schemaId、version,解码时必须先读 Header,再根据 schemaId 和 templateId 选择对应 Schema 与消息类型解码消息体。
+解码流程建议:
+读取 MessageHeader(固定长度),得到 schemaId、templateId、blockLength、version。
+根据 schemaId 选择解码器:0 → 使用旧版本进行解码;1 → 使用新版本进行解码。
+根据 templateId 确定具体消息类型(如 PublicTrade、OrderBook、Bbo 等),再按该 Schema 的布局解码消息体。
+使用 SBE 时,仅可订阅以下频道,其余频道不支持 SBE 推送。后续将扩展到其余频道。
+订阅不支持SBE的频道时,将返回订阅失败的消息
+通道名	说明
+futures.trades	公共成交
+futures.order_book	订单簿(深度)
+futures.order_book_update	订单簿增量更新
+futures.book_ticker	最优买卖(BBO)
+futures.obu	订单簿增量(OBU)
+futures.candlesticks	K 线
+futures.tickers	行情
+futures.usertrades	用户成交
+futures.positions	持仓
+futures.orders	订单
+不支持sbe将返回订阅失败:
+
+{
+  "time": 1770603321,
+  "time_ms": 1770603321767,
+  "conn_id": "57a8765578ea837e",
+  "trace_id": "3c75ba05569b3b292a2f36cfdd90d868",
+  "channel": "futures.autoorders",
+  "event": "subscribe",
+  "payload": [
+    "15760812",
+    "!all"
+  ],
+  "error": {
+    "code": 2,
+    "message": "channel futures.autoorders does not support SBE"
+  },
+  "result": {
+    "status": "fail"
+  }
+}
+Copy
+#System API
+提供系统状态检查,如 ping/pong.
+
+#Ping/Pong
+检查服务器/客户端连接.
+
+Gate websocket 使用协议层 ping/pong 消息。服务器会发起 ping 操作。如果客户端没有回复,客户端将被断开。
+
+websocket rfc 协议(opens new window)
+
+如果想主动检测连接状态,可以发送应用层 ping 消息,并接收 pong 消息。
+
+#请求参数
+频道
+
+futures.ping
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.ping"}')
+print(ws.recv())
+Copy
+futures.ping操作返回 JSON 结构如下:
+
+{
+  "time": 1545404023,
+  "time_ms": 1545404023123,
+  "channel": "futures.pong",
+  "event": "",
+  "result": null
+}
+Copy
+#服务升级通知
+服务在即将关闭进行升级时,会向当前连接主动推送一条系统通知,客户端收到后应尽快重连。
+
+服务端推送格式(SystemNotifyDTO):
+
+字段	类型	说明
+type	String	通知类型,如 upgrade
+msg	String	提示文案
+data	Object	可选,扩展数据
+示例(服务升级):
+
+{
+  "type": "upgrade",
+  "msg": "The connection will soon be closed for a service upgrade. Please reconnect."
+}
+#ticker 频道
+ticker是合约状态的高级概述。它向你展示了最高的, 最低的、最后的交易价格。它还包括每日交易量和价格等信息
+
+#订阅操作
+订阅永续合约 24hr 价格变动情况.
+
+#请求参数
+channel
+
+futures.tickers
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+payload	Array	是	合约列表
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.tickers","event": "subscribe", "payload" : ["BTC_USD"]}')
+print(ws.recv())
+Copy
+上面的订阅请求返回 JSON 结构如下:
+
+{
+  "time": 1545404023,
+  "time_ms": 1545404023123,
+  "channel": "futures.tickers",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#ticker 推送
+永续合约 24hr 价格变动情况推送
+
+#推送参数
+channel
+
+futures.tickers
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	String	合约名称
+last	String	最新成交价
+change_percentage	String	涨跌幅
+funding_rate	String	资金费率
+funding_rate_indicative	String	下一周期预测资金费率(已弃用,改用funding_rate)
+mark_price	String	标记价格
+index_price	String	指数价格
+total_size	String	总数量
+volume_24h	String	24 小时成交量
+quanto_base_rate	String	双币种合约中基础货币与结算货币的汇率。不存在于其他类型的合同中
+volume_24h_btc	String	近 24 小时 BTC 交易量(已弃用,请使用volume_24h_base、volume_24h_quote、volume_24h_settle代替)
+volume_24h_usd	String	近 24 小时美元交易量(已弃用,请使用volume_24h_base、volume_24h_quote、volume_24h_settle 代替)
+volume_24h_quote	String	近 24 小时交易量,以计价货币计
+volume_24h_settle	String	近 24 小时交易量,以结算货币计
+volume_24h_base	String	近 24 小时交易量,以基础货币计
+low_24h	String	近 24 小时最低交易价
+high_24h	String	近 24 小时最高交易价
+{
+  "time": 1541659086,
+  "time_ms": 1541659086123,
+  "channel": "futures.tickers",
+  "event": "update",
+  "result": [
+    {
+      "contract": "BTC_USD",
+      "last": "118.4",
+      "change_percentage": "0.77",
+      "funding_rate": "-0.000114",
+      "funding_rate_indicative": "0.01875",
+      "mark_price": "118.35",
+      "index_price": "118.36",
+      "total_size": "73648",
+      "volume_24h": "745487577",
+      "volume_24h_btc": "117",
+      "volume_24h_usd": "419950",
+      "quanto_base_rate": "",
+      "volume_24h_quote": "1665006",
+      "volume_24h_settle": "178",
+      "volume_24h_base": "5526",
+      "low_24h": "99.2",
+      "high_24h": "132.5"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅
+
+#请求参数
+channel
+
+futures.tickers
+
+event
+
+unsubscribe
+
+代码示例
+
+import json
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": 123456,
+  "channel": "futures.tickers",
+  "event": "unsubscribe",
+  "payload": ["BTC_USD"]
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545404900,
+  "time_ms": 1545404900123,
+  "channel": "futures.tickers",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#公有成交频道
+每当 Gate 发生交易时,该频道都会发送交易消息。它包括价格、金额、时间和类型等交易信息
+
+#公有成交订阅
+订阅公有成交更新通知
+
+#请求参数
+channel
+
+futures.trades
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+payload	Array	是	合约列表
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.trades","event": "subscribe", "payload" : ["BTC_USD"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545405058,
+  "time_ms": 1545405058123,
+  "channel": "futures.trades",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#公有成交推送
+通知最新交易更新
+
+#推送参数
+channel
+
+futures.trades
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	string	合约名称
+size	string/int	交易数量
+id	int	交易 ID
+create_time	int	交易消息创建时间
+create_time_ms	int	交易消息创建时间(以毫秒为单位)
+price	string	交易价格
+is_internal	bool	是否为内部成交。内部成交是指保险资金和 ADL 用户对强平指令的接管。由于不是市场深度上的正常撮合,交易价格可能会出现偏差,不会记录在 K 线上。如果不是内部交易,则该字段不会被返回。
+size 正数表示买家,负数表示卖家
+
+{
+  "channel": "futures.trades",
+  "event": "update",
+  "time": 1541503698,
+  "time_ms": 1541503698123,
+  "result": [
+    {
+      "size": "-108",
+      "id": 27753479,
+      "create_time": 1545136464,
+      "create_time_ms": 1545136464123,
+      "price": "96.4",
+      "contract": "BTC_USD",
+      "is_internal": true
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅公有成交更新通知
+
+#请求参数
+channel
+
+futures.trades
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send(
+  '{"time" : 123456, "channel" : "futures.trades", "event": "subscribe", "payload" : ["BTC_USD"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545404900,
+  "time_ms": 1545404900123,
+  "channel": "futures.trades",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#深度频道
+order_book 频道允许您跟踪 Gate 订单簿深度的状态。它以价格聚合的方式提供,可自定义精度。
+
+共有三种不同的订单簿渠道可供订阅:
+
+futures.order_book
+
+全量频道,定期使用all推送完整的有限级别订单簿.
+
+futures.book_ticker
+
+实时推送最佳买价和卖价.
+
+futures.order_book_update
+
+以指定的更新频率向用户订单簿推送订单簿的更新内容.
+
+不建议通过futures.order_book接收订单簿更新,使用 futures.order_book_update 可以以更少的流量提供更及时的更新
+
+如何维护本地订单簿:
+
+订阅 futures.order_book_update 并指定级别和更新频率,例如 ["BTC_USDT", "100ms", "100"] 每 100ms 推送 BTC_USDT 订单簿前 100 个级别的更新
+缓存 WebSocket 通知。每个通知都使用“U”和“u”来告诉第一个和最后一个 自上次通知以来更新 ID。
+使用 REST API 检索基本订单簿,并确保记录了订单簿 ID(参考 如下面的“baseID”) 例如https://api.gateio.ws/api/v4/futures/usdt/order_book?contract=BTC_USDT&limit=10&with_id=true 获取 BTC_USDT 的 10 级基础订单簿
+迭代缓存的 WebSocket 通知,找到第一个包含 baseID 的通知, 即 U <= baseId+1 和 u >= baseId+1,然后开始从中消费。请注意,size为 通知都是全量的 size,即应该使用它们覆盖替换原始的size。 如果 size 等于 0,则从订单簿中删除价格。
+转储所有满足 u < baseID+1 的通知。如果 baseID+1 < 第一个通知 U,则 意味着当前的基本订单簿落后于通知。从步骤 3 开始检索更新的内容基本订单簿。
+如果后续发现满足 U > baseID+1 的通知,则说明有更新 丢失的。从步骤 3 重建本地订单簿。
+注意:
+
+即使 WebSocket 推送中的 a, b 或者 asks, bids 为空,用户也需要更新本地订单簿的 id 和 timestamp,以确保本地订单簿与服务器保持一致。
+WebSocket 订阅的 level(档位数)应与 REST 快照的 limit 一致,否则可能导致增量更新无法覆盖快照档位,造成本地订单簿错位或不完整。
+#深度全量更新频道
+订阅深度.
+
+#请求参数
+channel
+
+futures.order_book
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+contract	String	是	合约名称
+limit	String	是	深度层级: 100, 50, 20, 10, 5, 1
+interval	String	是	价格合并精度: "0"
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.order_book","event": "subscribe", "payload" : ["BTC_USD", "20", "0"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545405058,
+  "time_ms": 1545405058123,
+  "channel": "futures.order_book",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#全量深度推送
+全量深度更新推送
+
+#推送参数
+channel
+
+futures.order_book
+
+event
+
+all
+
+params
+
+推送参数
+名称	类型	描述
+result	object	深度信息
+»t	Integer	深度生成时间戳(以毫秒为单位)
+»contract	String	合约名称
+»id	Integer	深度 ID
+»asks	Array	深度卖方的档位列表
+»»p	String	档位价格
+»»s	String	档位的数量
+»bids	Array	深度买方的档位列表
+»»p	String	档位价格
+»»s	String	档位的数量
+»l	String	深度层级(例如 100 即代表 100 层的深度更新)
+{
+  "channel": "futures.order_book",
+  "event": "all",
+  "time": 1541500161,
+  "time_ms": 1541500161123,
+  "result": {
+    "t": 1541500161123,
+    "contract": "BTC_USD",
+    "id": 93973511,
+    "asks": [
+      {
+        "p": "97.1",
+        "s": "2245"
+      },
+      {
+        "p": "97.1",
+        "s": "2245"
+      }
+    ],
+    "bids": [
+      {
+        "p": "97.1",
+        "s": "2245"
+      },
+      {
+        "p": "97.1",
+        "s": "2245"
+      }
+    ],
+    "l": "20"
+  }
+}
+Copy
+#全量深度取消订阅
+取消订阅指定市场的深度
+
+#请求参数
+channel
+
+futures.order_book
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.order_book","event": "unsubscribe", "payload" : ["BTC_USD", "20", "0"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545445847,
+  "time_ms": 1545445847123,
+  "channel": "futures.order_book",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#最佳买卖价订阅
+订阅深度最佳买卖价
+
+#请求参数
+channel
+
+futures.book_ticker
+
+event
+
+subscribe
+
+params
+
+payload是一个包含合约市场的列表.
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send('{"time" : 123456, "channel" : "futures.book_ticker","event": "subscribe", "payload" : ["BTC_USDT"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545405058,
+  "time_ms": 1545405058123,
+  "channel": "futures.book_ticker",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#最佳买卖价的推送
+如果 a 为空字符串,则表示空买价;如果 b 为空字符串,则表示空卖价。
+
+最新买卖价的推送
+
+#推送参数
+channel
+
+futures.book_ticker
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	object	深度的最佳买卖价
+»t	Integer	最佳买卖价行情生成的时间戳(以毫秒为单位)
+»u	Integer	深度的 ID
+»s	String	合约名称
+»b	String	最佳买方的价格,如果没有买方,则为空串
+»B	String/Integer	最佳买方的数量,如果没有买方,则为 0
+»a	String	最佳卖方的价格,如果没有卖方,则为空串
+»A	String/Integer	最佳卖方的数量,如果没有卖方,则为 0
+{
+  "time": 1615366379,
+  "time_ms": 1615366379123,
+  "channel": "futures.book_ticker",
+  "event": "update",
+  "result": {
+    "t": 1615366379123,
+    "u": 2517661076,
+    "s": "BTC_USD",
+    "b": "54696.6",
+    "B": "37000",
+    "a": "54696.7",
+    "A": "47061"
+  }
+}
+Copy
+#最佳买卖价的取消订阅
+取消指定合约市场的最佳买卖订阅
+
+#请求
+channel
+
+futures.book_ticker
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send('{"time" : 123456, "channel" : "futures.book_ticker","event": "unsubscribe", "payload" : ["BTC_USDT"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545445847,
+  "time_ms": 1545445847123,
+  "channel": "futures.book_ticker",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#合约深度更新推送订阅
+订阅深度更新推送
+
+#请求参数
+channel
+
+futures.order_book_update
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+contract	String	是	合约名称
+frequency	String	是	更新频率,20ms or 100ms
+level	String	否	可选的深度层级。允许以下层级:100、50、20;20ms频率 只支持 20层
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send('{"time" : 123456, "channel" : "futures.order_book_update","event": "subscribe", "payload" : ["BTC_USDT", "100ms", "100"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545405058,
+  "time_ms": 1545405058123,
+  "channel": "futures.order_book_update",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#深度更新推送
+深度更新推送
+
+#推送参数
+channel
+
+futures.order_book_update
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Object	自上次更新以来发生变更要价和出价
+»t	Integer	订单簿生成时间戳(以毫秒为单位)
+»full	Boolean	true 代表全量的深度(假设订阅 level 为 100,推送出来则是 100 层的深度);用户接收到之后需要替换本地深度;false 代表增量的深度,为 false 时,不传输该字段
+»s	String	合约名称
+»U	Integer	本次更新开始的订单簿更新 ID
+»u	Integer	本次更新结束的订单簿更新 ID
+»b	Array	买方变动列表
+»»p	String	变更的档位价格
+»»s	String/Integer	档位的待成交数量。如果为 0,则从订单簿中删除该价格
+»a	Array	卖方变动列表
+»»p	String	变更的档位价格
+»»s	String/Integer	档位的待成交数量。如果为 0,则从订单簿中删除该价格
+»l	String	深度层级(例如 100 即代表 100 层的深度更新)
+{
+  "time": 1615366381,
+  "time_ms": 1615366381123,
+  "channel": "futures.order_book_update",
+  "event": "update",
+  "result": {
+    "t": 1615366381417,
+    "s": "BTC_USD",
+    "U": 2517661101,
+    "u": 2517661113,
+    "b": [
+      {
+        "p": "54672.1",
+        "s": "0"
+      },
+      {
+        "p": "54664.5",
+        "s": "58794"
+      }
+    ],
+    "a": [
+      {
+        "p": "54743.6",
+        "s": "0"
+      },
+      {
+        "p": "54742",
+        "s": "95"
+      }
+    ],
+    "l": "100"
+  }
+}
+Copy
+#深度更新取消订阅
+取消指定合约的市场的深度更新订阅
+
+#请求参数
+channel
+
+futures.order_book_update
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send(
+  '{"time" : 123456, "channel" : "futures.order_book_update", "event": "unsubscribe", "payload" : ["BTC_USDT", "100ms"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545445847,
+  "time_ms": 1545445847123,
+  "channel": "futures.order_book_update",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#深度频道V2
+提供一种更快更新的获取深度信息的方法.
+
+#维护本地深度
+说明:
+
+全量深度推送(full=true): 当频道推送的深度为全量深度时,需要将该深度数据完整替换本地深度,并将深度ID更新为消息中的字段 u。服务端可能会重复推送全量深度。
+订阅该频道时,首次推送为全量深度。
+增量深度推送(full=false): 增量消息中不会显示 full 字段,此时消息包含字段 U(深度起始ID)和 u(深度结束ID)。
+如果 U = 本地深度ID + 1,则表示深度连续更新:
+将本地深度ID替换为消息中的 u。
+若更新中的 a 和 b 不为空,分别按价格更新对应的买、卖深度数量(level[0] 为价格,level[1] 为数量)。当数量 level[1]= "0" 时,需移除对应档位。
+若 U ≠ 本地深度ID + 1,则深度数据不连续,需要取消订阅该市场,并重新订阅以获取初始化深度。
+订阅限制: 针对同一合约的同一深度流,一个链接只允许订阅一次,重复订阅会返回错误。失败示例:
+{
+  "time": 1747391482,
+  "time_ms": 1747391482960,
+  "id": 1,
+  "conn_id": "d9db9373dc5e081e",
+  "trace_id": "ee001938590e183db957bd5ba71651c0",
+  "channel": "futures.obu",
+  "event": "subscribe",
+  "payload": [
+    "ob.BTC_USDT.400"
+  ],
+  "error": {
+    "code": 2,
+    "message": "Alert sub ob.BTC_USDT.400"
+  },
+  "result": {
+    "status": "fail"
+  }
+}
+Copy
+#深度频道V2订阅
+#请求参数
+channel
+
+futures.obu
+
+event
+
+subscribe
+
+params
+
+payload是一个包含流名称的列表. 格式为: ob.{symbol}.{level}; 例如 ob.BTC_USDT.400、ob.BTC_USDT.50
+
+其中level枚举为:400、50;更新频率: 400档为100ms;50档为20ms;
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/usdt")
+ws.send('{"time" : 123456, "channel" : "futures.obu",
+        "event": "subscribe", "payload" : ["ob.BTC_USDT.400"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1747391482,
+  "time_ms": 1747391482384,
+  "id": 1,
+  "conn_id": "d9db9373dc5e081e",
+  "trace_id": "ee001938590e183db957bd5ba71651c0",
+  "channel": "futures.obu",
+  "event": "subscribe",
+  "payload": [
+    "ob.BTC_USDT.400"
+  ],
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#深度v2订阅推送
+深度频道V2的消息推送
+
+#推送参数
+channel
+
+futures.obu
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Object	自上次更新以来发生变更要价和出价
+»t	Integer	订单簿生成时间戳(以毫秒为单位)
+»full	Boolean	true 代表全量的深度;false 代表增量的深度,为 false 时,不传输该字段
+»s	String	深度流的名称
+»U	Integer	本次更新开始的订单簿更新 ID
+»u	Integer	本次更新结束的订单簿更新 ID
+»b	Array[OrderBookArray]	自上次更新以来的 bids 更新
+»» OrderBookArray	Array[String]	[Price, Amount] 数组对, Amount=0应当从本地深度中移除
+»a	Array[OrderBookArray]	自上次更新以来的 asks 更新
+»» OrderBookArray	Array[String]	[Price, Amount] 数组对, Amount=0应当从本地深度中移除
+全量推送示例:
+
+{
+	"channel": "futures.obu",
+	"result": {
+		"t": 1743673026995,
+		"full": true,
+		"s": "ob.BTC_USDT.400",
+		"u": 79072179673,
+		"b": [
+			["83705.9", "30166"]
+		],
+		"a": [
+			["83706", "4208"]
+		]
+	},
+	"time_ms": 1743673026999
+}
+Copy
+增量推送示例:
+
+{
+	"channel": "futures.obu",
+	"result": {
+		"t": 1743673027017,
+		"s": "ob.BTC_USDT.400",
+		"U": 79072179674,
+		"u": 79072179694,
+		"b": [
+			["83702.2", "62"],
+			["83702.1", "0"],
+			["83702", "0"],
+			["83685.6", "120"],
+			["83685", "239"]
+		]
+	},
+	"time_ms": 1743673027020
+}
+Copy
+#深度频道V2取消订阅
+取消指定合约的市场的深度频道V2订阅
+
+#请求参数
+channel
+
+futures.obu
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send(
+  '{"time" : 123456, "channel" : "futures.obu", "event": "unsubscribe", "payload" : ["ob.BTC_USDT.400"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1743673617,
+  "time_ms": 1743673617242,
+  "id": 1,
+  "conn_id": "7b06ff199a98ab0e",
+  "trace_id": "8f86e4021a84440e502f73fde5b94918",
+  "channel": "futures.obu",
+  "event": "unsubscribe",
+  "payload": ["ob.BTC_USDT.400"],
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#K 线频道
+提供一种访问 K 线信息的方法.
+
+#K 线订阅
+如果在contract前面加上mark_,则将订阅合约的标记价格 K 线;如果 前缀为“index_”,将订阅指数价格 K 线.
+
+#请求参数
+channel
+
+futures.candlesticks
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	描述
+interval	String	Interval : "10s", "1m", "5m", "15m", "30m", "1h", "4h", "8h", "1d", "7d"
+contract	String	合约名称
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.candlesticks","event": "subscribe", "payload" : ["1m", "BTC_USD"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545445847,
+  "time_ms": 1545445847123,
+  "channel": "futures.candlesticks",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#k 线消息推送
+k 线的消息推送
+
+#推送参数
+channel
+
+futures.candlesticks
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+t	Integer	时间
+o	String	开盘价格
+c	String	收盘价格
+h	String	最高价格
+l	String	最低价格
+v	String/Integer	成交量
+n	String	合约名称
+a	String	成交原始币种数量
+w	Boolean	true 表示窗口已关闭。注:可能会缺失 true 的消息,但不影响数据的完整性
+{
+  "time": 1542162490,
+  "time_ms": 1542162490123,
+  "channel": "futures.candlesticks",
+  "event": "update",
+  "result": [
+    {
+      "t": 1545129300,
+      "v": "27525555",
+      "c": "95.4",
+      "h": "96.9",
+      "l": "89.5",
+      "o": "94.3",
+      "n": "1m_BTC_USD",
+      "a": "314732.87412",
+      "w": false
+    },
+    {
+      "t": 1545129300,
+      "v": "27525555",
+      "c": "95.4",
+      "h": "96.9",
+      "l": "89.5",
+      "o": "94.3",
+      "n": "1m_BTC_USD",
+      "a": "314732.87412",
+      "w": true
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅指定市场 K 线信息
+
+#请求参数
+channel
+
+futures.candlesticks
+
+event
+
+unsubscribe
+
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send(
+  '{"time" : 123456, "channel" : "futures.candlesticks", "event": "unsubscribe", "payload" : ["1m", "BTC_USD"]}')
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545445847,
+  "time_ms": 1545445847123,
+  "channel": "futures.candlesticks",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#公共强平订单频道
+提供一种接收Gate强平订单信息的方式,每个合约每1秒最多推一条强平订单数据
+
+#公共强平订单订阅
+如果您想订阅所有合约中的强平订单推送,请在订阅请求列表中使用 !all
+
+订阅公共强平订单推送
+
+#请求参数
+channel
+
+futures.public_liquidates
+
+event
+
+subscribe
+
+params
+
+名称	类型	必选	描述
+contract	String	是	合约名称列表
+代码示例
+
+import json
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": 123456,
+    "channel": "futures.public_liquidates",
+    "event": "subscribe",
+    "payload": ["BTC_USD","ETH_USD"],
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+    "time": 1545459681,
+    "time_ms": 1545459681123,
+    "channel": "futures.public_liquidates",
+    "event": "subscribe",
+    "result": {
+        "status": "success"
+    }
+}
+Copy
+#公共强平订单推送
+推送公共强制平仓更新
+
+#推送参数
+channel
+
+futures.public_liquidates
+
+event
+
+update
+
+params
+
+名称	类型	描述
+result	Array	Array of objects
+名称	类型	描述
+price	Float	订单价格
+size	String/Integer	强平订单数量
+time_ms	Integer	时间(以毫秒为单位)
+contract	String	合约名称
+{
+    "channel": "futures.public_liquidates",
+    "event": "update",
+    "time": 1541505434,
+    "time_ms": 1541505434123,
+    "result": [
+        {
+        "price": 215.1,
+        "size": "-124",
+        "time_ms": 1541486601123,
+        "contract": "BTC_USD",
+        }
+    ]
+}
+Copy
+#取消订阅
+取消订阅公共强平订单更新
+
+#请求参数
+channel
+
+futures.public_liquidates
+
+event
+
+unsubscribe
+
+代码示例
+
+import json
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": 123456,
+    "channel": "futures.public_liquidates",
+    "event": "unsubscribe",
+    "payload": ["BTC_USD"],
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+ {
+    "time": 1545459681,
+    "time_ms": 1545459681123,
+     "channel": "futures.public_liquidates",
+     "event": "unsubscribe",
+     "result": {
+        "status": "success"
+     }
+}
+Copy
+#合约统计信息频道
+contract_stats 通道允许您获取合约统计信息
+
+#订阅操作
+订阅合约统计信息
+
+#请求参数
+channel
+
+futures.contract_stats
+
+event
+
+subscribe
+
+params
+
+名称	类型	必选	描述
+contract	String	Yes	合约名称
+interval	String	Yes	Interval : "1m", "5m", "15m", "30m", "1h", "4h", "8h", "1d", "3d", "7d"
+代码示例
+
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+ws.send('{"time" : 123456, "channel" : "futures.contract_stats","event": "subscribe", "payload" : ["BTC_USD","1m"]}')
+print(ws.recv())
+Copy
+上面的订阅请求返回 JSON 结构如下:
+
+{
+  "time": 1545404023,
+  "time_ms": 1545404023123,
+  "channel": "futures.contract_stats",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#contract_stats 推送
+合约统计信息推送
+
+#推送参数
+channel
+
+futures.contract_stats
+
+event
+
+update
+
+params
+
+名称	类型	描述
+result	Array	Array of objects
+名称	类型	描述
+time	Integer	统计时间(时间戳)
+contract	string	合约名称
+mark_price	Float	当前标记价格
+lsr_taker	Float	多空吃单比
+lsr_account	Float	多空持仓用户比
+long_liq_size	string/Integer	做多爆仓量(张)
+long_liq_amount	Float	做多爆仓量(交易币种)
+long_liq_usd	Float	做多爆仓量(计价币种)
+short_liq_size	string/Integer	做空爆仓量(张)
+short_liq_amount	Float	做空爆仓量(交易币种)
+short_liq_usd	Float	做空爆仓量(计价币种)
+open_interest	string/Integer	总持仓量(张)
+open_interest_usd	Float	总持仓量(计价币种)
+top_lsr_account	Float	大户多空账户比
+top_lsr_size	Float	大户多空持仓比
+{
+  "time": 1541659086,
+  "time_ms": 1541659086123,
+  "channel": "futures.contract_stats",
+  "event": "update",
+  "result": [
+    {
+      "time": 1603865400,
+      "contract":"BTC_USDT",
+      "lsr_taker": 100,
+      "lsr_account": 0.5,
+      "long_liq_size": "0",
+      "short_liq_size": "0",
+      "open_interest": "124724",
+      "short_liq_usd": 0,
+      "mark_price": "8865",
+      "top_lsr_size": 1.02,
+      "short_liq_amount": 0,
+      "long_liq_amount": 0,
+      "open_interest_usd": 1511,
+      "top_lsr_account": 1.5,
+      "long_liq_usd": 0
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅
+
+#请求参数
+channel
+
+futures.contract_stats
+
+event
+
+unsubscribe
+
+params
+
+名称	类型	必选	描述
+contract	String	Yes	合约名称
+interval	String	Yes	Interval : "1m", "5m", "15m", "30m", "1h", "4h", "8h", "1d", "3d", "7d"
+注意:contract为unsub_all,表示全部取消
+
+代码示例
+
+import json
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": 123456,
+    "channel": "futures.contract_stats",
+    "event": "unsubscribe",
+    "payload": ["BTC_USD","1m"]
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的请求返回 JSON 结构如下:
+
+{
+  "time": 1545404900,
+  "time_ms": 1545404900123,
+  "channel": "futures.contract_stats",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#订单频道
+提供接收用户订单的推送
+
+需要认证.
+
+#订单订阅
+如果您想订阅所有合约中的订单更新,请在合约列表中使用 !all。
+
+订阅订单更新推送
+
+#请求参数
+channel
+
+futures.orders
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.orders",
+  "event": "subscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.orders",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#订单推送
+下单、更新或完成时通知用户订单信息
+
+#推送参数
+channel
+
+futures.orders
+
+event
+
+update
+
+params
+
+推送结果参数含义请参考http接口.
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+create_time	Integer	订单创建时间(已弃用)
+create_time_ms	Integer	订单创建时间戳(以毫秒为单位)
+fill_price	Float	订单成交价格
+finish_as	String	订单是如何完成的。
+- filled:全部成交
+- cancelled:手动取消
+- liquidated:因清算而取消
+- ioc:生效时间为 IOC,立即完成
+- auto_deleveraging:ADL 完成
+- reduce_only:因减仓设置而增仓而取消
+- position_close:因平仓而取消
+- stp:订单发生自成交限制而被撤销
+- _new:新建
+- _update:成交或部分成交或更新订单
+- reduce_out: 只减仓被排除的不容易成交的挂单
+iceberg	String/Integer	冰山下单显示的数量,不指定或传 0 都默认为普通下单。目前不支持全部冰山。
+id	Integer	订单 ID
+is_close	Bool	该订单是否为 close position
+is_liq	Bool	该订单是否为 liquidation
+left	String/Integer	剩余可交易数量
+mkfr	Float	Maker 费用
+is_reduce_only	Bool	该订单是否为 reduce-only
+status	String	订单状态
+- open: 等待交易
+- finished: 完成
+tkfr	Float	taker 费用
+price	Float	订单价格。 0 表示市价订单,tif 设置为 ioc
+refu	Integer	推荐用户 ID
+refr	Float	
+size	String/Integer	订单大小。指定正数进行出价,指定负数进行询问
+text	String	用户定义的信息
+tif	String	有效时间
+- gtc:GoodTillCancelled
+- ioc:ImmediateOrCancelled,仅接受者
+- poc:PendingOrCancelled,只进行后订单,始终享受挂单费用
+- fok: FillOrKill,完全填充或不填充
+type=market 时仅支持 ioc 和 fok
+finish_time	Integer	订单结束 unix 时间戳(以秒为单位),未结束订单此字段返回0
+finish_time_ms	Integer	订单结束 unix 时间戳(以毫秒为单位),未结束订单此字段返回0
+user	String	用户 ID
+contract	String	合约名称
+stp_id	String	同一 stp_id 组内的用户之间的订单不允许自交易
+1.如果匹配的两个订单的 stp_id 非零且相等,则不会被执行。而是根据 taker 的 stp_act 执行相应的策略。
+2.对于未设置 STP 组的订单,stp_id 默认返回 0
+stp_act	String	自我交易预防行动。用户可以通过该字段设置自我交易防范策略
+1.用户加入 STP Group 后,可以通过 stp_act 来限制用户的自我交易防范策略。如果不传 stp_act,则默认为 cn 策略。
+2.当用户没有加入 STP 组时,传递 stp_act 参数时会返回错误。
+3.如果用户下单时没有使用'stp_act','stp_act'将返回'-'
+- cn: 取消最新订单,取消新订单并保留旧订单
+- co: 取消最旧订单,取消旧订单并保留新订单
+- cb:取消两者,新旧订单都会被取消
+amend_text	String	用户修改订单时备注的自定义数据
+update_id	Integer	更新id
+update_time	Integer	更新时间 (毫秒时间戳)
+biz_info	String	用户可以备注这次修改的信息
+stop_profit_price	String	止盈价格
+stop_loss_price	String	止损价格
+market_order_slip_ratio	String	该笔市价单的预设的最大滑点比率(不代表实际的滑点),0.03代表3%的最大滑点
+{
+  "channel": "futures.orders",
+  "event": "update",
+  "time": 1541505434,
+  "time_ms": 1541505434123,
+  "result": [
+    {
+      "contract": "BTC_USD",
+      "create_time": 1628736847,
+      "create_time_ms": 1628736847325,
+      "fill_price": 40000.4,
+      "finish_as": "filled",
+      "finish_time": 1628736848,
+      "finish_time_ms": 1628736848321,
+      "iceberg": "0",
+      "id": 4872460,
+      "is_close": false,
+      "is_liq": false,
+      "is_reduce_only": false,
+      "left": "0",
+      "mkfr": -0.00025,
+      "price": 40000.4,
+      "refr": 0,
+      "refu": 0,
+      "size": "1",
+      "status": "finished",
+      "text": "-",
+      "tif": "gtc",
+      "tkfr": 0.0005,
+      "user": "110xxxxx",
+      "update_id": 1,
+      "update_time": 1541505434123,
+      "stop_loss_price": "",
+      "stop_profit_price": "",
+      "market_order_slip_ratio": "0.03"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅订单更新通知
+
+#请求参数
+channel
+
+futures.orders
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.orders",
+  "event": "unsubscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.orders",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#用户私有成交频道
+提供接收用户交易的方式
+
+需要认证
+
+#用户私有成交订阅
+如果您想订阅所有的市场交易更新,请在请求参数列表中使用!all。
+
+订阅私有成交更新
+
+#请求参数
+channel
+
+futures.usertrades
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.usertrades",
+  "event": "subscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.usertrades",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#用户私有成交推送
+推送用户私有成交更新
+
+#推送参数
+channel
+
+futures.usertrades
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	String	合约名称
+create_time	Integer	创建时间
+create_time_ms	Integer	创建时间(以毫秒为单位)
+id	String	交易 ID
+order_id	String	订单 ID
+price	String	交易价格
+size	String/Integer	交易数量
+role	String	用户角色 (maker/taker)
+text	String	订单自定义信息,用户可以用该字段设置自定义 ID,用户自定义字段必须满足以下条件:
+
+1. 必须以 t- 开头
+2. 不计算 t- ,长度不能超过 28 字节
+3. 输入内容只能包含数字、字母、下划线(_)、中划线(-) 或者点(.)
+
+除用户自定义信息以外,以下为内部保留字段,标识订单来源:
+
+- web: 网页
+- api: API 调用
+- app: 移动端
+- auto_deleveraging: 自动减仓
+- liquidation: 老经典模式仓位强制平仓
+- liq-xxx: a. 新经典模式仓位强制平仓,包含逐仓、单向全仓、双向全仓非对冲仓位强平。 b. 统一账户单币种保证金模式逐仓强制平仓
+- hedge-liq-xxx: 新经典模式双向全仓对冲部分强制平仓,即同时平多空仓位
+- pm_liquidate: 统一账户跨币种保证金模式强制平仓
+- comb_margin_liquidate: 统一账户组合保证金模式强制平仓
+- scm_liquidate: 统一账户单币种保证金模式仓位强制平仓
+- insurance: 保险
+- clear: 合约下架清退
+fee	Float	手续费
+point_fee	Float	点卡手续费
+{
+  "time": 1543205083,
+  "time_ms": 1543205083123,
+  "channel": "futures.usertrades",
+  "event": "update",
+  "result": [
+    {
+      "id": "3335259",
+      "create_time": 1628736848,
+      "create_time_ms": 1628736848321,
+      "contract": "BTC_USD",
+      "order_id": "4872460",
+      "size": "1",
+      "price": "40000.4",
+      "role": "maker",
+      "text": "api",
+      "fee": 0.0009290592,
+      "point_fee": 0
+    }
+  ]
+}
+Copy
+#取消订阅
+取消私有成交订阅
+
+#请求参数
+channel
+
+futures.usertrades
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.usertrades",
+  "event": "unsubscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.usertrades",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#强制平仓频道
+提供一种接收用户强制平仓信息的方式
+
+需要认证
+
+#清算订阅
+如果您想订阅所有合约中的强制平仓推送,请在订阅请求列表中使用 !all
+
+订阅用户强制平仓推送
+
+#请求参数
+channel
+
+futures.liquidates
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.liquidates",
+  "event": "subscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.liquidates",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#强制平仓推送
+推送强制平仓更新
+
+#推送参数
+channel
+
+futures.liquidates
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+entry_price	Float	平均入场价
+fill_price	Float	平均执行价格
+leverage	Float	杠杆大小
+liq_price	Float	清算价格
+margin	Float	Margin
+mark_price	Float	标记价格
+order_id	Integer	订单 ID
+order_price	Float	订单价格
+left	String/Integer	订单未完成数量
+size	Integer	原始订单数量
+time	Integer	时间
+time_ms	Integer	时间(以毫秒为单位)
+user	String	用户 ID
+contract	String	合约名称
+{
+  "channel": "futures.liquidates",
+  "event": "update",
+  "time": 1541505434,
+  "time_ms": 1541505434123,
+  "result": [
+    {
+      "entry_price": 209,
+      "fill_price": 215.1,
+      "left": 0,
+      "leverage": 0.0,
+      "liq_price": 213,
+      "margin": 0.007816722941,
+      "mark_price": 213,
+      "order_id": 4093362,
+      "order_price": 215.1,
+      "size": "-124",
+      "time": 1541486601,
+      "time_ms": 1541486601123,
+      "contract": "BTC_USD",
+      "user": "1040xxxx"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅清算更新
+
+#请求参数
+channel
+
+futures.liquidates
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.liquidates",
+  "event": "unsubscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.liquidates",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#自动减仓频道
+提供一种接收用户自动减仓信息的方法
+
+需要认证
+
+#自动减仓订阅
+如果您想订阅所有合约的自动减仓更新,请在请求参数列表中使用!all
+
+订阅用户自动减仓更新
+
+#请求参数
+channel
+
+futures.auto_deleverages
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.auto_deleverages",
+  "event": "subscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.auto_deleverages",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#自动减仓推送
+自动减仓消息
+
+#推送参数
+channel
+
+futures.auto_deleverages
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+entry_price	Float	入场价格
+fill_price	Float	执行价格
+position_size	Integer	持仓规模
+trade_size	Integer	交易数量
+time	Integer	时间
+time_ms	Integer	时间(以毫秒为单位)
+user	String	用户 ID
+contract	String	合约名称
+{
+  "channel": "futures.auto_deleverages",
+  "event": "update",
+  "time": 1541505434,
+  "time_ms": 1541505434123,
+  "result": [
+    {
+      "entry_price": 209,
+      "fill_price": 215.1,
+      "position_size": "10",
+      "trade_size": "10",
+      "time": 1541486601,
+      "time_ms": 1541486601123,
+      "contract": "BTC_USD",
+      "user": "1040"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅自动减仓
+
+#请求参数
+channel
+
+futures.auto_deleverages
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.auto_deleverages",
+  "event": "unsubscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.auto_deleverages",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#平仓频道
+提供一种接收用户仓位平仓信息的方法
+
+需要认证
+
+#平仓订阅
+如果您想订阅所有合约的平仓更新,请在合约列表中使用 !all
+
+订阅用户平仓信息更新
+
+#请求参数
+channel
+
+futures.position_closes
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+  "time": int(time.time()),
+  "channel": "futures.position_closes",
+  "event": "subscribe",
+  "payload": ["20011", "BTC_USD"],
+  "auth": {
+    "method": "api_key",
+    "KEY": "xxxx",
+    "SIGN": "xxxx"
+  }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.position_closes",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#平仓信息推送
+平仓信息推送
+
+#推送参数
+channel
+
+futures.position_closes
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	String	合约名称
+pnl	Number	利润损失
+side	String	方向 (long or short)
+text	String	附带信息
+time	Integer	时间
+time_ms	Integer	时间(以毫秒为单位)
+user	String	用户 ID
+{
+  "channel": "futures.position_closes",
+  "event": "update",
+  "time": 1541505434,
+  "time_ms": 1541505434123,
+  "result": [
+    {
+      "contract": "BTC_USD",
+      "pnl": -0.000624354791,
+      "side": "long",
+      "text": "web",
+      "time": 1547198562,
+      "time_ms": 1547198562123,
+      "user": "211xxxx"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅平仓更新
+
+#请求参数
+channel
+
+futures.position_closes
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.position_closes",
+    "event": "unsubscribe",
+    "payload": ["20011", "BTC_USD"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.position_closes",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#余额频道
+提供一种接收用户余额信息的方法
+
+需要认证
+
+#余额信息订阅
+订阅用户余额更新
+
+#请求参数
+channel
+
+futures.balances
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.balances",
+    "event": "subscribe",
+    "payload": ["20011"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.balances",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#余额更新推送
+通知余额更新信息
+
+#推送参数
+channel
+
+futures.balances
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+balance	Number	余额最终数量
+change	Number	余额变化数量
+text	String	附带信息
+time	Integer	时间
+time_ms	Integer	时间(以毫秒为单位)
+type	String	变更类型:
+dnw: 出入金
+pnl:盈亏
+refr: 推荐人费用
+fund: 资金费用
+cross_settle: 统一账户结算
+point_dnw: 点卡出入金
+point_fee: 点卡手续费
+point_refr: 点卡推荐人费用
+bonus_dnw: 体验金出入金
+pv_dnw: 仓位体验券充值提现
+fee: 手续费
+user	String	用户 ID
+currency	String	币种
+{
+  "channel": "futures.balances",
+  "event": "update",
+  "time": 1541505434,
+  "time_ms": 1541505434123,
+  "result": [
+    {
+      "balance": 9.998739899488,
+      "change": -0.000002074115,
+      "text": "BTC_USD:3914424",
+      "time": 1547199246,
+      "time_ms": 1547199246123,
+      "type": "fee",
+      "user": "211xxx",
+      "currency": "btc"
+    }
+  ]
+}
+Copy
+#取消订阅
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.balances",
+    "event": "unsubscribe",
+    "payload": ["20011"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.balances",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#降低风险率频道
+推送用户降低风险率信息
+
+需要认证
+
+#降低风险率订阅
+如果您想订阅所有合约的降低风险率更新,请在合约列表中使用 !all。
+
+订阅用户降低风险率更新
+
+#请求参数
+channel
+
+futures.reduce_risk_limits
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.reduce_risk_limits",
+    "event": "subscribe",
+    "payload": ["20011", "BTC_USD"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.reduce_risk_limits",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#降低风险率推送
+通知降低风险限制更新
+
+#推送参数
+channel
+
+futures.reduce_risk_limits
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+cancel_orders	Integer	Cancel orders
+contract	String	合约名称
+leverage_max	Integer	最大杠杆
+liq_price	Float	清算价格
+maintenance_rate	Float	Maintenance rate
+risk_limit	Integer	风险限额
+time	Integer	时间
+time_ms	Integer	时间(以毫秒为单位)
+user	String	用户 ID
+{
+  "time": 1551858330,
+  "time_ms": 1551858330123,
+  "channel": "futures.reduce_risk_limits",
+  "event": "update",
+  "result": [
+    {
+      "cancel_orders": 0,
+      "contract": "ETH_USD",
+      "leverage_max": 10,
+      "liq_price": 136.53,
+      "maintenance_rate": 0.09,
+      "risk_limit": 450,
+      "time": 1551858330,
+      "time_ms": 1551858330123,
+      "user": "20011"
+    }
+  ]
+}
+Copy
+#取消订阅
+退订降低风险限制更新
+
+#请求参数
+channel
+
+futures.reduce_risk_limits
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.reduce_risk_limits",
+    "event": "unsubscribe",
+    "payload": ["20011", "BTC_USD"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+#仓位频道
+提供一种接收用户仓位信息的方法
+
+需要认证
+
+#仓位订阅
+如果您想订阅所有合约的持仓更新,请在合约列表中使用 !all
+
+订阅用户仓位更新
+
+#请求参数
+channel
+
+futures.positions
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+user id	String	是	用户 ID (该字段已废弃,仅做占位符使用)
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.positions",
+    "event": "subscribe",
+    "payload": ["20011", "BTC_USD"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.positions",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#仓位信息推送
+推送仓位更新.
+
+#推送参数
+channel
+
+futures.positions
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	String	合约名称
+cross_leverage_limit	Float	全仓模式下的杠杆倍数
+entry_price	Float	开仓价格
+history_pnl	Float	已平仓的仓位总盈亏
+history_point	Float	已平仓的点卡总盈亏
+last_close_pnl	Float	最近一次平仓的盈亏
+leverage	Integer	杠杆倍数,0代表全仓,正数代表逐仓
+leverage_max	Integer	当前风险限额下,允许的最大杠杆倍数
+liq_price	Float	爆仓价格
+maintenance_rate	Float	当前风险限额下,维持保证金比例
+margin	Float	保证金
+realised_pnl	Float	已实现盈亏
+realised_point	Float	点卡已实现盈亏
+risk_limit	Integer	风险限额
+size	String/Integer	合约 size
+time	Integer	更新 unix 时间戳
+time_ms	Integer	更新 unix 时间戳(以毫秒为单位)
+user	String	用户 ID
+update_id	Integer	消息序列号,每次推送 order 之后会自增 1
+{
+  "time": 1588212926,
+  "time_ms": 1588212926123,
+  "channel": "futures.positions",
+  "event": "update",
+  "result": [
+    {
+      "contract": "BTC_USD",
+      "cross_leverage_limit": 0,
+      "entry_price": 40000.36666661111,
+      "history_pnl": -0.000108569505,
+      "history_point": 0,
+      "last_close_pnl": -0.000050123368,
+      "leverage": 0,
+      "leverage_max": 100,
+      "liq_price": 0.1,
+      "maintenance_rate": 0.005,
+      "margin": 49.999890611186,
+      "mode": "single",
+      "realised_pnl": -1.25e-8,
+      "realised_point": 0,
+      "risk_limit": 100,
+      "size": "3",
+      "time": 1628736848,
+      "time_ms": 1628736848321,
+      "user": "110xxxxx",
+      "update_id": 170919
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅仓位更新
+
+#请求参数
+channel
+
+futures.positions
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.positions",
+    "event": "unsubscribe",
+    "payload": ["20011", "BTC_USD"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.positions",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#仓位 Adl 排名频道
+推送用户仓位 adl 排名信息的频道
+
+需要认证
+
+#仓位 adl 订阅
+如果您想订阅所有合约的 adl 更新,请在合约列表中使用 !all
+
+订阅用户仓位 adl 更新
+
+#请求参数
+channel
+
+futures.position_adl_rank
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://ws-testnet.gate.com/v4/ws/futures/usdt")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.position_adl_rank",
+    "event": "subscribe",
+    "payload": ["BTC_USDT"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.position_adl_rank",
+  "event": "subscribe",
+  "payload": [
+    "BTC_USDT"
+  ],
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#仓位 adl 信息推送
+推送仓位更新.
+
+#推送参数
+channel
+
+futures.position_adl_rank
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+contract	String	合约名称
+mode	String	持仓模式
+rank_division	Integer	排名区间(1~6,1为最优先被ADL的区间,5为最靠后被ADL的区间。6:爆仓中不参与ADL排序)
+time_ms	Integer	消息推送的毫秒时间戳
+user_id	Integer	用户 ID
+{
+    "time": 1588212926,
+    "time_ms": 1588212926123,
+    "channel": "futures.position_adl_rank",
+    "event": "update",
+    "result": [
+        {
+            "contract": "BTC_USDT",
+            "mode": "single",
+            "rank_division": 1,
+            "time_ms": 1588212926119,
+            "user_id": 2124426495
+        }
+    ]
+}
+Copy
+#取消订阅
+取消订阅仓位更新
+
+#请求参数
+channel
+
+futures.position_adl_rank
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://ws-testnet.gate.com/v4/ws/futures/usdt")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.position_adl_rank",
+    "event": "unsubscribe",
+    "payload": ["BTC_USDT"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.position_adl_rank",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#自动订单频道
+提供一种接收用户自动订单信息的方法
+
+需要认证
+
+#自动订单订阅
+如果您想订阅所有合约中的自动订单更新,请在合约列表中使用!all
+
+订阅用户自动订单更新
+
+#请求参数
+channel
+
+futures.autoorders
+
+event
+
+subscribe
+
+params
+
+请求参数
+名称	类型	必选	描述
+contract	String	是	合约名称
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.autoorders",
+    "event": "subscribe",
+    "payload": ["BTC_USDT"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }
+}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.autoorders",
+  "event": "subscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#自动订单消息推送
+通知自动订单更新
+
+#推送参数
+channel
+
+futures.autoorders
+
+event
+
+update
+
+params
+
+推送参数
+名称	类型	描述
+result	Array	Array of objects
+推送参数
+名称	类型	描述
+user	Number	用户 ID
+trigger	Object	
+initial	Object	
+id	Number	自动订单 ID
+trade_id	Number	交易 ID
+status	String	订单状态
+reason	String	变更原因
+create_time	Number	创建时间
+name	String	名称
+is_stop_order	boolean	是否停止
+stop_trigger	Object	
+order_type	String	止盈/止损类型,详情参见 http api
+me_order_id	Number	订单止盈/止损对应订单 ID.
+{
+  "time": 1596798126,
+  "time_ms": 1596798126123,
+  "channel": "futures.autoorders",
+  "event": "update",
+  "result": [
+    {
+      "user": 123456,
+      "trigger": {
+        "strategy_type": 0,
+        "price_type": 0,
+        "price": "10000",
+        "rule": 2,
+        "expiration": 86400
+      },
+      "initial": {
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "10000",
+        "tif": "gtc",
+        "text": "web",
+        "iceberg": "0",
+        "is_close": false,
+        "is_reduce_only": false,
+        "auto_size": ""
+      },
+      "id": 9256,
+      "trade_id": 0,
+      "status": "open",
+      "reason": "",
+      "create_time": 1596798126,
+      "name": "price_autoorders",
+      "is_stop_order": false,
+      "stop_trigger": {
+        "rule": 0,
+        "trigger_price": "",
+        "order_price": ""
+      },
+      "order_type": "close-long-order",
+      "me_order_id": "213867453823"
+    }
+  ]
+}
+Copy
+#取消订阅
+取消订阅自动订单更新
+
+#请求参数
+channel
+
+futures.autoorders
+
+event
+
+unsubscribe
+
+代码示例
+
+import json, time
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws-testnet.gateio.ws/v4/ws/btc")
+req = {
+    "time": int(time.time()),
+    "channel": "futures.autoorders",
+    "event": "unsubscribe",
+    "payload": ["BTC_USDT"],
+    "auth": {
+        "method": "api_key",
+        "KEY": "xxxx",
+        "SIGN": "xxxx"
+    }}
+ws.send(json.dumps(req))
+print(ws.recv())
+Copy
+上面的命令返回 JSON 结构如下:
+
+{
+  "time": 1545459681,
+  "time_ms": 1545459681123,
+  "channel": "futures.autoorders",
+  "event": "unsubscribe",
+  "result": {
+    "status": "success"
+  }
+}
+Copy
+#账户交易 API
+#Websocket 交易 API
+WebSocket API 允许通过 WebSocket 连接下单、取消、修改、查询订单.
+
+#Websocket API 客户端请求
+客户端发起的 api 请求遵循通用的 JSON 格式, 包含以下字段:
+
+名称	类型	必选	描述
+time	Integer	是	请求时间(以秒为单位)。请求时间和服务器时间之间的差距不得超过 60 秒
+id	Integer	否	可选的请求 ID,将由服务器发回,以帮助您识别服务器响应哪个请求
+channel	String	是	要访问的 WebSocket 频道
+event	String	是	固定为api
+payload	Object	是	可选请求详细参数
+»req_id	String	是	消息的唯一标识符由客户端提供,将在响应消息中返回,用于标识相应的请求。
+»timestamp	String	是	签名时间(秒)
+»api_key	String	是	Gate APIv4 APIKey
+»signature	String	是	使用 GateAPIv4 密钥和请求信息生成的身份验证签名,
+详细信息请参见[Websocket API 身份验证](#Websocket API 身份验证)部分
+»req_param	[]Byte	是	请求 api 参数
+请注意,payload.req_param 的类型是与频道(channel字段)绑定的,频道不同payload.req_param 的字段也不同,以 futures.order_place 为例,payload.req_param 与 apiv4 /futures/{settle}/orders (opens new window)。 例如,您可以对 BTC_USDT 下限价单
+
+代码示例
+
+#!/usr/bin/python
+
+import time
+import json
+import hmac
+import hashlib
+import websocket
+import threading
+
+
+API_KEY = "xxxxx"
+SECRET = "xxxxx"
+WS_URL = "wss://fx-ws.gateio.ws/v4/ws/usdt"
+CHANNEL_LOGIN = "futures.login"
+CHANNEL_ORDER_PLACE = "futures.order_place"
+
+def get_ts():
+    return int(time.time())
+
+def get_ts_ms():
+    return int(time.time() * 1000)
+
+def get_signature(secret, channel, request_param_bytes, ts):
+    key = f"api\n{channel}\n{request_param_bytes.decode()}\n{ts}"
+    return hmac.new(secret.encode(), key.encode(), hashlib.sha512).hexdigest()
+
+def build_login_request():
+    ts = get_ts()
+    req_id = f"{get_ts_ms()}-1"
+    request_param = b""
+
+    sign = get_signature(SECRET, CHANNEL_LOGIN, request_param, ts)
+
+    payload = {
+        "api_key": API_KEY,
+        "signature": sign,
+        "timestamp": str(ts),
+        "req_id": req_id
+    }
+
+    return {
+        "time": ts,
+        "channel": CHANNEL_LOGIN,
+        "event": "api",
+        "payload": payload
+    }
+
+
+def build_order_request():
+    ts = get_ts()
+    req_id = f"{get_ts_ms()}-2"
+    order_param = {
+        "contract": "BTC_USDT",
+        "size": 6024,
+        "iceberg": 0,
+        "price": "3765",
+        "tif": "gtc",
+        "text": "t-my-custom-id",
+        "stp_act": "-"
+    }
+
+
+    payload = {
+        "req_id": req_id,
+        "req_param": order_param
+    }
+
+    return {
+        "time": ts,
+        "channel": CHANNEL_ORDER_PLACE,
+        "event": "api",
+        "payload": payload
+    }
+
+
+def on_message(ws, message):
+    print(f"recv: {message}")
+
+def on_error(ws, error):
+    print(f"error: {error}")
+
+def on_close(ws, close_status_code, close_msg):
+    print("connection closed")
+
+def on_open(ws):
+    print("WebSocket opened")
+
+    login_payload = build_login_request()
+    print("login payload:", login_payload)
+    ws.send(json.dumps(login_payload))
+
+    def delayed_order():
+        time.sleep(2)
+        order_payload = build_order_request()
+        print("order payload:", order_payload)
+        ws.send(json.dumps(order_payload))
+
+    threading.Thread(target=delayed_order).start()
+
+custom_headers = {
+    "X-Gate-Size-Decimal": "1"
+}
+
+if __name__ == "__main__":
+    ws = websocket.WebSocketApp(
+        WS_URL,
+        on_message=on_message,
+        on_error=on_error,
+        on_close=on_close,
+        on_open=on_open,
+        header=custom_headers
+    )
+    ws.run_forever()
+
+Copy
+{
+  "time": 1680772890,
+  "channel": "futures.order_place",
+  "event": "api",
+  "payload": {
+    "req_id": "xxxx",
+    "req_param": {
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "80048.240000",
+      "tif": "gtc",
+      "text": "t-my-custom-id"
+    }
+  }
+}
+Copy
+#Websocket API 服务响应
+服务器响应包括对客户端请求的 ack 响应和 api 结果消息推送。 服务器响应遵循通用的 JSON 格式,其中包含以下字段:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»x_gate_ratelimit_requests_remain	Integer	(仅涉及下单/改单/撤单)当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	(仅涉及下单/改单/撤单)当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	(仅涉及下单/改单/撤单)已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+data	Object	请求响应的数据
+»result	Object	如果这是 ack 响应,则结果是请求的payload,否则结果是 api 的响应
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+服务器回声确认响应示例(目前仅在下单请求中有回声响应)
+
+{
+  "request_id": "request-id-1",
+  "ack": true,
+  "header": {
+    "response_time": "1681195121499",
+    "status": "200",
+    "channel": "futures.order_place",
+    "event": "api",
+    "client_id": "::1-0x140031563c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gate_ratelimit_reset_timestamp": 1681195121499
+  },
+  "data": {
+    "result": {
+      "req_id": "request-id-1",
+      "req_param": {
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31503.280000",
+        "tif": "gtc",
+        "text": "t-my-custom-id"
+      }
+    }
+  }
+}
+Copy
+服务器 API 响应示例
+
+{
+  "request_id": "request-id-1",
+  "ack": false,
+  "header": {
+    "response_time": "1681195121639",
+    "status": "200",
+    "channel": "futures.order_place",
+    "event": "api",
+    "client_id": "::1-0x140031563c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gate_ratelimit_reset_timestamp": 1681195121639
+  },
+  "data": {
+    "result": {
+      "id": 74046511,
+      "user": 6790020,
+      "create_time": 1681195121.754,
+      "finish_time": 1681195121.754,
+      "finish_as": "filled",
+      "status": "finished",
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31503.3",
+      "tif": "gtc",
+      "fill_price": "31500",
+      "text": "t-my-custom-id",
+      "tkfr": "0.0003",
+      "mkfr": "0",
+      "stp_id": 2,
+      "stp_act": "cn",
+      "amend_text": "-"
+    }
+  }
+}
+Copy
+#错误
+错误响应详情具有以下格式:
+
+
+名称	类型	描述
+label	String	错误类型
+message	String	详细错误信息
+限频相关的错误码说明:
+
+错误码	描述
+100	限流内部异常错误
+311	合约限流
+312	合约成交比率限流
+错误响应通知示例
+
+{
+  "request_id": "request-id-1",
+  "ack": false,
+  "header": {
+    "response_time": "1681195360034",
+    "status": "401",
+    "channel": "futures.login",
+    "event": "api",
+    "client_id": "::1-0x140001a2600",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d"
+  },
+  "data": {
+    "errs": {
+      "label": "INVALID_KEY",
+      "message": "Invalid key provided"
+    }
+  }
+}
+Copy
+Error 推送示例(限速)
+
+{
+  "request_id": "xxxx",
+  "header": {
+    "response_time": "1677816784084",
+    "status": "429",
+    "channel": "futures.order_place",
+    "event": "api",
+    "client_id": "::1-0x14002ba2300",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_limit": 100,
+    "x_gate_ratelimit_reset_timestamp": 1677816785084
+  },
+  "data": {
+    "errs": {
+      "label": "TOO_MANY_REQUESTS",
+      "message": "Request Rate limit Exceeded (311)"
+    }
+  }
+}
+Copy
+#登录
+注意:您使用的 GateAPIv4 密钥对必须具有合约账户对应的权限(例如:order-place 频道必须具有合约账户写入权限), 如果启用了密钥的白名单,则您的出站 IP 地址必须在密钥的 IP 白名单中.
+
+#登录请求
+客户端 API 请求
+
+payload参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,将由服务器发回,以帮助您识别服务器响应哪个请求,
+它与外部的id不同
+api_key	string	是	Apiv4 key
+req_header	object	是	Apiv4 自定义 header
+signature	string	是	Apiv4 签名
+timestamp	string	是	Unix 时间戳(以秒为单位)
+WebSocket api 操作认证使用与 Gate APIv4 API 相同的签名计算方法,即 HexEncode(HMAC_SHA512(secret,signature_string)),但有以下区别:
+
+签名字符串拼接方式:<event>\n<channel>\n<req_param>\n<timestamp>, 其中<event>、<channel>、<req_param>、<timestamp>是对应的请求信息
+login频道中的 req_param始终为空字符串
+身份验证信息在请求正文中的payload字段中发送。
+代码示例
+
+import hmac
+import hashlib
+import json
+import time
+import websocket
+import ssl
+
+def get_api_signature(secret, channel, request_param, ts):
+    key = f"api\n{channel}\n{request_param}\n{ts}"
+    hash_object = hmac.new(secret.encode(), key.encode(), hashlib.sha512)
+    return hash_object.hexdigest()
+
+class ApiPayload:
+    def __init__(self, api_key, signature, timestamp, req_id, request_param):
+        self.api_key = api_key
+        self.signature = signature
+        self.timestamp = timestamp
+        self.req_id = req_id
+        self.request_param = request_param
+
+class ApiRequest:
+    def __init__(self, ts, channel, event, payload):
+        self.time = ts
+        self.channel = channel
+        self.event = event
+        self.payload = payload
+
+def main():
+    api_key = "YOUR_API_KEY"
+    secret = "YOUR_API_SECRET"
+    request_param = ""
+    channel = "futures.login"
+    ts = int(time.time())
+    request_id = f"{int(time.time() * 1000)}-1"
+
+    payload = ApiPayload(
+        api_key=api_key,
+        signature=get_api_signature(secret, channel, request_param, ts),
+        timestamp=str(ts),
+        req_id=request_id,
+        request_param=request_param
+    )
+
+    req = ApiRequest(ts=ts, channel=channel, event="api", payload=payload)
+
+    print(get_api_signature(secret, channel, request_param, ts))
+
+    req_json = json.dumps(req, default=lambda o: o.__dict__)
+    print(req_json)
+
+    # Connect to WebSocket
+    ws_url = "wss://fx-ws.gateio.ws/v4/ws/usdt"  # Replace with your WebSocket URL
+    websocket.enableTrace(False)
+    ws = websocket.create_connection(ws_url, sslopt={"cert_reqs": ssl.CERT_NONE})
+
+    # Function to receive messages
+    def recv_messages():
+        while True:
+            try:
+                message = ws.recv()
+                print(f"recv: {message}")
+            except Exception as e:
+                print(f"Error receiving message: {e}")
+                ws.close()
+                break
+
+    # Start receiving messages in a separate thread
+    import threading
+    receive_thread = threading.Thread(target=recv_messages)
+    receive_thread.start()
+
+    # Send the request
+    ws.send(req_json)
+
+    # Keep the main thread running
+    receive_thread.join()
+
+if __name__ == "__main__":
+    main()
+Copy
+请求示例
+
+{
+  "time": 1681984544,
+  "channel": "futures.login",
+  "event": "api",
+  "payload": {
+    "api_key": "ea83fad2604399da16bf97e6eea772a6",
+    "signature": "6fa3824c8141f2b2283108558ec50966d7caf749bf04a3b604652325b50b47d2343d569d848373d58e65c49d9622ba2e73dc25797abef11c9f20c07da741591e",
+    "timestamp": "1681984544",
+    "req_id": "request-1"
+  }
+}
+Copy
+#登录响应
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+data	Object	请求响应的数据
+»result	Object	如果这是 ack 响应,则结果是请求的payload,否则结果是 api 的响应
+»»api_key	String	登录成功的 apikey
+»»uid	String	登录成功的用户 ID
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+登录响应示例
+
+{
+  "request_id": "request-1",
+  "header": {
+    "response_time": "1681985856666",
+    "status": "200",
+    "channel": "futures.login",
+    "event": "api",
+    "clientId": "",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d"
+  },
+  "data": {
+    "result": {
+      "api_key": "ea83fad2604399da16bf97e6eea772a6",
+      "uid": "110284739"
+    }
+  }
+}
+Copy
+#下单
+futures.order_place
+
+您可以通过此频道进行下单操作.
+
+本频道和以下的 APIV4 功能相同:
+
+POST /futures/{
+  settle
+}/orders
+#下单请求
+payload参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	使用 api 下单参数; api 下单参数详细信息api(opens new window)
+req_header	object	否	Apiv4 自定义请求头
+req_param API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+contract	string	是	合约
+size	int64	是	订单大小。指定正数进行出价,指定负数进行询问
+iceberg	string	否	冰山订单的显示尺寸。0 表示非冰山。请注意,您需要支付隐藏尺寸的接受者费用
+price	string	否	订单价格。0 表示市价订单,tif设置为ioc
+close	bool	否	设置为true平仓,size设置为 0
+reduce_only	bool	否	设置为true仅减少订单
+tif	string	否	有效时间
+text	string	否	用户定义的信息。如果不为空,则必须遵循以下规则:
+auto_size	string	否	将侧面设置为关闭双模式位置。close_long闭合长边;而close_short短的。注意size还需要设置为 0
+stp_act	string	否	自我交易预防行动。用户可以通过该字段设置自助交易防范策略
+market_order_slip_ratio	string	否	该笔市价单的预设的最大滑点比率(不代表实际的滑点),0.03代表3%的最大滑点
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+#详细描述
+tif: 有效时间
+
+gtc:取消前有效
+ioc: ImmediateOrCancelled, 仅接受者
+poc:PendingOrCancelled,仅发布订单,始终享受挂单费用
+fok:FillOrKill,完全填充或不填充
+text: 订单自定义信息,用户可以用该字段设置自定义 ID,用户自定义字段必须满足以下条件:
+
+必须以 t- 开头
+不计算 t- ,长度不能超过 28 字节
+输入内容只能包含数字、字母、下划线(_)、中划线(-) 或者点(.)
+不填,默认 apiv4-ws,来自 ws
+web:来自网络
+api:来自 API
+app:来自手机
+auto_deleveraging:来自 ADL
+liquidation:来自清算
+insurance:来自保险
+stp_act:自我交易预防行动。用户可以通过该字段设置自助交易防范策略 用户加入后STP Group,他可以通过stp_act限制用户的自我交易防范策略。如果stp_act不通过则默认为cn策略。 当用户没有加入时STP group,传递参数时会返回错误stp_act。 如果用户下单时没有使用stp_act,stp_act将返回-
+
+cn:取消最新订单,取消新订单并保留旧订单
+co:取消最旧的订单,取消旧订单并保留新订单
+cb:取消两者,新旧订单都会被取消
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+api_order = {
+      "contract": "BTC_USDT",
+      "size": 10,
+      "price": "31503.280000",
+      "tif": "gtc",
+      "text": "t-my-custom-id"
+    }
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send(json.dumps(
+    {"time": int(time.time()),
+    "channel": "futures.order_place",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_order
+    }}
+))
+
+print(ws.recv())
+Copy
+请求示例
+
+{
+  "time": 1681195484,
+  "channel": "futures.order_place",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-1",
+    "req_param": {
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31503.280000",
+      "tif": "gtc",
+      "text": "t-my-custom-id"
+    }
+  }
+}
+Copy
+#订单请求回声消息
+订单确认回声通知示例
+
+{
+  "request_id": "request-id-1",
+  "ack": true,
+  "header": {
+    "response_time": "1681195484268",
+    "status": "200",
+    "channel": "futures.order_place",
+    "event": "api",
+    "client_id": "::1-0x140001a2600",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": {
+      "req_id": "request-id-1",
+      "req_header": null,
+      "req_param": {
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31503.280000",
+        "tif": "gtc",
+        "text": "t-my-custom-id"
+      }
+    }
+  }
+}
+Copy
+#下单结果通知
+下单时返回订单信息 响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+ack	Bool	"ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。
+如果ack为 false(false 该字段不会出现在响应中),则说明该消息是响应消息,可以判断请求是否成功<br / >通过检查data.errs。
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+»x_gate_ratelimit_requests_remain	Integer	当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+data	Object	请求响应的数据
+»result	Object	如果这是 ack 响应,则结果是请求的payload,否则结果是 api 的响应
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+响应返回示例
+
+{
+  "request_id": "request-id-1",
+  "ack": false,
+  "header": {
+    "response_time": "1681195484360",
+    "status": "200",
+    "channel": "futures.order_place",
+    "event": "api",
+    "client_id": "::1-0x140001a2600",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": {
+      "id": 74046514,
+      "user": 6790020,
+      "create_time": 1681195484.462,
+      "finish_time": 1681195484.462,
+      "finish_as": "filled",
+      "status": "finished",
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31503.3",
+      "tif": "gtc",
+      "fill_price": "31500",
+      "text": "t-my-custom-id",
+      "tkfr": "0.0003",
+      "mkfr": "0",
+      "stp_id": 2,
+      "stp_act": "cn",
+      "amend_text": "-"
+    }
+  }
+}
+Copy
+#批量下单
+futures.order_batch_place
+
+您可以通过该频道批量下单
+
+本频道和以下的 APIV4 功能相同:
+
+POST /futures/{
+  settle
+}/batch_orders
+#批量下单请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	参考 api 批量下单的请求数组; api 批量下单详情api(opens new window)
+req_header	object	否	Apiv4 自定义 header
+req_param API 订单模型的 JSON 字节数据可以参考单个下单,是多个单个下单数组,详情参考下单
+
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+api_order=[
+      {
+        "contract": "BTC_USDT",
+        "size": 10,
+        "price": "31403.180000",
+        "tif": "gtc",
+        "text": "t-my-custom-id"
+      }
+    ]
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_batch_place",
+    "event": "api",
+    "payload": {
+        "header":{
+            "x-gate-channel-id":"xxxx",
+        },
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_order
+    }
+}))
+
+print(ws.recv())
+Copy
+请求示例
+
+{
+  "time": 1681196536,
+  "channel": "futures.order_batch_place",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-6",
+    "req_param": [
+      {
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31403.180000",
+        "tif": "gtc",
+        "text": "t-my-custom-id"
+      }
+    ]
+  }
+}
+Copy
+#批量下单确认通知
+确认通知示例
+
+{
+  "request_id": "request-id-6",
+  "ack": true,
+  "header": {
+    "response_time": "1681196536283",
+    "status": "200",
+    "channel": "futures.order_batch_place",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": {
+      "req_id": "request-id-6",
+      "req_header": null,
+      "req_param": [
+        {
+          "contract": "BTC_USDT",
+          "size": "10",
+          "price": "31403.180000",
+          "tif": "gtc",
+          "text": "t-my-custom-id"
+        }
+      ]
+    }
+  }
+}
+Copy
+#批量下单结果通知
+批量下单订单信息返回
+
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+ack	Bool	"ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。
+如果ack为 false(false 该字段不会出现在响应中),则说明该消息是响应消息,可以判断请求是否成功<br / >通过检查data.errs。
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+»x_gate_ratelimit_requests_remain	Integer	当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+data	Object	请求响应的数据
+»result	Object	如果这是 ack 响应,则结果是请求的payload,否则结果是 api 的响应
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+响应返回示例
+
+{
+  "request_id": "request-id-6",
+  "ack": false,
+  "header": {
+    "response_time": "1681196536532",
+    "status": "200",
+    "channel": "futures.order_batch_place",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": [
+      {
+        "succeeded": true,
+        "id": 74046545,
+        "user": 6790020,
+        "create_time": 1681196536.592,
+        "status": "open",
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31403.2",
+        "tif": "gtc",
+        "left": "10",
+        "fill_price": "0",
+        "text": "t-my-custom-id",
+        "tkfr": "0.0003",
+        "mkfr": "0"
+      }
+    ]
+  }
+}
+Copy
+#订单取消
+futures.order_cancel
+
+您可以通过此频道取消订单
+
+本频道和以下的 APIV4 功能相同:
+
+DELETE /futures/{
+  settle
+}/orders/{
+  order_id
+}
+#订单取消请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	API 取消订单,详情至api(opens new window)
+req_header	object	否	Apiv4 自定义请求头
+req_param API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+order_id	string	是	成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即text 字段)。
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+api_cancel_order = {
+      "order_id": "74046514"
+    }
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_cancel",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_cancel_order
+    }
+}))
+
+print(ws.recv())
+Copy
+订单取消请求示例
+
+{
+  "time": 1681195485,
+  "channel": "futures.order_cancel",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-5",
+    "req_param": {
+      "order_id": "74046514"
+    }
+  }
+}
+Copy
+#订单取消通知
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+»x_gate_ratelimit_requests_remain	Integer	当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+data	Object	请求响应的数据
+»result	Object	订单取消参数,详情至api(opens new window)
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+订单取消返回示例
+
+{
+  "request_id": "request-id-5",
+  "header": {
+    "response_time": "1681196536282",
+    "status": "200",
+    "channel": "futures.order_cancel",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": {
+      "id": 74046543,
+      "user": 6790020,
+      "create_time": 1681196535.01,
+      "finish_time": 1681196536.343,
+      "finish_as": "cancelled",
+      "status": "finished",
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31303.2",
+      "tif": "gtc",
+      "left": "10",
+      "fill_price": "0",
+      "text": "t-my-custom-id",
+      "tkfr": "0.0003",
+      "mkfr": "0",
+      "stp_id": 2,
+      "stp_act": "cn",
+      "amend_text": "-"
+    }
+  }
+}
+Copy
+#取消所有 ID 列表内的订单
+您可以使用此频道futures.order_cancel_ids取消所有 ID 列表内的订单。
+
+可以指定多个不同的订单id。一次请求最多只能撤销 20 条记录
+
+以下是 API 的功能:
+
+POST /futures/{settle}/batch_cancel_orders
+#取消所有 ID 列表内的订单请求
+Payload 格式:
+
+字段	类型	必选	描述
+req_id	string	是	服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
+req_param	array	是	订单 ID 列表
+req_header	object	否	apiv4 自定义 header
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+代码示例:请求前要先登录
+
+#!/usr/bin/python
+
+import time
+import json
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+cancelWithIdsParam = ["1694883366","123"]
+ws.send(json.dumps({
+    "time":int(time.time()),
+    "channel":"futures.order_cancel_ids",
+    "event":"api",
+    "payload":{
+        "req_id":"test_1",
+        "req_param": cancelWithIdsParam
+    }
+}))
+
+print(ws.recv())
+Copy
+客户端请求示例
+
+{
+  "time": 1681986208,
+  "channel": "futures.order_cancel_ids",
+  "event": "api",
+  "payload": {
+    "req_id": "request-9",
+    "req_param": [
+      "1700664343",
+      "123"
+    ]
+  }
+}
+Copy
+#取消所有 ID 列表内的订单推送
+推送格式:
+
+字段	类型	描述
+request_id	String	消息的唯一标识符
+header	Map	响应的元信息
+»response_time	String	响应发送时间(以毫秒为单位)
+»channel	String	请求的频道
+»event	String	请求事件
+»client_id	String	唯一客户端标识 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+data	Object	请求响应的数据
+»result	Object	响应详见api(opens new window)
+»errs	Object	只有在请求失败时才可用
+»»label	String	以字符串格式表示错误类型
+»»message	String	错误信息详情
+取消订单推送示例
+
+{
+  "request_id": "request-9",
+  "header": {
+    "response_time": "1681986208564",
+    "status": "200",
+    "channel": "futures.order_cancel_ids",
+    "event": "api",
+    "client_id": "::1-0x140001623c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d"
+  },
+  "data": {
+    "result": [
+      {
+        "id": "1694883366",
+        "user_id": 111,
+        "succeeded": true
+      },
+      {
+        "id": "123",
+        "user_id": 111,
+        "message": "ORDER_NOT_FOUND"
+      }
+    ]
+  }
+}
+Copy
+#取消匹配的未结束订单
+futures.order_cancel_cp
+
+您可以通过此渠道取消所有匹配的未结束的订单
+
+本频道和以下的 APIV4 功能相同:
+
+DELETE /futures/{
+  settle
+}/orders
+#请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	详情至api(opens new window)
+req_header	object	否	Apiv4 自定义请求头
+req_param API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+contract	string	是	合约
+side	string	否	所有出价或要价。如果没有特别说明,两者都包括在内。
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+api_cancel_all_order = {
+      "contract": "BTC_USDT",
+      "side": "bid"
+    }
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_cancel_cp",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_cancel_all_order
+    }
+}))
+
+print(ws.recv())
+Copy
+客户请求示例
+
+{
+  "time": 1681196537,
+  "channel": "futures.order_cancel_cp",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-7",
+    "req_param": {
+      "contract": "BTC_USDT",
+      "side": "bid"
+    }
+  }
+}
+Copy
+#响应结果
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+»x_gate_ratelimit_requests_remain	Integer	当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+data	Object	请求响应的数据
+»result	Object	详情至api(opens new window)
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+订单取消返回示例
+
+{
+  "request_id": "request-id-7",
+  "header": {
+    "response_time": "1681196537567",
+    "status": "200",
+    "channel": "futures.order_cancel_cp",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": [
+      {
+        "id": 74046545,
+        "user": 6790020,
+        "create_time": 1681196536.592,
+        "finish_time": 1681196537.626,
+        "finish_as": "cancelled",
+        "status": "finished",
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31403.2",
+        "tif": "gtc",
+        "left": "10",
+        "fill_price": "0",
+        "text": "t-my-custom-id",
+        "tkfr": "0.0003",
+        "mkfr": "0",
+        "stp_id": 2,
+        "stp_act": "cn",
+        "amend_text": "-"
+      }
+    ]
+  }
+}
+Copy
+#修改订单
+futures.order_amend
+
+您可以通过此频道修改未结束的订单
+
+本频道和以下的 APIV4 功能相同:
+
+PUT /futures/{settle}/orders/{order_id}
+#请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	API 修改订单参数,详情至api(opens new window)
+req_header	object	否	Apiv4 自定义请求头
+req_param API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+order_id	string	是	成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即text 字段)。
+size	int64	否	必选。交易数量,正数为买入,负数为卖出。平仓委托则设置为 0。
+price	string	否	价格
+amend_text	int64	否	修改订单时的自定义信息
+req_header 自定义 header 数据:
+
+字段	类型	必选	描述
+x-gate-exptime	string	否	指定过期的时间戳(毫秒)。如果 ws 收到请求的时间大于过期时间,请求将被拒绝
+#详细描述
+=> size: 新订单尺寸,包括已填充部分。
+
+如果新尺寸小于或等于已填充尺寸,订单将被取消。
+订单面必须与原始面相同。
+平仓订单大小无法更改。
+对于仅减少订单,增加尺寸可能会导致其他仅减少订单被取消。
+如果价格不变,减少数量不会改变其在订单簿中的优先级,而增加数量则会以当前价格将其移至最后。
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+api_amend_order = {
+      "order_id": "74046543",
+      "price": "31303.180000"
+    }
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_amend",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_amend_order
+    }
+}))
+
+print(ws.recv())
+Copy
+客户请求示例
+
+{
+  "time": 1681196536,
+  "channel": "futures.order_amend",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-4",
+    "req_param": {
+      "order_id": "74046543",
+      "price": "31303.180000"
+    }
+  }
+}
+Copy
+#响应结果
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+»x_gate_ratelimit_requests_remain	Integer	当前时间窗口剩余可用请求数(为0不展示)
+»x_gate_ratelimit_limit	Integer	当前频率限制上限(为0不展示)
+»x_gat_ratelimit_reset_timestamp	Integer	已超过当前窗口频率限制,表示下个可用时间窗口的时间戳(毫秒),即什么时候可以恢复访问;未超过当前窗口频率限制,表示返回的是当前服务器时间(毫秒)
+data	Object	请求响应的数据
+»result	Object	详情至api(opens new window)
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+订单修改返回示例
+
+{
+  "request_id": "request-id-4",
+  "header": {
+    "response_time": "1681196536251",
+    "status": "200",
+    "channel": "futures.order_amend",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d",
+    "x_gate_ratelimit_requests_remain": 99,
+    "x_gate_ratelimit_limit": 100,
+    "x_gat_ratelimit_reset_timestamp": 1736408263764
+  },
+  "data": {
+    "result": {
+      "id": 74046543,
+      "user": 6790020,
+      "create_time": 1681196535.01,
+      "status": "open",
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31303.2",
+      "tif": "gtc",
+      "left": "10",
+      "fill_price": "0",
+      "text": "t-my-custom-id",
+      "tkfr": "0.0003",
+      "mkfr": "0",
+      "stp_id": 2,
+      "stp_act": "cn",
+      "amend_text": "-"
+    }
+  }
+}
+Copy
+#获取订单列表
+futures.order_list
+
+您可以通过此频道获取订单列表
+
+本频道和以下的 APIV4 功能相同:
+
+GET /futures/{settle}/orders
+#订单列表请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	API 请求订单列表参数,详情至api(opens new window)
+req_param API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+contract	string	否	合约标识,如果指定则只返回该合约相关数据
+status	string	是	只列出具有此状态的订单
+limit	int	否	单个列表中返回的最大记录数
+offset	int	否	列表偏移量,从 0 开始
+last_id	string	否	使用先前列表查询结果中最后一条记录的id 指定列表起始点
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+api_list_order = {
+      "contract": "BTC_USDT",
+      "status": "open"
+    }
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_list",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_list_order
+    }
+}
+))
+
+print(ws.recv())
+Copy
+客户请求示例
+
+{
+  "time": 1681196535,
+  "channel": "futures.order_list",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-3",
+    "req_param": {
+      "contract": "BTC_USDT",
+      "status": "open"
+    }
+  }
+}
+Copy
+#订单列表响应
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+data	Object	请求响应的数据
+»result	Object	详情至api(opens new window)
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+订单列表返回示例
+
+{
+  "request_id": "request-id-3",
+  "header": {
+    "response_time": "1681196536017",
+    "status": "200",
+    "channel": "futures.order_list",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d"
+  },
+  "data": {
+    "result": [
+      {
+        "id": 74046543,
+        "user": 6790020,
+        "create_time": 1681196535.01,
+        "finish_time": 1681196535.01,
+        "update_time": 1681196535.01,
+        "finish_as": "filled",
+        "status": "open",
+        "contract": "BTC_USDT",
+        "size": "10",
+        "price": "31403.2",
+        "tif": "gtc",
+        "left": "10",
+        "fill_price": "0",
+        "text": "t-my-custom-id",
+        "tkfr": "0.0003",
+        "mkfr": "0",
+        "stp_id": 2,
+        "stp_act": "cn",
+        "amend_text": "-"
+      }
+    ]
+  }
+}
+Copy
+#查询订单详情
+futures.order_status
+
+您可以通过该频道查询订单详情
+
+本频道和以下的 APIV4 功能相同:
+
+GET /futures/{settle}/orders/{order_id}
+#订单详情请求
+payload 参数:
+
+名称	类型	必选	描述
+req_id	string	是	请求 id,服务器会发回,帮助你识别服务器响应的是哪个请求,
+它与外部的id不同
+req_param	object	是	详情至api(opens new window)
+req_param` API 订单模型的 JSON 字节数据:
+
+字段	类型	必选	描述
+order_id	string	是	成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即text 字段)。
+代码示例:请求前要先登录
+
+import time
+import json
+
+# pip install websocket_client
+from websocket import create_connection
+
+ws = create_connection("wss://fx-ws.gateio.ws/v4/ws/usdt")
+
+api_status_order = {
+      "order_id": "74046543"
+    }
+
+ws.send(json.dumps({
+    "time": int(time.time()),
+    "channel": "futures.order_status",
+    "event": "api",
+    "payload": {
+        "req_id": "1ewq-3123w-5",
+        "req_param": api_status_order
+    }
+}))
+
+print(ws.recv())
+Copy
+客户请求示例
+
+{
+  "time": 1681196535,
+  "channel": "futures.order_status",
+  "event": "api",
+  "payload": {
+    "req_id": "request-id-2",
+    "req_param": {
+      "order_id": "74046543"
+    }
+  }
+}
+Copy
+#订单详情响应
+响应参数:
+
+名称	类型	描述
+request_id	String	对应的请求 ID
+header	Map	响应元信息
+»response_time	String	响应发送时间(毫秒)
+»channel	String	请求频道
+»event	String	请求event
+»client_id	String	唯一的客户端 ID
+»x_in_time	Integer	ws 接收请求的时间(以微秒为单位)
+»x_out_time	Integer	ws 返回响应的时间(以微秒为单位)
+»conn_id	String	与客户端建立连接的链接Id(同一个连接的链接Id保持一致)
+»conn_trace_id	String	与客户端建立连接的TraceId
+»trace_id	String	执行下单操作的TraceId
+data	Object	请求响应的数据
+»result	Object	详情至api(opens new window)
+»errs	Object	仅当请求失败时可用
+»»label	String	错误类型
+»»message	String	详细错误信息
+订单详情返回示例
+
+{
+  "request_id": "request-id-2",
+  "header": {
+    "response_time": "1681196535985",
+    "status": "200",
+    "channel": "futures.order_status",
+    "event": "api",
+    "client_id": "::1-0x14002cfa0c0",
+    "x_in_time": 1681985856667508,
+    "x_out_time": 1681985856667598,
+    "conn_id": "5e74253e9c793974",
+    "conn_trace_id": "1bde5aaa0acf2f5f48edfd4392e1fa68",
+    "trace_id": "e410abb5f74b4afc519e67920548838d"
+  },
+  "data": {
+    "result": {
+      "id": 74046543,
+      "user": 6790020,
+      "create_time": 1681196535.01,
+      "status": "open",
+      "contract": "BTC_USDT",
+      "size": "10",
+      "price": "31403.2",
+      "tif": "gtc",
+      "left": "10",
+      "fill_price": "0",
+      "text": "t-my-custom-id",
+      "tkfr": "0.0003",
+      "mkfr": "0",
+      "stp_id": 2,
+      "stp_act": "cn",
+      "amend_text": "-"
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
index 520ba13..91f5dcc 100644
--- a/src/main/resources/application-test.yml
+++ b/src/main/resources/application-test.yml
@@ -7,9 +7,9 @@
   profiles:
     active: app
   datasource:
-    url: jdbc:mysql://47.76.217.51:3306/db_base?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
-    username: db_base
-    password: P@ssw0rd!123
+    url: jdbc:mysql://120.27.238.55:3406/db_base?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
+    username: ct_test
+    password: 123456
     driver-class-name: com.mysql.jdbc.Driver
     type: com.alibaba.druid.pool.DruidDataSource
     druid:
@@ -48,13 +48,13 @@
   ## redis配置
   redis:
     # Redis数据库索引(默认为 0)
-    database: 13
+    database: 8
     # Redis服务器地址
-    host: 47.76.217.51
+    host: 120.27.238.55
     # Redis服务器连接端口
-    port: 6379
+    port: 6479
     # Redis 密码
-    password: lianghua1!qaz2@WSX
+    password: d3y6dsdl;f.327
     lettuce:
       pool:
         # 连接池中的最小空闲连接
@@ -69,10 +69,10 @@
     timeout: 500000
 
   rabbitmq:
-    host: 47.76.217.51
+    host: 120.27.238.55
     port: 5672
-    username: lianghua20210816
-    password: lianghua20210816
+    username: ct_rabbit
+    password: 123456
     publisher-confirm-type: correlated
 
 
@@ -102,7 +102,7 @@
   rabbit-consumer: false
   block-job: false
   websocket: false
-  quant: true
+  quant: false
 
 aliyun:
   oss:

--
Gitblit v1.9.1