BitMEX API 使用方法详解:配置与使用教程

时间:2025-02-16 阅读数:40人阅读

BitMEX API 使用方法与配置教程

BitMEX 是一个知名的加密货币衍生品交易所,其强大的 API 接口允许开发者和交易者自动化交易策略、获取市场数据以及执行其他操作。本文将详细介绍 BitMEX API 的使用方法与配置,帮助你快速上手。

1. BitMEX API 概览

BitMEX API 采用表述性状态转移 (REST) 架构风格,同时提供 WebSocket 接口以满足实时数据流的需求。这两种接口共同为开发者提供了全面且灵活的访问 BitMEX 平台功能的途径。

  • REST API: 这是一个同步的请求-响应式接口,主要用于执行交易订单,查询账户余额、保证金、持仓等信息,以及获取历史交易数据、结算数据和指数数据。每个 REST API 请求都必须经过严格的身份验证,以确保账户安全和数据完整性。身份验证通常通过 API 密钥和签名来实现,签名是使用您的密钥对请求参数进行加密哈希的结果。
  • WebSocket API: 这是一个双向的、基于事件驱动的实时通信协议。它允许客户端订阅 BitMEX 交易所的实时市场数据流,包括最新的行情报价(如买一价和卖一价)、订单簿深度(买单和卖单的集合)、以及最近成交的交易记录。部分 WebSocket 接口,例如账户信息的实时推送,同样需要进行身份验证,以保护用户的隐私和安全。使用 WebSocket API 能够实现低延迟的数据更新,对于高频交易和实时策略至关重要。

2. 准备工作

