# 现货 WebSocket v4

    WebSocket 应用示例

    # !/usr/bin/env python
    # coding: utf-8
    
    import hashlib
    import hmac
    import json
    import logging
    import time
    
    # pip install -U websocket_client
    from websocket import WebSocketApp
    
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    
    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, interval, event):
            while not event.wait(interval):
                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("spot.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 whatever message you 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("spot.trades", ['BTC_USDT'], False)
    
    
    if __name__ == "__main__":
        logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.DEBUG)
        app = GateWebSocketApp("wss://api.gateio.ws/ws/v4/",
                               "YOUR_API_KEY",
                               "YOUR_API_SECRET",
                               on_open=on_open,
                               on_message=on_message)
        app.run_forever(ping_interval=5)
    
    package main
    
    import (
    	"crypto/hmac"
    	"crypto/sha512"
    	"crypto/tls"
    	"encoding/hex"
    	"encoding/json"
    	"fmt"
    	"io"
    	"net/url"
    	"time"
    
    	"github.com/gorilla/websocket"
    )
    
    type Msg struct {
    	Time    int64    `json:"time"`
    	Channel string   `json:"channel"`
    	Event   string   `json:"event"`
    	Payload []string `json:"payload"`
    	Auth    *Auth    `json:"auth"`
    }
    
    type Auth struct {
    	Method string `json:"method"`
    	KEY    string `json:"KEY"`
    	SIGN   string `json:"SIGN"`
    }
    
    const (
    	Key    = "YOUR_API_KEY"
    	Secret = "YOUR_API_SECRETY"
    )
    
    func sign(channel, event string, t int64) string {
    	message := fmt.Sprintf("channel=%s&event=%s&time=%d", channel, event, t)
    	h2 := hmac.New(sha512.New, []byte(Secret))
    	io.WriteString(h2, message)
    	return hex.EncodeToString(h2.Sum(nil))
    }
    
    func (msg *Msg) sign() {
    	signStr := sign(msg.Channel, msg.Event, msg.Time)
    	msg.Auth = &Auth{
    		Method: "api_key",
    		KEY:    Key,
    		SIGN:   signStr,
    	}
    }
    
    func (msg *Msg) send(c *websocket.Conn) error {
    	msgByte, err := json.Marshal(msg)
    	if err != nil {
    		return err
    	}
    	return c.WriteMessage(websocket.TextMessage, msgByte)
    }
    
    func NewMsg(channel, event string, t int64, payload []string) *Msg {
    	return &Msg{
    		Time:    t,
    		Channel: channel,
    		Event:   event,
    		Payload: payload,
    	}
    }
    
    func main() {
    	u := url.URL{Scheme: "wss", Host: "api.gateio.ws", Path: "/ws/v4/"}
    	websocket.DefaultDialer.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
    	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    	if err != nil {
    		panic(err)
    	}
    	c.SetPingHandler(nil)
    
    	// read msg
    	go func() {
    		for {
    			_, message, err := c.ReadMessage()
    			if err != nil {
    				c.Close()
    				panic(err)
    			}
    			fmt.Printf("recv: %s\n", message)
    		}
    	}()
    
    	t := time.Now().Unix()
    	pingMsg := NewMsg("spot.ping", "", t, []string{})
    	err = pingMsg.send(c)
    	if err != nil {
    		panic(err)
    	}
    
    	// subscribe order book
    	orderBookMsg := NewMsg("spot.order_book", "subscribe", t, []string{"BTC_USDT"})
    	err = orderBookMsg.send(c)
    	if err != nil {
    		panic(err)
    	}
    
    	// subscribe positions
    	ordersMsg := NewMsg("spot.orders", "subscribe", t, []string{"BTC_USDT"})
    	ordersMsg.sign()
    	err = ordersMsg.send(c)
    	if err != nil {
    		panic(err)
    	}
    
    	select {}
    }
    

    Gate.io 提供了一个简单而健壮的 Websocket API 来集成现货交易状态信息为您的业务或应用提供支持。

    我们当前使用 Python 作为代码示例,将来会有更多语言示例支持!

    代码示例位于右侧深色区域,您可以点击右上方的标签切换示例的编程语言。

    # 服务地址

    Websocket 链接地址:

    • wss://api.gateio.ws/ws/v4/

    # SDK

    我们提供了 WebSocket SDK 来帮助开发者进行业务复用。

    SDK 的源代码 在 gatews (opens new window) GitHub 仓库。

    # 变更历史

    2024-01-17

    • 新增 w 窗口关闭标识到 K 线频道更新推送

    2023-04-21

    • 新增 freeze,freeze_change,change_type 字段到 spot.cross_balances 频道推送

    2022-12-12

    • 新增 avg_deal_price 字段到 spot.orders 频道推送

    2022-12-07

    • 新增 freeze,freeze_change,change_type 字段到 spot.balances 频道推送

    2022-11-22

    • 新增消息发送毫秒时间戳 time_ms 到全部频道推送

    2022-07-05

    • 新增 spot.cross_loan 频道通知用户用户全仓保证金借款和利息更新

    2021-07-23

    • 增加 spot.cross_balances 频道来通知 全仓杠杆余额(cross margin balance) 更新
    • 增加 text 字段在 spot.usertrades 服务通知中

    2021-04-27

    • 增加 毫秒时间戳 在 spot.orders, spot.balances, spot.margin_balancesspot.funding_balances 服务通知中

    2021-03-17

    • 增加文档阐述如何维护本地深度
    • 增加 毫秒时间戳 t 在所有的 order book 频道的 result

    2021-01-26

    • 初代版本发布

    # Websocket API 概述

    WebSocket 操作分为不同的频道。频道可以是公共的或私有的。 公共频道可以直接订阅,而私有频道需要使用 Gate APIv4 密钥对进行身份验证(有关详细信息,请参阅下面的身份验证 (opens new window))。

    所有频道都支持以下事件:

    • subscribe

    ​ 由客户端发起。客户端使用此方法告诉服务器它对此频道感兴趣,并要求服务器在频道相关数据更改时通知 新数据。

    • unsubscribe

      由客户端发起。客户端使用此方法告诉服务器它不再对此频道感兴趣,并停止发送任何进一步的频道更新。

    • update

      由服务器发起。服务器使用此方法将更改的数据发送给所有订阅此频道的客户端。客户端不能使用此操作事件。

    # 客户端请求

    客户端请求示例

    {
      "time": 1611541000,
      "id": 123456789,
      "channel": "spot.orders",
      "event": "subscribe",
      "payload": ["BTC_USDT", "GT_USDT"],
      "auth": {
        "method": "api_key",
        "KEY": "xxxx",
        "SIGN": "xxxx"
      }
    }
    

    从客户端发起的 subscribeunsubscribe 请求都是通用 JSON 格式且包含以下字段:

    字段 类型 必选 描述
    time Integer 精确到秒的请求时间。请求时间和服务器时间之间的间隔不能超过 60 秒。
    id Integer 请求 id(可选),服务器将此 id 发送回来,用来帮助您确定服务器响应哪个请求
    channel String 需要订阅的 websocket 频道
    auth Auth 私有频道的身份验证凭证。详见 身份验证(Authentication) 细节部分
    event String 频道的操作事件。例如 subscribe, unsubscribe
    payload Any 请求详细参数(可选)

    注意,payload 的类型是基于 channel 的,不同 channel 需要的 payload 参数不同。但 subscribeunsubscribe 的 payload 在同一个 channel 中使用的格式都是相同的。

    spot.orders 频道为例,此频道需要的 payload 格式是一个货币列表。你可以指定 ["BTC_USDT", "ETH_USDT", "etc"] 作为 subscribe 的 payload 以接收关于这些货币对的订单更新通知。然后在 unsubscribe payload 中指定 ["etc"] 来去掉这个货币对的订单更新通知。

    为了简单起见,下面的频道(channel)描述只给出对应频道的 payload 格式,但是您需要发送完整的请求来执行频道订阅操作。

    # 服务端响应

    服务端响应示例

    {
      "time": 1611541000,
      "channel": "spot.orders",
      "event": "subscribe",
      "error": null,
      "result": {
        "status": "success"
      }
    }
    

    服务端响应包括对 客户端请求的响应 和 服务端发起的更新消息通知。 与请求类似,服务端响应与客户端请求格式都是几乎相同的 JSON 格式:

    字段 类型 描述
    time Integer 精确到秒的响应时间
    id Integer 从客户端请求 payload 中提取的请求 ID (如果请求参数中有的话)
    channel String WebSocket 频道名称
    event String 服务端频道事件(即,update)或 用于从客户端发起的请求的 event
    error Error 如果服务端正常接受客户端的请求,则返回为空;否则,返回请求被拒绝的详情。
    result Any 返回来自服务端的新数据通知 或 对客户端请求的响应。如果有错误返回则 error 不为空,没有错误则此字段为空。

    注意:如果它是服务端发起的数据更新通知 那么 result 的类型是基于 channel 的,不同 channel 的 result 类型有所不同。

    但如果是对客户端订阅请求的响应,那么 result 为固定的 {"status": "success"}。 验证订阅请求是否成功,您只需要检查 error 字段是否为空即可,不需要再解析 result 字段。

    为了简单起见,下面的频道(channel)描述只给出对应频道的 payload 格式。

    # Error

    错误对象的格式如下:

    字段 类型 描述
    code Integer 错误码
    message String 错误详情描述

    请求异常时,服务端返回的消息会包含一个 error 对象,包括对应的错误码和具体的错误信息:

    code message
    1 Invalid request body format(无效请求格式)
    2 Invalid argument provided(提供的参数无效)
    3 Server side error happened.(服务端发生异常)

    # 鉴权

    WARNING

    注意:您使用的 GateAPIv4 密钥对至少开了 spot(现货) read(读)权限, 如果启用密钥白名单,则您的出方向 IP 地址必须在密钥的 IP 白名单中。

    # 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': 'spot.orders',
        'event': 'subscribe',
        'payload': ["BTC_USDT", "GT_USDT"]
    }
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    print(json.dumps(request))
    

    如果频道是私有的,例如 spot.orders 频道用于获取用户订单更新,那么客户端请求需要携带身份验证信息。

    身份验证由请求体中的 auth 字段发送,格式如下:

    字段 类型 描述
    method String 身份验证方法。目前只接受一个方法 api_key
    KEY String Gate APIv4 用户 key 字符串
    SIGN String 使用 GateAPIv4 secret 和请求信息生成的认证签名

    WebSocket 认证使用与 Gate APIv4 API 相同的签名计算方法,即: HexEncode(HMAC_SHA512(secret, signature_string)),但有以下区别:

    1. 签名字符串连接方法: channel=<channel>&event=<event>&time=<time>, 这里的 <channel>, <event>, <time> 对应的请求信息
    2. 身份验证信息在 auth 字段的请求主体中发送。

    您可以登录到控制台查看 Gate APIv4 密钥和秘密.

    # System API

    系统 API 用于检索服务元信息,用于订阅。

    # 应用层 ping/pong 消息

    spot.ping

    代码示例

    import time
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send('{"time": %d, "channel" : "spot.ping"}' % int(time.time()))
    print(ws.recv())
    

    响应示例

    {
      "time": 1545404023,
      "channel": "spot.pong",
      "event": "",
      "error": null,
      "result": null
    }
    

    检查与服务器的连接是否仍然存活。

    这是一种额外的连接可达性检查。服务器使用协议层的 ping/pong (opens new window) 消息来检查客户端是否仍然连接。它不强制要求使用这种方法。如果您使用一些知名的 WebSocket 客户端库,通常不需要关心这个 API。

    然而,从客户端的角度来看,这个 API 可以帮助客户端主动检查与服务器的连接是否仍然可达。此外,如果服务器接收到客户端的spot.ping 请求,它还将重置客户端的超时计时器。

    TIP

    此频道不需要身份验证

    # Tickers 频道

    spot.tickers

    更新速度: 1000ms

    Ticker 是对现货交易状态的高级概览。它显示了最高、最低和最后的交易价格。它还包括每日成交量以及价格在过去一天内的变化情况等信息。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.tickers",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 货币对列表

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606291803,
      "channel": "spot.tickers",
      "event": "update",
      "result": {
        "currency_pair": "BTC_USDT",
        "last": "19106.55",
        "lowest_ask": "19108.71",
        "highest_bid": "19106.55",
        "change_percentage": "3.66",
        "base_volume": "2811.3042155865",
        "quote_volume": "53441606.52411221454674732293",
        "high_24h": "19417.74",
        "low_24h": "18434.21"
      }
    }
    

    通知结果格式:

    字段 类型 描述
    result Object Ticker 对象
    » currency_pair String 货币对
    » last String 最新成交价
    » lowest_ask String 卖方最低价
    » highest_bid String 买方最高价
    » change_percentage String 涨跌百分比,跌用负数标识,如 -7.45
    » base_volume String 交易货币成交量
    » quote_volume String 计价货币成交量
    » high_24h String 24 小时最高价
    » low_24h String 24 小时最低价

    # 公共成交频道

    spot.trades

    更新速度: 实时

    该频道在每次发生交易时发送交易消息。它包括交易的详细信息,如价格、数量、时间和类型。

    只有吃单方会被通知。

    请注意,这是一个公共频道。对于私有交易通知,请参阅下面的 用户私有成交 部分。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.trades",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 货币对列表

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606292218,
      "channel": "spot.trades",
      "event": "update",
      "result": {
        "id": 309143071,
        "create_time": 1606292218,
        "create_time_ms": "1606292218213.4578",
        "side": "sell",
        "currency_pair": "GT_USDT",
        "amount": "16.4700000000",
        "price": "0.4705000000",
        "range": "2390902-2390902"
      }
    }
    

    请注意,公共交易频道只通知交易中的吃单方。下面的私有用户交易频道将通知所有与用户相关的交易。

    通知结果格式:

    字段 类型 描述
    result Object 公共成交详情
    » id Integer 成交 ID
    » create_time Integer 成交时间,精确到秒
    » create_time_ms String 成交时间,毫秒精度
    » side String 买单或者卖单
    » currency_pair String 交易货币对
    » amount String 交易数量
    » price String 交易价
    » range String 成交范围(格式: "开始 ID-结束 ID")

    # 字段数据枚举

    Property Value
    side buy
    side sell

    # K 线频道

    spot.candlesticks

    更新速度: 2000ms

    提供 K 线 信息订阅。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.candlesticks",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["1m", "BTC_USDT"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 订阅参数。从左到右是 interval, cp
    » interval String K 线数据点间隔时间
    » cp String 交易货币对

    # 字段数据枚举

    Property Value
    interval 10s
    interval 30s
    interval 1m
    interval 3m
    interval 5m
    interval 15m
    interval 30m
    interval 1h
    interval 2h
    interval 4h
    interval 6h
    interval 8h
    interval 12h
    interval 1d
    interval 7d
    interval 30d

    要订阅多个货币对或具有不同时间间隔的数据,只需发送多个带有不同参数的订阅请求即可。

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606292600,
      "channel": "spot.candlesticks",
      "event": "update",
      "result": {
        "t": "1606292580",
        "v": "2362.32035",
        "c": "19128.1",
        "h": "19128.1",
        "l": "19128.1",
        "o": "19128.1",
        "n": "1m_BTC_USDT",
        "a": "3.8283",
        "w": true
      }
    }
    

    通知结果格式:

    字段 类型 描述
    result Object K 线数
    »t String Unix 时间戳,精确到秒
    »v String 交易量,只有市场行情的 K 线数据里有该值
    »c String 收盘价
    »h String 最高价
    »l String 最低价
    »o String 开盘价
    »n String 订阅名称,格式为 <interval>_<cp>
    »a String 基础货币交易金额
    »w Boolean true 表示窗口已关闭。注:可能会缺失 true 的消息,但不影响数据的完整性

    # 订单簿/深度频道

    深度有 3 个订阅频道,分别满足不同的需求。它们是:

    • spot.book_ticker

      及时推送订阅货币对的最优卖/买(ask/bid)单。

    • spot.order_book_update

      定时推送 深度增量更新数据,可用于维护本地深度。

    • spot.order_book

      基于订阅的 level,定时推送深度全量更新

    每个货币对的深度更新都有一个内部更新 ID,该 ID 在每个订单成交后递增 1。深度更新 ID 对应于 REST API 的 GET /api/v4/spot/order_book 响应中的ID 字段。

    如何维护本地订单簿/深度:

    1. 以指定的 level 和更新频率订阅 spot.order_book_update。 例如 ["BTC_USDT", "1000ms", "10"] 每 1s 推送 BTC_USDT 订单簿/深度的前 10 个的更新。

    2. 缓存 WebSocket 通知。每个通知用 Uu 来分别标识自上条通知的起始 ID 和最新 ID。

    3. 使用 REST API 获取基础订单簿/深度,并确保订单簿/深度 ID 被记录(下面称为baseID)

      例如使用:https://api.gateio.ws/api/v4/spot/order_book?currency_pair=BTC_USDT&limit=100&with_id=true 获取 10 个 BTC_USDT 基础深度。

    4. 迭代缓存的 WebSocket 通知,然后找到第一个包含 baseID 的, 例如U <= baseId+1u >= baseId+1,然后开始消费通知。注意 size 在通知里都是绝对值。 使用他们替换对应价格 price 中的原始 size。 如果 size 等于 0,从订单簿/深度中删除价格。

    5. 转储所有满足要求的通知 u < baseID+1。 如果 baseID+1 < first notification U,那将 意味着当前基础深度已经落后当前的通知。从第三步重新开始获取最新的基础深度。

    6. 如其后有发现任何满足 U > baseID+1的通知,那意味着一些更新通知丢失。需要从第三步开始重构本地深度。

    SDK GitHub repository (opens new window) 中可以找到实现上述方法的示例的应用程序

    # 最优买卖价

    spot.book_ticker

    更新速度: 每 10ms

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.book_ticker",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 交易货币对列表

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606293275,
      "channel": "spot.book_ticker",
      "event": "update",
      "result": {
        "t": 1606293275123,
        "u": 48733182,
        "s": "BTC_USDT",
        "b": "19177.79",
        "B": "0.0003341504",
        "a": "19179.38",
        "A": "0.09"
      }
    }
    

    通知结果格式:

    字段 类型 描述
    result Object Order book ticker object
    » t Integer 深度更新毫秒时间戳
    » u Integer 深度更新 ID
    » s String 货币对
    » b String 最优买单价
    » B String 最优买单数量
    » a String 最优卖单价
    » A String 最优卖单数量

    # 深度增量更新频道

    spot.order_book_update

    更新速度: 1000ms 或 100ms

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.order_book_update",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT", "100ms"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 订阅参数,从左到右是 cpinterval
    » cp String 货币对
    » interval String 通知更新速度

    # 字段枚举值

    Property Value
    interval 100ms
    interval 1000ms

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606294781,
      "time_ms": 1606294781236,
      "channel": "spot.order_book_update",
      "event": "update",
      "result": {
        "t": 1606294781123,
        "e": "depthUpdate",
        "E": 1606294781,
        "s": "BTC_USDT",
        "U": 48776301,
        "u": 48776306,
        "b": [
          ["19137.74", "0.0001"],
          ["19088.37", "0"]
        ],
        "a": [["19137.75", "0.6135"]]
      }
    }
    

    通知结果格式:

    字段 类型 描述
    result Object 自从上次更新变化后的卖买单列表(asks/bids)
    » t Integer 深度更新变化毫秒时间戳
    » e String 忽略这个参数
    » E Integer 深度更新时间戳(精确到秒).已经弃用,建议使用 t 字段
    » s String 货币对
    » U Integer 自动上次深度后的第一个深度 ID
    » u Integer 自动上次深度后的最新深度 ID
    » b Array[OrderBookArray] 自上次更新以来的 bids 更新,按价格从高到低排序
    »» OrderBookArray Array[String] [Price, Amount] 数组对
    » a Array[OrderBookArray] 自上次更新以来的 asks 更新,按价格从地到高排序
    »» OrderBookArray Array[String] [Price, Amount] 数组对

    # 深度全量更新频道

    spot.order_book

    更新速度: 1000ms 或 100ms

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    ws.send(json.dumps({
        "time": int(time.time()),
        "channel": "spot.order_book",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT", "5", "100ms"]
    }))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 订阅参数,从左到右分别是 cp, level, interval
    » cp String 货币对
    » level String 深度长度
    » interval String 通知更新速度

    # 字段枚举值

    Property Value
    level 5
    level 10
    level 20
    level 30
    level 50
    level 100
    interval 100ms
    interval 1000ms

    TIP

    此频道不需要身份验证

    # 服务端推送

    通知示例:

    {
      "time": 1606295412,
      "time_ms": 1606295412213,
      "channel": "spot.order_book",
      "event": "update",
      "result": {
        "t": 1606295412123,
        "lastUpdateId": 48791820,
        "s": "BTC_USDT",
        "bids": [
          ["19079.55", "0.0195"],
          ["19079.07", "0.7341"],
          ["19076.23", "0.00011808"],
          ["19073.9", "0.105"],
          ["19068.83", "0.1009"]
        ],
        "asks": [
          ["19080.24", "0.1638"],
          ["19080.91", "0.1366"],
          ["19080.92", "0.01"],
          ["19081.29", "0.01"],
          ["19083.8", "0.097"]
        ]
      }
    }
    

    通知结果格式:

    字段 类型 描述
    result Object Order book levels
    » t Integer 深度更新毫秒时间戳
    » lastUpdateId Integer 深度副本当前的深度 ID
    » s String 货币对
    » bids Array[OrderBookArray] 在当前快照的 顶层 bids(买单) 数据,按价格从高到低排序
    »» OrderBookArray Array[String] [Price, Amount] 数组对
    » asks Array[OrderBookArray] 在当前快照的 顶层 asks(卖单) 数据,按价格从低到高排序
    »» OrderBookArray Array[String] [Price, Amount] 数组对

    # 订单频道

    spot.orders

    更新速度: 实时

    通知已订阅货币对中创建的订单的更改,包括订单创建、成交、关闭和取消。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.orders",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT"]
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 货币对列表

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    如果你想订阅全部货币对订单更新,你可以使用!all来作为货币对列表参数。

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1694655225,
      "time_ms": 1694655225315,
      "channel": "spot.orders",
      "event": "update",
      "result": [
        {
          "id": "399123456",
          "text": "t-testtext",
          "create_time": "1694655225",
          "update_time": "1694655225",
          "currency_pair": "BTC_USDT",
          "type": "limit",
          "account": "spot",
          "side": "sell",
          "amount": "0.0001",
          "price": "26253.3",
          "time_in_force": "gtc",
          "left": "0.0001",
          "filled_total": "0",
          "avg_deal_price": "0",
          "fee": "0",
          "fee_currency": "USDT",
          "point_fee": "0",
          "gt_fee": "0",
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "create_time_ms": "1694655225315",
          "update_time_ms": "1694655225315",
          "user": 3497082,
          "event": "put",
          "stp_id": 0,
          "stp_act": "-",
          "finish_as": "open",
          "biz_info": "-",
          "amend_text": "-"
        }
      ]
    }
    

    更新的订单列表。请注意,可能会在一条通知中更新多个货币对的订单。

    通知结果格式:

    字段 类型 描述
    result Array[Object] 更新订单列表
    » id String 订单 ID
    » user Integer 用户 ID
    » text String 用户自定义订单信息
    » create_time String 订单创建时间,精确到秒
    » create_time_ms String 订单创建时间,精确到毫秒
    » update_time String 订单最新更新时间,精确到秒
    » update_time_ms String 订单最新更新时间,精确到毫秒
    » event String 订单事件
    - put: 订单创建
    - update: 订单成交更新
    - finish: 订单关闭或者取消
    » currency_pair String 交易货币对
    » type String 订单类型. limit - 限价单
    » account String 账户类型. spot - 现货账户; margin - 杠杆账户;cross_margin - 全仓杠杆账户
    » side String 买单或者卖单
    » amount String 交易数量
    » price String 交易价
    » time_in_force String Time in force 策略。
    - gtc: GoodTillCancelled
    - ioc: ImmediateOrCancelled ,立即成交或者取消,只吃单不挂单
    - poc: PendingOrCancelled,被动委托,只挂单不吃单
    » left String 交易货币未成交数量
    » filled_total String 已成交总金额
    »avg_deal_price String 订单成交均价
    » fee String 成交扣除的手续费
    » fee_currency String 手续费计价单位
    » point_fee String 手续费抵扣使用的点卡数量
    » gt_fee String 手续费抵扣使用的 GT 数量
    » gt_discount Boolean 是否开启 GT 抵扣
    » rebated_fee String 返还的手续费
    » rebated_fee_currency String 返还手续费计价单位
    »auto_repay Boolean 启用或禁用跨保证金订单生成的自动借贷的自动还款功能。默认情况下禁用。请注意以下事项:
    1. 该字段仅对跨保证金订单有效。保证金账户不支持为订单设置自动还款
    2. auto_borrowauto_repay 不能同时在同一订单中设置为 true.
    »auto_borrow Boolean 在杠杆或全仓杠杆交易中使用,以允许在余额不足时自动借入足够的金额
    »stp_id Integer 具有相同stp_id组的用户之间的订单不允许自成交。有关详细信息,请参阅 ApiV4。
    »stp_act String 自成交预防操作。用户可以使用此字段设置自成交预防策略。
    »finish_as String 订单的完成状态说明如下.
    - open:正在处理
    - filled:完全成交
    - cancelled:手动取消
    - ioc:时效性为IOC,立即完成
    - stp:因自成交预防而取消
    »amend_text String 用户在修改订单时添加的自定义数据。

    # 字段枚举值

    Property Value
    类型 limit
    类型 market
    类型 limit_repay
    类型 market_repay
    类型 limit_borrow
    类型 market_borrow
    类型 limit_borrow_repay
    account spot
    account margin
    account portfolio
    side buy
    side sell
    time_in_force gtc
    time_in_force ioc
    time_in_force poc

    # 用户私有成交频道

    spot.usertrades

    更新速度: 实时

    通知用户在指定货币对中的个人交易。与spot.trades 频道不同,这是一个私有频道,并通知与用户相关的所有交易,不论交易角色(Maker/Taker)如何。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.usertrades",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload": ["BTC_USDT"]
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    订阅参数格式:

    字段 类型 必选 描述
    payload Array[String] 货币对列表

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    如果你想订阅全部用户合约成交更新,你可以使用 !all 来作为合约列表参数。

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1605176741,
      "channel": "spot.usertrades",
      "event": "update",
      "result": [
        {
          "id": 5736713,
          "user_id": 1000001,
          "order_id": "30784428",
          "currency_pair": "BTC_USDT",
          "create_time": 1605176741,
          "create_time_ms": "1605176741123.456",
          "side": "sell",
          "amount": "1.00000000",
          "role": "taker",
          "price": "10000.00000000",
          "fee": "0.00200000000000",
          "point_fee": "0",
          "gt_fee": "0",
          "text": "apiv4"
        }
      ]
    }
    

    更新的用户交易列表。请注意,可能会在一条通知中更新多个货币对的交易。

    通知结果格式:

    字段 类型 描述
    result Array[UserTrade] Updated user trades list
    » id Integer 成交 ID
    » user_id Integer 用户 ID
    » order_id String 关联的订单 ID
    » currency_pair String 交易货币对
    » create_time Integer 成交时间,精确到秒
    » create_time_ms String 成交时间,毫秒精度
    » side String 买单或者卖单
    » amount String 交易数量
    » role String 交易角色 (maker/taker)
    » price String 交易价
    » fee String 成交扣除的手续费
    » fee_currency String 手续费计价单位
    » point_fee String 手续费抵扣使用的点卡数量
    » gt_fee String 手续费抵扣使用的 GT 数量
    » text String 用户自定义信息

    # 字段枚举值

    Property Value
    side buy
    side sell
    role maker
    role taker

    # 现货余额频道

    spot.balances

    更新速度: 实时

    通知用户现货账户余额更新

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.balances",
        "event": "subscribe",  # "unsubscribe" for unsubscription
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    不需要 payload

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1605248616,
      "time_ms": 1605248616763,
      "channel": "spot.balances",
      "event": "update",
      "result": [
        {
          "timestamp": "1667556323",
          "timestamp_ms": "1667556323730",
          "user": "1000001",
          "currency": "USDT",
          "change": "0",
          "total": "222244.3827652",
          "available": "222244.3827",
          "freeze": "5",
          "freeze_change": "5.000000",
          "change_type": "order-create"
        }
      ]
    }
    

    通知结果格式:

    字段 类型 描述
    result Array[SpotBalance] 新的余额更新列表
    » timestamp String 余额更新时间戳戳,精确到秒
    » timestamp_ms String 余额更新时间戳戳,精确到毫秒
    » user String 用户 ID
    » currency String 变更的货币
    » change String 变更数量
    » total String 总现货余额
    » available String 可用现货余额
    »freeze String 冻结余额数量
    »freeze_change String 余额锁定的变动金额
    »change_type String 余额变动类型
    - withdraw
    - deposit
    - trade-fee-deduct
    - order-create: 订单创建
    - order-match: 订单成交更新
    - order-update: 取消订单或修改订单
    - margin-transfer
    - future-transfer
    - cross-margin-transfer
    - other

    # 保证金余额频道

    spot.margin_balances

    更新速度: 实时

    通知用户保证金余额更新。任何保证金资金的存入或借款都将生成新的通知。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.margin_balances",
        "event": "subscribe",  # "unsubscribe" for unsubscription
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    不需要 payload

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1605248616,
      "channel": "spot.margin_balances",
      "event": "update",
      "result": [
        {
          "timestamp": "1605248812",
          "timestamp_ms": "1605248812123",
          "user": "1000001",
          "currency_pair": "BTC_USDT",
          "currency": "BTC",
          "change": "-0.002",
          "available": "999.999836",
          "freeze": "1",
          "borrowed": "0",
          "interest": "0"
        }
      ]
    }
    

    通知结果格式:

    字段 类型 描述
    result Array[MarginBalance] 保证金余额更新列表
    » timestamp String 保证金更新时间戳戳,精确到秒
    » timestamp_ms String 保证金更新时间戳戳,精确到毫秒
    » user String 用户 ID
    » currency_pair String 货币对
    » currency String 变化货币
    » change String 变更数量
    » available String 可用保证金余额
    » freeze String 锁定的金额,例如用于资金账簿
    » borrowed String 借贷总额
    » interest String 借款未付利息总额

    # 借贷余额频道

    spot.funding_balances

    更新速度: 实时

    通知用户资金余额更新,包括新的借贷贷款的创建、取消或被他人借用。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.funding_balances",
        "event": "subscribe",  # "unsubscribe" for unsubscription
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    不需要 payload

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1605248616,
      "channel": "spot.funding_balances",
      "event": "update",
      "result": [
        {
          "timestamp": "1605248616",
          "timestamp_ms": "1605248616123",
          "user": "1000001",
          "currency": "USDT",
          "change": "100",
          "freeze": "100",
          "lent": "0"
        }
      ]
    }
    

    通知结果格式:

    字段 类型 描述
    result Array[FundingBalance] 借贷余额更新列表
    » timestamp String 更新时间戳,精确到秒
    » timestamp_ms String 更新时间戳,精确到毫秒
    » user String 用户 ID
    » currency String 变更货币
    » change String 变更数量
    » freeze String 锁定的金额,例如用于资金账簿
    » lent String 贷出款额

    # 全仓杠杆余额频道

    spot.cross_balances

    更新速度: 实时

    通知用户全仓杠杆账户余额更新

    注意,未完成的订单在部分或全部完成之前不会触发余额更新。

    # 客户端订阅

    代码示例:

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.cross_balances",
        "event": "subscribe",  # "unsubscribe" for unsubscription
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    不需要 payload

    WARNING

    需要认证

    # 服务端推送

    通知示例:

    {
      "time": 1605248616,
      "time_ms": 1605248616763,
      "channel": "spot.cross_balances",
      "event": "update",
      "result": [
        {
          "timestamp": "1605248616",
          "timestamp_ms": "1605248616123",
          "user": "1000001",
          "currency": "USDT",
          "change": "100",
          "total": "1032951.325075926",
          "available": "1022943.325075926",
          "freeze": "0",
          "freeze_change": "0",
          "change_type": "cross-margin-transfer"
        }
      ]
    }
    

    通知结果格式:

    字段 类型 描述
    result Array[SpotBalance] 余额更新列表
    » timestamp String 更新时间戳,精确到秒
    » timestamp_ms String 更新时间戳,精确到毫秒
    » user String 用户 ID
    » currency String 变更货币
    » change String 变更数量
    » total String 总现货余额
    » available String 可用余额
    »freeze String 冻结余额数量
    »freeze_change String 余额锁定的变动金额
    »change_type String 余额变动类型
    - withdraw
    - deposit
    - trade-fee-deduct
    - order-create: 订单创建
    - order-match: 订单成交更新
    - order-update: 取消订单或修改订单
    - margin-transfer
    - future-transfer
    - cross-margin-transfer
    - other

    # 全仓保证金借贷频道 (废弃)

    spot.cross_loan

    更新速度: 实时

    此频道已被弃用,因为数据已过时

    通知用户交叉保证金借款和利息更新

    任何交叉保证金借款或还款操作都会生成新的通知。

    1. 如果发生贷款或还款操作,将同时通知此频道和spot.cross_balances(余额变动)频道,但spot.cross_balances 频道通知只包含余额变动(没有贷款信息),而此频道通知将包含余额、已借金额和利息信息。
    2. 此频道仅在发生贷款或还款时通知,如果只有交易发生,此频道不会通知。

    # 客户端订阅

    代码示例

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.cross_loan",
        "event": "subscribe",  # "unsubscribe" for unsubscription
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    不需要 payload

    WARNING

    需要认证

    # 服务端推送

    推送示例

    {
      "time": 1658289372,
      "time_ms": 1658289372763,
      "channel": "spot.cross_loan",
      "event": "update",
      "result": {
        "timestamp": 1658289372338,
        "user": "1000001",
        "currency": "BTC",
        "change": "0.01",
        "total": "4.992341029566",
        "available": "0.078054772536",
        "borrowed": "0.01",
        "interest": "0.00001375"
      }
    }
    

    推送格式:

    字段 类型 描述
    result Object 新的全仓保证金借款和利息更新消息
    »timestamp int64 秒级时间戳
    »user String 用户 ID
    »currency String 变更的货币
    »change String 变更数量
    »total String 总现货余额
    »available String 可用余额
    »borrowed String 已借金额
    »interest String 从借款产生的未付利息总额

    # 自动订单频道

    spot.priceorders

    更新速度: 实时

    通知用户自动订单的更新。

    # 客户端订阅

    代码示例

    import time
    import json
    
    # pip install websocket_client
    from websocket import create_connection
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    request = {
        "time": int(time.time()),
        "channel": "spot.priceorders",
        "event": "subscribe",  # "unsubscribe" for unsubscription
        "payload" : ["!all"],
    }
    # refer to Authentication section for gen_sign implementation
    request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
    ws.send(json.dumps(request))
    print(ws.recv())
    

    Payload 格式:

    字段 类型 必选 描述
    payload Array[String] List of currency pairs

    您可以多次订阅/取消订阅。除非明确取消订阅,否则之前订阅的货币对不会被覆盖。

    如果你想订阅全部货币对订单更新,你可以使用!all来作为货币对列表参数。

    WARNING

    需要认证

    # 服务端推送

    推送示例

    {
      "time": 1691847986,
      "time_ms": 1691847986454,
      "channel": "spot.priceorders",
      "event": "update",
      "result": {
        "market": "METAN_USDT",
        "uid": "13679450",
        "id": "247480109",
        "currency_type": "METAN",
        "exchange_type": "USDT",
        "reason": "",
        "err_msg": "",
        "fired_order_id": 0,
        "instant_cancel": false,
        "trigger_price": "0.00302",
        "trigger_rule": "<=",
        "trigger_expiration": 900,
        "price": "0.00300",
        "amount": "26666.667",
        "source": "",
        "order_type": "limit",
        "side": "buy",
        "engine_type": "normal",
        "is_stop_order": false,
        "stop_trigger_price": "",
        "stop_trigger_rule": "",
        "stop_price": "",
        "ctime": "1691517983131",
        "ftime": "1691517983131"
      }
    }
    

    推送格式:

    字段 类型 描述
    result Object
    »market String 市场名称
    »uid String 用户 ID
    »id String 订单 id
    »currency_type String 货币类型
    »exchange_type String 交易货币类型
    »reason String 订单结束的附加描述信息
    »err_msg String 错误信息
    »fired_order_id int 触发后委托单 ID
    »instant_cancel bool 是否即时取消
    »trigger_price String 触发价格
    »trigger_rule String 触发规则
    »trigger_expiration int 触发最长等待触发时间,超时则取消该订单,单位是秒 s
    »price String 挂单价格
    »amount String 挂单数量
    »source String source
    »order_type String 订单类型,目前默认为限价单
    »side String 买卖方向
    - buy: 买
    - sell: 卖
    »engine_type String 引擎类型
    »is_stop_order bool 是否为止损单
    »stop_trigger_price String 触发价格
    »stop_trigger_rule String 触发规则
    »stop_price String 止损价格
    »ctime String 创建时间
    »ftime String 结束时间

    # 现货账户交易

    # Websocket API

    WebSocket API 允许通过 WebSocket 连接下单、取消、修改和查询订单。

    # Websocket API 客户端 API 请求

    客户端请求示例

    
    package main
    
    import (
    	"crypto/hmac"
    	"crypto/sha512"
    	"crypto/tls"
    	"encoding/hex"
    	"encoding/json"
    	"fmt"
    	"github.com/gorilla/websocket"
    	"net/url"
    	"strconv"
    	"time"
    )
    
    func GetApiSignature(secret, channel string, requestParam []byte, ts int64) string {
    	hash := hmac.New(sha512.New, []byte(secret))
    	key := fmt.Sprintf("%s\n%s\n%s\n%d", "api", channel, string(requestParam), ts)
    	hash.Write([]byte(key))
    	return hex.EncodeToString(hash.Sum(nil))
    }
    
    func main() {
    
    	// 1. login
    	apiKey := "xxxxx"
    	secret := "xxxxx"
    	requestParam := ""
    	channel := "spot.login"
    	ts := time.Now().Unix()
    	requestId := fmt.Sprintf("%d-%d", time.Now().UnixMilli(), 1)
    
    	req := ApiRequest{
    		Time:    ts,
    		Channel: "spot.login",
    		Event:   "api",
    		Payload: ApiPayload{
    			ApiKey:       apiKey,
    			Signature:    GetApiSignature(secret, channel, []byte(requestParam), ts),
    			Timestamp:    strconv.FormatInt(ts, 10),
    			RequestId:    requestId,
    			RequestParam: []byte(requestParam),
    		},
    	}
    
    	fmt.Println(GetApiSignature(secret, channel, []byte(requestParam), ts))
    	marshal, _ := json.Marshal(req)
    	fmt.Println(string(marshal))
    
    	// connect the ws
    	u := url.URL{Scheme: "ws", Host: "xx.xx.xxx.xx:xxx", Path: "xxx"}
    	websocket.DefaultDialer.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
    	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    	if err != nil {
    		panic(err)
    	}
    	c.SetPingHandler(nil)
    
    	// read msg
    	go func() {
    		for {
    			_, message, err := c.ReadMessage()
    			if err != nil {
    				c.Close()
    				panic(err)
    			}
    			fmt.Printf("recv: %s\n", message)
    		}
    	}()
    
    	err = c.WriteMessage(websocket.TextMessage, marshal)
    
    	//ws create an order
    	orderParam := orderParam{
    		Text:         "t-123456",
    		CurrencyPair: "ETH_BTC",
    		Type:         "limit",
    		Account:      "spot",
    		Side:         "buy",
    		Iceberg:      "0",
    		Amount:       "1",
    		Price:        "5.00032",
    		TimeInForce:  "gtc",
    		AutoBorrow:   false,
    		StpAct:       "cn",
    	}
    	orderParamBytes, _ := json.Marshal(orderParam)
    
    	//warn: if you want create batch_orders, the `RequestParam` : []byte([{orderParam},{orderParam},...])
    	order_place := ApiRequest{
    		Time:    ts,
    		Channel: "spot.order_place",
    		Event:   "api",
    		Payload: ApiPayload{
    			RequestId:    requestId,
    			RequestParam: []byte(orderParamBytes),
    		},
    	}
    	orderReqByte, _ := json.Marshal(order_place)
    	err = c.WriteMessage(websocket.TextMessage, orderReqByte)
    
    	if err != nil {
    		panic(err)
    	}
    
    	select {}
    }
    
    type ApiRequest struct {
    	App     string     `json:"app,omitempty"`
    	Time    int64      `json:"time"`
    	Id      *int64     `json:"id,omitempty"`
    	Channel string     `json:"channel"`
    	Event   string     `json:"event"`
    	Payload ApiPayload `json:"payload"`
    }
    type ApiPayload struct {
    	ApiKey       string          `json:"api_key,omitempty"`
    	Signature    string          `json:"signature,omitempty"`
    	Timestamp    string          `json:"timestamp,omitempty"`
    	RequestId    string          `json:"req_id,omitempty"`
    	RequestParam json.RawMessage `json:"req_param,omitempty"`
    }
    
    type OrderParam struct {
    	Text         string `json:"text,omitempty"`
    	CurrencyPair string `json:"currency_pair,omitempty"`
    	Type         string `json:"type,omitempty"`
    	Account      string `json:"account,omitempty"`
    	Side         string `json:"side,omitempty"`
    	Iceberg      string `json:"iceberg,omitempty"`
    	Amount       string `json:"amount,omitempty"`
    	Price        string `json:"price,omitempty"`
    	TimeInForce  string `json:"time_in_force,omitempty"`
    	AutoBorrow   bool   `json:"auto_borrow,omitempty"`
    	StpAct       string `json:"stp_act,omitempty"`
    }
    
    

    客户端发起的api请求遵循通用的 JSON 格式,包含以下字段:

    字段 类型 必选 描述
    time Integer 请求时间(以秒为单位)。请求时间和服务器时间之间的差距不得超过 60 秒
    id Integer 可选的请求 ID,服务器将回传该 ID,以帮助您识别服务器响应的是哪个请求
    channel String WebSocket 要订阅的频道
    event String 固定为"api"
    payload Object 可选的请求详细参数
    »req_id String 由客户端提供的消息的唯一标识符。它将在响应消息中返回,用于识别相应的请求。
    »req_param []Byte 请求的 API 参数

    请注意,payload.req_param的类型与频道相关。以spot.order_place为例,payload.req_param 与 apiv4 的 /spot/orders (opens new window)/spot/batch_orders (opens new window) 相同。 您可以参考例子使用示例在 GT_USDT 上下一个限价订单。

    # Websocket API 服务端推送

    服务端 ack 推送示例

    {
      "request_id": "request-2",
      "ack": true,
      "header": {
        "response_time": "1681985856667",
        "status": "200",
        "channel": "spot.order_place",
        "event": "api",
        "client_id": "::1-0x140033dc0c0"
      },
      "data": {
        "result": {
          "req_id": "request-2",
          "req_header": null,
          "req_param": {
            "text": "t-my-custom-id",
            "currency_pair": "GT_USDT",
            "type": "limit",
            "account": "spot",
            "side": "buy",
            "amount": "1",
            "price": "1"
          }
        }
      }
    }
    

    服务端 api 推送示例

    {
      "request_id": "request-2",
      "header": {
        "response_time": "1681986204784",
        "status": "200",
        "channel": "spot.order_place",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "id": "1700664330",
          "text": "t-my-custom-id",
          "amend_text": "-",
          "create_time": "1681986204",
          "update_time": "1681986204",
          "create_time_ms": 1681986204832,
          "update_time_ms": 1681986204832,
          "status": "open",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "1",
          "time_in_force": "gtc",
          "iceberg": "0",
          "left": "1",
          "fill_price": "0",
          "filled_total": "0",
          "fee": "0",
          "fee_currency": "GT",
          "point_fee": "0",
          "gt_fee": "0",
          "gt_maker_fee": "0.0015",
          "gt_taker_fee": "0.0015",
          "gt_discount": true,
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "stp_id": 1,
          "stp_act": "cn",
          "finish_as": "open"
        }
      }
    }
    

    服务器响应包括对客户端请求的确认响应和 API 结果的回调消息更新。 服务器响应遵循通用的 JSON 格式,包含以下字段:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。
    如果"ack"为 false,这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 如果这是一个"ack"响应,那么"result"是请求的有效载荷(payload),否则"result"是 API 的响应。
    »errs Object 这只在请求失败时可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误消息详情

    # Error

    Error 推送示例

    {
      "request_id": "xxxx",
      "ack": false,
      "header": {
        "response_time": "1677816784084",
        "status": "401",
        "channel": "spot.login",
        "event": "api",
        "client_id": "::1-0x14002ba2300"
      },
      "data": {
        "errs": {
          "label": "INVALID_KEY",
          "message": "Invalid key provided"
        }
      }
    }
    

    错误对象的格式如下:

    字段 类型 描述
    label String 以字符串格式表示错误类型
    message String 错误信息详情

    # Login

    ::: 警告: 注意:您使用的 GateAPIv4 密钥对必须具有相应的权限(例如,订单下单频道必须具有现货写入权限),并且如果启用了密钥的 IP 白名单,则您的出站 IP 地址必须在白名单中。 :::

    # Login 请求

    代码示例

    package main
    
    import (
    	"crypto/hmac"
    	"crypto/sha512"
    	"encoding/hex"
    	"encoding/json"
    	"fmt"
    	"strconv"
    	"time"
    )
    
    func GetApiSignature(secret, channel string, requestParam []byte, ts int64) string {
    	hash := hmac.New(sha512.New, []byte(secret))
    	key := fmt.Sprintf("%s\n%s\n%s\n%d", "api", channel, string(requestParam), ts)
    	hash.Write([]byte(key))
    	return hex.EncodeToString(hash.Sum(nil))
    }
    
    // example WebSocket signature calculation implementation in go
    func main() {
    	apiKey := "YOUR_API_KEY"
    	secret := "YOUR_API_SECRET"
    	requestParam := ""
    	channel := "spot.login"
    	ts := time.Now().Unix()
    	requestId := fmt.Sprintf("%d-%d", time.Now().UnixMilli(), 1)
    
    	req := ApiRequest{
    		Time:    ts,
    		Channel: "",
    		Event:   "api",
    		Payload: ApiPayload{
    			ApiKey:       apiKey,
    			Signature:    GetApiSignature(secret, channel, []byte(requestParam), ts),
    			Timestamp:    strconv.FormatInt(ts, 10),
    			RequestId:    requestId,
    			RequestParam: []byte(requestParam),
    		},
    	}
    
    	fmt.Println(GetApiSignature(secret, channel, []byte(requestParam), 1677813908) ==
    		"2a8d9735bc0fa5cc7db97841482f317b515663d2a666abe8518ab214efada11b3da77ddc1e5fde529d5f780efa3366e302f5e3d2f7670460ae115801442e7461")
    
    	marshal, _ := json.Marshal(req)
    	fmt.Println(string(marshal))
    
    	// connect ws service
    	u := url.URL{Scheme: "ws", Host: "xxxx", Path: "xxxx"}
    	websocket.DefaultDialer.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
    	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    	if err != nil {
    		panic(err)
    	}
    	c.SetPingHandler(nil)
    
    	// read msg
    	go func() {
    		for {
    			_, message, err := c.ReadMessage()
    			if err != nil {
    				c.Close()
    				panic(err)
    			}
    			fmt.Printf("recv: %s\n", message)
    		}
    	}()
    
    	err = c.WriteMessage(websocket.TextMessage, marshal)
    	if err != nil {
    		panic(err)
    	}
    
    	select {}
    }
    
    type ApiRequest struct {
    	App     string     `json:"app,omitempty"`
    	Time    int64      `json:"time"`
    	Id      *int64     `json:"id,omitempty"`
    	Channel string     `json:"channel"`
    	Event   string     `json:"event"`
    	Payload ApiPayload `json:"payload"`
    }
    type ApiPayload struct {
    	ApiKey       string          `json:"api_key,omitempty"`
    	Signature    string          `json:"signature,omitempty"`
    	Timestamp    string          `json:"timestamp,omitempty"`
    	RequestId    string          `json:"req_id,omitempty"`
    	RequestParam json.RawMessage `json:"req_param,omitempty"`
    }
    
    

    请求示例

    {
      "time": 1681984544,
      "channel": "spot.login",
      "event": "api",
      "payload": {
        "api_key": "ea83fad2604399da16bf97e6eea772a6",
        "signature": "6fa3824c8141f2b2283108558ec50966d7caf749bf04a3b604652325b50b47d2343d569d848373d58e65c49d9622ba2e73dc25797abef11c9f20c07da741591e",
        "timestamp": "1681984544",
        "req_id": "request-1"
      }
    }
    
    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)) ,但有以下不同之处:

    1. 签名字符串的连接方法:"<event>\n<channel>\n<req_param>\n<timestamp>" ,其中<event><channel><req_param><timestamp> 是对应的请求信息。
    2. login频道中的req_param始终为空字符串。
    3. 认证信息在请求体中以字段payload发送。

    # Login 推送

    Login 推送示例

    {
      "request_id": "request-1",
      "ack": false,
      "header": {
        "response_time": "1681985856666",
        "status": "200",
        "channel": "spot.login",
        "event": "api",
        "clientId": ""
      },
      "data": {
        "result": {
          "api_key": "ea83fad2604399da16bf97e6eea772a6",
          "uid": "110284739"
        }
      }
    }
    

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。
    如果"ack"为 false(false 该字段不会出现在响应中),这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 如果这是"ack"响应,则"result"是请求的有效载荷,否则"result"是 API 的响应
    »»api_key String 登录成功的 API 密钥
    »»uid String 登录用户 ID
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 下单

    spot.order_place

    您可以使用此频道和事件api下订单

    以下是 API 的功能:

    POST /spot/orders
    POST /spot/batch_orders
    

    # 下单请求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    placeParam = {"text":"t-my-custom-id","currency_pair":"GT_USDT","type":"limit","account":"spot","side":"buy","amount":"1","price":"1"}
    batchPlaceParam = [
                        {"text":"t-my-custom-id-1","currency_pair":"GT_USDT","type":"limit","account":"spot","side":"buy","amount":"1","price":"1"},
                        {"text":"t-my-custom-id-2","currency_pair":"GT_USDT","type":"limit","account":"spot","side":"buy","amount":"1","price":"1.1"}
                      ]
    
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    channel = "spot.order_place"
    
    // create a order
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            // create a order
            "req_param": placeParam
            // batch orders
            //"req_param": batchPlaceParam
        }
    }))
    
    for i in range(2):
        data = ws.recv()
        print("data: ", data)
    
    package main
    
    import (
    	"crypto/hmac"
    	"crypto/sha512"
    	"crypto/tls"
    	"encoding/hex"
    	"encoding/json"
    	"fmt"
    	"github.com/gorilla/websocket"
    	"net/url"
    	"strconv"
    	"time"
    )
    
    // example WebSocket create order in go
    func main() {
    
    	u := url.URL{Scheme: "ws", Host: "xxxx", Path: "xxx"}
    	websocket.DefaultDialer.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
    	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    	if err != nil {
    		panic(err)
    	}
    	c.SetPingHandler(nil)
    
    	// read msg
    	go func() {
    		for {
    			_, message, err := c.ReadMessage()
    			if err != nil {
    				c.Close()
    				panic(err)
    			}
    			fmt.Printf("recv: %s\n", message)
    		}
    	}()
    
    	// warn: before order, you should login first, pls refer to the channel `spot.login`;
    	// order_place
    	orderParam := OrderParam{
    		Text:         "t-123456",
    		CurrencyPair: "ETH_BTC",
    		Type:         "limit",
    		Account:      "spot",
    		Side:         "buy",
    		Iceberg:      "0",
    		Amount:       "1",
    		Price:        "5.00032",
    		TimeInForce:  "gtc",
    		AutoBorrow:   false,
    		StpAct:       "cn",
    	}
    	paramBytes, _ := json.Marshal(orderParam)
    	requestId := fmt.Sprintf("%d-%d", time.Now().UnixMilli(), 1)
    	order_place := ApiRequest{
    		Time:    time.Now().Unix(),
    		Channel: "spot.order_place",
    		Event:   "api",
    		Payload: ApiPayload{
    			RequestId:    requestId,
    			RequestParam: []byte(paramBytes),
    		},
    	}
    	orderPlaceReqByte, _ := json.Marshal(order_place)
    	err = c.WriteMessage(websocket.TextMessage, orderPlaceReqByte)
    
    	if err != nil {
    		panic(err)
    	}
    
    	select {}
    }
    
    type ApiRequest struct {
    	App     string     `json:"app,omitempty"`
    	Time    int64      `json:"time"`
    	Id      *int64     `json:"id,omitempty"`
    	Channel string     `json:"channel"`
    	Event   string     `json:"event"`
    	Payload ApiPayload `json:"payload"`
    }
    type ApiPayload struct {
    	ApiKey       string          `json:"api_key,omitempty"`
    	Signature    string          `json:"signature,omitempty"`
    	Timestamp    string          `json:"timestamp,omitempty"`
    	RequestId    string          `json:"req_id,omitempty"`
    	RequestParam json.RawMessage `json:"req_param,omitempty"`
    }
    
    type OrderParam struct {
    	Text         string `json:"text,omitempty"`
    	CurrencyPair string `json:"currency_pair,omitempty"`
    	Type         string `json:"type,omitempty"`
    	Account      string `json:"account,omitempty"`
    	Side         string `json:"side,omitempty"`
    	Iceberg      string `json:"iceberg,omitempty"`
    	Amount       string `json:"amount,omitempty"`
    	Price        string `json:"price,omitempty"`
    	TimeInForce  string `json:"time_in_force,omitempty"`
    	AutoBorrow   bool   `json:"auto_borrow,omitempty"`
    	StpAct       string `json:"stp_act,omitempty"`
    }
    

    请求参数示例

    下单

    {
      "time": 1681986203,
      "channel": "spot.order_place",
      "event": "api",
      "payload": {
        "req_id": "request-2",
        "req_param": {
          "text": "t-my-custom-id",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "1"
        }
      }
    }
    

    批量下单

    {
      "time": 1681986203,
      "channel": "spot.order_place",
      "event": "api",
      "payload": {
        "req_id": "request-2",
        "req_param": [
          {
            "text": "t-my-custom-id-1",
            "currency_pair": "GT_USDT",
            "type": "limit",
            "account": "spot",
            "side": "buy",
            "amount": "1",
            "price": "1"
          },
          {
            "text": "t-my-custom-id-2",
            "currency_pair": "GT_USDT",
            "type": "limit",
            "account": "spot",
            "side": "buy",
            "amount": "2",
            "price": "1"
          }
        ]
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的id不同
    req_param object API 订单模型的 JSON 字节数据,可以是包含 API 订单模型的数组;API 订单模型的详细信息请参考API (opens new window)
    req_header object apiv4 自定义 header

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    text string 订单自定义信息,用户可以用该字段设置自定义 ID,用户自定义字段必须满足以下条件:
    currency_pair string 交易货币对
    type object 订单类型
    account string 账户类型,spot - 现货账户,margin - 杠杆账户,cross_margin - 全仓杠杆账户,unified - 统一账户
    side string 买单或者卖单
    amount string 交易数量
    price string 交易价,type=limit时必填
    time_in_force object Time in force 策略。
    iceberg string 冰山下单显示的数量,不指定或传 0 都默认为普通下单。目前不支持全部冰山。
    auto_borrow string 杠杆(包括逐仓全仓)交易时,如果账户余额不足,是否由系统自动借入不足部分
    auto_repay string 全仓杠杆下单是否开启自动还款,默认关闭。需要注意的是:
    stp_act string Self-Trading Prevention Action,用户可以用该字段设置自定义限制自成交策略。

    # 详细描述

    text: 订单自定义信息,用户可以用该字段设置自定义 ID,用户自定义字段必须满足以下条件:

    • 必须以 t- 开头
    • 不计算 t- ,长度不能超过 28 字节
    • 输入内容只能包含数字、字母、下划线(_)、中划线(-) 或者点(.)
    • 不填,默认 apiv4-ws

    type: 订单类型

    • limit : 限价单
    • market : 市价单

    account: 账户类型,spot - 现货账户,margin - 杠杆账户,cross_margin - 全仓杠杆账户,unified - 统一账户 统一账户(旧)只能设置 cross_margin

    amount: 交易数量 typelimit时,指交易货币,即需要交易的货币,如BTC_USDT中指BTCtypemarket时,根据买卖不同指代不同

    • side : buy 指代计价货币,BTC_USDT中指USDT
    • side : sell 指代交易货币,BTC_USDT中指BTC

    time_in_force: Time in force 策略。

    • gtc: GoodTillCancelled
    • ioc: ImmediateOrCancelled,立即成交或者取消,只吃单不挂单
    • poc: PendingOrCancelled,被动委托,只挂单不吃单
    • fok: FillOrKill,全部成交或者全部取消 type=market时仅支持iocfok

    auto_repay: 全仓杠杆下单是否开启自动还款,默认关闭。需要注意的是:

    • 此字段仅针对全仓杠杆有效。逐仓杠杆不支持订单级别的自动还款设置,只能通过 POST /margin/auto_repay 修改用户级别的设置
    • auto_borrowauto_repay 不支持同时开启

    stp_act: Self-Trading Prevention Action,用户可以用该字段设置自定义限制自成交策略。

    • 用户在设置加入STP用户组后,可以通过传递 stp_act 来限制用户发生自成交的策略,没有传递 stp_act 默认按照 cn 的策略。

    • 用户在没有设置加入STP用户组时,传递 stp_act 参数会报错。

    • 用户没有使用 stp_act 发生成交的订单,stp_act 返回 -

    • cn: Cancel newest,取消新订单,保留老订单

    • co: Cancel oldest,取消⽼订单,保留新订单

    • cb: Cancel both,新旧订单都取消

    # Ack 推送

    单笔订单的 "ack" 推送示例

    {
      "request_id": "request-2",
      "ack": true,
      "header": {
        "response_time": "1681986203814",
        "status": "200",
        "channel": "spot.order_place",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "req_id": "request-2",
          "req_header": null,
          "req_param": {
            "text": "t-my-custom-id",
            "currency_pair": "GT_USDT",
            "type": "limit",
            "account": "spot",
            "side": "buy",
            "amount": "1",
            "price": "1"
          },
          "api_key": "",
          "timestamp": "",
          "signature": ""
        }
      }
    }
    

    订单数组的 "ack" 推送示例

    {
      "request_id": "xxxx",
      "ack": true,
      "header": {
        "response_time": "1677810708738",
        "status": "200",
        "channel": "spot.order_place",
        "event": "api",
        "client_id": "::1-0x140002f63c0"
      },
      "data": {
        "result": {
          "req_id": "xxxx",
          "req_header": null,
          "req_param": [
            {
              "text": "t-my-custom-id",
              "currency_pair": "GT_USDT",
              "type": "limit",
              "account": "spot",
              "side": "buy",
              "amount": "1",
              "price": "1"
            },
            {
              "text": "t-my-custom-id",
              "currency_pair": "GT_USDT",
              "type": "limit",
              "account": "spot",
              "side": "buy",
              "amount": "1",
              "price": "1"
            }
          ]
        }
      }
    }
    

    # 下单推送

    下单 推送示例

    单笔订单的推送示例

    {
      "request_id": "request-2",
      "header": {
        "response_time": "1681986204784",
        "status": "200",
        "channel": "spot.order_place",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "id": "1700664330",
          "text": "t-my-custom-id",
          "amend_text": "-",
          "create_time": "1681986204",
          "update_time": "1681986204",
          "create_time_ms": 1681986204832,
          "update_time_ms": 1681986204832,
          "status": "open",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "1",
          "time_in_force": "gtc",
          "iceberg": "0",
          "left": "1",
          "fill_price": "0",
          "filled_total": "0",
          "fee": "0",
          "fee_currency": "GT",
          "point_fee": "0",
          "gt_fee": "0",
          "gt_maker_fee": "0.0015",
          "gt_taker_fee": "0.0015",
          "gt_discount": true,
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "stp_id": 1,
          "stp_act": "cn",
          "finish_as": "open"
        }
      }
    }
    

    已更新的订单列表。请注意,可能会在一条通知中更新多个货币对的订单

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false(false 该字段不会出现在响应中),这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 如果这是"ack"响应,则"result"是请求的有效载荷,否则"result"是 API 的响应
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 取消订单

    您可以使用此频道和事件cancel取消一个未成交的订单

    以下是 API 的功能:

    DELETE /spot/orders/{
      order_id
    }
    

    # 取消订单请求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    time = int(time.time())
    cancelParam = {"order_id":"1694883366","currency_pair":"GT_USDT"}
    channel = "spot.order_cancel"
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    
    
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            "req_param": cancelParam
        }
    }))
    
    print(ws.recv())
    

    取消订单请求示例

    {
      "time": 1681986206,
      "channel": "spot.order_cancel",
      "event": "api",
      "payload": {
        "req_id": "request-5",
        "req_param": {
          "order_id": "1700664330",
          "currency_pair": "GT_USDT"
        }
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
    req_param object 有关 API 取消订单的详细信息,请查看API (opens new window)

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    order_id string 成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即 text 字段)。
    currency_pair string 交易货币对
    account string 账户类型,spot - 现货账户,margin - 杠杆账户,cross_margin - 全仓杠杆账户,unified - 统一账户

    # 取消订单推送

    取消订单推送示例

    {
      "request_id": "request-5",
      "header": {
        "response_time": "1681986206282",
        "status": "200",
        "channel": "spot.order_cancel",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "id": "1700664330",
          "text": "t-my-custom-id",
          "amend_text": "-",
          "create_time": "1681986204",
          "update_time": "1681986206",
          "create_time_ms": 1681986204832,
          "update_time_ms": 1681986206330,
          "status": "cancelled",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "2",
          "time_in_force": "gtc",
          "iceberg": "0",
          "left": "1",
          "fill_price": "0",
          "filled_total": "0",
          "fee": "0",
          "fee_currency": "GT",
          "point_fee": "0",
          "gt_fee": "0",
          "gt_maker_fee": "0.0015",
          "gt_taker_fee": "0.0015",
          "gt_discount": true,
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "stp_id": 1,
          "stp_act": "cn",
          "finish_as": "cancelled"
        }
      }
    }
    

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false(false 该字段不会出现在响应中),这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 单个订单取消的响应详细信息,请查看API (opens new window)
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 取消所有 ID 列表内的订单

    您可以使用此频道和事件cancel_ids取消所有未成交的订单。

    以下是 API 的功能:

    POST /spot/cancel_batch_orders
    

    # 取消所有 ID 列表内的订单请求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    time = int(time.time())
    cancelWithIdsParam = [{"id":"1694883366","currency_pair":"GT_USDT"}]
    channel = "spot.order_cancel_ids"
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    
    
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            "req_param": cancelWithIdsParam
        }
    }))
    
    print(ws.recv())
    

    客户端请求示例

    {
      "time": 1681986208,
      "channel": "spot.order_cancel_ids",
      "event": "api",
      "payload": {
        "req_id": "request-9",
        "req_param": [
          {
            "currency_pair": "GT_USDT",
            "id": "1700664343"
          }
        ]
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
    req_param object 详情见 api (opens new window)

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    currency_pair string 交易货币对
    id string 订单 ID 或者用户自定义 ID 。如果使用自定义 ID,只能在订单创建后的 30 分钟内有效
    account string 撤销的订单如果是全仓杠杆账户订单或是统一账户 apikey,该字段必须指定且设置为 cross_margin

    # 取消所有 ID 列表内的订单推送

    取消订单推送示例

    {
      "request_id": "request-9",
      "header": {
        "response_time": "1681986208564",
        "status": "200",
        "channel": "spot.order_cancel_ids",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": [
          {
            "currency_pair": "GT_USDT",
            "id": "1700664343",
            "succeeded": true
          }
        ]
      }
    }
    

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false(false 该字段不会出现在响应中),这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 响应详见api (opens new window)
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 使用指定的货币对取消所有订单

    您可以使用此频道和事件cancel_cp取消所有未成交的订单

    以下是 API 的功能:

    DELETE /spot/orders
    

    # 使用指定的货币对取消所有订单请求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    time = int(time.time())
    cancelParam = {"side":"buy","currency_pair":"GT_USDT"}
    channel = "spot.order_cancel_cp"
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    
    
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            "req_param": cancelParam
        }
    }))
    
    print(ws.recv())
    
    {
      "time": 1681986207,
      "channel": "spot.order_cancel_cp",
      "event": "api",
      "payload": {
        "req_id": "request-7",
        "req_param": {
          "currency_pair": "GT_USDT",
          "side": "buy"
        }
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
    req_param object detail toapi (opens new window)

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    currency_pair string 交易货币对
    side string 指定全部买单或全部卖单,不指定则两者都包括
    account string 指定查询账户。不指定默认现货,保证金和逐仓杠杆账户。指定 cross_margin 则查询全仓杠杆账户。

    # 使用指定的货币对取消所有订单推送

    取消订单推送示例

    {
      "request_id": "request-7",
      "header": {
        "response_time": "1681986207412",
        "status": "200",
        "channel": "spot.order_cancel_cp",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": [
          {
            "id": "1700664337",
            "text": "t-my-custom-id",
            "amend_text": "-",
            "create_time": "1681986206",
            "update_time": "1681986207",
            "create_time_ms": 1681986206384,
            "update_time_ms": 1681986207444,
            "status": "cancelled",
            "currency_pair": "GT_USDT",
            "type": "limit",
            "account": "spot",
            "side": "buy",
            "amount": "1",
            "price": "1",
            "time_in_force": "gtc",
            "iceberg": "0",
            "left": "1",
            "fill_price": "0",
            "filled_total": "0",
            "fee": "0",
            "fee_currency": "GT",
            "point_fee": "0",
            "gt_fee": "0",
            "gt_maker_fee": "0.0015",
            "gt_taker_fee": "0.0015",
            "gt_discount": true,
            "rebated_fee": "0",
            "rebated_fee_currency": "USDT",
            "stp_id": 1,
            "stp_act": "cn",
            "finish_as": "cancelled"
          }
        ]
      }
    }
    

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false(false 该字段不会出现在响应中),这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 响应详情见api (opens new window)
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 修改订单

    您可以使用此频道和事件amend来修改一个未成交的订单。

    以下是 API 的功能:

    PATCH /spot/orders/{order_id}
    

    # 修改订单需求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    time = int(time.time())
    amendParam = {"order_id":"1694883366","currency_pair":"GT_USDT","price":"2"}
    channel = "spot.order_amend"
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    
    
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            "req_param": amendParam
        }
    }))
    
    print(ws.recv())
    

    客户端请求示例

    {
      "time": 1681986206,
      "channel": "spot.order_amend",
      "event": "api",
      "payload": {
        "req_id": "request-4",
        "req_param": {
          "order_id": "1700664330",
          "currency_pair": "GT_USDT",
          "price": "2"
        }
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
    req_param object API 修改订单,详细信息请参考api (opens new window)

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    amount string 交易数量,amountprice必须指定其中一个
    price string 交易价,amountprice必须指定其中一个
    amend_text string 用户可以备注这次修改的信息。
    order_id string 成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即 text 字段)。
    currency_pair string 交易对
    account string 指定查询账户。不指定默认现货,保证金和逐仓杠杆账户。指定 cross_margin 则查询全仓杠杆账户。

    # 修改订单推送

    修改订单 推送示例

    {
      "request_id": "request-4",
      "header": {
        "response_time": "1681986206145",
        "status": "200",
        "channel": "spot.order_amend",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "id": "1700664330",
          "text": "t-my-custom-id",
          "amend_text": "-",
          "create_time": "1681986204",
          "update_time": "1681986206",
          "create_time_ms": 1681986204832,
          "update_time_ms": 1681986206176,
          "status": "open",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "2",
          "time_in_force": "gtc",
          "iceberg": "0",
          "left": "1",
          "fill_price": "0",
          "filled_total": "0",
          "fee": "0",
          "fee_currency": "GT",
          "point_fee": "0",
          "gt_fee": "0",
          "gt_maker_fee": "0.0015",
          "gt_taker_fee": "0.0015",
          "gt_discount": true,
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "stp_id": 1,
          "stp_act": "cn",
          "finish_as": "open"
        }
      }
    }
    

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool "ack"消息的返回表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false,这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 响应详见api (opens new window)
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情

    # 订单状态

    您可以使用此频道和事件status来查询一个订单。

    以下是 API 的功能:

    GET /spot/orders/{order_id}
    

    # 订单状态请求

    代码示例

    #!/usr/bin/python
    
    import time
    import json
    # pip install websocket_client
    from websocket import create_connection
    
    
    time = int(time.time())
    statusParam = {"order_id":"1694883366","currency_pair":"GT_USDT"}
    channel = "spot.order_status"
    
    ws = create_connection("wss://api.gateio.ws/ws/v4/")
    
    
    ws.send(json.dumps({
        "time":time,
        "channel":channel,
        "event":"api",
        "payload":{
            "req_id":"test_1",
            "req_param": statusParam
        }
    }))
    
    print(ws.recv())
    

    客户端请求示例

    {
      "time": 1681986205,
      "channel": "spot.order_status",
      "event": "api",
      "payload": {
        "req_id": "request-3",
        "req_param": {
          "order_id": "1700664330",
          "currency_pair": "GT_USDT"
        }
      }
    }
    

    Payload 格式:

    字段 类型 必选 描述
    req_id string 服务器将发送回的请求 ID,用于帮助您识别服务器响应的是哪个请求,它与外部的 id 不同。
    req_param object 详见api (opens new window)

    req_param API 订单模型的 JSON 字节数据:

    字段 类型 必选 描述
    order_id string 成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即 text 字段)。
    currency_pair string 交易对
    account string 指定查询账户。不指定默认现货,保证金和逐仓杠杆账户。指定 cross_margin 则查询全仓杠杆账户。

    # 详细描述

    order_id: 成功创建订单时返回的订单 ID 或者用户创建时指定的自定义 ID(即 text 字段)。 基于自定义 ID 的操作只在挂单中可查,当结束订单(成交/取消)后,在结束之后 1 小时内可查,过期之后只能使用订单 ID

    account: 指定查询账户。不指定默认现货,保证金和逐仓杠杆账户。指定 cross_margin 则查询全仓杠杆账户。 统一账户只能指定 cross_margin

    # 订单状态推送

    订单状态 推送示例

    {
      "request_id": "request-3",
      "header": {
        "response_time": "1681986205829",
        "status": "200",
        "channel": "spot.order_status",
        "event": "api",
        "client_id": "::1-0x140001623c0"
      },
      "data": {
        "result": {
          "id": "1700664330",
          "text": "t-my-custom-id",
          "amend_text": "-",
          "create_time": "1681986204",
          "update_time": "1681986204",
          "create_time_ms": 1681986204939,
          "update_time_ms": 1681986204939,
          "status": "open",
          "currency_pair": "GT_USDT",
          "type": "limit",
          "account": "spot",
          "side": "buy",
          "amount": "1",
          "price": "1",
          "time_in_force": "gtc",
          "iceberg": "0",
          "left": "1",
          "fill_price": "0",
          "filled_total": "0",
          "fee": "0",
          "fee_currency": "GT",
          "point_fee": "0",
          "gt_fee": "0",
          "gt_maker_fee": "0.0015",
          "gt_taker_fee": "0.0015",
          "gt_discount": true,
          "rebated_fee": "0",
          "rebated_fee_currency": "USDT",
          "stp_id": 1,
          "stp_act": "cn",
          "finish_as": "open"
        }
      }
    }
    

    已更新的订单列表。请注意,可能会在一条通知中更新多个货币对的订单。

    推送格式:

    字段 类型 描述
    request_id String 消息的唯一标识符
    ack Bool 该字段表示 WebSocket 的确认消息(目前在下单接口中存在)。如果"ack"为 false,这意味着该消息是一个响应消息,您可以通过检查"data.errs"来确定请求是否成功。
    header Map 响应的元信息
    »response_time String 响应发送时间(以毫秒为单位)
    »channel String 请求的频道
    »event String 请求事件
    »client_id String 唯一客户端标识 ID
    data Object 签名时间(以秒为单位)
    »result Object 响应详见api (opens new window)
    »errs Object 只有在请求失败时才可用
    »»label String 以字符串格式表示错误类型
    »»message String 错误信息详情