> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qfex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket 概览

QFEX 提供两个 WebSocket 接口：

* [mds.qfex.com](wss://mds.qfex.com)：公开行情及参考数据。
* [trade.qfex.com](wss://trade.qfex.com)：订单提交及私有数据。

行情数据公开，无需身份认证。交易接口需要 API 密钥，连接建立后必须在 1 分钟内完成[身份认证](https://docs.qfex.com/cn/websocket/channels/trade/authenticate.md)。

要在子账户中操作，请在认证载荷中包含 `account_id`；省略时使用主账户。

要将交易手续费归因给开发者，请在同一认证载荷中包含 `builder_code`。详情见 [Builder Codes](https://docs.qfex.com/cn/qfex/builder-code.md)及[身份认证](https://docs.qfex.com/cn/websocket/channels/trade/authenticate.md)。

## 开始使用

访问私有数据或下单时，必须连接 `trade.qfex.com` 并完成认证。以下示例演示如何连接、使用 HMAC-SHA256 认证并维持连接。

> [accordion] Python 配置
>
> ```python theme={null}
> # pip install websocket-client
> import hashlib
> import hmac
> import json
> import secrets
> import time
> import websocket
>
> PUB_KEY = "qfex_pub_xxxxx"
> SECRET_KEY = "qfex_secret_yyyyyy"
>
> def build_auth_message():
>     nonce = secrets.token_hex(16)
>     unix_ts = int(time.time())
>     payload = f"{nonce}:{unix_ts}".encode()
>     signature = hmac.new(SECRET_KEY.encode(), payload, hashlib.sha256).hexdigest()
>     return {
>         "type": "auth",
>         "params": {
>             "hmac": {
>                 "public_key": PUB_KEY,
>                 "nonce": nonce,
>                 "unix_ts": unix_ts,
>                 "signature": signature,
>             }
>         },
>     }
>
> def on_open(ws):
>     print("Connected")
>     ws.send(json.dumps(build_auth_message()))
>
> def on_message(ws, message):
>     print("Received:", message)
>
> ws = websocket.WebSocketApp(
>     "wss://trade.qfex.com?api_key=" + PUB_KEY,
>     on_open=on_open,
>     on_message=on_message
> )
>
> ws.run_forever()
> ```

> [accordion] Node 配置
>
> ```javascript theme={null}
> // npm i ws
> import crypto from "crypto";
> import WebSocket from "ws";
>
> const pubKey = "qfex_pub_xxxxx";
> const secretKey = "qfex_secret_yyyyyy";
>
> function buildAuthMessage() {
>   const nonce = crypto.randomBytes(16).toString("hex");
>   const unixTs = Math.floor(Date.now() / 1000);
>   const payload = `${nonce}:${unixTs}`;
>   const signature = crypto
>     .createHmac("sha256", secretKey)
>     .update(payload)
>     .digest("hex");
>
>   return {
>     type: "auth",
>     params: {
>       hmac: {
>         public_key: pubKey,
>         nonce,
>         unix_ts: unixTs,
>         signature,
>       },
>     },
>   };
> }
>
> const ws = new WebSocket(`wss://trade.qfex.com?api_key=${pubKey}`);
>
> ws.on("open", () => {
>   console.log("Connected");
>   ws.send(JSON.stringify(buildAuthMessage()));
> });
>
> ws.on("message", (msg) => {
>   console.log("Received:", msg.toString());
> });
> ```

> [accordion] Go 配置
>
> ```go theme={null}
> // go get github.com/gorilla/websocket
> package main
>
> import (
>   "crypto/hmac"
>   "crypto/rand"
>   "crypto/sha256"
>   "encoding/hex"
>   "fmt"
>   "log"
>   "time"
>   "github.com/gorilla/websocket"
> )
>
> func main() {
>   pubKey := "qfex_pub_xxxxx"
>   secretKey := []byte("qfex_secret_yyyyyy")
>
>   c, _, err := websocket.DefaultDialer.Dial("wss://trade.qfex.com?api_key="+pubKey, nil)
>   if err != nil {
>     log.Fatal("dial:", err)
>   }
>   defer c.Close()
>
>   // Build Auth Message
>   nonceBytes := make([]byte, 16)
>   rand.Read(nonceBytes)
>   nonce := hex.EncodeToString(nonceBytes)
>   unixTs := time.Now().Unix()
>   message := fmt.Sprintf("%s:%d", nonce, unixTs)
>
>   h := hmac.New(sha256.New, secretKey)
>   h.Write([]byte(message))
>   signature := hex.EncodeToString(h.Sum(nil))
>
>   auth := map[string]any{
>     "type": "auth",
>     "params": map[string]any{
>       "hmac": map[string]any{
>         "public_key": pubKey,
>         "nonce":      nonce,
>         "unix_ts":    unixTs,
>         "signature":  signature,
>       },
>     },
>   }
>
>   c.WriteJSON(auth)
>
>   for {
>     _, message, err := c.ReadMessage()
>     if err != nil {
>       log.Println("read:", err)
>       return
>     }
>     fmt.Printf("recv: %s\n", message)
>   }
> }
> ```

## 身份认证

`trade.qfex.com` 要求身份认证。

1. **连接**：将 API 公开密钥作为查询参数提供：

   ```
   wss://trade.qfex.com?api_key=YOUR_PUBLIC_KEY
   ```

2. **认证**：在 1 分钟内发送使用私密密钥签署的认证消息。可使用 **HMAC-SHA256 签名**（推荐）或有效的 **JWT 令牌**。

认证载荷及参数的完整说明见[身份认证文档](https://docs.qfex.com/cn/websocket/channels/trade/authenticate.md)。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.