REST 基本信息
- 接口可能需要用户的 API Key,如何创建API-KEY请参考用户中心 这里
- Base URL: https://openapi.pumpkin.xyz/futures/ 下面所有示例以BASE_URL代替
- 所有接口的响应都是JSON格式
- 所有接口都带有权重基数,每次请求都会消耗对应的权重数,高频操作会导致IP封禁1h。
- 接口前面带(TRADE)则代表需要交易权限
- 所有时间、时间戳均为UNIX时间,单位为毫秒
- 所有数据类型采用JAVA的数据类型定义
接口基本参数传递规则
请求方法与参数位置
- GET:所有参数应在 query string(URL 查询参数)中传递。为兼容性和可预测性,不应在 GET 请求中依赖或传送 request body。
- POST / PUT / DELETE:参数可以通过以下任意方式传递,且允许混合使用:
- query string(URL 查询参数)
- request body,Content-Type: application/x-www-form-urlencoded
参数优先级
- 当同名参数同时出现在 query string 与 request body 中时,服务器将以 query string 中的值为准(优先级:query > body)。
编码与 Content-Type
- body 使用 application/x-www-form-urlencoded 时,body 必须为经过 URL 编码的键值对(例如 key1=value1&key2=value2)。
- query string 的键值也应进行 URL 编码(例如对空格、特殊字符进行百分号编码)。
- 请求中必须正确设置 Content-Type 头以便服务器正确解析 body。
示例(curl):
curl --location --request GET 'BASE_URL/v2/balance/list' \ --header 'X_ACCESS_KEY: CEm6kiOLFUurrC72afj8W7r9RLsqdjQKOGARAv080gkgWXgkikfvRhvtGiyUnebP' \ --header 'X_SIGNATURE: 5d9e9d4ad1515802dc3fa3c695bca0776f6d82c52793a0625193db088d4978dd'
访问频率限制
鉴权与限流策略说明。
鉴权
- 使用请求头进行鉴权:
- X_ACCESS_KEY: 用户访问 Key
- X_SIGNATURE: 签名,用于校验请求合法性
权重与配额规则
- 每个 API 会定义一个“接口权重”(每次调用消耗的权重值)。
- 每个用户有两个维度的配额:
- 每分钟总权重:用于限制短期访问速率(每分钟一个计数器)。
- 每日总权重:用于限制全天累计访问(默认每日 100000)。
- 配额消耗:
- 每次请求到达时,按该接口的权重同时扣减“当前分钟剩余权重”和“当日剩余权重”。
- 仅当两个维度的剩余权重都足够时,才允许此次请求通过;否则拒绝请求并返回限流错误。
重置时点(时间基准)
- 所有重置都基于服务端时间(避免客户端时钟差异)。
- 每分钟配额在“下一分钟的 0 秒”更新(即按分钟边界重置)。
- 示例:在 12:34:xx 期间使用的是 12:34 分钟的配额;当时间到 12:35:00 时,12:35 分钟的配额开始生效。
- 每日配额在次日更新(基于服务端日期,通常在 00:00 重置)。
处理超额请求(建议)
- 当检测到配额不足时,返回 HTTP 439 (Too Many Requests) 或自定义错误码,并在响应中告知:
- 限额类型
- 当前权重
- 限制权重
- 剩余重试时间(例如距离下一分钟或次日重置的秒数)
示例(伪流程)
- 接收到请求 -> 验证 X_ACCESS_KEY 与 X_SIGNATURE。
- 查询该用户当前分钟剩余权重与当日剩余权重。
- 若两者均 >= 本接口权重,则扣减对应权重,放行请求。
- 若任一不足,则返回限流错误(439),并告知重试时间或剩余配额。
交易对白名单限制
对于交易接口币对交易权限的限制,仅当用户设置了交易权限并提交了交易对白名单时生效。
相关限制接口
| 方法 | 接口 | 描述 |
|---|---|---|
| POST | /v2/order/create |
创建订单 |
| POST | /v2/order/create-batch |
批量创建订单 |
| POST | /v2/entrust/create-plan |
创建计划委托 |
| POST | /v2/entrust/create-profit |
创建止盈止损 |
| POST | /v2/position/adjust-leverage |
调整杠杆 |
| POST | /v2/position/margin |
调整保证金 |
| POST | /v2/position/change-type |
修改持仓类型 |
限制规则
| 规则项 | 说明 |
|---|---|
| 白名单数量限制 | 最多可设置30个交易对 |
| 交易权限限制 | 仅允许在白名单中的交易对进行交易 |
| 错误码 | 467 |
| 错误消息 | symbol-not-in-allowed |
使用说明
- 白名单设置:用户可通过API管理界面设置交易对白名单
- 生效范围:仅对已设置交易权限的API Key生效
- 校验时机:在创建订单、委托等交易操作时进行校验
- 默认行为:如未设置白名单,则不进行交易对限制
API Key 使用规范
概述
API Key 用于鉴别调用方身份和控制权限。若服务需要 API Key,请按照以下规范传递与管理。
传递方式
- 必须通过 HTTP 请求头传递:使用字段名 X_ACCESS_KEY。
- 示例(curl):
- curl -H "X_ACCESS_KEY: your_api_key_here"
- 示例(curl):
- 请勿将 API Key 放入 URL 查询参数(query string)或公开的客户端代码中,以避免泄露。
- 所有请求必须通过 HTTPS 发送,防止中间人窃取密钥。
敏感性
- API Key 为大小写敏感。传递时请保持精确一致。
权限与管理
- API Key 可在用户中心或key管理面板中配置权限,例如:
- 读取平台信息
- 发送交易指令
- 推荐采用最小权限原则:为不同用途生成不同 Key,并只赋予必要权限。
密钥轮换与撤销
- 建议定期轮换(更换)API Key,避免长期暴露风险。
- 如发现密钥泄露或异常访问,应立即在用户中心清除并更换新 Key。
错误与响应
- 未携带或无效的 API Key:返回
1,并提示原因。 - 被撤销或权限不足的请求:返回
-1,并说明缺失的权限。
示例响应(示意)
- 1:
- { "returnCode": 1, "msgInfo": "sign-error" }
- -1:
- { "returnCode": -1, "msgInfo": "contract-not-support" }
签名算法
调用这些接口时,除了接口本身所需的参数外,还需要在请求头中携带 X_SIGNATURE 即签名参数。
- 使用 HMAC SHA256 算法
- API私钥 作为 HMAC SHA256 的密钥
- 其他请求体参数作为 HMAC SHA256 的操作对象
- 得到的输出即为签名
- 签名大小写不敏感
签名请求参数拼接方式
调用接口时需要将请求所携带参数和API私钥使用HMAC SHA256算法生成签名值
- API私钥从管理页面获取,创建时只展示一次
- 参数采用TreeMap拼接,基于键的字母顺序排序
行情接口
获取服务器时间
import time
import hmac
import hashlib
import requests
url = "BASE_URL/v2/public/time"
access_key = "your_api_accessKey"
secret_key = "your_api_secretKey"
timestamp = str(int(time.time() * 1000))
signature = hmac.new(secret_key.encode('utf-8'), timestamp.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": access_key,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
data = resp.json()
print("HTTP status:", resp.status_code)
print("Response:", data)
if data.get("code") == 0 and "data" in data:
print("serverTime:", data["data"].get("serverTime"))
else:
print("Error:", data.get("message"))
import crypto from "crypto";
import fetch from "node-fetch";
const url = "BASE_URL/v2/public/time";
const accessKey = "your_api_accessKey";
const secretKey = "your_api_secretKey";
const timestamp = Date.now().toString();
const signature = crypto.createHmac("sha256", secretKey).update(timestamp).digest("hex");
const headers = {
"X_ACCESS_KEY": accessKey,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
async function getServerTime() {
const resp = await fetch(url, { method: "GET", headers });
const data = await resp.json();
console.log("HTTP status:", resp.status);
console.log("Response:", data);
if (data.code === 0 && data.data) {
console.log("serverTime:", data.data.serverTime);
} else {
console.error("Error:", data.message);
}
}
getServerTime().catch(console.error);
描述:获取服务器当前时间戳,用于同步客户端时间。
接口权重:1
请求方式:GET
请求地址:/v2/public/time
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应字段
| 字段 | 类型 | 描述 | 示例 |
|---|---|---|---|
| data | Long | 服务器当前时间戳(毫秒) | 1769582710262 |
响应示例:
{
"code": 0,
"msg": "success",
"data": 1769582710262,
"bizCode": null
}
字段说明:
data:服务器当前时间戳(毫秒)
获取交易对列表
import requests
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
base_url = "BASE_URL"
path = "/v2/public/symbol/list"
params = {"status": "TRADING"}
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(base_url + path, headers=headers, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()
print(data)
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const baseUrl = "BASE_URL";
const path = "/v2/public/symbol/list";
const params = { status: "TRADING" };
axios.get(baseUrl + path, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.error(err.response ? err.response.data : err.message);
});
描述:获取平台支持的所有交易对基本信息列表。
接口权重:1
请求方式:GET
请求地址:/v2/public/symbol/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(body):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| status | 否 | 交易对状态:TRADING(交易中) | TRADING |
响应字段说明
| 字段 | 类型 | 描述 | 示例 |
|---|---|---|---|
| id | Long | 交易对ID | 1 |
| symbol | String | 交易对名称 | btc_usdt |
| contractType | String | 合约类型 | PERPETUAL(永续) |
| underlyingType | String | 标的类型 | U_BASED(U本位),COIN(币本位) |
| contractSize | BigDecimal | 合约乘数(面值) | 0.001 |
| tradeSwitch | Boolean | 交易开关 | true |
| state | Integer | 状态 | 1(正常) |
| initLeverage | Integer | 初始杠杆倍数 | 20 |
| initPositionType | String | 初始仓位类型 | ISOLATED(逐仓) |
| baseCoin | String | 标的资产 | BTC |
| quoteCoin | String | 报价资产 | USDT |
| baseCoinPrecision | Integer | 标的币种精度 | 8 |
| baseCoinDisplayPrecision | Integer | 标的币种显示精度 | 8 |
| quoteCoinPrecision | Integer | 报价币种精度 | 2 |
| quoteCoinDisplayPrecision | Integer | 报价币种显示精度 | 2 |
| quantityPrecision | Integer | 数量精度 | 3 |
| pricePrecision | Integer | 价格精度 | 2 |
| supportOrderType | String | 支持订单类型 | LIMIT,MARKET |
| supportTimeInForce | String | 支持有效方式 | GTC,IOC,FOK |
| supportEntrustType | String | 支持计划委托类型 | STOP_MARKET,STOP_LIMIT,TAKE_PROFIT_MARKET,TAKE_PROFIT_LIMIT |
| supportPositionType | String | 支持仓位类型 | ISOLATED,CROSS |
| minPrice | BigDecimal | 最小价格 | 0.01 |
| minQty | BigDecimal | 最小数量 | 0.001 |
| minNotional | BigDecimal | 最小名义价值 | 10.00 |
| maxNotional | BigDecimal | 最大名义价值 | 1000000.00 |
| multiplierDown | BigDecimal | 限价卖单下限百分比 | 0.95 |
| multiplierUp | BigDecimal | 限价买单价格上限百分比 | 1.05 |
| maxOpenOrders | Integer | 最多open订单数 | 100 |
| maxEntrusts | Integer | 最多open条件单数 | 100 |
| makerFee | BigDecimal | Maker手续费率 | 0.0002 |
| takerFee | BigDecimal | Taker手续费率 | 0.0005 |
| liquidationFee | BigDecimal | 强平手续费率 | 0.0005 |
| marketTakeBound | BigDecimal | 市价单最多价格偏离 | 0.005 |
| depthPrecisionMerge | Integer | 盘口精度合并 | 4 |
| labels | List |
标签 | ["HOT", "NEW"] |
| onboardDate | Long | 上线时间(毫秒时间戳) | 1651500001000 |
| enName | String | 合约英文名称 | btc_usdt Perpetual |
| cnName | String | 合约中文名称 | btc_usdt 永续 |
| minStepPrice | BigDecimal | 最小价格变动单位 | 0.1 |
| robotRate | BigDecimal | 做市资金占比(%) | 10 |
| pfRatio | BigDecimal | 对冲池资金比例(%) | 0 |
| tfRatio | BigDecimal | 国库资金比例(%) | 0 |
| plate | String | 分区配置(JSON字符串) | "[\"22\",\"23\",\"24\",\"86\"]" |
| baseCoinName | String | 标的币种名称 | btc |
| quoteCoinName | String | 报价币种名称 | usdt |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"id": 1,
"symbol": "btc_usdt",
"contractType": "PERPETUAL",
"underlyingType": "U_BASED",
"contractSize": "0.0001",
"tradeSwitch": true,
"state": 0,
"initLeverage": 25,
"initPositionType": "CROSSED",
"baseCoin": "btc",
"quoteCoin": "usdt",
"baseCoinPrecision": 8,
"baseCoinDisplayPrecision": 4,
"quoteCoinPrecision": 4,
"quoteCoinDisplayPrecision": 8,
"quantityPrecision": 0,
"pricePrecision": 1,
"supportOrderType": "LIMIT,MARKET",
"supportTimeInForce": "GTC,FOK,IOC,GTX",
"supportEntrustType": "TAKE_PROFIT,STOP,TAKE_PROFIT_MARKET,STOP_MARKET,TRAILING_STOP_MARKET",
"supportPositionType": "CROSSED,ISOLATED",
"minPrice": null,
"minQty": "1",
"minNotional": "1",
"maxNotional": "100000000",
"multiplierDown": "0.1",
"multiplierUp": "0.1",
"maxOpenOrders": 100,
"maxEntrusts": 100,
"makerFee": "0.0002",
"takerFee": "0.0005",
"liquidationFee": "0.0005",
"marketTakeBound": "0.005",
"depthPrecisionMerge": 4,
"labels": [
"HOT"
],
"onboardDate": 1651500001000,
"enName": "btc_usdt Perpetual",
"cnName": "btc_usdt 永续",
"minStepPrice": "0.1",
"robotRate": "10",
"pfRatio": "0",
"tfRatio": "0",
"plate": "[\"22\",\"23\",\"24\",\"86\"]",
"baseCoinName": "btc",
"quoteCoinName": "usdt"
},
{
"id": 2,
"symbol": "eth_usdt",
"contractType": "PERPETUAL",
"underlyingType": "U_BASED",
"contractSize": "0.001",
"tradeSwitch": true,
"state": 0,
"initLeverage": 10,
"initPositionType": "CROSSED",
"baseCoin": "eth",
"quoteCoin": "usdt",
"baseCoinPrecision": 8,
"baseCoinDisplayPrecision": 4,
"quoteCoinPrecision": 8,
"quoteCoinDisplayPrecision": 8,
"quantityPrecision": 0,
"pricePrecision": 2,
"supportOrderType": "LIMIT,MARKET",
"supportTimeInForce": "GTC,FOK,IOC,GTX",
"supportEntrustType": "TAKE_PROFIT,STOP,TAKE_PROFIT_MARKET,STOP_MARKET,TRAILING_STOP_MARKET",
"supportPositionType": "CROSSED,ISOLATED",
"minPrice": null,
"minQty": "1",
"minNotional": "1",
"maxNotional": "100000000",
"multiplierDown": "0.1",
"multiplierUp": "0.1",
"maxOpenOrders": 100,
"maxEntrusts": 100,
"makerFee": "0.0002",
"takerFee": "0.0005",
"liquidationFee": "0.0005",
"marketTakeBound": "0.005",
"depthPrecisionMerge": 4,
"labels": [
"HOT"
],
"onboardDate": 1651298519000,
"enName": "eth_usdt Perpetual",
"cnName": "eth_usdt 永续",
"minStepPrice": "0.01",
"robotRate": "10",
"pfRatio": "0",
"tfRatio": "0",
"plate": "[\"24\",\"86\"]",
"baseCoinName": "eth",
"quoteCoinName": "usdt"
}
],
"bizCode": null
}
交易对详情
import requests
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
base_url = "BASE_URL"
path = "/v2/public/symbol/detail"
params = {"symbol": "btc_usdt"}
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(base_url + path, headers=headers, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()
print(data)
if data.get("code") == 0:
detail = data.get("data", {})
print("pricePrecision:", detail.get("pricePrecision"))
print("quantityPrecision:", detail.get("quantityPrecision"))
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const baseUrl = "BASE_URL";
const path = "/v2/public/symbol/detail";
const params = { symbol: "btc_usdt" };
axios.get(baseUrl + path, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
})
.then(res => {
console.log(res.data);
if (res.data.code === 0) {
const d = res.data.data;
console.log("pricePrecision:", d.pricePrecision);
console.log("quantityPrecision:", d.quantityPrecision);
}
})
.catch(err => {
console.error(err.response ? err.response.data : err.message);
});
描述:获取指定交易对的详细信息,包括精度、最小交易量、手续费等。
接口权重:1
请求方式:GET
请求地址:/v2/public/symbol/detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识 | btc_usdt |
响应字段说明
| 字段 | 类型 | 描述 | 示例 |
|---|---|---|---|
| id | Long | 交易对ID | 1 |
| symbol | String | 交易对名称 | btc_usdt |
| contractType | String | 合约类型 | PERPETUAL(永续) |
| underlyingType | String | 标的类型 | USDT(U本位),COIN(币本位) |
| contractSize | BigDecimal | 合约乘数(面值) | 0.001 |
| tradeSwitch | Boolean | 交易开关 | true |
| state | Integer | 状态 | 1(正常) |
| initLeverage | Integer | 初始杠杆倍数 | 20 |
| initPositionType | String | 初始仓位类型 | ISOLATED(逐仓) |
| baseCoin | String | 标的资产 | BTC |
| quoteCoin | String | 报价资产 | USDT |
| baseCoinPrecision | Integer | 标的币种精度 | 8 |
| baseCoinDisplayPrecision | Integer | 标的币种显示精度 | 8 |
| quoteCoinPrecision | Integer | 报价币种精度 | 2 |
| quoteCoinDisplayPrecision | Integer | 报价币种显示精度 | 2 |
| quantityPrecision | Integer | 数量精度 | 3 |
| pricePrecision | Integer | 价格精度 | 2 |
| supportOrderType | String | 支持订单类型 | LIMIT,MARKET |
| supportTimeInForce | String | 支持有效方式 | GTC,IOC,FOK |
| supportEntrustType | String | 支持计划委托类型 | STOP_MARKET,STOP_LIMIT,TAKE_PROFIT_MARKET,TAKE_PROFIT_LIMIT |
| supportPositionType | String | 支持仓位类型 | ISOLATED,CROSS |
| minPrice | BigDecimal | 最小价格 | 0.01 |
| minQty | BigDecimal | 最小数量 | 0.001 |
| minNotional | BigDecimal | 最小名义价值 | 10.00 |
| maxNotional | BigDecimal | 最大名义价值 | 1000000.00 |
| multiplierDown | BigDecimal | 限价卖单下限百分比 | 0.95 |
| multiplierUp | BigDecimal | 限价买单价格上限百分比 | 1.05 |
| maxOpenOrders | Integer | 最多open订单数 | 200 |
| maxEntrusts | Integer | 最多open条件单数 | 20 |
| makerFee | BigDecimal | Maker手续费率 | 0.0002 |
| takerFee | BigDecimal | Taker手续费率 | 0.0005 |
| liquidationFee | BigDecimal | 强平手续费率 | 0.0002 |
| marketTakeBound | BigDecimal | 市价单最多价格偏离 | 0.10 |
| depthPrecisionMerge | Integer | 盘口精度合并 | 8 |
| labels | List |
标签 | ["HOT", "NEW"] |
| onboardDate | Long | 上线时间(毫秒时间戳) | 1640995200000 |
| enName | String | 合约英文名称 | Bitcoin Perpetual |
| cnName | String | 合约中文名称 | 比特币永续合约 |
| minStepPrice | BigDecimal | 最小价格变动单位 | 0.01 |
| robotRate | BigDecimal | 做市资金占比(%) | 30.00 |
| pfRatio | BigDecimal | 对冲池资金比例(%) | 50.00 |
| tfRatio | BigDecimal | 国库资金比例(%) | 20.00 |
| plate | String | 分区配置(JSON字符串) | "[1,10]" |
| baseCoinName | String | 标的币种名称 | Bitcoin |
| quoteCoinName | String | 报价币种名称 | Tether |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"symbol": "btc_usdt",
"contractType": "PERPETUAL",
"underlyingType": "U_BASED",
"contractSize": "0.0001",
"tradeSwitch": true,
"state": 0,
"initLeverage": 25,
"initPositionType": "CROSSED",
"baseCoin": "btc",
"quoteCoin": "usdt",
"baseCoinPrecision": 8,
"baseCoinDisplayPrecision": 4,
"quoteCoinPrecision": 4,
"quoteCoinDisplayPrecision": 8,
"quantityPrecision": 0,
"pricePrecision": 1,
"supportOrderType": "LIMIT,MARKET",
"supportTimeInForce": "GTC,FOK,IOC,GTX",
"supportEntrustType": "TAKE_PROFIT,STOP,TAKE_PROFIT_MARKET,STOP_MARKET,TRAILING_STOP_MARKET",
"supportPositionType": "CROSSED,ISOLATED",
"minPrice": null,
"minQty": "1",
"minNotional": "1",
"maxNotional": "100000000",
"multiplierDown": "0.1",
"multiplierUp": "0.1",
"maxOpenOrders": 100,
"maxEntrusts": 100,
"makerFee": "0.0002",
"takerFee": "0.0005",
"liquidationFee": "0.0005",
"marketTakeBound": "0.005",
"depthPrecisionMerge": 4,
"labels": [
"HOT"
],
"onboardDate": 1651500001000,
"enName": "btc_usdt Perpetual",
"cnName": "btc_usdt 永续",
"minStepPrice": "0.1",
"robotRate": "10",
"pfRatio": "0",
"tfRatio": "0",
"plate": "[\"22\",\"23\",\"24\",\"86\"]",
"baseCoinName": "btc",
"quoteCoinName": "usdt"
},
"bizCode": null
}
获取合约币种列表
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/symbol/all"
params = {}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params or None, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
async function fetchAllSymbols() {
try {
const res = await axios.get("BASE_URL/v2/public/symbol/all", {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchAllSymbols();
描述:获取所有交易对的完整配置信息,包括合约规格、风险限额等。
接口权重:1
请求方式:GET
请求地址:/v2/public/symbol/all
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应示例:
{
"code": 0,
"msg": "success",
"data": [
"btc_usdt",
"eth_usdt",
"sol_usdt",
"atom_usdt",
"doge_usdt",
"bnb_usdt",
"hype_usdt",
"xrp_usdt",
"aster_usdt",
"link_usdt",
"pump_usdt",
"trx_usdt",
"sui_usdt",
"1000pepe_usdt",
"1000shib_usdt",
"aevo_usdt",
"wlfi_usdt"
],
"bizCode": null
}
行情Tickers
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/ticker"
params = {"symbol": "btc_usdt", "timeRangeType": "D"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/ticker";
const params = { symbol: "btc_usdt", timeRangeType: "D" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchTickerSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchTickerSigned();
描述:获取单个交易对的最新行情数据,包括最新价、24小时成交量、涨跌幅等。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/ticker
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencodedunderlying-type: usdt (usdt代表U本位 coin代表币本位)
查询参数(query):
| 参数 | 必填 | 描述 | 示例 | 枚举值 |
|---|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt | - |
| timeRangeType | 是 | 时间范围类型 | H24 | 见下方详细枚举 |
timeRangeType枚举:
| 枚举值 | 描述 | UTC时区偏移 | 说明 |
|---|---|---|---|
H24 |
24小时滚动数据 | UTC | 过去24小时滚动数据 |
UTC_P_12 |
UTC+12时区 | +12:00 | 基于UTC+12时区的交易日数据 |
UTC_P_11 |
UTC+11时区 | +11:00 | 基于UTC+11时区的交易日数据 |
UTC_P_10 |
UTC+10时区 | +10:00 | 基于UTC+10时区的交易日数据 |
UTC_P_9 |
UTC+9时区 | +09:00 | 基于UTC+9时区的交易日数据 |
UTC_P_8 |
UTC+8时区 | +08:00 | 基于UTC+8时区的交易日数据 |
UTC_P_7 |
UTC+7时区 | +07:00 | 基于UTC+7时区的交易日数据 |
UTC_P_6 |
UTC+6时区 | +06:00 | 基于UTC+6时区的交易日数据 |
UTC_P_5 |
UTC+5时区 | +05:00 | 基于UTC+5时区的交易日数据 |
UTC_P_4 |
UTC+4时区 | +04:00 | 基于UTC+4时区的交易日数据 |
UTC_P_3 |
UTC+3时区 | +03:00 | 基于UTC+3时区的交易日数据 |
UTC_P_2 |
UTC+2时区 | +02:00 | 基于UTC+2时区的交易日数据 |
UTC_P_1 |
UTC+1时区 | +01:00 | 基于UTC+1时区的交易日数据 |
UTC_P_0 |
UTC+0时区 | +00:00 | 基于UTC+0时区的交易日数据 |
UTC_N_1 |
UTC-1时区 | -01:00 | 基于UTC-1时区的交易日数据 |
UTC_N_2 |
UTC-2时区 | -02:00 | 基于UTC-2时区的交易日数据 |
UTC_N_3 |
UTC-3时区 | -03:00 | 基于UTC-3时区的交易日数据 |
UTC_N_4 |
UTC-4时区 | -04:00 | 基于UTC-4时区的交易日数据 |
UTC_N_5 |
UTC-5时区 | -05:00 | 基于UTC-5时区的交易日数据 |
UTC_N_6 |
UTC-6时区 | -06:00 | 基于UTC-6时区的交易日数据 |
UTC_N_7 |
UTC-7时区 | -07:00 | 基于UTC-7时区的交易日数据 |
UTC_N_8 |
UTC-8时区 | -08:00 | 基于UTC-8时区的交易日数据 |
UTC_N_9 |
UTC-9时区 | -09:00 | 基于UTC-9时区的交易日数据 |
UTC_N_10 |
UTC-10时区 | -10:00 | 基于UTC-10时区的交易日数据 |
UTC_N_11 |
UTC-11时区 | -11:00 | 基于UTC-11时区的交易日数据 |
UTC_N_12 |
UTC-12时区 | -12:00 | 基于UTC-12时区的交易日数据 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
c |
String | 最新价格 | "89192.3" |
h |
String | 统计周期内最高价 | "89493.3" |
l |
String | 统计周期内最低价 | "87255.6" |
a |
String | 统计周期内成交量(基础币种) | "7216921.4" |
v |
String | 统计周期内成交额(计价币种) | "63836031.32165" |
o |
String | 统计周期开始时的第一笔成交价 | "88289.9" |
r |
String | 统计周期内的涨跌幅(百分比,例如"0.0102"表示1.02%) | "0.0102" |
说明:
- 统计周期:
- 当
timeRangeType=H24时,统计过去24小时滚动数据 - 当
timeRangeType为其他时区值时,统计对应时区当日(00:00-当前时间)的数据
- 当
- 交易对格式:返回的交易对标识为小写字母,中间用下划线分隔(如 "btc_usdt")
- 涨跌幅计算:
r = (c - o) / o,以字符串形式表示百分比 - 价格精度:所有价格字段均为字符串,以避免浮点数精度问题
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"t": 1769584725803,
"s": "btc_usdt",
"c": "89192.3",
"h": "89493.3",
"l": "87255.6",
"a": "7216921.4",
"v": "63836031.32165",
"o": "88289.9",
"r": "0.0102"
},
"bizCode": null
}
行情列表
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/tickers"
params = {"timeRangeType": "D"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/tickers";
const params = { timeRangeType: "D" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchTickersSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchTickersSigned();
描述:获取所有交易对的24小时行情数据汇总。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/tickers
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencodedunderlying-type: usdt (usdt代表U本位 coin代表币本位)
查询参数(query):
| 参数 | 必填 | 描述 | 示例 | 枚举值 |
|---|---|---|---|---|
| timeRangeType | 是 | 时间范围类型 | H24 | H24(24小时) |
timeRangeType枚举:
| 枚举值 | 描述 | UTC时区偏移 | 说明 |
|---|---|---|---|
H24 |
24小时滚动数据 | UTC | 过去24小时滚动数据 |
UTC_P_12 |
UTC+12时区 | +12:00 | 基于UTC+12时区的交易日数据 |
UTC_P_11 |
UTC+11时区 | +11:00 | 基于UTC+11时区的交易日数据 |
UTC_P_10 |
UTC+10时区 | +10:00 | 基于UTC+10时区的交易日数据 |
UTC_P_9 |
UTC+9时区 | +09:00 | 基于UTC+9时区的交易日数据 |
UTC_P_8 |
UTC+8时区 | +08:00 | 基于UTC+8时区的交易日数据 |
UTC_P_7 |
UTC+7时区 | +07:00 | 基于UTC+7时区的交易日数据 |
UTC_P_6 |
UTC+6时区 | +06:00 | 基于UTC+6时区的交易日数据 |
UTC_P_5 |
UTC+5时区 | +05:00 | 基于UTC+5时区的交易日数据 |
UTC_P_4 |
UTC+4时区 | +04:00 | 基于UTC+4时区的交易日数据 |
UTC_P_3 |
UTC+3时区 | +03:00 | 基于UTC+3时区的交易日数据 |
UTC_P_2 |
UTC+2时区 | +02:00 | 基于UTC+2时区的交易日数据 |
UTC_P_1 |
UTC+1时区 | +01:00 | 基于UTC+1时区的交易日数据 |
UTC_P_0 |
UTC+0时区 | +00:00 | 基于UTC+0时区的交易日数据 |
UTC_N_1 |
UTC-1时区 | -01:00 | 基于UTC-1时区的交易日数据 |
UTC_N_2 |
UTC-2时区 | -02:00 | 基于UTC-2时区的交易日数据 |
UTC_N_3 |
UTC-3时区 | -03:00 | 基于UTC-3时区的交易日数据 |
UTC_N_4 |
UTC-4时区 | -04:00 | 基于UTC-4时区的交易日数据 |
UTC_N_5 |
UTC-5时区 | -05:00 | 基于UTC-5时区的交易日数据 |
UTC_N_6 |
UTC-6时区 | -06:00 | 基于UTC-6时区的交易日数据 |
UTC_N_7 |
UTC-7时区 | -07:00 | 基于UTC-7时区的交易日数据 |
UTC_N_8 |
UTC-8时区 | -08:00 | 基于UTC-8时区的交易日数据 |
UTC_N_9 |
UTC-9时区 | -09:00 | 基于UTC-9时区的交易日数据 |
UTC_N_10 |
UTC-10时区 | -10:00 | 基于UTC-10时区的交易日数据 |
UTC_N_11 |
UTC-11时区 | -11:00 | 基于UTC-11时区的交易日数据 |
UTC_N_12 |
UTC-12时区 | -12:00 | 基于UTC-12时区的交易日数据 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
c |
String | 最新价格 | "89192.3" |
h |
String | 统计周期内最高价 | "89493.3" |
l |
String | 统计周期内最低价 | "87255.6" |
a |
String | 统计周期内成交量(基础币种) | "7216921.4" |
v |
String | 统计周期内成交额(计价币种) | "63836031.32165" |
o |
String | 统计周期开始时的第一笔成交价 | "88289.9" |
r |
String | 统计周期内的涨跌幅(百分比,例如"0.0102"表示1.02%) | "0.0102" |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"t": 1769597269001,
"s": "btc_usdt",
"c": "89452.1",
"h": "89650.4",
"l": "87255.6",
"a": "7469238.6",
"v": "66159976.89515",
"o": "87735.3",
"r": "0.0195"
},
{
"t": 1769597267407,
"s": "eth_usdt",
"c": "3027.95",
"h": "3035.20",
"l": "2900.31",
"a": "5151240",
"v": "15335904.01611",
"o": "2902.23",
"r": "0.0433"
}
],
"bizCode": null
}
聚合行情
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/agg-ticker"
params = {"symbol": "btc_usdt", "timeRangeType": "D"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/agg-ticker";
const params = { symbol: "btc_usdt", timeRangeType: "D" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchAggTickerSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchAggTickerSigned();
描述:获取单个交易对的聚合行情数据,包含更多统计指标。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/agg-ticker
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt |
| timeRangeType | 是 | 时间范围类型 | H24 |
timeRangeType枚举:
| 枚举值 | 描述 | UTC时区偏移 | 说明 |
|---|---|---|---|
H24 |
24小时滚动数据 | UTC | 过去24小时滚动数据 |
UTC_P_12 |
UTC+12时区 | +12:00 | 基于UTC+12时区的交易日数据 |
UTC_P_11 |
UTC+11时区 | +11:00 | 基于UTC+11时区的交易日数据 |
UTC_P_10 |
UTC+10时区 | +10:00 | 基于UTC+10时区的交易日数据 |
UTC_P_9 |
UTC+9时区 | +09:00 | 基于UTC+9时区的交易日数据 |
UTC_P_8 |
UTC+8时区 | +08:00 | 基于UTC+8时区的交易日数据 |
UTC_P_7 |
UTC+7时区 | +07:00 | 基于UTC+7时区的交易日数据 |
UTC_P_6 |
UTC+6时区 | +06:00 | 基于UTC+6时区的交易日数据 |
UTC_P_5 |
UTC+5时区 | +05:00 | 基于UTC+5时区的交易日数据 |
UTC_P_4 |
UTC+4时区 | +04:00 | 基于UTC+4时区的交易日数据 |
UTC_P_3 |
UTC+3时区 | +03:00 | 基于UTC+3时区的交易日数据 |
UTC_P_2 |
UTC+2时区 | +02:00 | 基于UTC+2时区的交易日数据 |
UTC_P_1 |
UTC+1时区 | +01:00 | 基于UTC+1时区的交易日数据 |
UTC_P_0 |
UTC+0时区 | +00:00 | 基于UTC+0时区的交易日数据 |
UTC_N_1 |
UTC-1时区 | -01:00 | 基于UTC-1时区的交易日数据 |
UTC_N_2 |
UTC-2时区 | -02:00 | 基于UTC-2时区的交易日数据 |
UTC_N_3 |
UTC-3时区 | -03:00 | 基于UTC-3时区的交易日数据 |
UTC_N_4 |
UTC-4时区 | -04:00 | 基于UTC-4时区的交易日数据 |
UTC_N_5 |
UTC-5时区 | -05:00 | 基于UTC-5时区的交易日数据 |
UTC_N_6 |
UTC-6时区 | -06:00 | 基于UTC-6时区的交易日数据 |
UTC_N_7 |
UTC-7时区 | -07:00 | 基于UTC-7时区的交易日数据 |
UTC_N_8 |
UTC-8时区 | -08:00 | 基于UTC-8时区的交易日数据 |
UTC_N_9 |
UTC-9时区 | -09:00 | 基于UTC-9时区的交易日数据 |
UTC_N_10 |
UTC-10时区 | -10:00 | 基于UTC-10时区的交易日数据 |
UTC_N_11 |
UTC-11时区 | -11:00 | 基于UTC-11时区的交易日数据 |
UTC_N_12 |
UTC-12时区 | -12:00 | 基于UTC-12时区的交易日数据 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
c |
String | 最新价格 | "89192.3" |
h |
String | 统计周期内最高价 | "89493.3" |
l |
String | 统计周期内最低价 | "87255.6" |
a |
String | 统计周期内成交量(基础币种) | "7216921.4" |
v |
String | 统计周期内成交额(计价币种) | "63836031.32165" |
o |
String | 统计周期开始时的第一笔成交价 | "88289.9" |
r |
String | 统计周期内的涨跌幅(百分比,例如"0.0102"表示1.02%) | "0.0102" |
i |
String | 指数价格 | "89423.4" |
m |
String | 标记价格 | "89429.2" |
bp |
String | 买一价格 | "89422.8" |
ap |
String | 卖一价格 | "89424.1" |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"t": 1769597496859,
"s": "btc_usdt",
"c": "89423.3",
"h": "89650.4",
"l": "87255.6",
"a": "7475284.7",
"v": "66214057.48860",
"o": "87735.3",
"r": "0.0192",
"i": "89423.4",
"m": "89429.2",
"bp": "89422.8",
"ap": "89424.1"
},
"bizCode": null
}
聚合行情列表
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/agg-tickers"
params = {"timeRangeType": "D"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/agg-tickers";
const params = { timeRangeType: "D" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchAggTickersSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchAggTickersSigned();
描述:获取所有交易对的聚合行情数据列表。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/agg-tickers
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 | 枚举值 |
|---|---|---|---|---|
| timeRangeType | 是 | 时间范围类型 | H24 | H24(24小时) |
timeRangeType枚举:
| 枚举值 | 描述 | UTC时区偏移 | 说明 |
|---|---|---|---|
H24 |
24小时滚动数据 | UTC | 过去24小时滚动数据 |
UTC_P_12 |
UTC+12时区 | +12:00 | 基于UTC+12时区的交易日数据 |
UTC_P_11 |
UTC+11时区 | +11:00 | 基于UTC+11时区的交易日数据 |
UTC_P_10 |
UTC+10时区 | +10:00 | 基于UTC+10时区的交易日数据 |
UTC_P_9 |
UTC+9时区 | +09:00 | 基于UTC+9时区的交易日数据 |
UTC_P_8 |
UTC+8时区 | +08:00 | 基于UTC+8时区的交易日数据 |
UTC_P_7 |
UTC+7时区 | +07:00 | 基于UTC+7时区的交易日数据 |
UTC_P_6 |
UTC+6时区 | +06:00 | 基于UTC+6时区的交易日数据 |
UTC_P_5 |
UTC+5时区 | +05:00 | 基于UTC+5时区的交易日数据 |
UTC_P_4 |
UTC+4时区 | +04:00 | 基于UTC+4时区的交易日数据 |
UTC_P_3 |
UTC+3时区 | +03:00 | 基于UTC+3时区的交易日数据 |
UTC_P_2 |
UTC+2时区 | +02:00 | 基于UTC+2时区的交易日数据 |
UTC_P_1 |
UTC+1时区 | +01:00 | 基于UTC+1时区的交易日数据 |
UTC_P_0 |
UTC+0时区 | +00:00 | 基于UTC+0时区的交易日数据 |
UTC_N_1 |
UTC-1时区 | -01:00 | 基于UTC-1时区的交易日数据 |
UTC_N_2 |
UTC-2时区 | -02:00 | 基于UTC-2时区的交易日数据 |
UTC_N_3 |
UTC-3时区 | -03:00 | 基于UTC-3时区的交易日数据 |
UTC_N_4 |
UTC-4时区 | -04:00 | 基于UTC-4时区的交易日数据 |
UTC_N_5 |
UTC-5时区 | -05:00 | 基于UTC-5时区的交易日数据 |
UTC_N_6 |
UTC-6时区 | -06:00 | 基于UTC-6时区的交易日数据 |
UTC_N_7 |
UTC-7时区 | -07:00 | 基于UTC-7时区的交易日数据 |
UTC_N_8 |
UTC-8时区 | -08:00 | 基于UTC-8时区的交易日数据 |
UTC_N_9 |
UTC-9时区 | -09:00 | 基于UTC-9时区的交易日数据 |
UTC_N_10 |
UTC-10时区 | -10:00 | 基于UTC-10时区的交易日数据 |
UTC_N_11 |
UTC-11时区 | -11:00 | 基于UTC-11时区的交易日数据 |
UTC_N_12 |
UTC-12时区 | -12:00 | 基于UTC-12时区的交易日数据 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
c |
String | 最新价格 | "89192.3" |
h |
String | 统计周期内最高价 | "89493.3" |
l |
String | 统计周期内最低价 | "87255.6" |
a |
String | 统计周期内成交量(基础币种) | "7216921.4" |
v |
String | 统计周期内成交额(计价币种) | "63836031.32165" |
o |
String | 统计周期开始时的第一笔成交价 | "88289.9" |
r |
String | 统计周期内的涨跌幅(百分比,例如"0.0102"表示1.02%) | "0.0102" |
i |
String | 指数价格 | "89423.4" |
m |
String | 标记价格 | "89429.2" |
bp |
String | 买一价格 | "89422.8" |
ap |
String | 卖一价格 | "89424.1" |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"t": 1769597753585,
"s": "btc_usdt",
"c": "89402.7",
"h": "89650.4",
"l": "87255.6",
"a": "7482855.7",
"v": "66281760.94256",
"o": "87735.3",
"r": "0.0190",
"i": "89402.3",
"m": "89408.0",
"bp": "89401.8",
"ap": "89403.1"
},
{
"t": 1769597753488,
"s": "eth_usdt",
"c": "3025.00",
"h": "3035.20",
"l": "2900.31",
"a": "5173701",
"v": "15403913.82645",
"o": "2902.23",
"r": "0.0423",
"i": "3025.14",
"m": "3025.42",
"bp": "3024.34",
"ap": "3025.13"
}
],
"bizCode": null
}
深度数据
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/depth"
params = {"symbol": "btc_usdt", "level": 10}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/depth";
const params = { symbol: "btc_usdt", level: 10 };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchDepthSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error("Error:", err.response ? err.response.data : err.message);
}
}
fetchDepthSigned();
描述:获取指定交易对的订单簿深度信息。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/depth
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 | 约束 |
|---|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt | - |
| level | 是 | 档位数量 | 2 | 1-50 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
u |
String | updateId | "586765918776852548" |
b |
String | 买单 | "[价格, 数量]" |
a |
String | 卖单 | "[价格, 数量]" |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"t": 1769597897116,
"s": "btc_usdt",
"u": 586765918776852548,
"b": [
[
"89390.8",
"11630"
],
[
"89390.3",
"10970"
]
],
"a": [
[
"89392",
"2240"
],
[
"89392.3",
"2990"
]
]
},
"bizCode": null
}
字段说明:
a:卖单深度数组,按价格从低到高排序b:买单深度数组,按价格从高到低排序- 每个深度项格式:
[价格, 数量]
成交数据
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/deal"
params = {"symbol": "btc_usdt", "num": 50}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/deal";
const params = { symbol: "btc_usdt", num: 50 };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchDealsSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchDealsSigned();
描述:获取指定交易对的最新成交记录。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/deal
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 | 默认值 | 约束 |
|---|---|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt | - | - |
| num | 否 | 返回数量 | 2 | 50 | ≥1 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
t |
Long | 数据时间戳(毫秒) | 1769584725803 |
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
p |
String | 成交价 | "89300.7" |
a |
String | 成交量 | "21" |
m |
String | 买卖方向 | "ASK"或"BID" |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"t": 1769598709094,
"s": "btc_usdt",
"p": "89300.7",
"a": "3",
"m": "ASK"
},
{
"t": 1769598708455,
"s": "btc_usdt",
"p": "89300.8",
"a": "21",
"m": "BID"
}
],
"bizCode": null
}
字段说明:
m:成交方向,BID(买)/ASK(卖)
K线数据
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
def fetch_kline_signed(symbol="btc_usdt", interval="1h", startTime=None, endTime=None, limit=500):
url = "BASE_URL/v2/public/q/kline"
params = {"symbol": symbol, "interval": interval, "limit": limit}
if startTime is not None:
params["startTime"] = int(startTime)
if endTime is not None:
params["endTime"] = int(endTime)
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
data = fetch_kline_signed("btc_usdt", "1h")
print(data)
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
async function fetchKlineSigned(symbol = "btc_usdt", interval = "1h", startTime, endTime, limit = 500) {
const url = "BASE_URL/v2/public/q/kline";
const params = { symbol, interval, limit };
if (startTime !== undefined) params.startTime = Number(startTime);
if (endTime !== undefined) params.endTime = Number(endTime);
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
return res.data;
} catch (err) {
throw err.response ? err.response.data : err;
}
}
fetchKlineSigned("btc_usdt", "1h").then(console.log).catch(console.error);
描述:获取指定交易对的K线数据。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/kline
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识 | btc_usdt |
| interval | 是 | K线间隔:1m,5m,15m,30m,1h,4h,1d,1w,1M,3M,6M | 1h |
| startTime | 否 | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | 结束时间戳(毫秒) | 1672531200000 |
| limit | 否 | 返回K线数量(默认500,最大1000) | 500 |
interval枚举:
| 枚举值 | 描述 | 代码值 | 周期分钟数 | 对应集合名 |
|---|---|---|---|---|
1m |
1分钟K线 | 0 | 1 | kline_1m |
5m |
5分钟K线 | 1 | 5 | kline_5m |
15m |
15分钟K线 | 2 | 15 | kline_15m |
30m |
30分钟K线 | 3 | 30 | kline_30m |
1h |
1小时K线 | 4 | 60 | kline_1h |
4h |
4小时K线 | 5 | 240 | kline_4h |
1d |
日K线 | 9 | 1440 | kline_1d |
1w |
周K线 | 11 | 10080 | kline_1w |
1M |
月K线 | 12 | 43200 | kline_1mth |
3M |
季K线(3个月) | 13 | 129600 | kline_3mth |
6M |
半年K线(6个月) | 14 | 259200 | kline_6mth |
参数说明:
| 参数 | 类型 | 说明 | 注意事项 |
|---|---|---|---|
| symbol | String | 交易对标识符 | 格式为小写,用下划线分隔(如 "btc_usdt") |
| interval | String | K线周期 | 必须使用上述枚举值之一 |
| startTime | Long | 查询开始时间(毫秒时间戳) | 不传时,默认从当前时间向前推算 limit 条K线 |
| endTime | Long | 查询结束时间(毫秒时间戳) | 不传时,默认使用当前时间;如果传了 startTime 但未传 endTime,endTime 默认为当前时间 |
| limit | Integer | 返回的K线数量 | 取值范围 1-1000,默认500;如果同时传了 startTime 和 endTime,此参数可能被忽略 |
时间范围说明:
- 如果只传
startTime:返回从startTime到当前时间的数据,数量受limit限制 - 如果只传
endTime:返回从endTime向前推算limit条K线的数据 - 如果两者都传:返回
[startTime, endTime]范围内的所有K线数据 - 如果都不传:返回最新的
limit条K线数据
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
s |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
t |
Long | K线开始时间戳(毫秒) | 1769598000000 |
o |
String | 开盘价(本K线周期第一笔成交价) | "89362.3" |
c |
String | 收盘价(本K线周期最后一笔成交价) | "89308.7" |
h |
String | 最高价(本K线周期内的最高成交价) | "89440.7" |
l |
String | 最低价(本K线周期内的最低成交价) | "89275.7" |
a |
String | 成交量(基础币种,如BTC数量) | "63036.05" |
v |
String | 成交额(计价币种,如USDT金额) | "563190.2239020" |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"s": "btc_usdt",
"t": 1769598000000,
"o": "89362.3",
"c": "89308.7",
"h": "89440.7",
"l": "89275.7",
"a": "63036.05",
"v": "563190.2239020"
},
{
"s": "btc_usdt",
"t": 1769594400000,
"o": "89434.0",
"c": "89362.3",
"h": "89650.4",
"l": "89291.2",
"a": "297423.10",
"v": "2660580.4022515"
}
],
"bizCode": null
}
注意事项:
- K线数据按时间倒序返回(最新的数据在前)
- 所有价格、数量和金额字段均为字符串类型,以保持精度
- 交易对名称统一为小写字母,使用下划线分隔
- K线时间戳
t表示该K线周期的开始时间
标记价格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/mark-price"
params = {}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=None, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
async function fetchMarkPricesSigned() {
try {
const params = {};
const qs = new URLSearchParams(Object.keys(params).sort().reduce((acc, k) => {
acc[k] = params[k];
return acc;
}, {})).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
const res = await axios.get("BASE_URL/v2/public/q/mark-price", {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchMarkPricesSigned();
描述:获取所有交易对的标记价格。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/mark-price
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"s": "eth_usdt",
"p": "3017.12",
"t": 1769599670589
},
{
"s": "btc_usdt",
"p": "89367.3",
"t": 1769599670589
}
],
"bizCode": null
}
交易对标记价格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/symbol-mark-price"
params = {"symbol": "btc_usdt"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/symbol-mark-price";
const params = { symbol: "btc_usdt" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchSymbolMarkPriceSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchSymbolMarkPriceSigned();
描述:获取指定交易对的标记价格详情。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/symbol-mark-price
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识 | btc_usdt |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"s": "btc_usdt",
"p": "89434.7",
"t": 1769599787498
},
"bizCode": null
}
指数价格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/index-price"
params = {}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/index-price";
async function fetchIndexPriceSigned() {
try {
const params = {};
const qs = new URLSearchParams(Object.keys(params).sort().reduce((acc, k) => {
acc[k] = params[k];
return acc;
}, {})).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchIndexPriceSigned();
描述:获取所有交易对的指数价格。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/index-price
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"s": "eth_usdt",
"p": "3020.4",
"t": 1769599966917
},
{
"s": "btc_usdt",
"p": "89410.4",
"t": 1769599966917
}
],
"bizCode": null
}
交易对指数价格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/q/symbol-index-price"
params = {"symbol": "btc_usdt"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/q/symbol-index-price";
const params = { symbol: "btc_usdt" };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
async function fetchSymbolIndexPriceSigned() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchSymbolIndexPriceSigned();
描述:获取指定交易对的指数价格详情。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/symbol-index-price
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识 | btc_usdt |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"s": "btc_usdt",
"p": "89410.4",
"t": 1769599966917
},
"bizCode": null
}
资金费率
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
def fetch_funding_rate_signed(symbol="btc_usdt"):
url = "BASE_URL/v2/public/q/funding-rate"
params = {"symbol": symbol}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(fetch_funding_rate_signed("btc_usdt"))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
async function fetchFundingRateSigned(symbol = "btc_usdt") {
const url = "BASE_URL/v2/public/q/funding-rate";
const params = { symbol };
const sortedKeys = Object.keys(params).sort();
const entries = sortedKeys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
return res.data;
} catch (err) {
throw err.response ? err.response.data : err;
}
}
fetchFundingRateSigned("btc_usdt").then(console.log).catch(console.error);
描述:获取所有交易对的当前资金费率。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/funding-rate
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
fundingRate |
BigDecimal | 资金费率 | "0.000102" |
nextCollectionTime |
Long | 下次收取时间 | 1769616000000 |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"symbol": "btc_usdt",
"fundingRate": "0.000102",
"nextCollectionTime": 1769616000000
},
"bizCode": null
}
资金费率记录
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
BASE_URL = "BASE_URL"
PATH = "/v2/public/q/funding-rate-record"
URL = BASE_URL + PATH
def fetch_funding_rate_records_simple(symbol, id=None, direction="NEXT", limit=10):
params = {"symbol": symbol, "limit": limit}
if id is not None:
params["id"] = id
params["direction"] = direction
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
def fetch_funding_rate_records_signed(symbol, id=None, direction="NEXT", limit=10):
params = {"symbol": symbol, "limit": limit}
if id is not None:
params["id"] = id
params["direction"] = direction
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
symbol = "btc_usdt"
r = fetch_funding_rate_records_signed(symbol, limit=10)
print("First page:", r)
items = r.get("data", {}).get("items", [])
if items:
last_id = items[-1].get("id")
r2 = fetch_funding_rate_records_signed(symbol, id=last_id, direction="NEXT", limit=10)
print("Next page:", r2)
first_id = items[0].get("id")
r_prev = fetch_funding_rate_records_signed(symbol, id=first_id, direction="PREV", limit=10)
print("Prev page:", r_prev)
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const BASE_URL = "BASE_URL";
const PATH = "/v2/public/q/funding-rate-record";
const URL = BASE_URL + PATH;
async function fetchFundingRateRecordsSimple(symbol, id = undefined, direction = "NEXT", limit = 10) {
const params = { symbol, limit };
if (id !== undefined) {
params.id = id;
params.direction = direction;
}
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(URL, { headers, params, timeout: 10000 });
return res.data;
}
async function fetchFundingRateRecordsSigned(symbol, id = undefined, direction = "NEXT", limit = 10) {
const params = { symbol, limit };
if (id !== undefined) {
params.id = id;
params.direction = direction;
}
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(URL, { headers, params, timeout: 10000 });
return res.data;
}
(async () => {
try {
const symbol = "btc_usdt";
const first = await fetchFundingRateRecordsSigned(symbol, undefined, "NEXT", 10);
console.log("First page:", first);
const items = first.data && first.data.items ? first.data.items : [];
if (items.length) {
const lastId = items[items.length - 1].id;
const nextPage = await fetchFundingRateRecordsSigned(symbol, lastId, "NEXT", 10);
console.log("Next page:", nextPage);
const firstId = items[0].id;
const prevPage = await fetchFundingRateRecordsSigned(symbol, firstId, "PREV", 10);
console.log("Prev page:", prevPage);
}
} catch (err) {
console.error("Error:", err.response ? err.response.data : err.message);
}
})();
描述:获取指定交易对的历史资金费率记录。
接口权重:1
请求方式:GET
请求地址:/v2/public/q/funding-rate-record
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 | 默认值 | 枚举值 |
|---|---|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt | - | - |
| id | 否 | 游标ID | 1234567890 | - | - |
| direction | 否 | 分页方向 | NEXT | NEXT | NEXT, PREV |
| limit | 否 | 条数 | 10 | 10 | 1-100 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
id |
Long | id | id |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
fundingRate |
BigDecimal | 最新资金费率 | "0.000097" |
createdTime |
Long | 时间 | 1769587200000 |
collectionInternal |
Long | 收取时间间隔(秒) | 28800 |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"hasPrev": false,
"hasNext": true,
"items": [
{
"id": "586721053934975552",
"symbol": "btc_usdt",
"fundingRate": "0.000097",
"createdTime": 1769587200000,
"collectionInternal": 28800
},
{
"id": "586600257988164160",
"symbol": "btc_usdt",
"fundingRate": "0.00017",
"createdTime": 1769558400000,
"collectionInternal": 28800
}
]
},
"bizCode": null
}
分页说明:
此接口使用基于游标的分页机制:
- 首次请求:不传
id参数,返回最新的limit条记录 - 向后翻页:使用返回的最后一条记录的
id,设置direction=NEXT(默认) - 向前翻页:使用返回的第一条记录的
id,设置direction=PREV
杠杆档位列表
import requests
import hmac
import hashlib
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/leverage/bracket/list"
qs = ""
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/leverage/bracket/list";
(async () => {
try {
const qs = "";
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
})();
描述:获取所有交易对的杠杆档位配置。
接口权重:1
请求方式:GET
请求地址:/v2/public/leverage/bracket/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
字段说明:
symbol: 交易对标识符leverageBrackets: 杠杆分层配置列表bracket: 分层等级(数字越小,杠杆倍数越高)maxPosition: 该等级最大持仓量maxLeverage: 该等级最大杠杆倍数maintenanceMargin: 维持保证金率maintenanceAmount: 维持保证金金额
响应示例:
{
"code": 0,
"message": "success",
"data": [
{
"symbol": "btc_usdt",
"leverageBrackets": [
{
"symbolId": 1,
"bracket": 1,
"maxPosition": "1000.00000000",
"maxLeverage": "125",
"maintenanceMargin": "0.0040",
"maintenanceAmount": "0.00000000"
},
{
"symbolId": 1,
"bracket": 2,
"maxPosition": "5000.00000000",
"maxLeverage": "100",
"maintenanceMargin": "0.0050",
"maintenanceAmount": "0.00000000"
}
]
},
{
"symbol": "eth_usdt",
"leverageBrackets": [
{
"symbolId": 2,
"bracket": 1,
"maxPosition": "10000.00000000",
"maxLeverage": "125",
"maintenanceMargin": "0.0040",
"maintenanceAmount": "0.00000000"
}
]
}
]
}
杠杆档位详情
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
url = "BASE_URL/v2/public/leverage/bracket/detail"
params = {"symbol": "btc_usdt"}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const url = "BASE_URL/v2/public/leverage/bracket/detail";
const params = { symbol: "btc_usdt" };
async function fetchBracketDetailSimple() {
try {
const res = await axios.get(url, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
if (res.data.code === 0) {
const d = res.data.data;
console.log("symbol:", d.symbol);
d.leverageBrackets.forEach(b => {
console.log(" bracket:", b.bracket, "maxLeverage:", b.maxLeverage, "maxPosition:", b.maxPosition);
});
}
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchBracketDetailSimple();
描述:获取指定交易对的杠杆档位详情。
接口权重:1
请求方式:GET
请求地址:/v2/public/leverage/bracket/detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 说明 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识 | btc_usdt |
字段说明:
symbol: 交易对标识符leverageBrackets: 杠杆分层配置列表bracket: 分层等级(数字越小,杠杆倍数越高)maxPosition: 该等级最大持仓量maxLeverage: 该等级最大杠杆倍数maintenanceMargin: 维持保证金率maintenanceAmount: 维持保证金金额
响应示例:
{
"code": 0,
"message": "success",
"data": {
"symbol": "btc_usdt",
"leverageBrackets": [
{
"symbolId": 1,
"bracket": 1,
"maxPosition": "1000.00000000",
"maxLeverage": "125",
"maintenanceMargin": "0.0040",
"maintenanceAmount": "0.00000000",
"symbol": "btc_usdt"
},
{
"symbolId": 1,
"bracket": 2,
"maxPosition": "5000.00000000",
"maxLeverage": "100",
"maintenanceMargin": "0.0050",
"maintenanceAmount": "0.00000000",
"symbol": "btc_usdt"
}
]
}
}
获取交易对风险基金余额
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/v2/public/contract/risk-balance"
def build_signature(params):
if not params:
qs = ""
else:
qs = urlencode(sorted(params.items()))
return hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
def fetch_risk_balance_signed(symbol, id=None, direction="NEXT", limit=10):
params = {"symbol": symbol, "limit": limit}
if id is not None:
params["id"] = id
params["direction"] = direction
signature = build_signature(params)
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
first = fetch_risk_balance_signed("btc_usdt", limit=10)
print("first page:", first)
items = first.get("data", {}).get("items", []) or []
if items:
last_id = items[-1]["id"]
next_page = fetch_risk_balance_signed("btc_usdt", id=last_id, direction="NEXT", limit=10)
print("next page:", next_page)
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/v2/public/contract/risk-balance";
function buildSignature(params) {
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
return crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
}
async function fetchRiskBalanceSigned(symbol, id = undefined, direction = "NEXT", limit = 10) {
const params = { symbol, limit };
if (id !== undefined) {
params.id = id;
params.direction = direction;
}
const signature = buildSignature(params);
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(URL, { headers, params, timeout: 10000 });
return res.data;
}
(async () => {
try {
const first = await fetchRiskBalanceSigned("btc_usdt", undefined, "NEXT", 10);
console.log("first page:", first);
const items = (first.data && first.data.items) || [];
if (items.length) {
const lastId = items[items.length - 1].id;
const next = await fetchRiskBalanceSigned("btc_usdt", lastId, "NEXT", 10);
console.log("next page:", next);
}
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
})();
描述:获取指定交易对的风险基金余额历史记录。
接口权重:1
请求方式:GET
请求地址:/v2/public/contract/risk-balance
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识符 | btc_usdt |
| id | 否 | 游标ID(用于分页,基于此ID向后或向前查询) | 1234567890 |
| direction | 否 | 分页方向:NEXT(向后)或 PREV(向前) | NEXT |
| limit | 否 | 每页记录数(默认10,最小1) | 10 |
- 分页说明,此接口使用基于游标的分页机制:
- 首次请求:不传
id参数,返回最新的limit条记录 - 向后翻页:使用返回的最后一条记录的
id,设置direction=NEXT(默认) - 向前翻页:使用返回的第一条记录的
id,设置direction=PREV
- 首次请求:不传
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
id |
Long | id | id |
coin |
String | 币种 | "usdt" |
amount |
BigDecimal | 余额 | "0.000097" |
createdTime |
Long | 时间 | 1769587200000 |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"hasPrev": false,
"hasNext": true,
"items": [
{
"id": "587004485520343296",
"coin": "usdt",
"amount": "940677.25916082",
"createdTime": 1769654775364
},
{
"id": "586962652094284032",
"coin": "usdt",
"amount": "940676.44076082",
"createdTime": 1769644801498
}
]
},
"bizCode": null
}
字段说明:
type:类型,FUNDING(资金费率)/INSURANCE(保险基金)
获取交易对仓位头寸
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/v2/public/contract/open-interest"
def fetch_open_interest_signed(symbol="btc_usdt"):
params = {"symbol": symbol}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(fetch_open_interest_signed("btc_usdt"))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/v2/public/contract/open-interest";
async function fetchOpenInterestSigned(symbol = "btc_usdt") {
const params = { symbol };
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
try {
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
return res.data;
} catch (err) {
throw err.response ? err.response.data : err;
}
}
fetchOpenInterestSigned("btc_usdt").then(console.log).catch(console.error);
描述:获取交易对的持仓量数据。
接口权重:1
请求方式:GET
请求地址:/v2/public/contract/open-interest
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识符 | btc_usdt |
字段说明
openInterest: 多头持仓总量(基础币种数量)openInterestUsd: 多头持仓总价值(美元计价)time: 数据快照时间戳(毫秒)
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"symbol": "btc_usdt",
"openInterest": "95.2852",
"openInterestUsd": "9153000.787852",
"time": 1769668629274
},
"bizCode": null
}
DeFi合约列表
import time
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/common/v2/perpetual/contracts"
def fetch_contracts_signed(timestamp_ms=None):
if timestamp_ms is None:
timestamp_ms = int(time.time() * 1000)
params = {"timestamp": timestamp_ms}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
data = fetch_contracts_signed(1672531200000)
print(data)
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/common/v2/perpetual/contracts";
async function fetchContractsSigned(timestampMs = Date.now()) {
const params = { timestamp: timestampMs };
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
try {
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
console.log(res.data);
return res.data;
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
}
fetchContractsSigned(1672531200000);
描述:获取DeFi相关的水续合约信息(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/common/v2/perpetual/contracts
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| timestamp | 是 | 时间戳(毫秒),用于确定K线日期 ,这个时间以服务端时间为准 | 1769126400000 |
字段说明:
open: 当日开盘价close: 当日收盘价high: 当日最高价(注意字段名为hign,不是high)low: 当日最低价Amount: 当日交易额(合约数量)volume: 当日交易量(计价币种)
注意:
- 接口返回的是指定日期的日K线(1D)数据
- 字段
high在 JSON 中的属性名为hign Amount字段是交易额,表示合约数量乘以合约规模
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"symbol": "ETH_USDT",
"baseAsset": "ETH",
"quoteAsset": "USDT",
"open": 2950.79,
"close": 2954.81,
"hign": 3016.57,
"low": 2889.92,
"Amount": 5864.8700,
"volume": 17305605.20324
},
{
"symbol": "BTC_USDT",
"baseAsset": "BTC",
"quoteAsset": "USDT",
"open": 89511.8,
"close": 89552.0,
"hign": 91180.0,
"low": 88507.4,
"Amount": 744.7113,
"volume": 66833951.2478195
}
],
"bizCode": null
}
DeFi手续费
import time
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/common/v2/perpetual/fee"
def fetch_defi_fee_signed(timestamp_ms=None):
if timestamp_ms is None:
timestamp_ms = int(time.time() * 1000)
params = {"timestamp": timestamp_ms}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(fetch_defi_fee_signed(1672531200000))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/common/v2/perpetual/fee";
async function fetchDefiFeeSigned(timestampMs = Date.now()) {
const params = { timestamp: timestampMs };
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(URL, { headers, params, timeout: 10000 });
return res.data;
}
fetchDefiFeeSigned(1672531200000).then(console.log).catch(err => console.error(err.response ? err.response.data : err.message));
描述:获取DeFi相关的交易手续费信息(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/common/v2/perpetual/fee
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| timestamp | 是 | 时间戳(毫秒),用于确定计算日期 | 1769126400000 |
计算逻辑:
- 获取指定日期的所有交易对总交易量(USDT)
- 根据星期几(0-6对应周日到周六)使用不同的费率
- 费率表:["0.00041", "0.00047", "0.00026", "0.00031", "0.00044", "0.0004", "0.00037"]
- 总手续费 = 总交易量 × 对应费率
费率对应表:
| 星期 | 索引 | 费率 |
|---|---|---|
| 周日 | 0 | 0.00041 |
| 周一 | 1 | 0.00047 |
| 周二 | 2 | 0.00026 |
| 周三 | 3 | 0.00031 |
| 周四 | 4 | 0.00044 |
| 周五 | 5 | 0.00040 |
| 周六 | 6 | 0.00037 |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"totalFee": 56660.7559
},
"bizCode": null
}
CMC合约列表
import requests
import hmac
import hashlib
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/cmc/v2/perpetual/contracts"
qs = ""
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, timeout=10)
resp.raise_for_status()
print(resp.json())
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/cmc/v2/perpetual/contracts";
const qs = "";
const signature = crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
(async () => {
try {
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
})();
描述:获取CoinMarketCap格式的水续合约列表(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cmc/v2/perpetual/contracts
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
此接口不需要查询参数。
字段说明:
product_type: 产品类型- ✅
Perpetual: 永续合约 - ✅
Fixed: 定期合约
- ✅
对于永续合约:
creation_timestamp和expiry_timestamp为 null对于定期合约:包含
creation_timestamp(创建时间)和expiry_timestamp(到期时间)
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| ticker_id | string | 交易对标识符 | "BTC_USDT" |
| base_currency | string | 基础币种 | "BTC" |
| target_currency | string | 计价币种 | "USDT" |
| last_price | string | 最新价格 | "45000.00" |
| base_volume | string | 基础币种24小时交易量 | "1250.5" |
| usd_volume | string | 美元计价24小时交易量 | "56272500.00" |
| target_volume | string | 计价币种24小时交易量 | "56272500.00" |
| bid | string | 当前最优买价 | "44999.50" |
| ask | string | 当前最优卖价 | "45000.50" |
| high | string | 24小时最高价 | "45500.00" |
| low | string | 24小时最低价 | "44500.00" |
| product_type | string | 产品类型 ✅ Perpetual: 永续合约 ✅ Fixed: 定期合约 |
"Perpetual" |
| open_interest | string | 持仓量(基础币种) | "12500.00" |
| open_interest_usd | string | 持仓量(美元计价) | "562500000.00" |
| index_price | string | 指数价格 | "44950.00" |
| creation_timestamp | integer | 创建时间戳(定期合约) 定期合约: 有值 永续合约: null |
1638316800000 |
| expiry_timestamp | integer | 到期时间戳(定期合约) 定期合约: 有值 永续合约: null |
1640995200000 |
| funding_rate | string | 当前资金费率 | "0.0001" |
| next_funding_rate_timestamp | integer | 下一次资金费率收取时间戳 | 1672617600000 |
| maker_fee | string | 挂单手续费率 | "0.0002" |
| taker_fee | string | 吃单手续费率 | "0.0004" |
响应示例:
[
{
"ticker_id": "BTC_USDT",
"base_currency": "BTC",
"target_currency": "USDT",
"last_price": "45000.00",
"base_volume": "1250.5",
"usd_volume": "56272500.00",
"target_volume": "56272500.00",
"bid": "44999.50",
"ask": "45000.50",
"high": "45500.00",
"low": "44500.00",
"product_type": "Perpetual",
"open_interest": "12500.00",
"open_interest_usd": "562500000.00",
"index_price": "44950.00",
"creation_timestamp": 1638316800000,
"expiry_timestamp": 1640995200000,
"funding_rate": "0.0001",
"next_funding_rate_timestamp": 1672617600000,
"maker_fee": "0.0002",
"taker_fee": "0.0004"
},
{
"ticker_id": "ETH_USDT",
"base_currency": "ETH",
"target_currency": "USDT",
"last_price": "3000.00",
"base_volume": "50000.0",
"usd_volume": "150000000.00",
"target_volume": "150000000.00",
"bid": "2999.50",
"ask": "3000.50",
"high": "3100.00",
"low": "2950.00",
"product_type": "Perpetual",
"open_interest": "250000.00",
"open_interest_usd": "750000000.00",
"index_price": "2995.00",
"creation_timestamp": null,
"expiry_timestamp": null,
"funding_rate": "0.00015",
"next_funding_rate_timestamp": 1672617600000,
"maker_fee": "0.0002",
"taker_fee": "0.0004"
}
]
CMC合约规格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/cmc/v2/perpetual/contract_specs"
def contract_specs_signed(symbol: str):
params = {"symbol": symbol}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(contract_specs_signed("btc_usdt"))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/cmc/v2/perpetual/contract_specs";
function signParams(params = {}) {
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
return crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
}
async function contractSpecsSigned(symbol = "btc_usdt") {
const params = { symbol };
const signature = signParams(params);
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(URL, { headers, params, timeout: 10000 });
return res.data;
}
contractSpecsSigned("btc_usdt").then(console.log).catch(err => console.error(err.response ? err.response.data : err.message));
描述:获取CoinMarketCap格式的合约规格信息(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cmc/v2/perpetual/contract_specs
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识符 | BTC_USDT |
字段说明:
contract_type: 合约类型- ✅
Vanilla: 普通合约
- ✅
contract_price: 合约价格contract_price_currency: 合约价格计价币种
响应示例:
{
"contract_type": "Vanilla",
"contract_price": 88264.1,
"contract_price_currency": "USDT"
}
CMC深度
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
BASE = "BASE_URL"
def sign_params(params: dict) -> str:
qs = urlencode(sorted(params.items())) if params else ""
return hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
def contract_specs_simple(symbol):
url = f"{BASE}/cmc/v2/perpetual/contract_specs"
params = {"symbol": symbol}
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
}
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
return r.json()
def contract_specs_signed(symbol):
url = f"{BASE}/cmc/v2/perpetual/contract_specs"
params = {"symbol": symbol}
signature = sign_params(params)
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
return r.json()
def depth_simple(symbol):
url = f"{BASE}/cmc/v2/perpetual/depth"
params = {"symbol": symbol}
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
}
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
return r.json()
def depth_signed(symbol):
url = f"{BASE}/cmc/v2/perpetual/depth"
params = {"symbol": symbol}
signature = sign_params(params)
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
r = requests.get(url, headers=headers, params=params, timeout=10)
r.raise_for_status()
return r.json()
if __name__ == "__main__":
s = "btc_usdt"
print("contract_specs (simple):", contract_specs_simple(s))
print("contract_specs (signed):", contract_specs_signed(s))
print("depth (simple):", depth_simple(s))
print("depth (signed):", depth_signed(s))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const BASE = "BASE_URL";
function signParams(params = {}) {
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
return crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
}
async function contractSpecsSimple(symbol) {
const url = `${BASE}/cmc/v2/perpetual/contract_specs`;
const params = { symbol };
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(url, { headers, params, timeout: 10000 });
return res.data;
}
async function contractSpecsSigned(symbol) {
const url = `${BASE}/cmc/v2/perpetual/contract_specs`;
const params = { symbol };
const signature = signParams(params);
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(url, { headers, params, timeout: 10000 });
return res.data;
}
async function depthSimple(symbol) {
const url = `${BASE}/cmc/v2/perpetual/depth`;
const params = { symbol };
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": API_SECRET,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(url, { headers, params, timeout: 10000 });
return res.data;
}
async function depthSigned(symbol) {
const url = `${BASE}/cmc/v2/perpetual/depth`;
const params = { symbol };
const signature = signParams(params);
const headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
};
const res = await axios.get(url, { headers, params, timeout: 10000 });
return res.data;
}
(async () => {
try {
const s = "btc_usdt";
console.log("contractSpecsSimple:", await contractSpecsSimple(s));
console.log("contractSpecsSigned:", await contractSpecsSigned(s));
console.log("depthSimple:", await depthSimple(s));
console.log("depthSigned:", await depthSigned(s));
} catch (err) {
console.error(err.response ? err.response.data : err.message);
}
})();
描述:获取CoinMarketCap格式的深度数据(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cmc/v2/perpetual/depth
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| symbol | 是 | 交易对标识符 | BTC_USDT |
字段说明:
ticker_id: 交易对标识符asks: 卖单深度数组,每个元素为[价格, 数量],按价格从低到高排序bids: 买单深度数组,每个元素为[价格, 数量],按价格从高到低排序timestamp: 数据快照时间戳(毫秒)
响应示例:
{
"ticker_id": "btc_usdt",
"asks": [
["45001.00", "1.5"],
["45002.00", "2.3"],
["45003.00", "3.1"]
],
"bids": [
["44999.00", "2.1"],
["44998.00", "1.8"],
["44997.00", "0.9"]
],
"timestamp": 1672531200000
}
CG合约列表
import requests
import hmac
import hashlib
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/cg/v2/perpetual/contracts"
def fetch_cg_contracts_signed():
sig = hmac.new(API_SECRET.encode(), b"", hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": sig,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
try:
print(fetch_cg_contracts_signed())
except Exception as e:
print("Error:", e)
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/cg/v2/perpetual/contracts";
async function fetchCgContractsSigned() {
try {
const signature = crypto.createHmac("sha256", API_SECRET).update("").digest("hex");
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 10000,
});
console.log(res.data);
} catch (err) {
console.error("Error:", err.response ? err.response.data : err.message);
}
}
fetchCgContractsSigned();
描述:获取CoinGecko格式的水续合约列表(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cg/v2/perpetual/contracts
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
此接口不需要查询参数。
字段说明:
product_type: 产品类型- ✅
Perpetual: 永续合约 - ✅
Fixed: 定期合约
- ✅
对于永续合约:
creation_timestamp和expiry_timestamp为 null对于定期合约:包含
creation_timestamp(创建时间)和expiry_timestamp(到期时间)
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| ticker_id | string | 交易对标识符 | "ETH_USDT" |
| base_currency | string | 基础币种 | "ETH" |
| target_currency | string | 计价币种 | "USDT" |
| last_price | number | 最新价格 | 2953.89 |
| base_volume | number | 基础币种24小时交易量 | 4581.96385226 |
| usd_volume | number | 美元计价24小时交易量 | 13534617.20354 |
| target_volume | number | 计价币种24小时交易量 | 13534617.20354 |
| bid | number | 当前最优买价 | 2953.48 |
| ask | number | 当前最优卖价 | 2954.92 |
| high | number | 24小时最高价 | 3044.35 |
| low | number | 24小时最低价 | 2935.93 |
| product_type | string | 产品类型 ✅ Perpetual: 永续合约 ✅ Fixed: 定期合约 |
"Perpetual" |
| open_interest | number | 持仓量(基础币种) | 12932.388206500004760000 |
| open_interest_usd | number | 持仓量(美元计价) | 38210682.318490364060564000000 |
| index_price | number | 指数价格 | 2954.01 |
| index_currency | string | 指数计价币种 | "USDT" |
| funding_rate | number | 当前资金费率 | 0.000094 |
| next_funding_rate | number | 下一次资金费率 | 0.000094 |
| next_funding_rate_timestamp | integer | 下一次资金费率收取时间戳 | 1769673600000 |
| start_timestamp | integer | 开始时间戳 | 0 |
| end_timestamp | integer | 结束时间戳 | 0 |
| maker_fee | number | 挂单手续费率 | 0.000200000000000000 |
| taker_fee | number | 吃单手续费率 | 0.000500000000000000 |
响应示例:
[
{
"ticker_id": "ETH_USDT",
"base_currency": "ETH",
"target_currency": "USDT",
"last_price": 2953.89,
"base_volume": 4581.96385226,
"usd_volume": 13534617.20354,
"target_volume": 13534617.20354,
"bid": 2953.48,
"ask": 2954.92,
"high": 3044.35,
"low": 2935.93,
"product_type": "Perpetual",
"open_interest": 12932.388206500004760000,
"open_interest_usd": 38210682.318490364060564000000,
"index_price": 2954.01,
"index_currency": "USDT",
"funding_rate": 0.000094,
"next_funding_rate": 0.000094,
"next_funding_rate_timestamp": 1769673600000,
"start_timestamp": 0,
"end_timestamp": 0,
"maker_fee": 0.000200000000000000,
"taker_fee": 0.000500000000000000
},
{
"ticker_id": "BTC_USDT",
"base_currency": "BTC",
"target_currency": "USDT",
"last_price": 88277.4,
"base_volume": 890.30512045,
"usd_volume": 78593821.24044,
"target_volume": 78593821.24044,
"bid": 88276.9,
"ask": 88278.1,
"high": 90554.3,
"low": 87666.2,
"product_type": "Perpetual",
"open_interest": 813.704894400000045850,
"open_interest_usd": 72965740.53700200404752337500,
"index_price": 88277.4,
"index_currency": "USDT",
"funding_rate": 0.000084,
"next_funding_rate": 0.000084,
"next_funding_rate_timestamp": 1769673600000,
"start_timestamp": 0,
"end_timestamp": 0,
"maker_fee": 0.000200000000000000,
"taker_fee": 0.000500000000000000
}
]
CG合约规格
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/cg/v2/perpetual/contract_specs"
def contract_specs_signed(ticker_id: str):
params = {"ticker_id": ticker_id}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(contract_specs_signed("btc_usdt"))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/cg/v2/perpetual/contract_specs";
function signParams(params = {}) {
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
return crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
}
async function contractSpecsSigned(tickerId = "btc_usdt") {
const params = { ticker_id: tickerId };
const signature = signParams(params);
try {
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
return res.data;
} catch (err) {
throw err.response ? err.response.data : err;
}
}
contractSpecsSigned("btc_usdt").then(console.log).catch(console.error);
描述:获取CoinGecko格式的合约规格信息(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cg/v2/perpetual/contract_specs
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| ticker_id | 是 | 交易对标识符 | BTC_USDT |
字段说明:
contract_type: 合约类型- ✅
Vanilla: 普通合约
- ✅
contract_price: 合约价格contract_price_currency: 合约价格计价币种
响应示例:
{
"contract_type": "Vanilla",
"contract_price": "45000.00",
"contract_price_currency": "USDT"
}
CG深度
import requests
import hmac
import hashlib
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
URL = "BASE_URL/cg/v2/perpetual/depth"
def fetch_depth_signed(ticker_id: str, depth: int = 50):
params = {"ticker_id": ticker_id, "depth": depth}
qs = urlencode(sorted(params.items()))
signature = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.get(URL, headers=headers, params=params, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(fetch_depth_signed("btc_usdt", 50))
const axios = require("axios");
const crypto = require("crypto");
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
const URL = "BASE_URL/cg/v2/perpetual/depth";
function signParams(params = {}) {
const keys = Object.keys(params).sort();
const entries = keys.map(k => [k, params[k]]);
const qs = new URLSearchParams(entries).toString();
return crypto.createHmac("sha256", API_SECRET).update(qs).digest("hex");
}
async function fetchDepthSigned(tickerId = "btc_usdt", depth = 50) {
const params = { ticker_id: tickerId, depth };
const signature = signParams(params);
try {
const res = await axios.get(URL, {
headers: {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
},
params,
timeout: 10000,
});
return res.data;
} catch (err) {
throw err.response ? err.response.data : err;
}
}
fetchDepthSigned("btc_usdt", 50).then(console.log).catch(console.error);
描述:获取CoinGecko格式的深度数据(第三方数据接口)。
接口权重:1
请求方式:GET
请求地址:/cg/v2/perpetual/depth
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 描述 | 示例 |
|---|---|---|---|
| ticker_id | 是 | 交易对标识符 | BTC_USDT |
| depth | 否 | 深度数量(默认50) | 50 |
字段说明:
ticker_id: 交易对标识符asks: 卖单深度数组,每个元素为[价格, 数量],按价格从低到高排序bids: 买单深度数组,每个元素为[价格, 数量],按价格从高到低排序timestamp: 数据快照时间戳(毫秒)
响应示例:
{
"ticker_id": "btc_usdt",
"asks": [
["45001.00", "1.5"],
["45002.00", "2.3"],
["45003.00", "3.1"]
],
"bids": [
["44999.00", "2.1"],
["44998.00", "1.8"],
["44997.00", "0.9"]
],
"timestamp": 1672531200000
}
交易和账户接口
创建订单
import requests
import json
BASE_URL = "BASE_URL"
API_KEY = "your_api_accessKey"
X_SIGNATURE = "your_api_query_secretKey"
HEADERS = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": X_SIGNATURE,
"Content-Type": "application/x-www-form-urlencoded"
}
payload = {
"symbol": "btc_usdt",
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"price": "45000.00",
"origQty": "1.0",
"timeInForce": "GTC",
"reduceOnly": False
}
try:
response = requests.post(f"{BASE_URL}/v2/order/create",
headers=HEADERS, json=payload)
data = response.json()
if response.status_code == 200 and data.get("code") == 0:
print("Order created successfully")
print(f"Symbol: {payload['symbol']}, Type: {payload['orderType']}, "
f"Side: {payload['orderSide']}, Price: {payload['price']}, "
f"Quantity: {payload['origQty']}")
else:
print(f"Error: {data.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
const axios = require('axios');
const BASE_URL = 'BASE_URL';
const API_KEY = 'your_api_accessKey';
const X_SIGNATURE = 'your_api_query_secretKey';
const headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': X_SIGNATURE,
'Content-Type': 'application/x-www-form-urlencoded'
};
async function createOrder(orderOptions) {
try {
const payload = {
symbol: orderOptions.symbol,
orderType: orderOptions.orderType || 'LIMIT',
orderSide: orderOptions.orderSide,
positionSide: orderOptions.positionSide,
price: orderOptions.price,
origQty: orderOptions.origQty,
timeInForce: orderOptions.timeInForce || 'GTC',
reduceOnly: orderOptions.reduceOnly || false,
clientOrderId: orderOptions.clientOrderId,
leverage: orderOptions.leverage,
positionId: orderOptions.positionId,
triggerProfitPrice: orderOptions.triggerProfitPrice,
triggerStopPrice: orderOptions.triggerStopPrice,
marketOrderLevel: orderOptions.marketOrderLevel,
profitOrderType: orderOptions.profitOrderType,
stopOrderType: orderOptions.stopOrderType,
profitOrderPrice: orderOptions.profitOrderPrice,
stopOrderPrice: orderOptions.stopOrderPrice
};
Object.keys(payload).forEach(key => payload[key] === undefined && delete payload[key]);
const response = await axios.post(`${BASE_URL}/v2/order/create`,
payload, { headers });
if (response.data.code === 0) {
console.log('Order created successfully');
console.log(`Symbol: ${payload.symbol}, Type: ${payload.orderType}, ` +
`Side: ${payload.orderSide}, Price: ${payload.price}, ` +
`Quantity: ${payload.origQty}`);
return response.data;
} else {
throw new Error(response.data.message || 'Unknown error');
}
} catch (error) {
console.error('Error creating order:', error.message);
throw error;
}
}
createOrder({
symbol: 'btc_usdt',
orderType: 'LIMIT',
orderSide: 'BUY',
positionSide: 'LONG',
price: '45000.00',
origQty: '1.0',
timeInForce: 'GTC',
reduceOnly: false
})
.then(result => {
})
.catch(error => {
});
描述:创建新的交易订单(限价单或市价单、止盈止损订单)。
接口权重:20
请求方式:POST
请求地址:(TRADE)/v2/order/create
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数(body):
| 参数 | 必填 | 描述 | 示例 | 枚举值 |
|---|---|---|---|---|
| symbol | 是 | 交易对 | btc_usdt | - |
| orderType | 是 | 订单类型:LIMIT(限价)、MARKET(市价) | LIMIT | LIMIT, MARKET |
| orderSide | 是 | 买卖方向:BUY(买入)、SELL(卖出) | BUY | BUY, SELL |
| positionSide | 是 | 仓位方向:LONG(多头)、SHORT(空头)、BOTH(双向) | LONG | LONG, SHORT, BOTH |
| price | 否 | 价格(限价单必填,市价单选填) | 45000.00 | - |
| origQty | 是 | 数量(张) | 1.0 | - |
| timeInForce | 否 | 有效方式:GTC(成交为止)、IOC(立即成交或取消)、FOK(全部成交或取消)、GTX | GTC | GTC, IOC, FOK, GTX |
| reduceOnly | 否 | 只减仓(默认false) | false | true, false |
| clientOrderId | 否 | 自定义订单ID(1-32位字母数字) | myOrder123 | - |
| leverage | 是 | 杠杆倍数 | 20 | - |
| positionId | 否 | 仓位ID(平仓时需提供) | 123456 | - |
| triggerProfitPrice | 否 | 止盈触发价 | 46000.00 | - |
| triggerStopPrice | 否 | 止损触发价 | 44000.00 | - |
| marketOrderLevel | 否 | 市价最优档:1(对手价)、5、10、15挡 | 1 | 1, 5, 10, 15 |
| profitOrderType | 否 | 止盈订单类型:MARKET/LIMIT | MARKET | MARKET, LIMIT |
| stopOrderType | 否 | 止损订单类型:MARKET/LIMIT | MARKET | MARKET, LIMIT |
| profitOrderPrice | 否 | LIMIT止盈委托价(profitOrderType为LIMIT时必填) | 45900.00 | - |
| stopOrderPrice | 否 | LIMIT止损委托价(stopOrderType为LIMIT时必填) | 44100.00 | - |
注意事项
- 限价单:必须提供
price参数 - 市价单:
price参数可选,如果提供将作为参考价 - 平仓订单:平仓时必须提供
positionId和reduceOnly=true - 条件订单:设置止盈止损时需同时设置触发价和订单类型
- 只减仓:
reduceOnly=true时,订单只能减少现有仓位,不能增加仓位
响应示例:
{
"code": 0,
"msg": "success",
"data": "587077935051136448",
"bizCode": null
}
error:
{
"code": -1,
"msg": "order_leverage_not_match_position_leverage",
"data": null,
"bizCode": "1000"
}
批量创建订单
import requests
import json
import hashlib
import time
class FutureExchangeAPI:
def __init__(self, api_key, secret_key, base_url="BASE_URL"):
self.api_key = api_key
self.secret_key = secret_key
self.base_url = base_url
def _generate_signature(self, params_str):
return hashlib.md5((params_str + self.secret_key).encode()).hexdigest()
def create_batch_orders(self, orders_list):
endpoint = "/v2/order/create-batch"
url = self.base_url + endpoint
list_json = json.dumps(orders_list, separators=(',', ':'))
params = {
"list": list_json
}
sorted_params = "&".join([f"{k}={v}" for k, v in sorted(params.items())])
signature = self._generate_signature(sorted_params)
headers = {
"X_ACCESS_KEY": self.api_key,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
response = requests.post(url, headers=headers, data=params)
return response.json()
if __name__ == "__main__":
API_KEY = "your_api_accessKey"
SECRET_KEY = "your_api_query_secretKey"
client = FutureExchangeAPI(API_KEY, SECRET_KEY)
orders = [
{
"isCreate": True,
"symbol": "btc_usdt",
"price": 45000.00,
"origQty": 1.0,
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"positionId": 0,
"clientOrderId": "myOrder_123456789"
},
{
"isCreate": True,
"symbol": "eth_usdt",
"price": 2220.00,
"origQty": 2.0,
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"positionId": 0,
"clientOrderId": "myOrder_987654321"
},
{
"isCreate": False,
"orderId": 1234567890,
"symbol": "btc_usdt",
"price": 0,
"origQty": 0,
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"positionId": 0,
"clientOrderId": ""
}
]
try:
result = client.create_batch_orders(orders)
print("response result:", json.dumps(result, indent=2))
if result.get("code") == 0:
print("Batch order creation successful!")
else:
print(f"Failed to create batch orders: {result.get('msg')}")
except Exception as e:
print(f"Request exception: {str(e)}")
const crypto = require('crypto');
const axios = require('axios');
class FutureExchangeAPI {
constructor(apiKey, secretKey, baseUrl = 'BASE_URL') {
this.apiKey = apiKey;
this.secretKey = secretKey;
this.baseUrl = baseUrl;
}
_generateSignature(paramsStr) {
return crypto
.createHash('md5')
.update(paramsStr + this.secretKey)
.digest('hex');
}
async createBatchOrders(ordersList) {
const endpoint = '/v2/order/create-batch';
const url = this.baseUrl + endpoint;
const listJson = JSON.stringify(ordersList);
const params = {
list: listJson
};
const sortedParams = Object.keys(params)
.sort()
.map(key => `${key}=${params[key]}`)
.join('&');
const signature = this._generateSignature(sortedParams);
const headers = {
'X_ACCESS_KEY': this.apiKey,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded'
};
try {
const response = await axios.post(url, new URLSearchParams(params).toString(), { headers });
return response.data;
} catch (error) {
console.error('Request failed:', error.message);
if (error.response) {
console.error('response data:', error.response.data);
}
throw error;
}
}
}
(async () => {
const API_KEY = 'your_api_accessKey';
const SECRET_KEY = 'your_api_query_secretKey';
const client = new FutureExchangeAPI(API_KEY, SECRET_KEY);
const orders = [
{
isCreate: true,
symbol: 'btc_usdt',
price: 45000.00,
origQty: 1.0,
orderType: 'LIMIT',
orderSide: 'BUY',
positionSide: 'LONG',
timeInForce: 'GTC',
positionId: 0,
clientOrderId: 'myOrder_123456789'
},
{
isCreate: true,
symbol: 'eth_usdt',
price: 2220.00,
origQty: 2.0,
orderType: 'LIMIT',
orderSide: 'BUY',
positionSide: 'LONG',
timeInForce: 'GTC',
positionId: 0,
clientOrderId: 'myOrder_987654321'
},
{
isCreate: false,
orderId: 1234567890,
symbol: 'btc_usdt',
price: 0,
origQty: 0,
orderType: 'LIMIT',
orderSide: 'BUY',
positionSide: 'LONG',
timeInForce: 'GTC',
positionId: 0,
clientOrderId: ''
}
];
try {
const result = await client.createBatchOrders(orders);
console.log('response result:', JSON.stringify(result, null, 2));
if (result.code === 0) {
console.log('Batch order creation successful!');
} else {
console.log(`Failed to create batch orders: ${result.msg}`);
}
} catch (error) {
console.error('Request exception:', error.message);
}
})();
描述:批量创建多个订单。
接口权重:15
请求方式:POST
请求地址:(TRADE)/v2/order/create-batch
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数(body):
| 参数 | 必填 | 描述 | 示例 | 说明 |
|---|---|---|---|---|
| list | 是 | 数组参数转换的JSON格式数据 | "[ { "isCreate": true, "symbol": "btc_usdt", "price": 45000.00, "origQty": 1.0, "orderType": "LIMIT", "orderSide": "BUY", "positionSide": "LONG", "timeInForce": "GTC", "positionId": 0, "clientOrderId": "myOrder_123456789" }, { "isCreate": false, "orderId": 1234567890, "symbol": "btc_usdt" } ]" | - |
参数list说明
| 参数 | 必填 | 描述 | 示例 | 说明 |
|---|---|---|---|---|
| isCreate | 是 | 操作类型:true(下单)、false(撤单) | true | - |
| orderId | 是 | 订单ID(isCreate=false时必填) | 123456 | - |
| symbol | 是 | 交易对 | btc_usdt | - |
| price | 是 | 价格(isCreate=true时必填) | 45000.00 | - |
| origQty | 是 | 数量(张)(isCreate=true时必填) | 1.0 | - |
| orderType | 是 | 订单类型:LIMIT、MARKET(isCreate=true时必填) | LIMIT | - |
| orderSide | 是 | 买卖方向:BUY、SELL(isCreate=true时必填) | BUY | - |
| positionSide | 是 | 仓位方向:LONG、SHORT(isCreate=true时必填) | LONG | - |
| timeInForce | 是 | 有效方式:GTC、IOC、FOK、GTX(isCreate=true时必填) | GTC | - |
| positionId | 否 | 仓位ID | 123456 | - |
| clientOrderId | 否 | 自定义订单ID | myOrder123 | - |
请求体示例:
[
{
"isCreate": true,
"symbol": "btc_usdt",
"price": 45000.00,
"origQty": 1.0,
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"positionId": 0,
"clientOrderId": "myOrder_123456789"
},
{
"isCreate": false,
"orderId": 1234567890,
"symbol": "btc_usdt",
"price": 0,
"origQty": 0,
"orderType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"positionId": 0,
"clientOrderId": ""
}
]
响应示例:
{
"code": 0,
"msg": "success",
"data": true,
"bizCode": null
}
取消订单
import requests
import json
BASE_URL = "BASE_URL"
API_KEY = "your_api_accessKey"
X_SIGNATURE = "your_api_query_secretKey"
HEADERS = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": X_SIGNATURE,
"Content-Type": "application/x-www-form-urlencoded"
}
order_id = 1234567890
payload = {"orderId": order_id}
try:
response = requests.post(f"{BASE_URL}/v2/order/cancel",
headers=HEADERS, json=payload)
data = response.json()
if response.status_code == 200 and data.get("code") == 0:
print(f"Order {order_id} cancelled successfully")
else:
print(f"Error cancelling order {order_id}: {data.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
const axios = require('axios');
const BASE_URL = 'BASE_URL';
const API_KEY = 'your_api_accessKey';
const X_SIGNATURE = 'your_api_query_secretKey';
const headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': X_SIGNATURE,
'Content-Type': 'application/x-www-form-urlencoded'
};
async function cancelOrder(orderId) {
try {
const payload = { orderId };
const response = await axios.post(`${BASE_URL}/v2/order/cancel`,
payload, { headers });
if (response.data.code === 0) {
console.log(`Order ${orderId} cancelled successfully`);
return response.data;
} else {
throw new Error(response.data.message || 'Unknown error');
}
} catch (error) {
console.error(`Error cancelling order ${orderId}:`, error.message);
throw error;
}
}
cancelOrder(1234567890)
.then(result => {
})
.catch(error => {
});
描述:取消指定的订单。
接口权重:5
请求方式:POST
请求地址:(TRADE)/v2/order/cancel
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数(body):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| orderId | 是 | string | 订单ID | 1234567890 |
| symbol | 否 | string | 交易对标识符 | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
批量取消订单
import json
import hmac
import hashlib
from urllib.parse import urlencode
import requests
url = "BASE_URL/v2/order/cancel-batch"
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
orders = ["1234567890", "1234567891"]
body_dict = {"orders": json.dumps(orders)}
body_str = urlencode(body_dict)
signature = hmac.new(secret_key.encode("utf-8"), body_str.encode("utf-8"), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": access_key,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.post(url, data=body_str, headers=headers)
print(resp.status_code)
print(resp.text)
const crypto = require('crypto');
const url = "BASE_URL/v2/order/cancel-batch";
const accessKey = "YOUR_ACCESS_KEY";
const secretKey = "YOUR_SECRET_KEY";
const orders = ["1234567890", "1234567891"];
const params = new URLSearchParams();
params.append("orders", JSON.stringify(orders));
const bodyStr = params.toString();
const signature = crypto.createHmac('sha256', secretKey).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": accessKey,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
(async () => {
const resp = await fetch(url, {
method: "POST",
headers,
body: bodyStr
});
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
})();
描述:批量取消多个订单。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/order/cancel-batch
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数(数组格式):
["1234567890", "1234567891"]
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
取消所有订单
import json
import hmac
import hashlib
from urllib.parse import urlencode
import requests
url = "BASE_URL/v2/order/cancel-all"
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
body_dict = {"symbol": "btc_usdt"}
body_str = urlencode(body_dict)
signature = hmac.new(secret_key.encode("utf-8"), body_str.encode("utf-8"), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": access_key,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
resp = requests.post(url, data=body_str, headers=headers)
print(resp.status_code)
print(resp.text)
body_str_empty = ""
signature_empty = hmac.new(secret_key.encode("utf-8"), body_str_empty.encode("utf-8"), hashlib.sha256).hexdigest()
headers["X_SIGNATURE"] = signature_empty
resp_all = requests.post(url, data=body_str_empty, headers=headers)
print(resp_all.status_code)
print(resp_all.text)
const crypto = require('crypto');
const fetch = global.fetch || require('node-fetch');
const url = "BASE_URL/v2/order/cancel-all";
const accessKey = "YOUR_ACCESS_KEY";
const secretKey = "YOUR_SECRET_KEY";
async function cancelBySymbol(symbol) {
const params = new URLSearchParams();
params.append("symbol", symbol);
const bodyStr = params.toString();
const signature = crypto.createHmac('sha256', secretKey).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": accessKey,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(url, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelBySymbol("btc_usdt");
async function cancelAll() {
const bodyStr = "";
const signature = crypto.createHmac('sha256', secretKey).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": accessKey,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(url, { method: "POST", headers, body: bodyStr });
const result = await resp.json().catch(() => await resp.text());
console.log(resp.status, result);
}
cancelAll();
描述:取消当前用户的所有订单或指定交易对的所有订单。
接口权重:10
请求方式:POST
请求地址:(TRADE)/v2/order/cancel-all
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符(不传则取消所有) | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
查询订单列表
import hashlib
import hmac
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order/list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"symbol": "btc_usdt",
"state": "UNFINISHED",
"page": 1,
"size": 10,
# "startTime": 1672444800000,
# "endTime": 1672531200000,
}
params = {k: v for k, v in params.items() if v is not None}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items) # e.g. "page=1&size=10&state=UNFINISHED&symbol=btc_usdt"
signature = hmac.new(SECRET_KEY.encode('utf-8'), query_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded",
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers)
print(resp.status_code)
print(resp.text)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order/list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
const params = {
symbol: "btc_usdt",
state: "UNFINISHED",
page: 1,
size: 10,
// startTime: 1672444800000,
// endTime: 1672531200000
};
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) {
usp.append(k, String(v));
}
const queryStr = usp.toString(); // "page=1&size=10&state=UNFINISHED&symbol=btc_usdt"
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
(async () => {
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
})();
描述:查询订单列表,支持分页和筛选。
接口权重:2
请求方式:GET
请求地址:/v2/order/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| state | 否 | string | 订单状态:NEW/PARTIALLY_FILLED/FILLED等 | UNFINISHED |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
| page | 否 | integer | 页码(默认1) | 1 |
| size | 否 | integer | 每页数量(默认10) | 10 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"page": 1,
"ps": 10,
"total": 1,
"items": [
{
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
}
]
},
"bizCode": null
}
查询历史订单
import hashlib
import hmac
import time
import requests
from typing import Dict, List, Optional, Any
from urllib.parse import urlencode
class HistoryOrderAPI:
def __init__(self, base_url: str, access_key: str, secret_key: str):
self.base_url = base_url.rstrip('/')
self.access_key = access_key
self.secret_key = secret_key
self.session = requests.Session()
def _generate_signature(self, params: Dict[str, Any]) -> str:
sorted_params = sorted(params.items(), key=lambda x: x[0])
query_string = '&'.join(
[f"{key}={value}" for key, value in sorted_params]
)
signature = hmac.new(
self.secret_key.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def query_history_orders(
self,
symbol: Optional[str] = None,
order_id: Optional[str] = None,
direction: str = "NEXT",
limit: int = 10,
start_time: Optional[int] = None,
end_time: Optional[int] = None
) -> Dict[str, Any]:
try:
params = {
'timestamp': int(time.time() * 1000)
}
if symbol:
params['symbol'] = symbol
if order_id:
params['id'] = order_id
if direction in ['NEXT', 'PREV']:
params['direction'] = direction
if limit:
params['limit'] = limit
if start_time:
params['startTime'] = start_time
if end_time:
params['endTime'] = end_time
signature = self._generate_signature(params)
url = f"{self.base_url}/v2/order/list-history"
headers = {
'X_ACCESS_KEY': self.access_key,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
}
response = self.session.get(
url,
params=params,
headers=headers,
timeout=30
)
response.raise_for_status()
data = response.json()
if data.get('code') != 0:
error_msg = data.get('msg', 'Unknown error')
raise Exception(f"API error: {error_msg}")
return data.get('data', {})
except requests.exceptions.RequestException as e:
raise Exception(f"Request failed: {str(e)}")
except ValueError as e:
raise Exception(f"Invalid response format: {str(e)}")
def get_all_history_orders(
self,
symbol: str,
batch_size: int = 50,
max_orders: Optional[int] = None
) -> List[Dict[str, Any]]:
all_orders = []
last_order_id = None
has_more = True
try:
while has_more:
query_params = {
'symbol': symbol,
'limit': batch_size,
'direction': 'NEXT'
}
if last_order_id:
query_params['id'] = last_order_id
response = self.query_history_orders(**query_params)
if response.get('items'):
items = response['items']
all_orders.extend(items)
last_order_id = items[-1]['orderId']
has_more = len(items) == batch_size
if max_orders and len(all_orders) >= max_orders:
all_orders = all_orders[:max_orders]
break
else:
has_more = False
time.sleep(0.1)
return all_orders
except Exception as e:
raise
def get_orders_by_time_range(
self,
symbol: str,
start_time: int,
end_time: int,
limit: int = 100
) -> List[Dict[str, Any]]:
try:
response = self.query_history_orders(
symbol=symbol,
start_time=start_time,
end_time=end_time,
limit=limit,
direction='NEXT'
)
return response.get('items', [])
except Exception as e:
raise
def get_order_statistics(
self,
symbol: str,
days: int = 7
) -> Dict[str, Any]:
try:
end_time = int(time.time() * 1000)
start_time = end_time - (days * 24 * 60 * 60 * 1000)
orders = self.get_all_history_orders(
symbol=symbol,
max_orders=1000
)
if not orders:
return {
'total_orders': 0,
'buy_orders': 0,
'sell_orders': 0,
'filled_orders': 0,
'canceled_orders': 0,
'total_volume': 0,
'avg_trade_size': 0
}
stats = {
'total_orders': len(orders),
'buy_orders': 0,
'sell_orders': 0,
'filled_orders': 0,
'canceled_orders': 0,
'total_volume': 0,
'avg_trade_size': 0
}
for order in orders:
if order.get('orderSide') == 'BUY':
stats['buy_orders'] += 1
elif order.get('orderSide') == 'SELL':
stats['sell_orders'] += 1
if order.get('state') == 'FILLED':
stats['filled_orders'] += 1
if order.get('executedQty'):
try:
qty = float(order['executedQty'])
stats['total_volume'] += qty
except (ValueError, TypeError):
pass
elif order.get('state') == 'CANCELED':
stats['canceled_orders'] += 1
if stats['filled_orders'] > 0:
stats['avg_trade_size'] = stats['total_volume'] / stats['filled_orders']
return stats
except Exception as e:
raise
def example_usage():
BASE_URL = "https://api.example.com"
ACCESS_KEY = "your_api_accessKey"
SECRET_KEY = "your_api_secretKey"
api_client = HistoryOrderAPI(BASE_URL, ACCESS_KEY, SECRET_KEY)
try:
recent_orders = api_client.query_history_orders(
symbol="btc_usdt",
limit=10
)
import datetime
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
start_ts = int(yesterday.timestamp() * 1000)
end_ts = int(time.time() * 1000)
time_range_orders = api_client.get_orders_by_time_range(
symbol="btc_usdt",
start_time=start_ts,
end_time=end_ts,
limit=20
)
all_orders = api_client.get_all_history_orders(
symbol="btc_usdt",
batch_size=20
)
stats = api_client.get_order_statistics(
symbol="btc_usdt",
days=7
)
first_page = api_client.query_history_orders(
symbol="btc_usdt",
limit=5,
direction="NEXT"
)
if first_page.get('items'):
last_order = first_page['items'][-1]
second_page = api_client.query_history_orders(
symbol="btc_usdt",
order_id=last_order['orderId'],
limit=5,
direction="NEXT"
)
print(f"Order quantity on page 2: {len(second_page.get('items', []))}")
except Exception as e:
print(f"Example execution failed: {str(e)}")
if __name__ == "__main__":
example_usage()
const API_CONFIG = {
BASE_URL: 'https://api.example.com',
ACCESS_KEY: 'your_api_accessKey',
SECRET_KEY: 'your_api_secretKey'
};
function generateSignature(params, secretKey) {
const sortedKeys = Object.keys(params).sort();
const queryString = sortedKeys
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&');
const CryptoJS = require('crypto-js');
const signature = CryptoJS.HmacSHA256(queryString, secretKey).toString();
return signature;
}
async function queryHistoryOrders(options = {}) {
try {
const queryParams = {
...options,
timestamp: Date.now()
};
Object.keys(queryParams).forEach(key => {
if (queryParams[key] === null || queryParams[key] === undefined || queryParams[key] === '') {
delete queryParams[key];
}
});
const signature = generateSignature(queryParams, API_CONFIG.SECRET_KEY);
const queryString = Object.keys(queryParams)
.map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
.join('&');
const url = `${API_CONFIG.BASE_URL}/v2/order/list-history?${queryString}`;
const headers = {
'X_ACCESS_KEY': API_CONFIG.ACCESS_KEY,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
};
const response = await fetch(url, {
method: 'GET',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.code !== 0) {
throw new Error(`API error: ${data.msg || 'Unknown error'}`);
}
return data.data;
} catch (error) {
console.error('Failed to query historical orders:', error);
throw error;
}
}
async function exampleUsage() {
try {
const recentOrders = await queryHistoryOrders({
symbol: 'btc_usdt',
limit: 10
});
console.log('The last 10 orders:', recentOrders);
const timeRangeOrders = await queryHistoryOrders({
symbol: 'btc_usdt',
startTime: 1672444800000, // 2023-01-01 00:00:00
endTime: 1672531200000, // 2023-01-02 00:00:00
limit: 20
});
console.log('Time range order:', timeRangeOrders);
const firstPage = await queryHistoryOrders({
symbol: 'btc_usdt',
limit: 5,
direction: 'NEXT'
});
console.log('Page One:', firstPage);
if (firstPage.items && firstPage.items.length > 0) {
const lastOrderId = firstPage.items[firstPage.items.length - 1].orderId;
const secondPage = await queryHistoryOrders({
symbol: 'btc_usdt',
id: lastOrderId,
direction: 'NEXT',
limit: 5
});
console.log('Page Two:', secondPage);
}
} catch (error) {
console.error('Example execution failed:', error);
}
}
async function getAllHistoryOrders(options) {
const { symbol, batchSize = 50 } = options;
let allOrders = [];
let lastOrderId = null;
let hasMore = true;
try {
while (hasMore) {
const queryOptions = {
symbol: symbol,
limit: batchSize,
direction: 'NEXT'
};
if (lastOrderId) {
queryOptions.id = lastOrderId;
}
const response = await queryHistoryOrders(queryOptions);
if (response.items && response.items.length > 0) {
allOrders = allOrders.concat(response.items);
lastOrderId = response.items[response.items.length - 1].orderId;
hasMore = response.items.length === batchSize;
} else {
hasMore = false;
}
await new Promise(resolve => setTimeout(resolve, 100));
}
return allOrders;
} catch (error) {
console.error('Batch query of historical orders failed:', error);
throw error;
}
}
module.exports = {
queryHistoryOrders,
getAllHistoryOrders,
exampleUsage
};
if (typeof window !== 'undefined') {
window.TradeAPI = {
queryHistoryOrders,
getAllHistoryOrders
};
}
描述:查询历史订单,使用游标分页机制。
接口权重:2
请求方式:GET
请求地址:/v2/order/list-history
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| id | 否 | string | 游标ID | 1234567890 |
| direction | 否 | string | 分页方向:NEXT/PREV | NEXT |
| limit | 否 | integer | 每页数量(默认10) | 10 |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"page": 1,
"ps": 10,
"total": 1,
"items": [
{
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
}
]
},
"bizCode": null
}
查询订单详情
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order/detail"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"orderId": "587077935051136448"
}
params = {k: v for k, v in params.items() if v is not None}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), query_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order/detail";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getOrderDetail(orderId) {
const params = { orderId };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) {
usp.append(k, String(v));
}
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
getOrderDetail("587077935051136448").catch(console.error);
描述:根据订单ID查询订单详情。
接口权重:1
请求方式:GET
请求地址:/v2/order/detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数(query):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| orderId | 是 | string | 订单ID | 587077935051136448 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
},
"bizCode": null
}
查询成交记录
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order/trade-list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"orderId": "587077935051136448",
"symbol": "btc_usdt",
"startTime": None,
"endTime": None,
"page": 1,
"size": 10
}
params = {k: v for k, v in params.items() if v is not None}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), query_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order/trade-list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getTradeList(params) {
const entries = Object.entries(params || {}).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, String(v));
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
getTradeList({
orderId: "587077935051136448",
symbol: "btc_usdt",
page: 1,
size: 10
}).catch(console.error);
描述:查询订单的成交明细记录。
接口权重:2
请求方式:GET
请求地址:/v2/order/trade-list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| orderId | 否 | string | 订单ID | 587077935051136448 |
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
| page | 否 | integer | 页码(默认1) | 1 |
| size | 否 | integer | 每页数量(默认10) | 10 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
execId |
String(序列化后) | 成交记录ID(唯一标识) | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
quantity |
String(序列化后) | 成交数量(张) | "0.5" |
price |
String(序列化后) | 成交价格 | "88256.7" |
fee |
String(序列化后) | 手续费金额 | "0.0005" |
feeCoin |
String | 手续费币种 | "USDT" |
timestamp |
Long | 成交时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、execId、quantity、price、fee等字段在响应中会被JsonSerialize注解转换为字符串类型,避免前端处理大数字时精度丢失。 - 成交标识:
execId是每笔成交的唯一标识,同一订单可能有多笔成交记录。 - 手续费:
fee为负数表示扣除手续费,正数表示返还手续费(如 Maker 返佣)。 - 时间单位:
timestamp为毫秒级 Unix 时间戳。
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"page": 1,
"ps": 10,
"total": 8734,
"items": [
{
"orderId": "587077935051136448",
"execId": "587077935538634818",
"symbol": "btc_usdt",
"quantity": "1",
"price": "88256.7",
"fee": "0.0044",
"feeCoin": "usdt",
"timestamp": 1769672287213
},
{
"orderId": "584291373785223168",
"execId": "584291374195540034",
"symbol": "btc_usdt",
"quantity": "88",
"price": "89751.62",
"fee": "0.3949",
"feeCoin": "usdt",
"timestamp": 1769007919217
}
]
},
"bizCode": null
}
查询仓位列表
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/position/list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"symbol": "btc_usdt"
}
params = {k: v for k, v in params.items() if v is not None}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), query_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/position/list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getPositionList(params = {}) {
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, String(v));
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
getPositionList({ symbol: "btc_usdt" }).catch(console.error);
getPositionList({}).catch(console.error);
描述:获取用户的持仓信息,可指定交易对或获取所有持仓。
接口权重:2
请求方式:GET
请求地址:/v2/position/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
positionId |
String(序列化后) | 持仓ID | "1234567890123456789" |
positionType |
String | 仓位类型:CROSSED(全仓)、ISOLATED(逐仓) |
"ISOLATED" |
positionSide |
String | 持仓方向:LONG(多仓)、SHORT(空仓) |
"LONG" |
positionSize |
String(序列化后) | 持仓数量(张) | "10.5" |
closeOrderSize |
String(序列化后) | 平仓挂单数量(张) | "2.0" |
availableCloseSize |
String(序列化后) | 可平仓数量(张) | "8.5" |
entryPrice |
String(序列化后) | 开仓均价 | "45000.00" |
isolatedMargin |
String(序列化后) | 逐仓保证金(仅逐仓模式有效) | "500.00" |
openOrderMarginFrozen |
String(序列化后) | 开仓订单保证金占用 | "100.00" |
realizedProfit |
String(序列化后) | 已实现盈亏(可为正负) | "125.50" |
autoMargin |
Boolean | 是否自动追加保证金 | true |
leverage |
Integer | 杠杆倍数 | 20 |
contractSize |
String(序列化后) | 合约乘数(每张合约对应的标的数量) | "0.001" |
计算公式(供参考):
- 持仓市值 =
positionSize×entryPrice×contractSize - 可用保证金 =
isolatedMargin-openOrderMarginFrozen(仅逐仓) - 未实现盈亏 = (
当前价格-entryPrice) ×positionSize×contractSize× (positionSide为LONG时取+1,SHORT时取-1)
字段关系说明:
positionSize=closeOrderSize+availableCloseSizepositionType= "ISOLATED"时,isolatedMargin字段有效;"CROSSED"时,该字段通常为0或无意义leverage仅影响保证金计算,不影响实际持仓数量
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"symbol": "btc_usdt",
"positionId": "587077935156970752",
"positionType": "CROSSED",
"positionSide": "LONG",
"positionSize": "1",
"closeOrderSize": "0",
"availableCloseSize": "1",
"entryPrice": "88256.7",
"isolatedMargin": "0.4413",
"openOrderMarginFrozen": "0",
"realizedProfit": "-0.0008",
"autoMargin": false,
"leverage": 20,
"contractSize": "0.0001"
}
],
"bizCode": null
}
调整杠杆
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/position/adjust-leverage"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"symbol": "btc_usdt",
"leverage": 20
}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), body_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
const crypto = require('crypto');
const URL = "BASE_URL/v2/position/adjust-leverage";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function adjustLeverage(symbol, leverage) {
const params = { symbol, leverage };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, String(v));
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
adjustLeverage("btc_usdt", 20).catch(console.error);
描述:调整指定交易对的杠杆倍数,存在持仓时不能修改。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/position/adjust-leverage
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求参数(query):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| leverage | 是 | integer | 杠杆倍数(最小1) | 20 |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
调整保证金
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/position/margin"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
params = {
"symbol": "btc_usdt",
"positionSide": "LONG",
"positionId": "1234567890",
"margin": "100.00",
"type": "ADD" # "SUB"
}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), body_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
const crypto = require('crypto');
const URL = "BASE_URL/v2/position/margin";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function adjustMargin(params) {
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, String(v));
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
adjustMargin({
symbol: "btc_usdt",
positionSide: "LONG",
positionId: "1234567890",
margin: "100.00",
type: "ADD"
}).catch(console.error);
描述:调整逐仓仓位的保证金。
接口权重:5
请求方式:POST
请求地址:(TRADE)/v2/position/margin
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求参数(query):
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| positionSide | 是 | string | 持仓方向:LONG/SHORT | LONG |
| positionId | 是 | string | 持仓ID | 1234567890 |
| margin | 是 | string | 调整的保证金数量(正数) | 100.00 |
| type | 是 | string | 调整方向:ADD/SUB | ADD |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
平仓所有仓位
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/position/close-all"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def close_positions(symbol=None):
params = {}
if symbol is not None:
params["symbol"] = symbol
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), body_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
close_positions("btc_usdt")
close_positions()
const crypto = require('crypto');
const URL = "BASE_URL/v2/position/close-all";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function closePositions(symbol) {
const params = {};
if (symbol !== undefined && symbol !== null) params.symbol = String(symbol);
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
closePositions("btc_usdt").catch(console.error);
closePositions().catch(console.error);
描述:一键平掉用户的所有持仓或指定交易对的持仓。
接口权重:10
请求方式:POST
请求地址:(TRADE)/v2/position/close-all
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符(不传则平掉所有) | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
修改持仓类型
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/position/change-type"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def change_position_type(symbol, positionType, positionModel):
params = {
"symbol": symbol,
"positionType": positionType,
"positionModel": positionModel
}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), body_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
change_position_type("btc_usdt", "CROSSED", "AGGREGATION")
const crypto = require('crypto');
const URL = "BASE_URL/v2/position/change-type";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function changePositionType(symbol, positionType, positionModel) {
const params = {
symbol,
positionType,
positionModel
};
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, String(v));
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
changePositionType("btc_usdt", "CROSSED", "AGGREGATION").catch(console.error);
描述:修改持仓的模式和类型(全仓/逐仓,合仓/分仓)。
接口权重:3
请求方式:POST
请求地址:(TRADE)/v2/position/change-type
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| positionType | 是 | string | 仓位类型:CROSSED/ISOLATED | CROSSED |
| positionModel | 是 | string | 仓位模式:AGGREGATION/DISAGGREGATION | AGGREGATION |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
创建计划委托
import requests
import json
BASE_URL = "BASE_URL"
API_KEY = "your_api_accessKey"
X_SIGNATURE = "your_api_query_secretKey"
HEADERS = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": X_SIGNATURE,
"Content-Type": "application/x-www-form-urlencoded"
}
payload = {
"symbol": "btc_usdt",
"entrustType": "STOP",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"price": "45000.00",
"origQty": "1.0",
"stopPrice": "44500.00",
"triggerPriceType": "MARK_PRICE",
"positionId": "1234567890",
"marketOrderLevel": 1,
"expireTime": "1769759999000"
}
try:
response = requests.post(f"{BASE_URL}/v2/entrust/create-plan",
data=payload, headers=HEADERS)
data = response.json()
if response.status_code == 200 and data.get("code") == 0:
print("Plan entrust created successfully")
print(f"Entrust ID: {data.get('data', {}).get('entrustId')}")
else:
print(f"Error: {data.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
const axios = require('axios');
const BASE_URL = 'BASE_URL';
const API_KEY = 'your_api_accessKey';
const X_SIGNATURE = 'your_api_query_secretKey';
const headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': X_SIGNATURE,
'Content-Type': 'application/x-www-form-urlencoded'
};
async function createPlanEntrust(params) {
try {
const payload = {
symbol: params.symbol,
entrustType: params.entrustType,
orderSide: params.orderSide,
positionSide: params.positionSide,
timeInForce: params.timeInForce || 'GTC',
price: params.price?.toString(),
origQty: params.origQty.toString(),
stopPrice: params.stopPrice.toString(),
triggerPriceType: params.triggerPriceType || 'LATEST_PRICE',
positionId: params.positionId,
marketOrderLevel: params.marketOrderLevel,
expireTime: params.expireTime
};
const response = await axios.post(`${BASE_URL}/v2/entrust/create-plan`,
payload, { headers });
if (response.data.code === 0) {
console.log('Plan entrust created successfully');
return response.data;
} else {
throw new Error(response.data.message || 'Unknown error');
}
} catch (error) {
console.error('Error creating plan entrust:', error.message);
throw error;
}
}
createPlanEntrust({
symbol: 'btc_usdt',
entrustType: 'STOP',
orderSide: 'BUY',
positionSide: 'LONG',
timeInForce: 'GTC',
price: '45000.00',
origQty: 1.0,
stopPrice: '44500.00',
triggerPriceType: 'MARK_PRICE'
})
.then(result => {
console.log('Created plan entrust:', result.data.entrustId);
})
.catch(error => {
console.error('Failed:', error.message);
});
描述:创建计划委托订单(条件单)。当市场价格达到触发条件时,系统自动创建对应的限价或市价订单。
接口权重:10
请求方式:POST
请求地址:(TRADE)/v2/entrust/create-plan
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
1. 基础参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| entrustType | 是 | string | 委托类型:STOP(限价)、TAKE_PROFIT_MARKET(止盈市价) |
STOP |
| orderSide | 是 | string | 买卖方向:BUY/SELL |
BUY |
| positionSide | 是 | string | 持仓方向:LONG/SHORT |
LONG |
| timeInForce | 是 | string | 有效方式:GTC/IOC/FOK/GTX |
GTC |
| origQty | 是 | string | 数量(张)必须是整数 | 1.0 |
2. 价格参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| price | 是 | string | 订单价格 | 45000.00 |
| stopPrice | 是 | string | 触发价格 | 44500.00 |
3. 触发条件参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| triggerPriceType | 是 | string | 触发价格类型:MARK_PRICE(标记价格)/LATEST_PRICE(最新价格) |
MARK_PRICE |
4. 价单参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| marketOrderLevel | 否 | integer | 市价最优档:1(对手价)、2(当前价)、5、10、15挡,市价单有效 | 1 |
5. 平仓相关参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| positionId | 条件必填 | string | 仓位ID,平仓计划委托时必填 | 1234567890 |
6. 其他参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| expireTime | 否 | long | 过期时间(时间戳) | 1769759999000 |
触发逻辑说明:
- 限价触发单(STOP)
- 买单触发:当
当前价 ≤ stopPrice时,以price价格挂限价买单 - 卖单触发:当
当前价 ≥ stopPrice时,以price价格挂限价卖单 - 示例:
orderSide=BUY, stopPrice=44500, price=45000
当价格跌到44500时,以45000挂买单(高于触发价,确保能买入)
- 市价触发单(STOP_MARKET)
- 触发后以市价下单
- 可通过
marketOrderLevel控制吃单深度
- 平仓判断规则
在开平仓模式下,以下情况为平仓委托,必须提供 positionId:
- orderSide=BUY 且 positionSide=SHORT(买入平空)
- orderSide=SELL 且 positionSide=LONG(卖出平多)
- 价格限制规则
- 买单:
price ≤ stopPrice × (1 + multiplierUp)
multiplierUp为交易对最大上浮比例 - 卖单:
price ≥ stopPrice × (1 - multiplierDown)
multiplierDown为交易对最大下浮比例
精度要求:
- 数量精度:
origQty必须是整数(scale=0) - 价格精度:
price和stopPrice必须符合交易对的最小价格步长 - 触发价格:
stopPrice必须能被最小价格步长整除
交易模式说明:
- 买卖模式(BUY_SELL):
positionSide只能是LONG或SHORT - 开平仓模式(OPEN_CLOSE):
positionSide为BOTH
响应示例:
{
"code": 0,
"message": "success",
"data": {
"entrustId": "1234567890123456789",
"symbol": "btc_usdt",
"entrustType": "STOP",
"state": "NOT_TRIGGERED"
}
}
错误码说明:
invalid_params: 参数无效或不完整invalid_position_side: 仓位方向与交易模式不匹配invalid_price: 价格精度错误或不符合步长要求invalid_stop_price: 触发价格精度错误invalid_quantity_scale: 数量不是整数price_cannot_greater_than_stop_price_of: 买单价格超过触发价的上限price_cannot_less_than_stop_price_of: 卖单价格低于触发价的下限
创建止盈止损
import requests
import json
BASE_URL = "BASE_URL"
API_KEY = "your_api_accessKey"
X_SIGNATURE = "your_api_query_secretKey"
HEADERS = {
"X_ACCESS_KEY": API_KEY,
"X_SIGNATURE": X_SIGNATURE,
"Content-Type": "application/x-www-form-urlencoded"
}
payload = {
"symbol": "btc_usdt",
"positionSide": "LONG",
"origQty": "1.0",
"triggerPriceType": "MARK_PRICE",
"triggerProfitPrice": "46000.00",
"triggerStopPrice": "44000.00",
"positionId": "1234567890",
"profitOrderType": "MARKET",
"stopOrderType": "MARKET",
"profitFlag": 1,
"reduceOnly": True
}
try:
response = requests.post(f"{BASE_URL}/v2/entrust/create-profit",
data=payload, headers=HEADERS)
data = response.json()
if response.status_code == 200 and data.get("code") == 0:
print("Profit stop order created successfully")
print(f"Profit ID: {data.get('data', {}).get('profitId')}")
else:
print(f"Error: {data.get('message', 'Unknown error')}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
const axios = require('axios');
const BASE_URL = 'BASE_URL';
const API_KEY = 'your_api_accessKey';
const X_SIGNATURE = 'your_api_query_secretKey';
const headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': X_SIGNATURE,
'Content-Type': 'application/x-www-form-urlencoded'
};
async function createProfitEntrust(params) {
try {
const payload = {
symbol: params.symbol,
positionSide: params.positionSide,
origQty: params.origQty.toString(),
triggerPriceType: params.triggerPriceType || 'LATEST_PRICE',
triggerProfitPrice: params.triggerProfitPrice?.toString(),
triggerStopPrice: params.triggerStopPrice?.toString(),
positionId: params.positionId,
profitOrderType: params.profitOrderType || 'MARKET',
stopOrderType: params.stopOrderType || 'MARKET',
profitFlag: params.profitFlag || 1,
reduceOnly: params.reduceOnly !== false
};
const response = await axios.post(`${BASE_URL}/v2/entrust/create-profit`,
payload, { headers });
if (response.data.code === 0) {
console.log('Profit stop order created successfully');
return response.data;
} else {
throw new Error(response.data.message || 'Unknown error');
}
} catch (error) {
console.error('Error creating profit stop order:', error.message);
throw error;
}
}
createProfitEntrust({
symbol: 'btc_usdt',
positionSide: 'LONG',
origQty: 1.0,
triggerPriceType: 'MARK_PRICE',
triggerProfitPrice: 46000.00,
triggerStopPrice: 44000.00,
positionId: '1234567890',
profitFlag: 1
})
.then(result => {
console.log('Created profit stop order:', result.data.profitId);
})
.catch(error => {
console.error('Failed:', error.message);
});
描述:创建止盈止损订单。支持两种模式:1) 开仓止盈止损(无positionId) 2) 平仓止盈止损(有positionId)。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/entrust/create-profit
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
1. 基础参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| origQty | 是 | string | 数量(张),为0时表示平全部仓位 | 1.0 |
2. 触发条件参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| triggerPriceType | 否 | string | 触发价格类型:MARK_PRICE(标记价格)/LATEST_PRICE(最新价格),默认LATEST_PRICE |
MARK_PRICE |
| triggerProfitPrice | 否 | string | 止盈触发价格 | 46000.00 |
| triggerStopPrice | 否 | string | 止损触发价格 | 44000.00 |
3. 订单类型参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| profitOrderType | 否 | string | 止盈订单类型:MARKET/LIMIT,默认MARKET |
MARKET |
| stopOrderType | 否 | string | 止损订单类型:MARKET/LIMIT,默认MARKET |
MARKET |
| profitOrderPrice | 否 | string | LIMIT止盈订单的委托价格 | 45950.00 |
| stopOrderPrice | 否 | string | LIMIT止损订单的委托价格 | 44050.00 |
4. 模式选择参数 模式一:开仓止盈止损(positionId为空)
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| orderSide | 是 | string | 买卖方向:BUY/SELL |
BUY |
| positionSide | 是 | string | 仓位方向:LONG/SHORT/BOTH |
LONG |
模式二:平仓止盈止损(positionId不为空)
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| positionId | 否 | string | 仓位ID,为空时是开仓止盈止损 | 1234567890 |
| orderSide | 否 | string | 买卖方向,平仓时自动计算 | BUY |
5. 其他参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| reduceOnly | 否 | boolean | 是否只减仓,默认true |
true |
| profitFlag | 否 | integer | 1:全部止盈止损, 2:部分止盈止损,默认1 |
1 |
| expireTime | 否 | long | 过期时间(时间戳) | 1769759999000 |
注意:
- 止盈价格和止损价格至少需要设置一个
- 模式选择:
- 当
positionId为空时:创建开仓止盈止损,需要指定orderSide和positionSide - 当
positionId不为空时:创建平仓止盈止损,系统自动计算orderSide
- 当
- 数量说明:
origQty为0时:触发时平掉对应仓位的全部数量origQty为正数时:触发时平掉指定数量
- LIMIT订单:当订单类型为
LIMIT时,必须提供对应的委托价格(profitOrderPrice/stopOrderPrice) - 精度要求:
- 数量必须是整数(scale=0)
- 价格精度需符合交易对设置
- 交易模式:
BUY_SELL模式下:仓位方向只能是LONG或SHORTOPEN_CLOSE模式下:仓位方向为BOTH
响应示例:
{
"code": 0,
"message": "success",
"data": {
"profitId": "1234567890123456789",
"symbol": "btc_usdt",
"positionSide": "LONG",
"state": "NOT_TRIGGERED"
}
}
错误码说明:
invalid_params: 参数无效或不完整invalid_quantity_scale: 数量不是整数invalid_trigger_profit_price: 止盈价格精度错误invalid_trigger_stop_price: 止损价格精度错误more_than_available: 平仓数量超过可用平仓数量invalid_position_side: 仓位方向与交易模式不匹配
取消计划委托
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/entrust/cancel-plan"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_plan(entrust_id):
params = {"entrustId": str(entrust_id)}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_plan("1234567890")
const crypto = require('crypto');
const URL = "BASE_URL/v2/entrust/cancel-plan";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelPlan(entrustId) {
const params = { entrustId: String(entrustId) };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelPlan("1234567890").catch(console.error);
描述:取消指定的计划委托。
接口权重:5
请求方式:POST
请求地址:(TRADE)/v2/entrust/cancel-plan
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| entrustId | 是 | string | 计划委托ID | 1234567890 |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
取消止盈止损
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/entrust/cancel-profit-stop"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_profit(profit_id):
params = {"profitId": str(profit_id)}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_profit("1234567890")
const crypto = require('crypto');
const URL = "BASE_URL/v2/entrust/cancel-profit-stop";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelProfit(profitId) {
const params = { profitId: String(profitId) };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelProfit("1234567890").catch(console.error);
描述:取消指定的止盈止损委托。
接口权重:5
请求方式:POST
请求地址:(TRADE)/v2/entrust/cancel-profit-stop
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| profitId | 是 | string | 止盈止损ID | 1234567890 |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
更新止盈止损
import hmac
import hashlib
from urllib.parse import urlencode
import requests
import json
from decimal import Decimal, getcontext
getcontext().prec = 10
URL = "BASE_URL/v2/entrust/update-profit-stop"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
class ProfitEntrustAPI:
def __init__(self, access_key, secret_key):
self.access_key = access_key
self.secret_key = secret_key
def _generate_signature(self, body_str):
return hmac.new(
self.secret_key.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256
).hexdigest()
def _validate_params(self, params):
errors = []
if "profitId" not in params:
errors.append("profitId is a required parameter")
if ("triggerProfitPrice" not in params or params["triggerProfitPrice"] is None) and \
("triggerStopPrice" not in params or params["triggerStopPrice"] is None):
errors.append("At least one of triggerProfitPrice or triggerStopPrice needs to be provided")
profit_order_type = params.get("profitOrderType")
stop_order_type = params.get("stopOrderType")
if profit_order_type == "LIMIT":
trigger_profit = params.get("triggerProfitPrice")
profit_price = params.get("profitOrderPrice")
has_trigger = trigger_profit is not None and str(trigger_profit).strip() != ""
has_price = profit_price is not None and str(profit_price).strip() != ""
if has_trigger != has_price:
errors.append("LIMIT profit-limit order: Both triggerProfitPrice and profitOrderPrice must be provided simultaneously or neither should be provided")
if stop_order_type == "LIMIT":
trigger_stop = params.get("triggerStopPrice")
stop_price = params.get("stopOrderPrice")
has_trigger = trigger_stop is not None and str(trigger_stop).strip() != ""
has_price = stop_price is not None and str(stop_price).strip() != ""
if has_trigger != has_price:
errors.append("LIMIT stop-loss order: Both triggerStopPrice and stopOrderPrice must be provided simultaneously or neither must be provided")
orig_qty = params.get("origQty")
if orig_qty is not None:
try:
qty = Decimal(str(orig_qty))
if qty < 0:
errors.append("The quantity cannot be less than 0")
except:
errors.append("The quantity format is incorrect")
profit_flag = params.get("profitFlag")
if profit_flag is not None:
try:
flag = int(profit_flag)
if flag not in [0, 1, 2]:
errors.append("profitFlag must be 0, 1, or 2")
except:
errors.append("profitFlag must be an integer")
return errors
def update_profit_stop(self, params):
errors = self._validate_params(params)
if errors:
raise ValueError(f"Parameter verification failed: {', '.join(errors)}")
if "profitFlag" in params:
profit_flag = params["profitFlag"]
if profit_flag in ["0", "1"]:
params["profitFlag"] = "1"
else:
params["profitFlag"] = "2"
cleaned_params = {}
for k, v in params.items():
if v is not None:
if isinstance(v, bool):
cleaned_params[k] = "true" if v else "false"
else:
cleaned_params[k] = str(v).strip()
items = sorted(cleaned_params.items())
body_str = urlencode(items)
signature = self._generate_signature(body_str)
headers = {
"X_ACCESS_KEY": self.access_key,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
try:
result = resp.json()
return result
except ValueError:
return {"error": resp.text, "raw_response": resp.text}
if __name__ == "__main__":
api = ProfitEntrustAPI(ACCESS_KEY, SECRET_KEY)
try:
params1 = {
"profitId": "1234567890",
"triggerProfitPrice": "46500.00",
"triggerPriceType": "LATEST_PRICE",
"profitOrderType": "MARKET",
"profitFlag": "1"
}
result1 = api.update_profit_stop(params1)
params2 = {
"profitId": "1234567890",
"triggerProfitPrice": "47000.00",
"triggerStopPrice": "43000.00",
"profitOrderType": "LIMIT",
"stopOrderType": "LIMIT",
"profitOrderPrice": "47100.00",
"stopOrderPrice": "42900.00",
"triggerPriceType": "MARK_PRICE",
"origQty": "2.5",
"profitFlag": "1"
}
result2 = api.update_profit_stop(params2)
params3 = {
"profitId": "1234567890",
"origQty": "3.0",
"profitFlag": "2"
}
result3 = api.update_profit_stop(params3)
try:
params4 = {
"profitId": "1234567890",
"triggerProfitPrice": "47000.00",
"profitOrderType": "LIMIT",
"profitFlag": "1"
}
result4 = api.update_profit_stop(params4)
except ValueError as e:
print(f"expected error: {e}")
except Exception as e:
print(f"error: {e}")
const crypto = require('crypto');
const URL = "BASE_URL/v2/entrust/update-profit-stop";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
class ProfitEntrustAPI {
constructor(accessKey, secretKey) {
this.accessKey = accessKey;
this.secretKey = secretKey;
}
_generateSignature(bodyStr) {
return crypto.createHmac('sha256', this.secretKey)
.update(bodyStr)
.digest('hex');
}
_validateParams(params) {
const errors = [];
if (!params.profitId) {
errors.push("profitId is a required parameter");
}
const hasTriggerProfit = params.triggerProfitPrice != null && String(params.triggerProfitPrice).trim() !== '';
const hasTriggerStop = params.triggerStopPrice != null && String(params.triggerStopPrice).trim() !== '';
if (!hasTriggerProfit && !hasTriggerStop) {
errors.push("At least one of triggerProfitPrice or triggerStopPrice needs to be provided");
}
const profitOrderType = params.profitOrderType;
const stopOrderType = params.stopOrderType;
if (profitOrderType === 'LIMIT') {
const hasTriggerProfitPrice = hasTriggerProfit;
const hasProfitOrderPrice = params.profitOrderPrice != null && String(params.profitOrderPrice).trim() !== '';
if (hasTriggerProfitPrice !== hasProfitOrderPrice) {
errors.push("LIMIT profit-limit order: Both triggerProfitPrice and profitOrderPrice must be provided simultaneously or neither should be provided");
}
}
if (stopOrderType === 'LIMIT') {
const hasTriggerStopPrice = hasTriggerStop;
const hasStopOrderPrice = params.stopOrderPrice != null && String(params.stopOrderPrice).trim() !== '';
if (hasTriggerStopPrice !== hasStopOrderPrice) {
errors.push("LIMIT stop-loss order: Both triggerStopPrice and stopOrderPrice must be provided simultaneously or neither should be provided");
}
}
if (params.origQty != null) {
const qty = parseFloat(params.origQty);
if (isNaN(qty) || qty < 0) {
errors.push("The quantity cannot be less than 0");
}
}
if (params.profitFlag != null) {
const flag = parseInt(params.profitFlag);
if (isNaN(flag) || ![0, 1, 2].includes(flag)) {
errors.push("profitFlag must be 0, 1, or 2");
}
}
return errors;
}
async updateProfitStop(params) {
const errors = this._validateParams(params);
if (errors.length > 0) {
throw new Error(`Parameter verification failed: ${errors.join(', ')}`);
}
const processedParams = { ...params };
if (processedParams.profitFlag != null) {
const flag = parseInt(processedParams.profitFlag);
if (flag === 0 || flag === 1) {
processedParams.profitFlag = '1';
} else {
processedParams.profitFlag = '2';
}
}
const cleanedParams = {};
for (const [key, value] of Object.entries(processedParams)) {
if (value != null) {
if (typeof value === 'boolean') {
cleanedParams[key] = value ? 'true' : 'false';
} else {
cleanedParams[key] = String(value).trim();
}
}
}
const entries = Object.entries(cleanedParams);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = this._generateSignature(bodyStr);
const headers = {
"X_ACCESS_KEY": this.accessKey,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, {
method: "POST",
headers,
body: bodyStr
});
const contentType = resp.headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return await resp.json();
} else {
const text = await resp.text();
console.log(`非JSON响应: ${text}`);
return { error: text, rawResponse: text };
}
}
}
(async () => {
const api = new ProfitEntrustAPI(ACCESS_KEY, SECRET_KEY);
try {
const params1 = {
profitId: "1234567890",
triggerProfitPrice: "46500.00",
triggerPriceType: "LATEST_PRICE",
profitOrderType: "MARKET",
profitFlag: "1"
};
const result1 = await api.updateProfitStop(params1);
const params2 = {
profitId: "1234567890",
triggerProfitPrice: "47000.00",
triggerStopPrice: "43000.00",
profitOrderType: "LIMIT",
stopOrderType: "LIMIT",
profitOrderPrice: "47100.00",
stopOrderPrice: "42900.00",
triggerPriceType: "MARK_PRICE",
origQty: "2.5",
profitFlag: "1"
};
const result2 = await api.updateProfitStop(params2);
console.log("结果2:", JSON.stringify(result2, null, 2));
try {
const params3 = {
profitId: "1234567890",
triggerProfitPrice: "47000.00",
profitOrderType: "LIMIT",
profitFlag: "1"
};
const result3 = await api.updateProfitStop(params3);
} catch (error) {
console.log("expected error:", error.message);
}
} catch (error) {
console.error("error:", error.message);
}
})();
描述:修改止盈止损订单的多种参数。
接口权重:3
请求方式:POST
请求地址:(TRADE)/v2/entrust/update-profit-stop
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| profitId | 是 | string | 止盈止损记录ID | 1234567890 |
| triggerProfitPrice | 否 | string | 止盈触发价格 | 46500.00 |
| triggerStopPrice | 否 | string | 止损触发价格 | 43500.00 |
| triggerPriceType | 否 | string | 触发价格类型:MARK_PRICE/LATEST_PRICE | LATEST_PRICE |
| profitOrderType | 否 | string | 止盈订单类型:MARKET/LIMIT(默认MARKET) | MARKET |
| stopOrderType | 否 | string | 止损订单类型:MARKET/LIMIT(默认MARKET) | MARKET |
| origQty | 否 | string | 数量(张),必须≥0 | 2.5 |
| profitOrderPrice | 否 | string | LIMIT订单的止盈委托价 | 47000.00 |
| stopOrderPrice | 否 | string | LIMIT订单的止损委托价 | 43000.00 |
| profitFlag | 否 | string | 止盈止损标志:0/1/2(0和1都会转为1) | 1 |
重要验证规则:
- 必填检查:
profitId必须提供 - 价格必填:
triggerProfitPrice和triggerStopPrice至少提供一个 - LIMIT订单特殊规则:
- 如果
profitOrderType= "LIMIT",则triggerProfitPrice和profitOrderPrice必须同时提供或同时不提供 - 如果
stopOrderType= "LIMIT",则triggerStopPrice和stopOrderPrice必须同时提供或同时不提供
- 如果
- 数量限制:
origQty必须 ≥ 0 - profitFlag转换:
- 0 → 转换为 1
- 1 → 保持为 1
- 2 → 保持为 2
- 其他值 → 错误
- 默认值:
profitOrderType默认 "MARKET"stopOrderType默认 "MARKET"triggerPriceType默认 "LATEST_PRICE"
成功响应示例:
{
"code": 0,
"message": "success",
"data": {
"adjustId": 9876543210,
"status": "PROCESSING"
}
}
取消所有计划委托
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/entrust/cancel-all-plan"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_all_plans(symbol=None):
params = {}
if symbol is not None:
params["symbol"] = symbol
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_all_plans("btc_usdt")
cancel_all_plans()
const crypto = require('crypto');
const URL = "BASE_URL/v2/entrust/cancel-all-plan";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelAllPlans(symbol) {
const params = {};
if (symbol !== undefined && symbol !== null) params.symbol = String(symbol);
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelAllPlans("btc_usdt").catch(console.error);
cancelAllPlans().catch(console.error);
描述:撤销用户的所有计划委托(可指定交易对)。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/entrust/cancel-all-plan
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符(不传则撤销所有) | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
取消所有止盈止损
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "/v2/entrust/cancel-all-profit-stop"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_all_profit_stop(symbol=None):
params = {}
if symbol is not None:
params["symbol"] = symbol
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_all_profit_stop("btc_usdt")
cancel_all_profit_stop()
const crypto = require('crypto');
const URL = "BASE_URL/v2/entrust/cancel-all-profit-stop";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelAllProfitStop(symbol) {
const params = {};
if (symbol !== undefined && symbol !== null) params.symbol = String(symbol);
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelAllProfitStop("btc_usdt").catch(console.error);
cancelAllProfitStop().catch(console.error);
描述:撤销用户的所有止盈止损(可指定交易对)。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/entrust/cancel-all-profit-stop
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符(不传则撤销所有) | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
查询计划委托列表
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/entrust/plan-list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def plan_list(symbol=None, state=None, id=None, limit=None, direction=None):
params = {}
if symbol is not None: params["symbol"] = str(symbol)
if state is not None: params["state"] = str(state)
if id is not None: params["id"] = str(id)
if limit is not None: params["limit"] = str(limit)
if direction is not None: params["direction"] = str(direction) # "NEXT" or "PREV"
items = sorted(params.items())
query_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
res = plan_list(symbol="btc_usdt", state="NOT_TRIGGERED", limit=10, direction="NEXT")
print(res)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/entrust/plan-list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function planList(options = {}) {
const paramsObj = {};
for (const k of ["symbol", "state", "id", "limit", "direction"]) {
if (options[k] !== undefined && options[k] !== null) paramsObj[k] = String(options[k]);
}
const keys = Object.keys(paramsObj).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, paramsObj[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
return resp.json();
}
(async () => {
try {
const data = await planList({ symbol: "btc_usdt", state: "NOT_TRIGGERED", limit: 10, direction: "NEXT" });
console.log(data);
} catch (err) {
console.error(err);
}
})();
描述:查询当前用户的计划委托列表。
接口权重:2
请求方式:GET
请求地址:/v2/entrust/plan-list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| state | 否 | string | 订单状态:NOT_TRIGGERED/TRIGGERING等 | NOT_TRIGGERED |
| id | 否 | string | 分页ID | 1234567890 |
| limit | 否 | integer | 每页数量(默认10) | 10 |
| direction | 否 | string | 分页方向:NEXT/PREV | NEXT |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
entrustId |
String(序列化后) | 计划委托ID | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
entrustType |
String | 委托类型(条件单类型) | "STOP" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"GTC" |
closePosition |
Boolean | 是否触发全平仓 | false |
price |
String(序列化后) | 订单价格(触发后订单的委托价格) | "45000.00" |
origQty |
String(序列化后) | 委托数量(张) | "10" |
stopPrice |
String(序列化后) | 触发价格 | "45500.00" |
triggerPriceType |
String | 触发价格类型:MARK_PRICE、LATEST_PRICE等 |
"LATEST_PRICE" |
isOrdinary |
Boolean | 是否为普通计划单 | true |
state |
String | 委托状态:NOT_TRIGGERED:未触发TRIGGERING:触发中TRIGGERED:已触发USER_REVOCATION:用户撤销PLATFORM_REVOCATION:平台撤销EXPIRED:已过期 |
"NOT_TRIGGERED" |
marketOrderLevel |
Integer | 市价最优档位(触发后若为市价单有效) | 1 |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
响应示例:
{
"code": 0,
"message": "success",
"data": {
"page": 1,
"size": 10,
"total": 5,
"items": [
{
"entrustId": "1234567890",
"symbol": "btc_usdt",
"entrustType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"price": "45000.00",
"origQty": "1.0",
"stopPrice": "44500.00",
"triggerPriceType": "MARK_PRICE",
"state": "NOT_TRIGGERED",
"createdTime": 1672531200000
}
]
}
}
查询计划委托历史
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/entrust/plan-list-history"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def plan_list_history(symbol=None, id=None, direction=None, limit=None, startTime=None, endTime=None):
params = {}
if symbol is not None: params["symbol"] = str(symbol)
if id is not None: params["id"] = str(id)
if direction is not None: params["direction"] = str(direction) # "NEXT" or "PREV"
if limit is not None: params["limit"] = str(limit)
if startTime is not None: params["startTime"] = str(startTime) # milliseconds
if endTime is not None: params["endTime"] = str(endTime)
# sort & urlencode
items = sorted(params.items())
query_str = urlencode(items) # "" if no params
# signature: HMAC-SHA256(hex) over the query string (or empty string)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
result = plan_list_history(symbol="btc_usdt", limit=10, direction="NEXT")
print(result)
// Node 18+ has global fetch. For older Node, install node-fetch.
const crypto = require('crypto');
const BASE = "BASE_URL/v2/entrust/plan-list-history";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function planListHistory(options = {}) {
// options: { symbol, id, direction, limit, startTime, endTime }
const params = {};
for (const k of ["symbol", "id", "direction", "limit", "startTime", "endTime"]) {
if (options[k] !== undefined && options[k] !== null) params[k] = String(options[k]);
}
const keys = Object.keys(params).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, params[k]);
const queryStr = usp.toString(); // "" if no params
// signature: HMAC-SHA256(hex) over the query string (or empty string)
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
return resp.json();
}
(async () => {
try {
const res = await planListHistory({ symbol: "btc_usdt", limit: 10, direction: "NEXT" });
console.log(res);
} catch (err) {
console.error(err);
}
})();
描述:查询历史计划委托记录(不包括未触发和触发中的委托)。
接口权重:2
请求方式:GET
请求地址:/v2/entrust/plan-list-history
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| id | 否 | string | 游标ID | 1234567890 |
| direction | 否 | string | 分页方向:NEXT/PREV | NEXT |
| limit | 否 | integer | 每页数量(默认10) | 10 |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
entrustId |
String(序列化后) | 计划委托ID | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
entrustType |
String | 委托类型(条件单类型) | "STOP" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"GTC" |
closePosition |
Boolean | 是否触发全平仓 | false |
price |
String(序列化后) | 订单价格(触发后订单的委托价格) | "45000.00" |
origQty |
String(序列化后) | 委托数量(张) | "10" |
stopPrice |
String(序列化后) | 触发价格 | "45500.00" |
triggerPriceType |
String | 触发价格类型:MARK_PRICE、LATEST_PRICE等 |
"LATEST_PRICE" |
isOrdinary |
Boolean | 是否为普通计划单 | true |
state |
String | 委托状态:NOT_TRIGGERED:未触发TRIGGERING:触发中TRIGGERED:已触发USER_REVOCATION:用户撤销PLATFORM_REVOCATION:平台撤销EXPIRED:已过期 |
"NOT_TRIGGERED" |
marketOrderLevel |
Integer | 市价最优档位(触发后若为市价单有效) | 1 |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
响应示例:
{
"code": 0,
"message": "success",
"data": {
"page": 1,
"size": 10,
"total": 150,
"items": [
{
"entrustId": "1234567890",
"symbol": "btc_usdt",
"entrustType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"price": "45000.00",
"origQty": "1.0",
"stopPrice": "44500.00",
"triggerPriceType": "MARK_PRICE",
"state": "TRIGGERED",
"createdTime": 1672444800000
}
]
}
}
查询止盈止损列表
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/entrust/profit-list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def profit_list(symbol=None, state=None, id=None, limit=None, direction=None):
params = {}
if symbol is not None: params["symbol"] = str(symbol)
if state is not None: params["state"] = str(state)
if id is not None: params["id"] = str(id)
if limit is not None: params["limit"] = str(limit)
if direction is not None: params["direction"] = str(direction) # "NEXT" or "PREV"
items = sorted(params.items())
query_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(profit_list(symbol="btc_usdt", state="NOT_TRIGGERED", limit=10))
const crypto = require('crypto');
const BASE = "BASE_URL/v2/entrust/profit-list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function profitList(options = {}) {
const paramsObj = {};
for (const k of ["symbol", "state", "id", "limit", "direction"]) {
if (options[k] !== undefined && options[k] !== null) paramsObj[k] = String(options[k]);
}
const keys = Object.keys(paramsObj).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, paramsObj[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
return resp.json();
}
(async () => {
try {
const data = await profitList({ symbol: "btc_usdt", state: "NOT_TRIGGERED", limit: 10 });
console.log(data);
} catch (err) {
console.error(err);
}
})();
描述:查询当前用户的止盈止损列表。
接口权重:2
请求方式:GET
请求地址:/v2/entrust/profit-list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| state | 否 | string | 订单状态 | NOT_TRIGGERED |
| id | 否 | string | 分页ID | 1234567890 |
| limit | 否 | integer | 每页数量(默认10) | 10 |
| direction | 否 | string | 分页方向:NEXT/PREV | NEXT |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
profitId |
String(序列化后) | 止盈止损委托ID | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
origQty |
String(序列化后) | 委托数量(张) | "10" |
triggerPriceType |
String | 触发价格类型:MARK_PRICE(标记价格)、LATEST_PRICE(最新价格) |
"MARK_PRICE" |
triggerProfitPrice |
String(序列化后) | 止盈触发价格 | "46000.00" |
triggerStopPrice |
String(序列化后) | 止损触发价格 | "44000.00" |
entryPrice |
String(序列化后) | 开仓均价 | "45000.00" |
positionSize |
String(序列化后) | 持仓数量(张) | "10" |
isolatedMargin |
String(序列化后) | 逐仓保证金 | "225.00" |
executedQty |
String(序列化后) | 已成交数量(张) | "0" |
state |
String | 委托状态:NOT_TRIGGERED:未触发TRIGGERING:触发中TRIGGERED:已触发USER_REVOCATION:用户撤销PLATFORM_REVOCATION:平台撤销EXPIRED:已过期 |
"NOT_TRIGGERED" |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
响应示例:
{
"code": 0,
"message": "success",
"data": {
"page": 1,
"size": 10,
"total": 3,
"items": [
{
"profitId": "1234567890",
"symbol": "btc_usdt",
"positionSide": "LONG",
"origQty": "1.0",
"triggerPriceType": "MARK_PRICE",
"triggerProfitPrice": "46000.00",
"triggerStopPrice": "44000.00",
"entryPrice": "45000.00",
"positionSize": "1.0",
"isolatedMargin": "450.00",
"executedQty": "0.0",
"state": "NOT_TRIGGERED",
"createdTime": 1672531200000
}
]
}
}
查询计划委托详情
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/entrust/plan-detail"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_plan_detail(entrust_id):
if not entrust_id:
raise ValueError("entrustId is required")
params = {"entrustId": str(entrust_id)}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + "?" + query_str
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(get_plan_detail("1234567890"))
const crypto = require('crypto');
const BASE = "BASE_URL/v2/entrust/plan-detail";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getPlanDetail(entrustId) {
if (!entrustId) throw new Error("entrustId is required");
const params = { entrustId: String(entrustId) };
const keys = Object.keys(params).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, params[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
return resp.json();
}
getPlanDetail("1234567890").then(console.log).catch(console.error);
描述:根据委托ID查询计划委托详情。
接口权重:1
请求方式:GET
请求地址:/v2/entrust/plan-detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| entrustId | 是 | string | 计划委托ID | 1234567890 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
entrustId |
String(序列化后) | 计划委托ID | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
entrustType |
String | 委托类型(条件单类型) | "STOP" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"GTC" |
closePosition |
Boolean | 是否触发全平仓 | false |
price |
String(序列化后) | 订单价格(触发后订单的委托价格) | "45000.00" |
origQty |
String(序列化后) | 委托数量(张) | "10" |
stopPrice |
String(序列化后) | 触发价格 | "45500.00" |
triggerPriceType |
String | 触发价格类型:MARK_PRICE、LATEST_PRICE等 |
"LATEST_PRICE" |
isOrdinary |
Boolean | 是否为普通计划单 | true |
state |
String | 委托状态:NOT_TRIGGERED:未触发TRIGGERING:触发中TRIGGERED:已触发USER_REVOCATION:用户撤销PLATFORM_REVOCATION:平台撤销EXPIRED:已过期 |
"NOT_TRIGGERED" |
marketOrderLevel |
Integer | 市价最优档位(触发后若为市价单有效) | 1 |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
计划委托类型说明:
常见 entrustType 值:
STOP:普通限价触发单- 当价格达到
stopPrice时,以price价格挂出限价单
- 当价格达到
TAKE_PROFIT:止盈单- 达到止盈价位后平仓
STOP_LOSS:止损单- 达到止损价位后平仓
TAKE_PROFIT_STOP:止盈止损单- 同时设置止盈和止损(可能需其他字段配合)
TRAILING_STOP:跟踪止损单- 动态调整止损价位
触发逻辑(以买入为例):
场景1:限价触发买单(BUY)
- 条件:当前价 ≤
stopPrice(下跌到触发价) - 动作:以
price价格挂出限价买单 - 示例:
stopPrice="44000",price="43900"(低于触发价挂单)
- 条件:当前价 ≤
场景2:限价触发卖单(SELL)
- 条件:当前价 ≥
stopPrice(上涨到触发价) - 动作:以
price价格挂出限价卖单 - 示例:
stopPrice="46000",price="46100"(高于触发价挂单)
- 条件:当前价 ≥
场景3:市价触发单
- 当
price=0或price=null时,触发后以市价下单 marketOrderLevel控制吃单深度
- 当
特殊字段说明:
closePosition:true:触发后平掉对应方向的全部仓位false:正常开仓或平部分仓位
triggerPriceType:- 决定使用哪种价格判断触发条件
MARK_PRICE:标记价格(防操纵)LATEST_PRICE:最新成交价
isOrdinary:true:普通计划单(价格触发)false:高级计划单(可能包含更复杂条件)
状态流转:
- 正常触发:
NOT_TRIGGERED→TRIGGERING→TRIGGERED - 用户取消:
NOT_TRIGGERED→USER_REVOCATION - 系统拒绝:
NOT_TRIGGERED→PLATFORM_REVOCATION - 过期失效:
NOT_TRIGGERED→EXPIRED
响应示例:
{
"code": 0,
"message": "success",
"data": {
"entrustId": "1234567890",
"symbol": "btc_usdt",
"entrustType": "LIMIT",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "GTC",
"closePosition": false,
"price": "45000.00",
"origQty": "1.0",
"stopPrice": "44500.00",
"triggerPriceType": "MARK_PRICE",
"isOrdinary": true,
"state": "NOT_TRIGGERED",
"marketOrderLevel": null,
"createdTime": 1672531200000
}
}
查询止盈止损详情
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/entrust/profit-detail"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_profit_detail(profit_id):
if not profit_id:
raise ValueError("profitId is required")
params = {"profitId": str(profit_id)}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + "?" + query_str
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
print(get_profit_detail("1234567890"))
const crypto = require('crypto');
const BASE = "BASE_URL/v2/entrust/profit-detail";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getProfitDetail(profitId) {
if (!profitId) throw new Error("profitId is required");
const params = { profitId: String(profitId) };
const keys = Object.keys(params).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, params[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
return resp.json();
}
getProfitDetail("1234567890")
.then(console.log)
.catch(console.error);
描述:根据ID查询止盈止损详情。
接口权重:1
请求方式:GET
请求地址:/v2/entrust/profit-detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| profitId | 是 | string | 止盈止损ID | 1234567890 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
profitId |
String(序列化后) | 止盈止损委托ID | "1234567890123456789" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
origQty |
String(序列化后) | 委托数量(张) | "10" |
triggerPriceType |
String | 触发价格类型:MARK_PRICE(标记价格)、LATEST_PRICE(最新价格) |
"MARK_PRICE" |
triggerProfitPrice |
String(序列化后) | 止盈触发价格 | "46000.00" |
triggerStopPrice |
String(序列化后) | 止损触发价格 | "44000.00" |
entryPrice |
String(序列化后) | 开仓均价 | "45000.00" |
positionSize |
String(序列化后) | 持仓数量(张) | "10" |
isolatedMargin |
String(序列化后) | 逐仓保证金 | "225.00" |
executedQty |
String(序列化后) | 已成交数量(张) | "0" |
state |
String | 委托状态:NOT_TRIGGERED:未触发TRIGGERING:触发中TRIGGERED:已触发USER_REVOCATION:用户撤销PLATFORM_REVOCATION:平台撤销EXPIRED:已过期 |
"NOT_TRIGGERED" |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
字段详细说明:
- 触发条件相关
triggerPriceType:MARK_PRICE:使用标记价格触发(防止价格操纵)LATEST_PRICE:使用最新成交价触发
triggerProfitPrice:当市场价格达到此价格时触发止盈triggerStopPrice:当市场价格达到此价格时触发止损
- 持仓关联信息
entryPrice:对应持仓的开仓均价,用于计算盈亏比例positionSize:当前持仓总数量(可能大于委托数量)isolatedMargin:该持仓占用的保证金(仅逐仓模式)
- 数量关系
origQty:计划平仓的数量executedQty:已触发成交的数量(触发后才会更新)positionSize≥origQty(委托数量不能超过持仓)
- 状态流转
NOT_TRIGGERED→TRIGGERING→TRIGGERED(正常触发)NOT_TRIGGERED→USER_REVOCATION(用户主动撤销)NOT_TRIGGERED→PLATFORM_REVOCATION(系统拒绝,如仓位已平)NOT_TRIGGERED→EXPIRED(有效期过期)
- 触发逻辑示例(LONG仓位):
- 止盈触发:当
triggerPriceType对应的价格 ≥triggerProfitPrice - 止损触发:当
triggerPriceType对应的价格 ≤triggerStopPrice
- 止盈触发:当
计算示例:
假设 LONG 仓位:
- 开仓价:45000 USDT
- 止盈价:46000 USDT(盈利 2.22%)
- 止损价:44000 USDT(亏损 2.22%)
- 委托数量:10 张
- 合约乘数:0.001 BTC/张
预期盈利 = (46000 - 45000) × 10 × 0.001 = 100 USDT
预期亏损 = (44000 - 45000) × 10 × 0.001 = -100 USDT
响应示例:
{
"code": 0,
"message": "success",
"data": {
"profitId": "1234567890",
"symbol": "btc_usdt",
"positionSide": "LONG",
"origQty": "1.0",
"triggerPriceType": "MARK_PRICE",
"triggerProfitPrice": "46000.00",
"triggerStopPrice": "44000.00",
"entryPrice": "45000.00",
"positionSize": "1.0",
"isolatedMargin": "450.00",
"executedQty": "0.0",
"state": "NOT_TRIGGERED",
"createdTime": 1672531200000
}
}
查询委托列表
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order-entrust/list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_order_entrust_list(type=None, symbol=None, state=None,
startTime=None, endTime=None, forceClose=None,
page=None, size=None):
params = {}
if type is not None: params["type"] = str(type)
if symbol is not None: params["symbol"] = str(symbol)
if state is not None: params["state"] = str(state)
if startTime is not None: params["startTime"] = str(startTime)
if endTime is not None: params["endTime"] = str(endTime)
if forceClose is not None:
# send boolean as lowercase string to be explicit
params["forceClose"] = "true" if forceClose else "false"
if page is not None: params["page"] = str(page)
if size is not None: params["size"] = str(size)
# sort and encode
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items) # empty string if no params
# signature (HMAC-SHA256 hex)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
res = get_order_entrust_list(type="ORDER", symbol="btc_usdt", page=1, size=10)
print(res)
// Node 18+ has global fetch. For older Node, install node-fetch.
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order-entrust/list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getOrderEntrustList(options = {}) {
// options: { type, symbol, state, startTime, endTime, forceClose, page, size }
const params = {};
if (options.type !== undefined) params.type = String(options.type);
if (options.symbol !== undefined) params.symbol = String(options.symbol);
if (options.state !== undefined) params.state = String(options.state);
if (options.startTime !== undefined) params.startTime = String(options.startTime);
if (options.endTime !== undefined) params.endTime = String(options.endTime);
if (options.forceClose !== undefined) params.forceClose = options.forceClose ? "true" : "false";
if (options.page !== undefined) params.page = String(options.page);
if (options.size !== undefined) params.size = String(options.size);
// build sorted query string
const keys = Object.keys(params).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, params[k]);
const queryStr = usp.toString(); // "" if no params
// signature: HMAC-SHA256 hex
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
if (!resp.ok) throw new Error(`HTTP ${resp.status} ${await resp.text()}`);
const ct = resp.headers.get("content-type") || "";
return ct.includes("application/json") ? await resp.json() : await resp.text();
}
(async () => {
try {
const result = await getOrderEntrustList({ type: "ORDER", symbol: "btc_usdt", page: 1, size: 10 });
console.log(result);
} catch (err) {
console.error(err);
}
})();
描述:查询全部委托(包括限价/市价订单和计划委托)。
接口权重:2
请求方式:GET
请求地址:/v2/order-entrust/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| type | 否 | string | 类型:ORDER/ENTRUST | ORDER |
| symbol | 否 | string | 交易对标识符 | btc_usdt |
| state | 否 | string | 订单状态 | NEW |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
| forceClose | 否 | boolean | 是否强平 | false |
| page | 否 | integer | 页码(默认1) | 1 |
| size | 否 | integer | 每页数量(默认10) | 10 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
id |
String(序列化后) | 委托记录ID | "1234567890123456789" |
type |
String | 类型:ORDER(限价/市价委托)、ENTRUST(计划委托) |
"ORDER" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"LIMIT" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"GTC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格(限价单有效) | "45000.00" |
origQty |
String(序列化后) | 原始委托数量(张) | "10" |
avgPrice |
String(序列化后) | 成交均价 | "44980.50" |
executedQty |
String(序列化后) | 已成交数量(张) | "5" |
marginFrozen |
String(序列化后) | 占用保证金 | "250.50" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(条件单) | "46000.00" |
triggerStopPrice |
String(序列化后) | 止损触发价(条件单) | "44000.00" |
leverage |
Integer | 杠杆倍数 | 20 |
entrustOrderId |
Long | 条件触发关联订单ID(条件单) | 987654321 |
closeProfit |
String(序列化后) | 平仓盈亏(平仓订单有效) | "125.50" |
state |
String | 订单状态:NEW:新建PARTIALLY_FILLED:部分成交FILLED:全部成交CANCELED:用户撤销REJECTED:下单失败EXPIRED:已过期 |
"PARTIALLY_FILLED" |
createdTime |
Long | 创建时间(Unix时间戳,毫秒) | 1769672287213 |
entrustType |
String | 委托类型(条件单类型) | "TAKE_PROFIT_STOP" |
stopPrice |
String(序列化后) | 触发价格(条件单) | "45500.00" |
triggerPriceType |
String | 触发价格类型(如 LAST、INDEX等) |
"LAST" |
isOrdinary |
Boolean | 是否为普通计划单 | true |
marketOrderLevel |
Integer | 市价最优档位(市价单有效) | 1 |
forceClose |
Boolean | 是否为强平订单 | false |
字段分组说明:
- 基础订单信息
type、symbol、orderType、orderSide、positionSide、leverage
- 价格与数量
price、origQty、avgPrice、executedQty、marginFrozen- 未成交数量 =
origQty-executedQty
- 条件单专属字段
triggerProfitPrice、triggerStopPrice、entrustOrderIdentrustType、stopPrice、triggerPriceType、isOrdinary
- 状态与时间
state、createdTime、closeProfit、forceClose
- 市价单专属
marketOrderLevel(控制市价单吃单深度)
常见状态流转:
NEW→PARTIALLY_FILLED→FILLEDNEW→CANCELED(用户主动撤单)NEW→EXPIRED(限价单超时未成交)NEW→REJECTED(下单失败,如资金不足)
条件单类型参考:
TAKE_PROFIT:止盈单STOP_LOSS:止损单TAKE_PROFIT_STOP:止盈止损单TRAILING_STOP:跟踪止损单
响应示例(type=ORDER):
{
"code": 0,
"msg": "success",
"data": {
"page": 1,
"ps": 10,
"total": 1,
"items": [
{
"id": "587077935051136448",
"type": "ORDER",
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"leverage": null,
"entrustOrderId": null,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213,
"entrustType": null,
"stopPrice": null,
"triggerPriceType": null,
"isOrdinary": null,
"marketOrderLevel": null,
"forceClose": false
}
]
},
"bizCode": null
}
取消委托
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/order-entrust/cancel"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_order_entrust(type_, id_):
params = {
"type": type_,
"id": str(id_)
}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_order_entrust("ORDER", "1234567890")
const crypto = require('crypto');
const URL = "BASE_URL/v2/order-entrust/cancel";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelOrderEntrust(type, id) {
const params = { type: String(type), id: String(id) };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelOrderEntrust("ORDER", "1234567890").catch(console.error);
描述:撤销指定的委托(订单或计划委托)。
接口权重:5
请求方式:POST
请求地址:(TRADE)/v2/order-entrust/cancel
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| type | 是 | string | 类型:ORDER/ENTRUST | ORDER |
| id | 是 | string | 委托ID | 1234567890 |
响应示例:
{
"code": 0,
"message": "success",
"data": null
}
取消所有委托
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/order-entrust/cancel-all"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def cancel_all_entrusts(symbol=None):
params = {}
if symbol is not None:
params["symbol"] = symbol
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
cancel_all_entrusts("btc_usdt")
cancel_all_entrusts()
const crypto = require('crypto');
const URL = "BASE_URL/v2/order-entrust/cancel-all";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function cancelAllEntrusts(symbol) {
const params = {};
if (symbol !== undefined && symbol !== null) params.symbol = String(symbol);
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
cancelAllEntrusts("btc_usdt").catch(console.error);
cancelAllEntrusts().catch(console.error);
描述:撤销用户的所有委托(包括订单和计划委托),可指定交易对。
接口权重:8
请求方式:POST
请求地址:(TRADE)/v2/order-entrust/cancel-all
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 否 | string | 交易对标识符(不传则撤销所有) | btc_usdt |
响应示例:
{
"code": 0,
"message": "success",
"data": true
}
查询余额列表
import hmac
import hashlib
import requests
URL = "BASE_URL/v2/balance/list"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_balance_list():
payload = ""
signature = hmac.new(SECRET_KEY.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.get(URL, headers=headers, timeout=10)
print(resp.status_code)
try:
data = resp.json()
print(data)
except ValueError:
print(resp.text)
if __name__ == "__main__":
get_balance_list()
const crypto = require('crypto');
const URL = "BASE_URL/v2/balance/list";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
(async () => {
try {
const payload = "";
const signature = crypto.createHmac('sha256', SECRET_KEY).update(payload).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "GET", headers });
const text = await resp.text();
console.log(resp.status);
const ct = resp.headers.get("content-type") || "";
if (ct.includes("application/json")) {
console.log(JSON.parse(text));
} else {
console.log(text);
}
} catch (err) {
console.error(err);
}
})();
描述:获取用户所有币种的资金信息。
接口权重:2
请求方式:GET
请求地址:/v2/balance/list
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"coin": "usdt",
"walletBalance": "93164.5884631",
"openOrderMarginFrozen": "0",
"isolatedMargin": "0",
"crossedMargin": "0.4413",
"availableBalance": "93164.1471631",
"bonus": "0"
}
],
"bizCode": null
}
字段说明:
walletBalance: 钱包总余额openOrderMarginFrozen: 挂单冻结金额isolatedMargin: 逐仓保证金占用crossedMargin: 全仓保证金占用availableBalance: 可用余额bonus: 体验金/活动赠送余额
获取用户单币种资金
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/balance/detail"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_balance_detail(coin):
if not coin:
raise ValueError("coin is required")
params = {"coin": coin}
items = sorted(params.items())
query_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + "?" + query_str
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
get_balance_detail("btc")
const crypto = require('crypto');
const BASE = "BASE_URL/v2/balance/detail";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getBalanceDetail(coin) {
if (!coin) throw new Error("coin is required");
const params = { coin: String(coin) };
const keys = Object.keys(params).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, params[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const ct = resp.headers.get("content-type") || "";
const result = ct.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
getBalanceDetail("btc").catch(console.error);
描述:获取指定币种的用户资金详情。
接口权重:1
请求方式:GET
请求地址:/v2/balance/detail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| coin | 是 | string | 币种代码 | btc |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
coin |
String | 币种标识 | "USDT" |
walletBalance |
String(序列化后) | 钱包总余额 | "5000.75" |
openOrderMarginFrozen |
String(序列化后) | 订单保证金冻结(挂单占用) | "250.50" |
isolatedMargin |
String(序列化后) | 逐仓保证金(已开仓占用) | "1200.00" |
crossedMargin |
String(序列化后) | 全仓起始保证金(全仓模式占用) | "0.00" |
availableBalance |
String(序列化后) | 可用余额(可用于开仓/提现) | "3549.25" |
bonus |
String(序列化后) | 体验金余额(如有) | "100.00" |
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"coin": "btc",
"walletBalance": "0",
"openOrderMarginFrozen": "0",
"isolatedMargin": "0",
"crossedMargin": "0",
"availableBalance": "0",
"bonus": "0"
},
"bizCode": null
}
查询账单记录
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/balance/bills"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def get_bills(id=None, direction=None, limit=None, coin=None, symbol=None,
type_=None, startTime=None, endTime=None):
params = {
"id": id,
"direction": direction,
"limit": limit,
"coin": coin,
"symbol": symbol,
"type": type_,
"startTime": startTime,
"endTime": endTime
}
items = sorted((k, str(v)) for k, v in params.items() if v is not None)
query_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
get_bills(limit=10, coin="USDT", symbol="btc_usdt", startTime=1672444800000, endTime=1672531200000)
const crypto = require('crypto');
const BASE = "BASE_URL/v2/balance/bills";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function getBills(options = {}) {
const paramsObj = {};
for (const k of ["id", "direction", "limit", "coin", "symbol", "type", "startTime", "endTime"]) {
if (options[k] !== undefined && options[k] !== null) {
paramsObj[k] = String(options[k]);
}
}
const keys = Object.keys(paramsObj).sort();
const usp = new URLSearchParams();
for (const k of keys) usp.append(k, paramsObj[k]);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const ct = resp.headers.get("content-type") || "";
const result = ct.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
getBills({
limit: 10,
coin: "USDT",
symbol: "btc_usdt",
startTime: 1672444800000,
endTime: 1672531200000
}).catch(console.error);
描述:查询用户的账务流水记录,支持分页和筛选。
接口权重:2
请求方式:GET
请求地址:/v2/balance/bills
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| id | 否 | string | 游标ID(用于分页) | 1234567890 |
| direction | 否 | string | 分页方向:NEXT/PREV | NEXT |
| limit | 否 | integer | 每页记录数(默认10) | 10 |
| coin | 否 | string | 筛选币种 | BTC |
| symbol | 否 | string | 交易对 | btc_usdt |
| type | 否 | string | 账单类型 | FEE |
| startTime | 否 | integer | 开始时间戳(毫秒) | 1672444800000 |
| endTime | 否 | integer | 结束时间戳(毫秒) | 1672531200000 |
账单类型说明:
EXCHANGE: 划转CLOSE_POSITION: 平仓盈亏TAKE_OVER: 仓位接管QIANG_PING_MANAGER: 强平清算费FUND: 资金费用FEE: 手续费(开仓、平仓、强平)ADL: 自动减仓MERGE: 仓位合并
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
id |
String(序列化后) | 流水记录ID | "9876543210123456789" |
coin |
String | 币种标识 | "USDT" |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
type |
String | 流水类型:EXCHANGE:划转CLOSE_POSITION:平仓盈亏TAKE_OVER:仓位接管QIANG_PING_MANAGER:强平管理费(手续费)FUND:资金费用FEE:手续费(开仓、平仓、强平)ADL:自动减仓MERGE:仓位合并 |
"FEE" |
amount |
String(序列化后) | 变动数量(可为正负) | "-0.5000" |
side |
String | 资金方向:ADD:增加/划入SUB:减少/转出 |
"SUB" |
afterAmount |
String(序列化后) | 变动后余额 | "1250.7500" |
createdTime |
Long | 记录创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
type与side的关系:
type表示资金变动的业务场景side表示资金是增加还是减少- 例如:
type="FEE"且side="SUB"表示扣除手续费
- 数值符号规则:
- 通常
amount为正数表示收入,负数表示支出 side="ADD"时,amount通常为正side="SUB"时,amount通常为负
- 常见场景示例:
- 手续费扣除:
type="FEE",side="SUB",amount="-0.5000" - 资金费用收取:
type="FUND",side="SUB",amount="-0.0012" - 平仓盈利:
type="CLOSE_POSITION",side="ADD",amount="125.50" - 资金划入:
type="EXCHANGE",side="ADD",amount="1000.00"
afterAmount:
- 表示该笔流水变动后的账户余额(仅针对该币种)
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"hasPrev": false,
"hasNext": true,
"items": [
{
"id": "587083445113472257",
"coin": "usdt",
"symbol": "btc_usdt",
"type": "FUND",
"amount": "-0.00080000",
"side": "SUB",
"afterAmount": null,
"createdTime": 1769673600798
},
{
"id": "587077936180380928",
"coin": "usdt",
"symbol": "btc_usdt",
"type": "FEE",
"amount": "-0.00440000",
"side": "SUB",
"afterAmount": null,
"createdTime": 1769672287366
}
]
},
"bizCode": null
}
获取监听Key
import hmac
import hashlib
import requests
URL = "BASE_URL/v2/user/listen-key"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
payload = ""
signature = hmac.new(SECRET_KEY.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.get(URL, headers=headers, timeout=10)
print(resp.status_code)
print(resp.text)
try:
resp_json = resp.json()
listen_key = resp_json.get("data")
print("listenKey:", listen_key)
except Exception:
pass
const crypto = require('crypto');
const URL = "BASE_URL/v2/user/listen-key";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
(async () => {
const payload = "";
const signature = crypto.createHmac('sha256', SECRET_KEY).update(payload).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "GET", headers });
const result = await resp.text();
console.log(resp.status, result);
try {
const json = JSON.parse(result);
console.log("listenKey:", json.data);
} catch (e) { /* ignore parse error */ }
})();
描述:获取WebSocket用户数据流的监听Key,用于建立私有数据流连接。
接口权重:5
请求方式:GET
请求地址:/v2/user/listen-key
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
响应示例:
{
"code": 0,
"msg": "success",
"data": "FAD5A97BA1BD77BAF64F9770AD05ABFF",
"bizCode": null
}
字段说明:
FAD5A97BA1BD77BAF64F9770AD05ABFF: WebSocket监听Key,用于连接私有数据流,Key的有效期通常为1小时
重要说明:
- 监听Key有效期为60分钟,需要定期刷新
- 每个用户最多同时持有5个有效的监听Key
- 断开WebSocket连接后,对应的监听Key将被自动回收
- 用户可以通过重新调用此接口获取新的监听Key
查询当前订单
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order/listUnfinished"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def list_unfinished(symbol, direction):
params = {
"symbol": symbol,
"direction": direction
}
items = sorted(params.items())
query_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
query_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + "?" + query_str
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
list_unfinished("btc_usdt", "BUY")
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order/listUnfinished";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function listUnfinished(symbol, direction) {
const params = { symbol: String(symbol), direction: String(direction) };
const entries = Object.entries(params).sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
listUnfinished("btc_usdt", "BUY").catch(console.error);
描述:查询指定交易对和方向的当前有效订单(未成交订单)。
接口权重:1
请求方式:GET
请求地址:/v2/order/listUnfinished
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| symbol | 是 | string | 交易对标识符 | btc_usdt |
| direction | 是 | string | 买卖方向:BUY/SELL | BUY |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"message": "success",
"data": [
{
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
}
]
}
查询所有当前订单
import hmac
import hashlib
from urllib.parse import urlencode
import requests
BASE = "BASE_URL/v2/order/all/listUnfinished"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def list_unfinished(symbols):
"""
symbols: list of symbol strings or a single comma-separated string, e.g. ["btc_usdt","eth_usdt"] or "btc_usdt,eth_usdt"
"""
if isinstance(symbols, (list, tuple)):
list_str = ",".join(symbols)
else:
list_str = str(symbols)
params = {"list": list_str}
sorted_items = sorted(params.items())
query_str = urlencode(sorted_items)
signature = hmac.new(SECRET_KEY.encode('utf-8'), query_str.encode('utf-8'), hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = BASE + ("?" + query_str if query_str else "")
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
list_unfinished(["btc_usdt", "eth_usdt"])
const crypto = require('crypto');
const BASE = "BASE_URL/v2/order/all/listUnfinished";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function listUnfinished(symbols) {
const listStr = Array.isArray(symbols) ? symbols.map(String).join(',') : String(symbols);
const params = { list: listStr };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const queryStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(queryStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const url = BASE + (queryStr ? `?${queryStr}` : "");
const resp = await fetch(url, { method: "GET", headers });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
listUnfinished(["btc_usdt","eth_usdt"]).catch(console.error);
描述:查询多个交易对的当前有效订单。
接口权重:1
请求方式:GET
请求地址:/v2/order/all/listUnfinished
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
查询参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| list | 是 | string | 交易对列表(逗号分隔) | btc_usdt,eth_usdt |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"message": "success",
"data": [
{
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
}
]
}
根据ID列表查询订单
import hmac
import hashlib
from urllib.parse import urlencode
import requests
URL = "BASE_URL/v2/order/list-by-ids"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
def list_by_ids(ids):
"""
ids: list of id strings OR a single comma-separated string
"""
if isinstance(ids, (list, tuple)):
ids_str = ",".join(map(str, ids))
else:
ids_str = str(ids)
params = {"ids": ids_str}
items = sorted((k, v) for k, v in params.items() if v is not None)
body_str = urlencode(items)
signature = hmac.new(SECRET_KEY.encode('utf-8'),
body_str.encode('utf-8'),
hashlib.sha256).hexdigest()
headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post(URL, data=body_str, headers=headers, timeout=10)
print(resp.status_code)
try:
print(resp.json())
except ValueError:
print(resp.text)
list_by_ids("587077935051136448")
list_by_ids(["587077935051136448", "587077935051136449"])
const crypto = require('crypto');
const URL = "BASE_URL/v2/order/list-by-ids";
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const SECRET_KEY = "YOUR_SECRET_KEY";
async function listByIds(ids) {
const idsStr = Array.isArray(ids) ? ids.map(String).join(',') : String(ids);
const params = { ids: idsStr };
const entries = Object.entries(params).filter(([k, v]) => v !== undefined && v !== null);
entries.sort((a, b) => a[0].localeCompare(b[0]));
const usp = new URLSearchParams();
for (const [k, v] of entries) usp.append(k, v);
const bodyStr = usp.toString();
const signature = crypto.createHmac('sha256', SECRET_KEY).update(bodyStr).digest('hex');
const headers = {
"X_ACCESS_KEY": ACCESS_KEY,
"X_SIGNATURE": signature,
"Content-Type": "application/x-www-form-urlencoded"
};
const resp = await fetch(URL, { method: "POST", headers, body: bodyStr });
const contentType = resp.headers.get("content-type") || "";
const result = contentType.includes("application/json") ? await resp.json() : await resp.text();
console.log(resp.status, result);
}
listByIds("587077935051136448").catch(console.error);
listByIds(["587077935051136448", "587077935051136449"]).catch(console.error);
描述:根据订单ID列表查询订单详情。
接口权重:1
请求方式:POST
请求地址:/v2/order/list-by-ids
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| ids | 是 | string | 订单ID列表(多个订单ID用逗号分隔) | 587077935051136448 |
字段说明:
| 字段名 | 字段类型 | 描述 | 示例 |
|---|---|---|---|
orderId |
String(序列化后) | 订单ID | "587077935051136448" |
clientOrderId |
String | 自定义订单ID(可为空) | null |
symbol |
String | 交易对标识(小写,下划线分隔) | "btc_usdt" |
orderType |
String | 订单类型:LIMIT、MARKET等 |
"MARKET" |
orderSide |
String | 买卖方向:BUY、SELL |
"BUY" |
positionSide |
String | 持仓方向:LONG、SHORT |
"LONG" |
timeInForce |
String | 有效方式:GTC、IOC、FOK、GTX |
"IOC" |
closePosition |
Boolean | 是否为条件全平仓订单 | false |
price |
String(序列化后) | 委托价格 | "0" |
origQty |
String(序列化后) | 原始委托数量(张) | "1" |
avgPrice |
String(序列化后) | 成交均价 | "88256.7" |
executedQty |
String(序列化后) | 已成交数量(张) | "1" |
marginFrozen |
String(序列化后) | 占用保证金 | "0.4524" |
triggerProfitPrice |
String(序列化后) | 止盈触发价(可为空) | null |
triggerStopPrice |
String(序列化后) | 止损触发价(可为空) | null |
sourceId |
Long | 条件触发ID(可为空) | null |
forceClose |
Boolean | 是否为全平订单 | false |
closeProfit |
String(序列化后) | 平仓盈亏(可为空) | null |
state |
String | 订单状态:NEW、PARTIALLY_FILLED、PARTIALLY_CANCELED、FILLED、CANCELED、REJECTED、EXPIRED |
"FILLED" |
createdTime |
Long | 订单创建时间(Unix时间戳,毫秒) | 1769672287213 |
补充说明:
- 序列化说明:
orderId、price、origQty等字段在响应中会被JsonSerialize注解转换为字符串类型,防止前端处理大数字时精度丢失。 - 时间单位:
createdTime为毫秒级 Unix 时间戳。 - 数值字段:所有
BigDecimal类型的字段(如价格、数量、保证金)均以字符串形式返回,保留完整精度。
响应示例:
{
"code": 0,
"message": "success",
"data": [
{
"orderId": "587077935051136448",
"clientOrderId": null,
"symbol": "btc_usdt",
"orderType": "MARKET",
"orderSide": "BUY",
"positionSide": "LONG",
"timeInForce": "IOC",
"closePosition": false,
"price": "0",
"origQty": "1",
"avgPrice": "88256.7",
"executedQty": "1",
"marginFrozen": "0.4524",
"triggerProfitPrice": null,
"triggerStopPrice": null,
"sourceId": null,
"forceClose": false,
"closeProfit": null,
"state": "FILLED",
"createdTime": 1769672287213
}
]
}
合伙人返佣明细
import requests
import time
import hmac
import hashlib
import urllib.parse
# 配置信息
BASE_URL = "https://api.example.com"
API_KEY = "your_api_accessKey"
SECRET_KEY = "your_api_query_secretKey"
def generate_signature(params, secret_key):
"""
生成签名
:param params: 请求参数字典
:param secret_key: API密钥
:return: 签名字符串
"""
# 对参数按照key进行排序
sorted_params = sorted(params.items())
# 构建查询字符串
query_string = '&'.join([f"{k}={v}" for k, v in sorted_params])
# 使用HMAC-SHA256生成签名
signature = hmac.new(
secret_key.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def get_rebate_detail(rebate_start_date=None, rebate_end_date=None, symbol_id=None):
"""
获取合伙人返佣明细
:param rebate_start_date: 查询开始时间(毫秒时间戳)
:param rebate_end_date: 查询结束时间(毫秒时间戳)
:param symbol_id: 币对ID
:return: 返佣明细数据
"""
# 请求路径
path = "/v2/channel/rebateDetail"
url = BASE_URL + path
# 构建请求参数
params = {}
if rebate_start_date:
params['rebateStartDate'] = str(rebate_start_date)
if rebate_end_date:
params['rebateEndDate'] = str(rebate_end_date)
if symbol_id:
params['symbolId'] = str(symbol_id)
# 生成签名
signature = generate_signature(params, SECRET_KEY)
# 设置请求头
headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded'
}
try:
# 发送GET请求
response = requests.get(url, params=params, headers=headers)
response.raise_for_status()
# 解析响应数据
data = response.json()
if data.get('code') == 0:
print("请求成功!")
return data.get('data', [])
else:
print(f"请求失败:{data.get('msg')}")
return None
except requests.exceptions.RequestException as e:
print(f"请求异常:{e}")
return None
# 使用示例1:查询所有返佣明细
if __name__ == "__main__":
# 示例1:查询所有记录(不传任何参数)
print("示例1:查询所有返佣明细")
result = get_rebate_detail()
if result:
for item in result:
print(f"用户:{item['uid']}, 交易对:{item['symbol']}, 返佣金额:{item['totalRebateAmount']}")
print("-" * 50)
# 示例2:按时间区间查询
print("示例2:按时间区间查询")
start_time = 1769919603517 # 开始时间戳
end_time = 1772511603517 # 结束时间戳
result = get_rebate_detail(rebate_start_date=start_time, rebate_end_date=end_time)
if result:
for item in result:
print(f"用户:{item['uid']}, 交易对:{item['symbol']}, 返佣金额:{item['totalRebateAmount']}")
print("-" * 50)
# 示例3:按币对ID查询
print("示例3:按币对ID查询")
result = get_rebate_detail(symbol_id=1)
if result:
for item in result:
print(f"用户:{item['uid']}, 交易对:{item['symbol']}, 返佣金额:{item['totalRebateAmount']}")
print("-" * 50)
# 示例4:组合条件查询
print("示例4:组合条件查询(时间区间+币对ID)")
result = get_rebate_detail(
rebate_start_date=1769919603517,
rebate_end_date=1772511603517,
symbol_id=2
)
if result:
for item in result:
print(f"用户:{item['uid']}, 交易对:{item['symbol']}, 返佣金额:{item['totalRebateAmount']}")
// 使用axios库,需要先安装:npm install axios
const axios = require('axios');
const crypto = require('crypto');
// 配置信息
const BASE_URL = 'https://api.example.com';
const API_KEY = 'your_api_accessKey';
const SECRET_KEY = 'your_api_query_secretKey';
/**
* 生成签名
* @param {Object} params - 请求参数对象
* @param {string} secretKey - API密钥
* @returns {string} 签名字符串
*/
function generateSignature(params, secretKey) {
// 对参数按照key进行排序
const sortedParams = Object.keys(params)
.sort()
.reduce((acc, key) => {
acc[key] = params[key];
return acc;
}, {});
// 构建查询字符串
const queryString = Object.entries(sortedParams)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
// 使用HMAC-SHA256生成签名
return crypto
.createHmac('sha256', secretKey)
.update(queryString)
.digest('hex');
}
/**
* 获取合伙人返佣明细
* @param {Object} options - 查询参数
* @param {string} options.rebateStartDate - 查询开始时间(毫秒时间戳)
* @param {string} options.rebateEndDate - 查询结束时间(毫秒时间戳)
* @param {string} options.symbolId - 币对ID
* @returns {Promise<Array>} 返佣明细数据
*/
async function getRebateDetail({ rebateStartDate, rebateEndDate, symbolId } = {}) {
// 请求路径
const path = '/v2/channel/rebateDetail';
const url = BASE_URL + path;
// 构建请求参数(只添加有值的参数)
const params = {};
if (rebateStartDate) params.rebateStartDate = String(rebateStartDate);
if (rebateEndDate) params.rebateEndDate = String(rebateEndDate);
if (symbolId) params.symbolId = String(symbolId);
// 生成签名
const signature = generateSignature(params, SECRET_KEY);
// 设置请求头
const headers = {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded'
};
try {
// 发送GET请求
const response = await axios.get(url, { params, headers });
// 解析响应数据
const { code, msg, data } = response.data;
if (code === 0) {
console.log('请求成功!');
return data;
} else {
console.log(`请求失败:${msg}`);
return null;
}
} catch (error) {
console.error('请求异常:', error.message);
if (error.response) {
console.error('响应数据:', error.response.data);
}
return null;
}
}
// 使用示例
async function main() {
// 示例1:查询所有返佣明细
console.log('示例1:查询所有返佣明细');
const result1 = await getRebateDetail();
if (result1) {
result1.forEach(item => {
console.log(`用户:${item.uid}, 交易对:${item.symbol}, 返佣金额:${item.totalRebateAmount}`);
});
}
console.log('-'.repeat(50));
// 示例2:按时间区间查询
console.log('示例2:按时间区间查询');
const result2 = await getRebateDetail({
rebateStartDate: '1769919603517',
rebateEndDate: '1772511603517'
});
if (result2) {
result2.forEach(item => {
console.log(`用户:${item.uid}, 交易对:${item.symbol}, 返佣金额:${item.totalRebateAmount}`);
});
}
console.log('-'.repeat(50));
// 示例3:按币对ID查询
console.log('示例3:按币对ID查询');
const result3 = await getRebateDetail({
symbolId: '1'
});
if (result3) {
result3.forEach(item => {
console.log(`用户:${item.uid}, 交易对:${item.symbol}, 返佣金额:${item.totalRebateAmount}`);
});
}
console.log('-'.repeat(50));
// 示例4:组合条件查询
console.log('示例4:组合条件查询(时间区间+币对ID)');
const result4 = await getRebateDetail({
rebateStartDate: '1769919603517',
rebateEndDate: '1772511603517',
symbolId: '2'
});
if (result4) {
result4.forEach(item => {
console.log(`用户:${item.uid}, 交易对:${item.symbol}, 返佣金额:${item.totalRebateAmount}`);
});
}
}
// 浏览器环境下的示例(使用fetch)
/*
async function getRebateDetailBrowser(params = {}) {
const url = new URL('https://api.example.com/v2/channel/rebateDetail');
// 添加查询参数
Object.keys(params).forEach(key => {
if (params[key]) {
url.searchParams.append(key, params[key]);
}
});
// 生成签名(实际环境中签名应在后端生成)
const signature = generateSignature(params, SECRET_KEY);
const response = await fetch(url, {
method: 'GET',
headers: {
'X_ACCESS_KEY': API_KEY,
'X_SIGNATURE': signature,
'Content-Type': 'application/x-www-form-urlencoded'
}
});
const data = await response.json();
return data;
}
*/
// 执行示例
main().catch(console.error);
描述:根据时间区间和币对ID获取合伙人返佣明细。
接口权重:1
请求方式:GET
请求地址:/v2/channel/rebateDetail
认证要求:需要API密钥认证
请求头:
X_ACCESS_KEY: your_api_accessKeyX_SIGNATURE: your_api_query_secretKeyContent-Type: application/x-www-form-urlencoded
请求体参数:
| 参数 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
| rebateStartDate | 否 | string | 查询开始时间(UTC+8) | 1769919603517 |
| rebateEndDate | 否 | string | 查询结束时间(UTC+8) | 1772511603517 |
| symbolId | 否 | string | 币对ID | 1 |
字段说明:
| 字段名 | 类型 | 描述 | 示例 |
|---|---|---|---|
| uid | String | 用户UID | "10000591" |
| pumpkinUid | String | pumpkinUID | "10132346" |
| walletAddress | String | 钱包地址 | null |
| totalTradeAmount | BigDecimal | 合计交易金额 | 19993.5193 |
| totalFee | BigDecimal | 合计手续费 | 9.9967 |
| totalRebateAmount | BigDecimal | 合计返佣金额 | 3.9987 |
| rebateDate | Long | 返佣统计时间(Unix时间戳,毫秒) | 1769039700000 |
| symbol | String | 交易对标识(小写,下划线分隔) | "eth_usdt" |
| rebateType | Integer | 返佣类型:1-自返佣,2-直客,3-差价 | 2 |
| rate | BigDecimal | 返佣比例 | 0.4 |
| userType | Integer | 用户类型:1-合伙人,2-散户 | 2 |
| symbolId | Integer | 交易对ID | 2 |
响应示例:
{
"code": 0,
"msg": "success",
"data": [
{
"uid": "10000585",
"pumpkinsUid": "10132346",
"walletAddress": "0xa90e27355aad0edfae161c5ba42002c8b2cd2738",
"totalTradeAmount": 50616.55316,
"totalFee": 25.3079,
"totalRebateAmount": 12.65395,
"rebateDate": 1772610900000,
"symbol": "btc_usdt",
"rebateType": 3,
"rate": 0.5,
"userType": 1,
"symbolId": 1
},
{
"uid": "10000585",
"pumpkinsUid": "10132346",
"walletAddress": "0xa90e27355aad0edfae161c5ba42002c8b2cd2738",
"totalTradeAmount": 21081.90828,
"totalFee": 10.54095413,
"totalRebateAmount": 5.270476,
"rebateDate": 1772610900000,
"symbol": "eth_usdt",
"rebateType": 3,
"rate": 0.5,
"userType": 1,
"symbolId": 2
}
],
"bizCode": null
}
API 错误码与处理建议
下面表格除了含义外,还附带客户端应该采取的建议动作,便于接入方实现合理的重试与告警策略。
| 状态码 | 含义 | 客户端处理建议 |
|---|---|---|
1 |
错误的鉴权内容、行为或格式 | 检查请求签名/参数格式,修正后重试(不重试会失败) |
-1 |
错误的 API Key、账户信息或真实信息 | 检查并更换 API Key / 检查账户状态;若仍有问题联系运维/客服 |
403 |
违反 WAF 限制(Web 应用防火墙)会导致 IP 封禁 1 小时 | 暂停请求,排查请求特征(频率、payload),如误封联系客服解封 |
418 |
IP 受限(不在白名单) | 使用白名单内的 IP 或添加白名单 |
429 |
IP 访问频率过高,被封禁 | 按限流策略退避(指数退避 + 减速),减少请求频率后重试 |
439 |
访问频次超限(更细粒度) | 与 429 类似,优先降级/限流;审查请求模式 |
5XX |
服务端异常(Pumpkin 服务侧问题) | 记录日志并告警,短期内可重试(指数退避);持续失败联系服务方 |
503 |
请求已发到后端但无响应(未知状态) | 不可判断成功/失败:避免盲目重试造成重复提交,检查幂等性/查询订单状态后再决定是否重试 |
接口错误代码
每个接口都有可能抛出异常,异常响应格式如下:
{
"code": 1,
"msg": "sign-error"
}
{
"code": 429,
"msg": "ip_high_frequency",
"data": {
"type": "ip",
"current": 120,
"limit": 100,
"reset": 3600
}
}
WebSocket API 文档
WebSocket API基本信息
Base URL:
- 环境URL:
wss://testex-gateway.pumpkin.date/ws/market
连接协议:
- 协议版本:WebSocket RFC 6455
- 数据格式:JSON文本 或 Protobuf二进制
- 编码:UTF-8
心跳机制:
- 客户端发送心跳(每3秒):响应"ping"
- 服务器响应心跳:"pong"
- 注意:心跳是纯文本,不是JSON格式
订阅/取消订阅格式:
- 订阅请求:
{"events": ["topic1", "topic2"],"method": "sub"} - 取消订阅请求:
{"events": ["topic1", "topic2"],"method": "unsub"} - 成功响应:
{"code": 0,"msg": "success"} - 错误响应:
{"code": 40001,"msg": "错误信息"}
错误码表:
| 错误码 | 说明 |
|---|---|
| 0 | 成功 |
| 40001 | 无效的主题格式 |
| 40002 | 主题不存在 |
| 40003 | 订阅数量超限 |
| 40004 | 无效的参数 |
| 40005 | 权限不足 |
| 40006 | 频率限制 |
| 50001 | 服务器内部错误 |
| 50002 | 服务暂时不可用 |
WebSocket 行情接口
K线数据 (Kline):
1、主题格式:
kline@{symbol},{interval}symbol: 交易对,如trx_usdt,btc_usdt(小写,下划线分隔)interval: K线周期1m: 1分钟5m: 5分钟15m: 15分钟30m: 30分钟1h: 1小时4h: 4小时1d: 1天1w: 1周1M: 1月
2、请求示例:
json:{"events": ["kline@trx_usdt,1m"],"method": "sub"}
{
"events": ["kline@trx_usdt,1m"],
"method": "sub"
}
3、成功响应:
json:{"code": 0,"msg": "success"}
{
"code": 0,
"msg": "success"
}
4、数据推送格式 (JSON):
json:{ "e": "kline", "s": "trx_usdt", "k": { "s": "trx_usdt", "i": "1m", "t": 1646382900000, "o": "0.31865", "c": "0.31862", "h": "0.31865", "l": "0.31862", "v": "369", "a": "117.57114" } }
{
"e": "kline",
"s": "trx_usdt",
"k": {
"s": "trx_usdt",
"i": "1m",
"t": 1646382900000,
"o": "0.31865",
"c": "0.31862",
"h": "0.31865",
"l": "0.31862",
"v": "369",
"a": "117.57114"
}
}
message KlineVO {
string s = 1; // (trx_usdt)
string o = 2; // (0.31865)
string c = 3; // (0.31862)
string h = 4; // (0.31865)
string l = 5; // (0.31862)
string a = 6; // (117.57114)
string v = 7; // (369)
string i = 8; // (1m)
int64 t = 9; // (1646382900000)
}
5、字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| e | String | 事件类型,固定为"kline" |
| s | String | 交易对 |
| k.s | String | 交易对 |
| k.i | String | K线周期 |
| k.t | Long | K线开始时间戳(ms) |
| k.o | String | 开盘价 |
| k.c | String | 收盘价 |
| k.h | String | 最高价 |
| k.l | String | 最低价 |
| k.v | String | 成交量 |
| k.a | String | 成交额 |
最新成交数据 (Trade):
1、主题格式:
trade@{symbol}symbol: 交易对,如btc_usdt,trx_usdt
2、请求示例:
json:{"events": ["trade@btc_usdt"],"method": "sub"}
{
"events": ["trade@btc_usdt"],
"method": "sub"
}
3、成功响应:
json:{"code": 0,"msg": "success"}
{
"code": 0,
"msg": "success"
}
4、数据推送格式 (JSON):
json:{ "e": "trade", "s": "btc_usdt", "t": 1234567890123456, "p": "95150.62", "a": "7", "m": "BID" }
{
"e": "trade",
"s": "btc_usdt",
"t": 1234567890123456,
"p": "95150.62",
"a": "7",
"m": "BID"
}
message DealVO {
int64 t = 1; // 成交时间
string s = 2; // 交易对
string p = 3; // 成交价
string a = 4; // 成交量
string m = 5; // 买卖方向 (BID/ASK)
int64 id = 6; // 交易ID
}
5、字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| e | String | 事件类型,固定为"trade" |
| s | String | 交易对 |
| t | Long | 交易ID |
| p | String | 成交价格 |
| a | String | 成交数量 |
| m | String | 买卖方向: "BID"(买)/"ASK"(卖) |
订单簿数据 (Depth):
1、主题格式:
depth@{symbol},{level}symbol: 交易对,如btc_usdt,eth_usdtlevel: 深度级别5: 5档深度10: 10档深度20: 20档深度
2、请求示例:
json:{"events": ["depth@btc_usdt,10"],"method": "sub"}
{
"events": ["depth@btc_usdt,10"],
"method": "sub"
}
3、成功响应:
json:{"code": 0,"msg": "success"}
{
"code": 0,
"msg": "success"
}
4、数据推送格式 (JSON):
json
{
"e": "depth",
"s": "btc_usdt",
"U": 1234567890,
"u": 1234567891,
"b": [
["45000.00", "1.2345"],
["44999.50", "0.9876"],
["44999.00", "2.3456"]
],
"a": [
["45001.00", "0.5432"],
["45001.50", "1.2345"],
["45002.00", "0.8765"]
]
}
5、数据推送格式 (Protobuf):
6、增量更新:
{
"e": "depth.update",
"s": "btc_usdt",
"U": 1234567890,
"u": 1234567891,
"b": [
["45000.00", "1.2345"]
],
"a": [
["45001.00", "0.5432"]
]
}
message DepthVO {
string s = 1;
int64 U = 2;
int64 u = 3;
repeated PriceLevel bids = 4;
repeated PriceLevel asks = 5;
}
message PriceLevel {
string price = 1;
string quantity = 2;
}
7、字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| e | String | 事件类型,"depth"或"depth.update" |
| s | String | 交易对 |
| U | Long | 首次更新ID |
| u | Long | 最后更新ID |
| b | Array | 买盘深度 [[价格, 数量], ...] |
| a | Array | 卖盘深度 [[价格, 数量], ...] |
使用示例
class WebSocketClient {
constructor(url) {
this.url = url;
this.ws = null;
this.pingInterval = null;
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('WebSocket connected');
this.startHeartbeat();
};
this.ws.onmessage = (event) => {
if (typeof event.data === 'string') {
if (event.data === 'pong') {
console.log('Received heartbeat response');
return;
}
try {
const data = JSON.parse(event.data);
this.handleMessage(data);
} catch (error) {
console.log('Received text message:', event.data);
}
}
// Handling binary messages (protobuf)
else if (event.data instanceof ArrayBuffer || event.data instanceof Blob) {
this.handleBinaryMessage(event.data);
}
};
}
startHeartbeat() {
// Send a heartbeat every 3 seconds
this.pingInterval = setInterval(() => {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send('ping');
}
}, 3000);
}
subscribe(topics) {
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
console.error('WebSocket is not connected');
return;
}
const message = {
events: Array.isArray(topics) ? topics : [topics],
method: "sub"
};
this.ws.send(JSON.stringify(message));
}
unsubscribe(topics) {
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
console.error('WebSocket is not connected');
return;
}
const message = {
events: Array.isArray(topics) ? topics : [topics],
method: "unsub"
};
this.ws.send(JSON.stringify(message));
}
handleMessage(data) {
// 处理订阅响应
if (data.code !== undefined) {
if (data.code === 0) {
console.log('Operation successful:', data.msg);
} else {
console.error('Operation failed:', data.code, data.msg);
}
return;
}
// 处理数据推送
switch (data.e) {
case 'kline':
console.log('K-line data:', data);
break;
case 'trade':
console.log('trade data:', data);
break;
case 'depth':
case 'depth.update':
console.log('depth data:', data);
break;
default:
console.log('Unknown message type:', data);
}
}
handleBinaryMessage(binaryData) {
console.log('Received binary data, size:', binaryData.byteLength || binaryData.size);
// Here, it is necessary to parse the Protobuf according to the specific format
}
}
使用示例:
- 创建客户端: const client = new WebSocketClient(URL);
- 连接: client.connect();
- 订阅数据: setTimeout(() => { ... }, 1000);
- 订阅K线: client.subscribe('kline@trx_usdt,1m');
- 订阅成交: client.subscribe('trade@btc_usdt');
- 订阅深度: client.subscribe('depth@btc_usdt,10');
- 取消订阅: setTimeout(() => {client.unsubscribe('kline@trx_usdt,1m');}, 10000);
注意事项
- 频率限制:避免频繁订阅/取消订阅,建议批量操作
- 数据验证:始终验证接收到的数据格式
- 错误处理:实现完善的错误处理和重连机制
- 内存管理:及时清理不再需要的数据,避免内存泄漏
- 网络安全:生产环境使用WSS(WebSocket Secure)
- 日志记录:记录连接状态和重要事件,便于排查问题
- 兼容性:考虑不同浏览器的WebSocket实现差异
最佳实践
1. 连接管理: 重连机制
let reconnectTimer = null;
function reconnect() {
if (reconnectTimer) clearTimeout(reconnectTimer);
reconnectTimer = setTimeout(() => {
console.log('Try to reconnect...');
connectWebSocket();
}, 3000);
}
ws.onclose = function() {
console.log('Connection lost, preparing to reconnect');
reconnect();
};
2. 数据缓存:
- 缓存最新的数据
- 清理过期数据(30秒前)
const dataCache = {
kline: new Map(),
trade: new Map(),
depth: new Map()
};
function updateCache(type, symbol, data) {
const key = `${type}_${symbol}`;
dataCache[type].set(key, {
data: data,
timestamp: Date.now()
});
const now = Date.now();
for (let [key, value] of dataCache[type].entries()) {
if (now - value.timestamp > 30000) {
dataCache[type].delete(key);
}
}
}
3. 批量操作: 多个币对、多个时间批量操作
function batchSubscribe(topics) {
if (topics.length === 0) return;
const message = {
events: topics,
method: "sub"
};
ws.send(JSON.stringify(message));
}
batchSubscribe([
'kline@btc_usdt,1m',
'kline@eth_usdt,1m',
'trade@btc_usdt',
'depth@btc_usdt,10'
]);