在使用 BitMEX API 之前,为了确保交易的安全和便捷,你需要完成以下准备工作:

  • BitMEX 账户: 你必须在 BitMEX 官方网站( https://www.bitmex.com )注册一个账户。这是使用 BitMEX API 的先决条件。请务必使用安全强度高的密码,并启用双重验证(2FA),以增强账户安全性。
  • API 密钥: 成功登录 BitMEX 账户后,导航至账户设置中的 API 密钥管理页面。在此页面,创建一个新的 API 密钥。创建时,请仔细设置API密钥的权限,例如只允许读取数据或允许交易。务必妥善保管你的密钥, API Key ID (也称为 API 公钥)和 API Secret (也称为 API 私钥)是访问 API 的凭证,切勿泄露给任何第三方。一旦泄露,他人可能利用你的密钥进行恶意操作。建议将 API 密钥存储在安全的地方,例如使用环境变量或加密存储。API Secret只会在创建时显示一次,请立即保存。
  • 编程环境: 选择你熟悉的编程语言。BitMEX API 支持多种编程语言,包括但不限于 Python、Java、Node.js、C# 和 Go。根据你的编程偏好和项目需求选择合适的语言。本文后续示例将以 Python 为例进行讲解,因为 Python 拥有丰富的第三方库,可以简化 API 交互过程。确保你的编程环境中已安装必要的库,例如用于发送 HTTP 请求的 requests 库。
相关库: 安装必要的 Python 库,例如 requests 用于发送 HTTP 请求,websocket-client 用于连接 WebSocket。

bash pip install requests websocket-client

3. API 密钥权限管理

创建 API 密钥时,务必仔细选择并配置相应的权限。API 密钥的权限设置直接决定了密钥能够执行的操作范围。权限配置不当可能导致资金损失或其他安全风险。通常,交易所会提供细粒度的权限控制选项,以便用户精确地限制 API 密钥的功能。以下是一些常见的 API 密钥权限及其详细说明:

  • Order(订单管理): 该权限允许 API 密钥进行全面的订单操作,包括但不限于:
    • 下单(Place Order): 创建新的买入或卖出订单。
    • 修改订单(Modify Order): 更改现有订单的价格、数量等参数。
    • 取消订单(Cancel Order): 撤销尚未成交的订单。
    • 查询订单状态(Query Order Status): 获取指定订单的详细信息,例如订单状态、成交数量等。

    授予此权限需要谨慎,因为它允许 API 密钥完全控制交易账户的订单行为。

  • OrderCancel(仅取消订单): 该权限仅限于取消已经存在的订单。它不允许创建新的订单或修改现有订单的参数。

    此权限适用于只需要自动取消订单的场景,例如,当满足特定条件时自动取消挂单。

  • Withdraw(提币): 该权限允许 API 密钥从交易所账户提现数字货币。

    强烈建议:除非绝对必要,否则不要授予 API 密钥此权限。一旦 API 密钥泄露,拥有提币权限的密钥可能导致资金被盗。 如果必须使用提币功能,请务必采取额外的安全措施,例如设置提币白名单,限制提币地址。

  • Account(账户信息): 该权限允许 API 密钥查询账户相关信息,例如:
    • 账户余额(Account Balance): 查询各种数字货币的可用余额和总余额。
    • 交易历史(Transaction History): 获取账户的交易记录。
    • 持仓信息(Position Information): 查看当前持有的仓位信息(适用于合约交易)。

    该权限通常用于监控账户状态和进行数据分析。

为了最大程度地降低安全风险,最佳实践是始终遵循最小权限原则。这意味着,只授予 API 密钥完成其预期功能所需的最低权限集。定期审查和更新 API 密钥的权限也是一项重要的安全措施。如果不再需要某个权限,应立即将其撤销。

4. 使用 REST API

REST (Representational State Transfer) API 是一种广泛使用的软件架构风格,它允许不同的应用程序通过 HTTP 协议进行通信和数据交换。BitMEX 交易所提供了一套全面的 REST API,开发者可以利用这些 API 来获取市场数据、管理账户、执行交易等。以下示例展示了如何使用 Python 的 requests 库调用 BitMEX REST API。 requests 库是一个简单易用的 HTTP 客户端,可以方便地发送 HTTP 请求并处理响应。

在使用 BitMEX REST API 之前,您需要注册一个 BitMEX 账户并生成 API 密钥。API 密钥由一个 API 密钥 ID 和一个 API 密钥 Secret 组成。API 密钥用于对您的 API 请求进行身份验证,确保只有授权的用户才能访问您的账户。请务必妥善保管您的 API 密钥,不要将其泄露给他人。

BitMEX REST API 的基准 URL 是 https://www.bitmex.com/api/v1 。所有 API 请求都必须以这个 URL 开头。例如,要获取最新的交易数据,您可以向 https://www.bitmex.com/api/v1/trade 发送一个 GET 请求。

以下是一个使用 Python requests 库调用 BitMEX REST API 的示例代码,用于获取最新的交易数据:


import requests
import 

# API endpoint URL
url = "https://www.bitmex.com/api/v1/trade"

# Parameters for the API request (optional)
params = {
    "symbol": "XBTUSD",
    "count": 10
}

try:
    # Make the API request
    response = requests.get(url, params=params)

    # Raise an exception for bad status codes
    response.raise_for_status()

    # Parse the JSON response
    trades = response.()

    # Print the trades
    print(.dumps(trades, indent=4))

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")


这段代码首先导入了 requests 库。然后,它定义了 API endpoint URL 和可选的请求参数。 params 字典指定了要获取的交易对 (XBTUSD) 和要获取的交易数量 (10)。 requests.get() 函数发送一个 GET 请求到指定的 URL,并将 params 字典作为查询字符串参数传递。 response.raise_for_status() 函数检查响应状态码,如果状态码表示错误(例如 404 Not Found 或 500 Internal Server Error),则抛出一个异常。 response.() 函数将响应内容解析为 JSON 格式。 .dumps() 函数将 JSON 数据格式化并打印到控制台。

上面的示例代码只是一个简单的例子。BitMEX REST API 提供了许多不同的 endpoint,可以用于获取各种市场数据和管理您的账户。您可以参考 BitMEX API 文档了解更多信息。 在实际应用中,为了安全起见,你需要使用API密钥进行身份验证,这通常通过在请求头中添加签名来实现。详细的身份验证方法请参考BitMEX官方文档.

4.1 设置请求头:身份验证的关键

BitMEX REST API 强制要求在每个请求的头部包含特定的签名信息,这是进行身份验证和授权访问的必要步骤。服务器通过验证此签名来确认请求的来源和完整性,从而保证交易安全。

生成有效签名的详细步骤如下:

  1. 构建签名消息: 你需要将若干关键元素按照严格的顺序拼接成一个字符串。这些元素包括:
    • 请求方法: HTTP 方法,例如 GET POST PUT DELETE ,必须使用大写形式。
    • 请求路径: 不包含域名的 API 端点路径,例如 /api/v1/order 。请确保路径的准确性。
    • 过期时间戳(Nonce): 一个 Unix 时间戳,表示签名的有效截止时间。时间戳必须是整数,且通常设置为当前时间加上一个短暂的过期窗口(例如60秒)。
    • 请求体(可选): 如果请求包含 JSON 格式的请求体,则将其作为字符串包含在签名消息中。如果请求没有请求体,则使用空字符串。注意,请求体的顺序和格式必须与发送的请求完全一致,包括空格和换行符。
    拼接顺序至关重要: RequestMethod + RequestPath + Nonce + RequestBody
  2. HMAC-SHA256 加密: 使用你的 API Secret 作为密钥,对上述拼接好的字符串进行 HMAC-SHA256 加密。HMAC-SHA256 是一种带密钥的哈希算法,能够有效地防止篡改。
  3. Base64 编码: 将 HMAC-SHA256 加密后的二进制结果进行 Base64 编码。Base64 是一种将二进制数据转换为 ASCII 字符串的编码方式,以便在 HTTP 头部中传输。
  4. 添加请求头: 将生成的签名、API Key 和过期时间戳添加到 HTTP 请求的头部。具体的头部字段名称为 api-key , api-signature , 和 api-expires

以下 Python 代码示例展示了如何生成 BitMEX API 签名:

import hashlib
import hmac
import base64
import time
import requests

def generate_signature(api_secret, method, path, data='', expires=60):
    """生成 BitMEX API 签名"""
    nonce = int(round(time.time()) + expires)
    message = method + path + str(nonce) + data
    signature = hmac.new(api_secret.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(signature).decode('utf-8')
    return signature, nonce

以下示例展示了如何使用生成的签名向 BitMEX API 发送请求:

API_KEY = "YOUR_API_KEY"  # 替换为你的 API Key ID
API_SECRET = "YOUR_API_SECRET"  # 替换为你的 API Secret
BASE_URL = "https://www.bitmex.com/api/v1"  # BitMEX API 基础 URL (Production)

# 示例:获取订单
method = "GET"
path = "/order"
expires = 60
signature, nonce = generate_signature(API_SECRET, method, path, expires=expires)

headers = {
    'api-key': API_KEY,
    'api-signature': signature,
    'api-expires': str(nonce)
}

url = BASE_URL + path
response = requests.get(url, headers=headers)

print(response.status_code)
print(response.())

重要提示:

  • 始终妥善保管你的 API Secret ,切勿将其泄露给任何第三方。
  • 过期时间戳的设置需要合理,过短可能导致请求频繁失效,过长则会增加安全风险。建议使用默认的 60 秒。
  • 请务必检查你的系统时钟是否准确,时间偏差可能导致签名验证失败。
  • 在生产环境中,建议使用环境变量或配置文件来管理 API Key API Secret ,避免硬编码在代码中。
  • 仔细阅读 BitMEX API 文档,了解每个端点所需的具体参数和请求体格式。
  • 在进行任何交易操作前,请先在 BitMEX 的测试网络 (Testnet) 上进行充分的测试。

BASE_URL = "https://testnet.bitmex.com/api/v1" # BitMEX Testnet API 基础 URL (Testnet)

4.2 发送 GET 请求

以下示例展示了如何使用 Python 的 requests 库获取账户资金信息。 此过程涉及构建带有必要认证信息的 HTTP GET 请求,并处理服务器响应。

def get_wallet_balance(): """获取账户资金信息""" path = "/user/wallet" method = "GET" signature, nonce = generate_signature(API_SECRET, method, path) headers = { "api-key": API_KEY, "api-signature": signature, "api-expires": str(nonce) } url = BASE_URL + path response = requests.get(url, headers=headers) response.raise_for_status() # 检查响应状态码 return response.()

代码详解:

  • path = "/user/wallet" :定义API端点路径,指向获取用户钱包信息的资源位置。
  • method = "GET" :指定HTTP请求方法为GET,用于从服务器请求数据。
  • signature, nonce = generate_signature(API_SECRET, method, path) :调用 generate_signature 函数,使用API密钥( API_SECRET )、HTTP方法( method )和API路径( path )生成请求签名和时间戳(nonce),这是安全认证的关键步骤。
  • headers = { ... } :创建一个字典,用于设置HTTP请求头部。
    • "api-key": API_KEY :包含用于标识用户的API密钥。
    • "api-signature": signature :包含生成的请求签名,用于验证请求的完整性和真实性。
    • "api-expires": str(nonce) :包含请求的过期时间戳,以字符串形式表示,防止重放攻击。
  • url = BASE_URL + path :通过将基本URL( BASE_URL )与API路径( path )连接,构建完整的API端点URL。
  • response = requests.get(url, headers=headers) :使用 requests.get 函数发送GET请求到指定的URL,并将包含认证信息的请求头部传递给服务器。
  • response.raise_for_status() :检查HTTP响应状态码。如果状态码表示错误(例如,4xx或5xx),则引发HTTPError异常,表明请求失败。
  • return response.() :解析JSON格式的响应内容,并将其作为Python字典返回。 客户端可以利用返回的字典访问钱包余额等信息。

注意事项: 确保 API_KEY API_SECRET 安全存储,避免泄露。 generate_signature 函数的具体实现会根据交易所或API提供商的要求而有所不同,需要根据其官方文档进行调整。

调用示例

查询钱包余额是区块链应用中常见的操作,以下示例展示了如何调用 get_wallet_balance() 函数来获取指定钱包地址的余额。该函数通常会与区块链节点进行交互,通过RPC调用或SDK,从链上读取最新的账户信息。函数返回值通常是一个数字,代表账户余额,单位可能是代币的最小单位(例如,Wei)。


wallet_balance = get_wallet_balance()
print(wallet_balance)

上述代码首先调用 get_wallet_balance() 函数,并将返回的余额赋值给变量 wallet_balance 。然后,使用 print() 函数将 wallet_balance 的值输出到控制台。实际应用中,可能需要传入钱包地址作为参数,例如 wallet_balance = get_wallet_balance(wallet_address) 。同时,需要处理函数调用可能出现的异常情况,例如网络连接错误或节点无响应。

重要提示: 在实际开发中,需要确保 get_wallet_balance() 函数的实现是安全可靠的,防止恶意代码篡改余额数据。建议使用经过安全审计的区块链SDK或API来与区块链进行交互。需要注意不同区块链网络使用的余额单位可能不同,需要进行相应的单位转换。

4.3 发送 POST 请求

以下示例展示了如何使用 Python 编程语言下一个限价单,详细说明了构建请求、签名以及处理响应的步骤。

def place_limit_order(symbol, side, order_qty, price): """下一个限价单""" path = "/order" method = "POST" data = { "symbol": symbol, # 交易对,例如 'XBTUSD' "side": side, # 交易方向,'Buy' (买入) 或 'Sell' (卖出) "orderQty": order_qty, # 订单数量,以合约张数为单位 "price": price, # 限价单价格 "ordType": "Limit" # 订单类型,'Limit' 表示限价单 } data_str = str(data) # 必须转换为字符串,否则签名会出错。将 Python 字典转换为字符串,以便进行签名 signature, nonce = generate_signature(API_SECRET, method, path, data_str) # 生成请求签名和 nonce(时间戳) headers = { "api-key": API_KEY, # API 密钥 "api-signature": signature, # 请求签名,用于验证请求的真实性和完整性 "api-expires": str(nonce), # 请求过期时间,以时间戳表示 "Content-Type": "application/" # 指定请求体内容类型为 JSON } url = BASE_URL + path # 完整的 API 请求 URL response = requests.post(url, headers=headers, data=.dumps(data)) # 使用 requests 库发送 POST 请求,并将数据转换为 JSON 格式 response.raise_for_status() # 检查响应状态码,如果不是 200,则抛出异常 return response.() # 将响应内容解析为 JSON 格式并返回

代码解释:

  • symbol :指定交易的交易对,例如 'XBTUSD'。
  • side :指定交易方向,'Buy' 代表买入,'Sell' 代表卖出。
  • orderQty :指定订单的数量,通常以合约张数为单位。
  • price :指定限价单的价格。订单只有在市场价格达到或超过此价格时才会执行。
  • ordType :设置为 'Limit' 以表明这是一个限价单。
  • generate_signature :这是一个自定义函数,用于根据 API 密钥、请求方法、路径和数据生成签名。签名用于验证请求的真实性。
  • nonce :一个随机数,通常是 Unix 时间戳,用于防止重放攻击。
  • API_KEY API_SECRET :您的 API 密钥和密钥,用于身份验证。请务必妥善保管您的密钥。
  • BASE_URL :API 的基本 URL,例如 'https://www.bitmex.com/api/v1'。
  • Content-Type :设置为 'application/',表明请求体包含 JSON 格式的数据。
  • requests.post :使用 Python 的 requests 库发送 POST 请求。 data 参数使用 .dumps() 将 Python 字典转换为 JSON 字符串。
  • response.raise_for_status() :检查响应状态码,如果状态码表示错误(例如 400、500),则引发异常。
  • response.() :将响应内容解析为 JSON 格式,并将其作为 Python 字典返回。

注意事项:

  • 在实际应用中,请替换示例代码中的 API_KEY API_SECRET BASE_URL 为您自己的值。
  • 错误处理至关重要。示例代码仅包含基本的错误检查。您应该添加更全面的错误处理逻辑,以处理各种可能的错误情况。
  • 限价单只有在市场价格达到或超过指定价格时才会执行。如果市场价格没有达到指定价格,订单将保持挂单状态,直到被取消。
  • 交易涉及风险。在进行真实交易之前,请务必充分了解交易平台的使用规则和风险。建议先使用模拟账户进行练习。

调用示例

本示例演示如何通过 BitMEX API 下达一个限价买单。 place_limit_order 函数用于提交订单请求,该请求指定了交易标的、交易方向、订单数量和期望价格。

以下代码展示了使用 place_limit_order 函数创建一个在 XBTUSD (比特币/美元永续合约) 市场上,以 20000 美元的价格买入 100 张合约的限价单:

order = place_limit_order(symbol="XBTUSD", side="Buy", order_qty=100, price=20000)
print(order)

参数解释:

  • symbol : 指定交易的合约代码,例如 "XBTUSD"。
  • side : 指定交易方向,可以是 "Buy" (买入) 或 "Sell" (卖出)。
  • order_qty : 指定订单的数量,单位为合约张数。
  • price : 指定限价单的价格,即期望成交的价格。

place_limit_order 函数执行成功后,会返回一个包含订单信息的字典 ( order )。可以使用 print(order) 语句将该字典的内容打印到控制台,以便查看订单的详细信息,如订单ID、状态、创建时间等。

注意: 实际的 API 函数名称和参数可能因所使用的 BitMEX 客户端库而异。请参考相应的库文档获取准确的函数名和参数信息。在真实交易环境下使用 API 之前,建议先在测试网 (Testnet) 上进行测试。

4.4 错误处理

在与加密货币交易所或钱包的 API 交互时,健全的错误处理机制至关重要。程序必须能够妥善应对各种可能出现的异常情况,确保交易的可靠性和数据的准确性。

一种常用的错误处理方法是检查 HTTP 响应状态码。多数 HTTP 客户端库(例如 Python 的 requests 库或 JavaScript 的 fetch API)都提供了便捷的方法来访问和验证响应状态码。如果状态码指示错误(例如 4xx 表示客户端错误,5xx 表示服务器错误),则应该立即采取适当的措施。

response.raise_for_status() 是一个常用的方法,用于在 HTTP 响应状态码表示错误时引发异常。例如,在使用 Python 的 requests 库时,调用此方法会检查响应状态码是否在 200-399 范围内。如果不在该范围内,则会抛出一个 HTTPError 异常,其中包含有关错误的详细信息。

除了 HTTP 状态码之外,API 本身也可能会返回错误信息。这些错误信息通常以 JSON 格式包含在响应体中。程序需要解析响应体,检查是否存在错误代码或错误消息。常见的错误包括:

  • 余额不足: 尝试执行交易时,账户余额不足以支付交易费用或购买加密货币。
  • 订单数量超出限制: 尝试提交的订单数量超过了交易所允许的最大订单数量。
  • 无效的 API 密钥: 提供的 API 密钥无效或已过期,无法访问 API。
  • IP 地址限制: API 配置为仅允许来自特定 IP 地址的请求,当前请求的 IP 地址不在允许列表中。
  • 交易对不可用: 尝试交易的加密货币交易对目前不可用或已暂停交易。
  • 达到速率限制: 在短时间内发送了过多的 API 请求,触发了速率限制。

在处理 API 返回的错误信息时,应该记录错误日志,并向用户提供有意义的错误提示,以便用户能够了解问题的根源并采取相应的措施。例如,如果用户尝试提交超过账户余额的订单,则应该向用户显示“余额不足”的错误提示,并建议用户减少订单数量或充值账户。

5. 使用 WebSocket API

BitMEX 提供 WebSocket API 用于实时数据流的访问。通过 WebSocket 连接,可以接收市场行情、交易数据以及账户信息等更新。以下示例展示了如何使用 Python 的 websocket-client 库连接 BitMEX WebSocket API,并订阅交易数据。

确保已经安装了 websocket-client 库。可以使用 pip 进行安装:

pip install websocket-client

接下来,编写 Python 代码建立 WebSocket 连接并处理接收到的数据:

import websocket
import 

def on_message(ws, message):
    """接收到消息时的回调函数,处理接收到的数据"""
    print(f"Received: {message}")
    # 可以根据message的内容进行解析和处理
    try:
        data = .loads(message)
        # 示例:打印数据类型和数据内容
        if 'table' in data:
            print(f"Table: {data['table']}")
        if 'data' in data:
            print(f"Data: {data['data']}")
    except .JSONDecodeError:
        print(f"Error decoding JSON: {message}")

def on_error(ws, error):
    """发生错误时的回调函数,处理连接错误"""
    print(f"Error: {error}")

def on_close(ws, close_status_code, close_msg):
    """连接关闭时的回调函数,处理连接关闭事件"""
    print(f"### closed ### close_status_code: {close_status_code}, close_msg: {close_msg}")

def on_open(ws):
    """连接建立时的回调函数,发送订阅消息"""
    print("### connected ###")
    # 订阅 trade:XBTUSD,获取 XBTUSD 的实时交易数据
    subscription_message = .dumps({"op": "subscribe", "args": ["trade:XBTUSD"]})
    ws.send(subscription_message)
    print(f"Sent: {subscription_message}")

if __name__ == "__main__":
    #websocket.enableTrace(True) # 开启 debug 模式,输出详细的 WebSocket 交互日志
    # BitMEX WebSocket API URL (Production)
    websocket_url = "wss://www.bitmex.com/realtime"
    # BitMEX WebSocket API URL (Testnet) - 用于测试环境
    #websocket_url = "wss://testnet.bitmex.com/realtime"

    ws = websocket.WebSocketApp(websocket_url,
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

代码解释:

  • on_message(ws, message) : 当接收到服务器推送的消息时,该函数会被调用。示例中,我们尝试将接收到的消息解析为 JSON 格式,并打印 'table' 和 'data' 字段(如果存在)。可以根据需要修改此函数来处理不同的数据类型和消息。添加了JSON解析和错误处理。
  • on_error(ws, error) : 当发生错误时,该函数会被调用。它接收一个 error 参数,其中包含错误的详细信息。
  • on_close(ws, close_status_code, close_msg) : 当 WebSocket 连接关闭时,该函数会被调用。close_status_code 和 close_msg 参数提供有关关闭原因的信息。
  • on_open(ws) : 当 WebSocket 连接成功建立时,该函数会被调用。在该函数中,我们构建一个 JSON 格式的订阅消息,并通过 ws.send() 方法将其发送到服务器。消息 {"op": "subscribe", "args": ["trade:XBTUSD"]} 指示 BitMEX 服务器推送 XBTUSD 交易对的实时交易数据。
  • websocket.WebSocketApp(...) : 创建 WebSocketApp 对象,并传入相应的回调函数。
  • ws.run_forever() : 启动 WebSocket 客户端,保持连接并监听服务器推送的消息。

关于 Testnet:

上述代码中,注释掉的 wss://testnet.bitmex.com/realtime 是 BitMEX 的 Testnet WebSocket API URL。 Testnet 是一个模拟交易环境,允许开发者在不使用真实资金的情况下测试他们的应用程序。建议在开发和测试阶段使用 Testnet。

Debug 模式:

websocket.enableTrace(True) 用于启用 debug 模式。启用后,客户端将输出详细的 WebSocket 交互日志,有助于调试和排查问题。

注意:

  • BitMEX 的 WebSocket API 需要身份验证才能访问某些数据流(例如,账户信息)。需要提供 API 密钥和 secret。此示例仅演示了如何订阅公共数据流(例如,交易数据),无需身份验证。
  • 实际应用中,需要对接收到的数据进行更完善的错误处理和数据验证,以确保程序的稳定性和可靠性。
  • 根据 BitMEX 的 API 文档,选择需要订阅的数据流,并构造相应的订阅消息。

5.1 认证 WebSocket 连接

为了保障数据安全和用户隐私,部分WebSocket接口,例如 order (订单)和 position (持仓)等涉及敏感信息的接口,需要进行身份认证后才能访问。认证过程旨在验证客户端的合法性,防止未经授权的访问和潜在的安全风险。

  1. 生成过期时间戳: 创建一个代表连接有效期的Unix时间戳。该时间戳定义了认证凭证的有效期限,超过该时间点后,连接将失效,需要重新进行认证。建议设置一个合理的过期时间,避免频繁认证带来的性能开销,同时确保安全性。例如,可以将过期时间设置为当前时间后60秒。
  2. 生成签名: 使用您的 API Secret (API密钥密钥)对特定的字符串进行HMAC-SHA256加密,并进行Base64编码。签名的生成过程至关重要,它利用密钥对请求进行加密,确保数据的完整性和防篡改性。待签名的字符串由"GET/realtime"和步骤1中生成的过期时间戳拼接而成。HMAC-SHA256加密算法提供了一种安全可靠的哈希方法,而Base64编码则将加密后的二进制数据转换为文本格式,方便传输和处理。
  3. 发送认证请求: op (操作)参数设置为"authKey",表明这是一个认证请求。 args (参数)设置为一个列表,该列表包含三个元素:您的 API Key ID (API密钥ID)、步骤1中生成的过期时间戳以及步骤2中生成的签名。将这些信息封装在一个JSON对象中,并通过WebSocket连接发送到服务器。服务器将验证签名和时间戳,以确认客户端的身份。

以下Python代码示例展示了如何认证WebSocket连接:


import time
import hmac
import hashlib
import base64
import 

def authenticate_websocket(ws, api_key, api_secret):
    """认证 WebSocket 连接

    Args:
        ws: WebSocket连接对象。
        api_key: API Key ID.
        api_secret: API Secret.
    """
    expires = int(round(time.time()) + 60)
    data = "GET/realtime" + str(expires)
    signature = hmac.new(api_secret.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(signature).decode('utf-8')
    auth_data = {"op": "authKey", "args": [api_key, expires, signature]}
    ws.send(.dumps(auth_data))

代码解释:

  • time.time() : 获取当前时间的Unix时间戳。
  • hmac.new(api_secret.encode('utf-8'), data.encode('utf-8'), hashlib.sha256) : 使用API Secret对数据进行HMAC-SHA256加密。 api_secret data 都需要编码为UTF-8格式。
  • digest() : 返回加密后的消息摘要的二进制表示。
  • base64.b64encode(signature) : 对二进制的消息摘要进行Base64编码。
  • decode('utf-8') : 将Base64编码后的字节串解码为UTF-8字符串。
  • .dumps(auth_data) : 将包含认证信息的字典转换为JSON字符串,以便通过WebSocket发送。

注意事项:

  • 请务必妥善保管您的 API Key ID API Secret ,避免泄露。
  • 在生产环境中,建议使用更安全的随机数生成方法生成签名。
  • 服务器端可能会对时间戳的有效性进行验证,请确保客户端和服务器的时间同步。
  • 认证失败通常会导致WebSocket连接断开,请检查您的代码和配置是否正确。
  • 根据交易所的不同,认证的细节可能略有差异,例如请求方法(GET/POST)和签名算法,请参考具体的API文档。

on_open 函数中调用

on_open 函数是 WebSocket 连接建立成功后立即执行的回调函数。在这个函数中,我们可以执行一些初始化操作,例如身份验证和订阅频道。

示例代码:


def on_open(ws):
    """连接建立时的回调函数"""
    print("### connected ###")

    #  使用 API 密钥和 API 密钥进行身份验证,确保连接的安全
    authenticate_websocket(ws, API_KEY, API_SECRET)

    #  订阅 'order' 频道,接收订单更新。
    #  `dumps` 函数用于将 Python 字典转换为 JSON 字符串,以便通过 WebSocket 发送。
    ws.send(dumps({"op": "subscribe", "args": ["order"]}))

代码解释:

  • print("### connected ###") : 打印连接成功的消息,用于调试和日志记录。
  • authenticate_websocket(ws, API_KEY, API_SECRET) : 调用身份验证函数,使用您的 API 密钥和密钥对 WebSocket 连接进行身份验证。 API_KEY API_SECRET 是您从交易平台获得的凭据。
  • ws.send(dumps({"op": "subscribe", "args": ["order"]})) : 发送订阅消息到 WebSocket 服务器。 "op": "subscribe" 指明这是一个订阅操作。 "args": ["order"] 指定要订阅的频道为 "order",该频道会推送订单状态的更新。

请务必将 API_KEY API_SECRET 替换为您真实的 API 密钥和密钥,并确保 authenticate_websocket 函数已正确实现,以便安全地对 WebSocket 连接进行身份验证。

6. 常见问题

  • 签名错误: 签名验证失败通常意味着以下几点。
    • 仔细核对你的 API Secret 是否与 BitMEX 网站上生成的一致,避免复制粘贴过程中的错误。
    • 检查使用的签名算法(例如 HMAC-SHA256)是否与 BitMEX 要求的算法完全匹配。
    • 确保构建签名时,请求体(request body)是符合要求的字符串类型。某些编程语言或库可能会自动将请求体转换为其他类型,导致签名不一致。对于没有请求体的 GET 请求,通常需要使用空字符串 "" 进行签名。
    • 检查时间戳是否准确,并与服务器时间保持同步,过期的的时间戳会导致签名验证失败。
  • 权限不足: 权限问题表明你的 API 密钥缺乏执行特定操作的授权。
    • 登录 BitMEX 网站,进入 API 密钥管理页面,确认该 API 密钥被授予了执行目标操作(例如下单、查询余额)所需的权限。
    • 不同的 API 密钥可以拥有不同的权限集,确保你的密钥拥有足够的权限。
    • 注意区分只读权限和读写权限。某些操作需要读写权限才能执行。
  • 速率限制: BitMEX API 实施速率限制,以防止滥用和保障系统稳定性。
    • 如果你的请求频率超过了允许的限制,API 将返回 HTTP 429 错误(Too Many Requests)。
    • 采取措施控制你的请求频率,例如使用队列来限制并发请求的数量。
    • 考虑使用 WebSocket 接口获取实时数据。WebSocket 接口通常具有更高的速率限制,并且可以提供推送式的实时更新,避免频繁轮询 API。
    • 查阅 BitMEX API 文档,了解不同接口的速率限制策略,并据此调整你的请求行为。
    • 实现重试机制,当遇到 429 错误时,等待一段时间后自动重试请求。
  • 连接问题: 网络连接问题会阻止你的应用程序与 BitMEX API 服务器建立通信。
    • 确保你的网络连接正常,可以访问互联网。
    • 检查你的防火墙设置,确认它没有阻止你的应用程序向 BitMEX API 服务器发送请求。防火墙规则可能需要配置允许特定端口(例如 443)的 HTTPS 流量。
    • 代理服务器的设置可能也会影响 API 请求。确认你的应用程序正确配置了代理设置(如果需要)。
    • 使用 `ping` 或 `traceroute` 命令检查与 BitMEX API 服务器的网络连通性。
    • 检查 DNS 解析是否正确,确保你的应用程序能够正确解析 BitMEX API 服务器的域名。

7. 更多信息

  • BitMEX API 文档: 深入了解 BitMEX REST API 的所有可用端点、参数和响应格式。此文档提供了构建与 BitMEX 交易平台进行交互的应用程序所需的完整参考。 https://www.bitmex.com/api/explorer/
  • BitMEX WebSocket API 文档: BitMEX WebSocket API 允许开发者建立持久连接,以接收实时市场数据和交易更新。该文档详细介绍了如何订阅不同的数据流、处理接收到的消息以及利用 WebSocket API 实现低延迟交易策略。 https://www.bitmex.com/app/wsAPI

本文旨在帮助你有效地使用 BitMEX API 进行自动化交易和数据分析。在部署到真实交易环境之前,强烈建议你在 BitMEX Testnet 上对你的应用程序进行全面测试。Testnet 提供了一个模拟环境,允许你在不冒真金白银风险的情况下验证你的代码逻辑,处理错误,并确保其按照预期运行。 通过使用 Testnet,你可以最大限度地降低潜在的财务损失,并优化你的交易策略。