跳转到主要内容

Pionex API:完整指南

介绍 Pionex API:REST 基础地址 api.pionex.com,WebSocket 地址 wss://ws.pionex.com/wsPub,使用 HMAC-SHA256 签名并通过 PIONEX-KEY / PIONEX-SIGNATURE 请求头进行鉴权,频率限制为每秒 10 次请求,免费使用,支持现货、机器人、合约及理财相关端点。

1. Pionex API 是什么?

Pionex API 是一种程序化接口,让您可以通过自己的代码、脚本或第三方工具来控制您的 Pionex 账户 — 完全无需在 Pionex 网页应用中点击任何按钮。您在用户界面中能做的任何事情(查看余额、下现货订单、启动网格机器人、开立合约仓位、订阅双币投资产品),也都可以通过 API 完成。

API 使用两种相关的“方言”:

  • REST — 经典的 HTTP 请求。您提出一个问题(GET)或推送一项变更(POST、DELETE),并获得 JSON 格式的答复。最适合用于执行操作:下这笔订单、取消那个机器人、显示我的余额。

  • WebSocket — 一条长期保持的流式连接。服务器会实时向您推送更新。最适合用于不断变化的数据:实时价格、订单簿更新、成交的实时回报。

大多数集成会同时使用两者:REST 用于“立即执行某件事”,WebSocket 用于“当有变化时通知我”。

如需进入 API 密钥创建流程,请参阅步骤 4.1

API 适合哪些人使用?

用户群体

典型使用场景

初级交易者

只读脚本:将您的投资组合导入电子表格、将成交记录写入文件,或在机器人关闭时发送 Telegram 提醒。

量化 / 算法交易者

自定义策略、回测、做市机器人、统计套利。

开发者与金融科技团队

将 Pionex 交易功能嵌入另一款产品、构建税务申报工具,或将余额同步到投资组合仪表板。

进阶用户

并行运行数十个网格机器人、批量取消订单、执行定时定投任务。

您不需要是资深工程师。只要您能运行 Python 或 JavaScript 脚本,就能使用 Pionex API。最难的概念 — 请求签名 — 下文会用通俗的语言讲解,并附有可直接复制使用的示例。

一览速查

属性

数值

REST 基础网址(现货 / 机器人 / Earn)

REST 基础网址(合约)

WebSocket 公共流

身份验证

每个私有请求都使用 HMAC-SHA256 签名

必需的请求头

PIONEX-KEY, PIONEX-SIGNATURE

响应格式

JSON 信封:{ result, code, message, data }

速率限制

每个 IP 和每个账户每秒 10 次请求(基于权重);超出限制时返回 HTTP 429

使用费用

免费 — 您只需支付正常的交易手续费


2. 您可以构建什么

API 的端点分为四大类。请选择符合您构建目标的类别;您也可以自由组合使用。

2.1 Trade API — 现货交易

最基础、最核心的功能。使用您已持有的资金买卖加密货币。

  • 获取您的所有余额

  • 列出交易对及其规则(最小下单量、手续费率、小数精度)

  • 下限价单和市价单

  • 取消订单、列出未成交订单、获取订单历史

  • 获取您最近的成交记录(已执行的交易)

2.2 Bot API — 自动化策略

Bot API 对所有账户开放 — 无需申请。只需在您的 API 密钥上启用 Bot Reading / Bot Trading 权限即可。

Pionex 的招牌功能。以编程方式启动交易机器人并对其进行调整。

  • 现货网格机器人 — 在价格区间内反复低买高卖

  • 合约网格机器人 — 同样的理念,加上杠杆

  • AI 策略 — 让 Pionex 为您建议网格参数

  • 修改运行中机器人的价格区间或网格数量

  • 按百分比减少仓位,或完全取消机器人

支持的机器人类型与运行中操作

操作

现货网格

合约网格(逐仓,含币本位、杠杆网格)

智能跟单

创建

支持

支持

支持

查看订单详情

支持

支持

支持

修改价格区间或网格数

支持(adjustParams)

支持(adjustParams,type=adjust_params)

不支持

加仓

支持(investIn)

支持(adjustParams,type=invest_in)

不支持

减仓

不支持

支持(reduce)

不支持

追加 / 提取保证金

不适用

支持(addMargin / reduceMargin)

不支持

暂停与重启

不支持

支持(pause / resume)

不支持

修改止盈止损

不支持

支持(updateTriggerProfitLoss)

不支持

提取利润

支持(profit)

不支持

不支持

关闭机器人

支持(cancel)

支持(cancel)

支持(cancel)

全仓合约网格在 Bot API 中仅可查看。它会以 future_hedge_grid 出现在 GET /api/v1/bot/orders 中(包含多头和空头两条子网格的设置与状态),也会出现在 GET /api/v1/wallet/balancesFull 的 botAccount 中。您无法通过 API 创建它、查询其详情、修改它(区间、投资、保证金、暂停、止盈止损)或关闭它:

  • futuresGrid/order 对它返回 BOT_INTERNAL_ERROR;

  • 合约网格的操作接口会返回订单不存在;

  • futuresGrid/cancel 会被拒绝,返回代码 40300990(Operation is forbidden)。

上表的合约网格接口面向逐仓合约网格。全仓合约网格请在 App 或网页端操作。API 支持情况如有更新,会同步到本文。

App 里的其他机器人(马丁格尔/定投、屯币宝、无限网格、TWAP、套利、智能交易)同样没有 API 接口。表中标「不支持」的操作,只能在 App 或网页端完成。

2.3 Futures API — 合约交易

带杠杆的永续合约(最大杠杆倍数取决于交易对)。

通过 API 直接进行合约交易不可用。该功能仍处于内部开发阶段,尚未向任何账户开放 — 没有申请、候补名单或抢先体验流程。

  • 开立和平仓多头与空头仓位

  • 设置杠杆和保证金模式(逐仓或全仓)

  • 在单向持仓模式与双向持仓模式之间切换

  • 查看未实现盈亏、标记价格、强制平仓价格

  • 拉取资金费用历史记录

2.4 Earn API — 被动收益(测试版)

为偏好收益而非主动交易的用户提供的低操作门槛产品。

  • 浏览双币投资产品

  • 查看当前执行价、上涨 APY、下跌 APY

  • 订阅产品、列出进行中的投资、查看历史记录

注意:Earn 端点处于测试阶段,可能并非在所有地区都可使用。


3. 开始之前

您需要准备什么

  1. 一个状态良好的 Pionex 账户,如果您所在的司法辖区有要求,还需完成身份验证。

  2. 已启用双重身份验证 — 创建 API 密钥时必须启用。

  3. 一个开发环境 — 任何能够发出 HTTPS 请求的环境都可以。Python 3.9+ 或 Node.js 18+ 是最友好的选择,因为网上几乎所有示例都是用这两种语言之一编写的。

  4. 基本熟悉以下内容:

    • JSON(您以前见过 { "key": "value" } 这种格式)

    • 环境变量,或其他能让机密信息不出现在代码中的方式

    • 在终端中运行脚本

您不需要准备什么

  • 服务器。您可以直接在自己的笔记本电脑上运行。

  • 付费方案。API 是免费的。

  • 密码学学位。签名逻辑大约只有十行代码。

思维模型:一个请求是如何运作的

每一次经过身份验证的调用都遵循相同的五步模式:

  1. 您构建一个请求网址,例如 GET /api/v1/account/balances?timestamp=...

  2. 您根据请求方法、路径、排序后的查询参数和请求体,组装出一个“标准消息”字符串。

  3. 您使用 HMAC-SHA256 和您的 API Secret 对该字符串进行哈希,由此生成一个签名。

  4. 您发送请求时附带两个额外的请求头:PIONEX-KEY 和 PIONEX-SIGNATURE。

  5. Pionex 在其服务器端重新执行完全相同的哈希运算并进行比对。如果两者一致,您就通过了身份验证。

关键点:签名可以证明您知道 Secret,而无需通过网络发送 Secret 本身。


4. 创建您的第一个 API 密钥

步骤 1 — 打开 API 管理页面

  • 网页版:登录后,点击您的个人头像,选择 API 管理 — 或直接打开 https://www.pionex.com/zh-cn/my-account/api。

  • 手机 App:App 中没有内置的 API 菜单。请通过网页打开 API 管理 — 在手机浏览器中打开 pionex.com,或点击 点击此处,在 App 内打开该页面(应用内网页视图)。

在 API 管理页面中,您还可以编辑现有密钥的权限、标签和 IP 白名单,或删除(撤销)密钥。Secret 无法重新生成或重置 — 如果您丢失了它,请删除该密钥并创建新的密钥。

步骤 2 — 创建新的 API 密钥

点击 创建 API 密钥。系统会要求您填写:

  • 标签 — 为其取一个具体的名称,例如 grid-bot-laptop 或 read-only-portfolio。当您之后拥有多个密钥时,您会庆幸自己这样做。

  • 权限 — 请见下一节。

  • IP 白名单 (选填,但强烈建议) — 限制密钥只能从特定 IP 地址使用。您可以输入多个 IP,以逗号分隔。

创建密钥时提示 2FA 或验证码错误?

  • 谷歌验证码被拒:将手机的日期和时间设为「自动设置」,确认使用标注为 Pionex(您的邮箱或手机号)的那一条,并输入最新生成的验证码。完整步骤见谷歌验证码(2FA)错误排查。

  • 邮箱或短信验证码被拒:请输入最新收到的那一条。验证码 8 分钟内有效,重新获取会让之前的验证码失效。详见邮箱/短信验证码错误。

  • 仍然失败:刷新页面,或换用无痕窗口、其他浏览器再试。若谷歌验证器已丢失或持续报错,请重置:如何重置谷歌验证器。

创建 API 密钥前必须先启用双重身份验证(见「开始之前」)。

步骤 3 — 谨慎选择权限

权限

允许的操作

建议

读取

查看余额、订单、仓位、成交记录

始终启用。任何有用的功能都需要它。

交易(写入)

下单和取消订单、创建 / 调整 / 关闭机器人

仅在您的脚本确实需要交易时才启用。

Bot API 权限

Bot API 密钥有两个独立的开关:

  • Bot Reading(查看机器人订单、校验参数),

  • Bot Trading(创建/调整/取消机器人)。

无需单独申请访问权限 — 在密钥上启用您需要的开关即可

步骤 4 — 立即保存 Secret

点击 确认 后,Pionex 会向您显示两串字符:

  • API Key(有时称为 apiKey 或 PIONEX-KEY) — 半公开信息,类似用户名

  • Secret — 只显示一次,之后不会再显示。请像对待密码一样对待它。如果丢失,您必须删除该密钥并创建一个新的。

请将两者复制到安全的地方。推荐的做法是将它们设置为您 shell 配置文件中的环境变量,例如:

export PIONEX_KEY="paste_your_api_key_here"
export PIONEX_SECRET="paste_your_secret_here"

警告:切勿将密钥粘贴到会涉及公开或共享代码仓库的源代码中。

步骤 5 — 测试连通性(无需身份验证)

在签名任何内容之前,先确认网络是否正常:

curl "https://api.pionex.com/api/v1/common/symbols?symbol=BTC_USDT"

您应该会收到一个列出 BTC_USDT 交易规则的 JSON 信封。如果这一步失败,请先修复您的网络或防火墙,再继续往下操作。如果基础功能都无法运行,身份验证方面的错误会难以调试得多。


5. 核心概念

5.1 基础网址

用途

网址

现货、机器人、Earn(REST)

合约(REST)

公共 WebSocket

注意:合约的路径前缀是 /uapi/v1,而不是 /api/v1。把两者混淆是第一天常见的错误。

5.2 响应信封

每个 Pionex JSON 响应都具有这样的外层结构:

Success: { "result": true, "data": { ... }, "timestamp": 1783990000000 }
Error: { "result": false, "code": "APIKEY_LOST", "message": "Apikey lost", "timestamp": ... }

code 和 message 只会在出错时出现,并且 code 通常是字符串(例如 APIKEY_LOST、BOT_INVALID_ARGUMENT)。请注意,错误(包括身份验证失败)通常会以 HTTP 200 返回,并带有 result: false,因此请务必检查 result,而不是只看 HTTP 状态码。错误响应中的 timestamp 可能以秒而不是毫秒为单位(无效交易对的错误响应即为秒),因此请勿假定其单位。签名请求时发送的 timestamp 始终以毫秒为单位,见 5.4。

某些账户级别的拒绝会使用不同的结构:一个数字类型的 code、一个 reason 字符串,并且没有 result 字段。例如:

{ "code": 40300951, "reason": "P_TRADING_BOT_OPERATION_IS_FORBIDDEN", "message": "Operation is forbidden, banned for account frozen", "data": null }

如果 result 为 false,或者 result 缺失而 code 存在,则应将该响应视为失败。

提示:在读取 data 之前,请务必先检查 result。即使是 HTTP 200 的响应,在出现业务逻辑错误(例如“余额不足”)时,也可能带有 result: false。

5.3 交易对命名

市场

格式

示例

现货

BASE_QUOTE

BTC_USDT, ETH_USDT, SOL_BTC

永续合约

BASE_QUOTE_PERP

BTC_USDT_PERP, ETH_USDT_PERP

始终使用下划线分隔符和大写字母。

5.4 时间戳

  • 始终使用自 epoch 起的毫秒数 — 而不是秒。这是习惯 Unix 工具的人经常犯的错误。

  • 放在查询字符串中,绝不要放在请求体中,即使是 POST 请求也一样。

  • Pionex 可容忍 ±20 秒的时钟偏差,但不能偏差太多。如果您机器的时钟不准确,签名会失败,并提示“timestamp out of recv window”。如果您看到此提示,请同步您的系统时钟。

5.5 状态码

状态码

含义

处理方式

200

成功(仍须检查 result)

继续

400

参数错误

检查拼写、类型和必填字段

401

未授权

API 密钥或签名错误

403

禁止访问

请重新检查密钥权限。任何账户均不可使用直接合约交易 — 不存在可申请的合约访问权限。

429

触发速率限制

暂缓。请参阅“速率限制”章节。

500

服务器错误

采用指数退避策略重试


6. 身份验证:请求签名的工作原理

这是最让新手望而生畏的一节,但其实不必如此。只要您看过一个可运行的示例,其余部分就都是机械式的。

6.1 标准消息

对于每一个需要身份验证的请求,您都要构建一个字符串:

{METHOD}{PATH}?{SORTED_QUERY}{BODY}

规则:

  1. METHOD 为大写:GET、POST、DELETE。

  2. PATH 是包含开头斜杠的 URL 路径,例如 /api/v1/account/balances。

  3. SORTED_QUERY 是查询字符串,其参数按键名字母顺序排序并经过 URL 编码。

  4. BODY 是 POST 请求的 JSON 请求体,不含任何空白字符。在 Python 中:json.dumps(separators=(',',':'))。在 JavaScript 中,JSON.stringify(obj) 会产生相同的结果。

  5. 请完全丢弃值为 None 或 undefined 的参数。切勿发送 key=None。

  6. 即使是 POST 请求,timestamp 参数也要放在查询字符串中,而不是请求体中。

6.2 完整示例:对余额查询请求进行签名

请求:

GET /api/v1/account/balances?timestamp=1701234567890

您要签名的标准消息:

GET/api/v1/account/balances?timestamp=1701234567890

将该字符串和您的 Secret 输入 HMAC-SHA256,取十六进制摘要,并将其放入 PIONEX-SIGNATURE 请求头中。

6.3 Python 参考实现

import hmac import hashlib import time import os from urllib.parse import urlencode import requests  API_KEY = os.environ["PIONEX_KEY"] API_SECRET = os.environ["PIONEX_SECRET"] BASE_URL = "https://api.pionex.com"  def sign_get(path, params=None):     params = dict(params or {})     params["timestamp"] = int(time.time() * 1000)     query = urlencode(sorted(params.items()))     message = f"GET{path}?{query}"     signature = hmac.new(         API_SECRET.encode(),         message.encode(),         hashlib.sha256,     ).hexdigest()     headers = {         "PIONEX-KEY": API_KEY,         "PIONEX-SIGNATURE": signature,     }     return f"{BASE_URL}{path}?{query}", headers  url, headers = sign_get("/api/v1/account/balances") response = requests.get(url, headers=headers).json() print(response)

6.4 JavaScript / Node.js 参考实现

import crypto from "node:crypto";  const API_KEY = process.env.PIONEX_KEY; const API_SECRET = process.env.PIONEX_SECRET; const BASE_URL = "https://api.pionex.com";  function signGet(path, params = {}) {   const allParams = { ...params, timestamp: Date.now() };   const query = new URLSearchParams(     Object.entries(allParams).sort(([a], [b]) => a.localeCompare(b))   ).toString();   const message = `GET${path}?${query}`;   const signature = crypto     .createHmac("sha256", API_SECRET)     .update(message)     .digest("hex");   return {     url: `${BASE_URL}${path}?${query}`,     headers: {       "PIONEX-KEY": API_KEY,       "PIONEX-SIGNATURE": signature,     },   }; }  const { url, headers } = signGet("/api/v1/account/balances"); const r = await fetch(url, { headers }); console.log(await r.json());

6.5 对 POST 请求进行签名

请求体是标准消息的一部分。请构建一次、签名一次,然后将完全相同的字节作为请求体发送。

import json  def sign_post(path, body):     timestamp = int(time.time() * 1000)     query = urlencode([("timestamp", timestamp)])     body_str = json.dumps(body, separators=(",", ":"))  # no spaces     message = f"POST{path}?{query}{body_str}"     signature = hmac.new(         API_SECRET.encode(),         message.encode(),         hashlib.sha256,     ).hexdigest()     return (         f"{BASE_URL}{path}?{query}",         {             "PIONEX-KEY": API_KEY,             "PIONEX-SIGNATURE": signature,             "Content-Type": "application/json",         },         body_str,     )  url, headers, body_str = sign_post(     "/api/v1/trade/order",     {         "symbol": "BTC_USDT",         "side": "BUY",         "type": "LIMIT",         "quantity": "0.001",         "price": "30000.00",     }, ) requests.post(url, headers=headers, data=body_str).json()

常见陷阱:如果您让 HTTP 库重新序列化请求体(例如 requests.post(json=...)),它可能会添加空白字符,导致您的签名不匹配。请务必发送与您签名时完全相同的字节(data=body_str)。


7. 新手教程:读取您的账户

目标:打印出您的余额以及 BTC_USDT 的规则。大约需要 15 分钟。没有风险 — 使用只读密钥。

步骤 1 — 获取所有交易对(无需身份验证)

import requests r = requests.get(     "https://api.pionex.com/api/v1/common/symbols",     params={"symbol": "BTC_USDT"}, ) print(r.json()["data"]["symbols"][0])

您将了解 minQuantity、minAmount、baseScale 和 makerFeeRate — 这些都是您在下真实订单之前需要用到的数值。

步骤 2 — 签名您的第一次调用:账户余额

使用第 6.3 节中的 sign_get 辅助函数:

url, headers = sign_get("/api/v1/account/balances") data = requests.get(url, headers=headers).json()  for b in data["data"]["balances"]:     if float(b["free"]) > 0 or float(b["locked"]) > 0:         print(f"{b['coin']}: free={b['free']}, locked={b['locked']}")

如果您看到 401 或 result: false,请回头查看身份验证一节。如果您看到了真实的余额,说明您已通过身份验证。

步骤 3 — 综合运用:以 USDT 计价的投资组合价值

现在,您已具备计算“以 USDT 计的投资组合总价值”所需的一切:

  1. 获取余额。

  2. 对于每个非零币种,从公共 ticker 端点获取当前价格。

  3. 计算 (free + locked) * price 的总和。

这是一个完整、安全、只读的项目 — 非常适合作为第一个周末的练习。


8. 进阶:下单与管理订单

8.1 下限价单

url, headers, body = sign_post("/api/v1/trade/order", {     "symbol": "BTC_USDT",     "side": "BUY",     "type": "LIMIT",     "quantity": "0.001",     "price": "30000.00",     "clientOrderId": "my-order-001" }) print(requests.post(url, headers=headers, data=body).json())

提示:如果您的代码可能会重试,请务必设置 clientOrderId。没有它,重试可能会产生重复订单,使您最终持有两个未平仓仓位,而不是一个。

8.2 取消订单

DELETE /api/v1/trade/order?symbol=BTC_USDT&orderId=123456789

签名方式与 GET 完全相同(没有请求体)。

8.3 列出未成交订单

GET /api/v1/trade/openOrders?symbol=BTC_USDT

8.4 遍历历史订单(分页)

GET /api/v1/trade/allOrders?symbol=BTC_USDT&limit=100&fromId={lastSeenId}

持续使用您见到的最后一笔订单的 fromId 进行调用,直到返回的结果少于 limit 条为止。

8.5 发送前校验订单

您已从 /common/symbols 获得了这些字段。请在客户端使用它们:

  • quantity >= minQuantity

  • quantity <= maxQuantity

  • quantity * price >= minAmount(“最小名义价值”规则)

  • 将 quantity 取至 baseScale 位小数,将 price 取至 quoteScale 位小数

跳过这些检查,是订单被拒绝类支持工单的第二大常见原因。

8.6 行情数据端点

全部为公开端点,无需签名:

  • GET /api/v1/market/klines?symbol=BTC_USDT&interval=1M&limit=100 — K 线

  • GET /api/v1/market/tickers — 全部交易对的 24 小时统计数据

  • GET /api/v1/market/bookTickers — 最优买卖价

  • GET /api/v1/market/depth?symbol=BTC_USDT&limit=10 — 订单簿

  • GET /api/v1/market/trades?symbol=BTC_USDT&limit=50 — 最近成交

提示:这些端点同样接受永续合约交易对(例如 BTC_USDT_PERP)。不存在可用的 /uapi/v1/market/... — 合约行情数据同样通过这些 /api/v1 端点获取。

读取 market/depth。

  • 响应外层的 timestamp(见 5.2)为每次请求单独生成,CDN 不会缓存响应。

  • data.updateTime 是订单簿快照生成的时间,而不是响应的时间。在 BTC_USDT 等活跃交易对上,它约每 100 毫秒变化一次;在冷门交易对上,即使订单簿没有变化,快照也约每 5 秒刷新一次。

  • 因此 updateTime 总是早于外层 timestamp:在 BTC_USDT 上通常早约 0.2 秒,在冷门交易对上最多早约 5 秒。

  • 并发请求可能返回较旧的快照,但外层 timestamp 却较新,因此请以 updateTime 比较快照。

  • 以上时间均为典型值,并非保证。这些时间戳未公布任何时钟同步保证或误差上限。

合约行情数据(同样为公开):

  • GET /api/v1/market/fundingRates?symbol=BTC_USDT_PERP&limit=500 — 历史资金费率。limit 默认为 1,因此请自行设置。使用 endTime 向前翻页。

  • GET /api/v1/market/indexes?symbol=BTC_USDT_PERP — 当前指数价格、标记价格和下一次资金费率。

  • GET /api/v1/market/indexKlines 和 GET /api/v1/market/markKlines — 指数价格和标记价格 K 线。仅返回最新的 K 线:这些端点接受 endTime,但会忽略它。

  • GET /api/v1/market/openInterests — 仅提供当前快照,所有交易对在一次响应中返回。它不接受任何参数,并会忽略 symbol。

K 线参数(GET /api/v1/market/klines)

  • symbol:必填,例如 BTC_USDT、ETH_USDT_PERP。

  • interval:必填,只接受大写:1M、5M、15M、30M、60M、4H、8H、12H、1D。这里的 M 是分钟,15 分钟 K 线请填 15M;小写 15m 会返回 interval param error。

  • endTime:选填,毫秒时间戳(秒级时间戳会返回 MARKET_INVALID_TIME)。返回开盘时间不晚于 endTime 的 K 线;不填则返回最新的 K 线。

  • limit:选填,默认 100。

该接口不支持 startTime,传入也会被忽略。K 线按从新到旧排列。

查询一段时间区间:把区间结束时间设为 endTime,并设 limit=500;然后把 endTime 改成本次返回中最早一根的时间减 1 毫秒,重复请求,直到覆盖区间起点。15 分钟 K 线一天 96 根,30 天约 2,880 根,大约需要 6 次请求。

时区换算:时间戳本身不带时区,同一个时刻在全球都是同一个数字。UTC+8 时间先减 8 小时换成 UTC,再转成毫秒。例如 UTC+8 的 2026-09-29 15:15 等于 UTC 07:15,也就是 1790666100000;UTC+8 的 16:30 则是 1790670600000。

示例:curl "https://api.pionex.com/api/v1/market/klines?symbol=ETH_USDT_PERP&interval=15M&endTime=<区间结束的毫秒时间戳>&limit=500"

限制与深度。K 线、指数价格与标记价格 K 线以及资金费率的 limit 上限均为 500;超过该值会返回 MARKET_PARAMETER_ERROR。BTC、ETH 和 SOL 的合约日 K 线可追溯到 2023 年初。日内 K 线最多约 10,000 根,大约相当于 14 个月的 1 小时 K 线。资金费率可追溯到 2023 年初。


9. 进阶主题

9.1 现货网格机器人

网格机器人是一种参数化策略:选择一个价格区间和网格线数量。每格利润由这两项设置决定。机器人在价格下跌时逐步累积,在价格上涨时卖出,从价格震荡中获利。

POST /api/v1/bot/orders/spotGrid/create{  "base": "BTC",  "quote": "USDT",  "buOrderData": {    "top": "50000",    "bottom": "40000",    "row": 20,    "gridType": "arithmetic",    "quoteTotalInvestment": "1000"  }}

提示:请先使用 POST /api/v1/bot/orders/spotGrid/checkParams(请求体相同)进行校验 — 它会返回最低和最高投资额、推荐滑点以及预估手续费,且不会动用任何资金。

资金与风险。现货网格从不借款,因此您的最大亏损就是您投入的金额。请使用 investIn 向运行中的现货网格追加资金。只带 quoteInvest(不修改区间)的 adjustParams 会返回 BOT_INTERNAL_ERROR。借款仅存在于杠杆网格中,而杠杆网格属于合约网格。现货网格的响应包含 loanAmount、interestAmount、liquidatePrice 和 leverage;在现货网格上,这些值始终分别为 0、0、0 和 1。

机器人运行后,您可以:

  • POST /api/v1/bot/orders/spotGrid/adjustParams — 实时更改价格区间(top/bottom)或网格数量(row)

  • POST /api/v1/bot/orders/spotGrid/investIn — 向运行中的机器人追加资金

  • POST /api/v1/bot/orders/spotGrid/profit — 在不停止机器人的情况下提取已累积的利润。机器人没有可提取的网格利润时,会返回 BOT_INTERNAL_ERROR

  • POST /api/v1/bot/orders/spotGrid/cancel — 停止机器人。请在此调用中设置 closeSellModel(参见下文的关闭现货网格)

  • GET /api/v1/bot/orders/spotGrid/aiStrategy?base=BTC&quote=USDT — 获取 AI 建议的参数(注意:使用的是 base 和 quote,而不是 symbol)

关闭现货网格。取消调用中的 closeSellModel 决定机器人所持币种的处理方式:

  • NOT_SELL(默认) — 原样退还币种和计价币。

  • TO_QUOTE — 将币种卖出为计价币。

  • TO_USDT — 将币种卖出为 USDT。

请在取消调用中设置。通过 API 取消时,不会使用您在创建时设置的 closeSellModel。如果取消调用中省略了它,则适用 NOT_SELL。订单的 closeSellModel 字段在机器人运行期间显示创建时的值,取消之后则显示实际应用的值。卖出数量会向下取整到该币种的精度;任何剩余部分将以币种形式退还。

读取已关闭的现货网格。取消之后,GET /api/v1/bot/orders/spotGrid/order 会报告退还的内容:

  • unlockUsdtAmount — 关闭时退还的计价币:quoteAmountBeforeSell 加上所卖出币种的收入,再减去交易手续费。

  • baseAmount — 未卖出而直接退还的币种。

  • profitWithdrawn — 机器人运行期间从网格中移出的利润总额。它包含两部分:您提取的利润(例如通过 spotGrid/profit),以及转入自动复投(Auto Reinvest)的利润(见下文读取运行中的现货网格)。profitReinvest 记录自动复投的部分,因此您提取的利润为 profitWithdrawn − profitReinvest。这是累计总额,没有逐笔提取记录。已提取的利润不包含在 unlockUsdtAmount 中。

机器人整个生命周期的净结果:unlockUsdtAmount + profitWithdrawn + value of returned baseAmount − quoteTotalInvestment。totalFeeInQuote 和 totalFeeInBase 不包含开始时的买入以及结束时的卖出所产生的手续费。

读取运行中的现货网格。GET /api/v1/bot/orders/spotGrid/order 还会返回两个未列入公开 schema 的字段:

  • profitReinvest — 转入自动复投的网格利润。开启自动复投时,机器人当前的网格利润会立即转入其中;之后产生的网格利润不会立即计入。

  • nextAutoReinvestTime — 下一次计划自动复投的时间(毫秒)。关闭自动复投时为 0;开启自动复投后,会设为开启时刻之后 24 小时。

baseAmount 和 quoteAmount 是机器人当前的持仓,包含挂单中占用的资金:baseAmount × 当前价格 + quoteAmount 即为机器人当前的价值。

9.2 合约网格机器人

与现货网格形式相同,增加了 leverage 参数:

POST /api/v1/bot/orders/futuresGrid/create
{
"base": "BTC.PERP", // note the .PERP suffix on base
"quote": "USDT",
"buOrderData": {
"top": "65000", "bottom": "60000", "row": 10,
"gridType": "arithmetic",
"trend": "long", // REQUIRED: long | short | no_trend
"leverage": 2,
"quoteInvestment": "100"
}
}

提示:请先使用 POST /api/v1/bot/orders/futuresGrid/checkParams 进行校验(请求体相同 — 这里同样必须提供 trend) — 它会返回最低/最高投资额、预估强制平仓价格、保证金划分和手续费,且不会动用任何资金。

移动网格(Trailing Move,可选,创建时设置)。开启移动网格后,价格均线的变动达到设定比例时,网格区间会随之移动。这样做多或做空合约网格不用重建,就能跟随趋势。开启方法:在 futuresGrid/create 的 buOrderData 中加入下表字段。不传 movingIndicatorType,创建的机器人就不带移动网格。

字段

类型

含义

示例

movingIndicatorType

string

开启移动网格。只接受 sma(简单移动平均)。

"sma"

movingIndicatorInterval

string

计算均线所用的 K 线周期。只接受 1m。

"1m"

movingIndicatorParam

string(JSON 文本)

均线长度(K 线根数),以 JSON 字符串传入。length 只能是 10、360、720 或 1440。配合 1m K 线,720 即 720 分钟(12 小时)均线,也是 App 的默认值。

"{\"length\":720}"

movingTrailingUpParam

string(小数比例)

开启移动网格时必填,没有默认值。均线朝网格方向变动多少后,网格才移动:做多网格看上涨,做空网格看下跌。这是比例,不是价格:"0.05" = 5%。请填 0.01–0.5(1%–50%),与 App 允许的范围一致。

"0.05"

movingTop

string(价格)

可选,网格上沿的上限。某次移动会让上沿超过该值时,网格只移到该值为止;上沿到达该值后,不再上移。不传表示不设上限。

"80000"

movingBottom

string(价格)

可选,网格下沿的下限。下移时规则相同。不传表示不设下限。

"50000"

创建时的校验。校验不通过时,返回 result: false,错误码为 BOT_INVALID_ARGUMENT。

  • trend 必须是 long 或 short。中性网格(no_trend)开启移动网格会被拒绝,提示 moving grid order not support no_trend。

  • movingIndicatorType 为 sma 时,movingIndicatorInterval、movingIndicatorParam、movingTrailingUpParam 三个字段都必填,且取值要合法。

  • 当前价格必须在 bottom 与 top 之间,否则提示 ticker price out of range。如果用 condition 设了触发价,则改为检查触发价。

  • checkParams 同样接受这些移动网格字段。建议先调用它,拿到当前设置下的滑点和最低投资额。

移动是怎样进行的。

  • 触发条件是均线的变动幅度,不是现价有没有跌出或涨出区间。基准值在开单时记录,每次移动后重新记录。

  • 每次移动都和修改区间一样,会按新区间重算仓位:新区间需要的仓位更小,多出部分以市价平掉,计入已实现盈亏;需要的仓位更大,则补足。

  • 不设 movingTop 和 movingBottom 时,移动次数和累计幅度都没有限制。

  • 机器人暂停期间不会移动。如果暂停期间已满足条件,恢复后会在下一次检测时补执行。

  • API 只能设置顺势移动。逆势移动(做多网格下移、做空网格上移)只能在 App 或网页端设置。

创建之后。

  • 不能通过 API 开启、关闭或修改移动网格,请在 App 或网页端操作。

  • 开启移动网格后,adjustParams 的 type=adjust_params(手动改区间)和 type=invest_in_trigger 会被拒绝,提示 move indicator enable。type=invest_in(追加投资)不受影响。

示例(top 和 bottom 请按当前价格设置,确保现价在区间内):

POST /api/v1/bot/orders/futuresGrid/create
{
"base": "BTC.PERP",
"quote": "USDT",
"buOrderData": {
"top": "65000", "bottom": "60000", "row": 10,
"grid_type": "arithmetic",
"trend": "long",
"leverage": 2,
"quoteInvestment": "100",
"movingIndicatorType": "sma",
"movingIndicatorInterval": "1m",
"movingIndicatorParam": "{\"length\":720}",
"movingTrailingUpParam": "0.05",
"movingTop": "80000"
}
}

机器人运行后,您可以:

  • POST /api/v1/bot/orders/futuresGrid/adjustParams — 当 type=adjust_params 时,更改价格区间(top/bottom)或网格数量(row);当 type=invest_in 时,追加投资

  • POST /api/v1/bot/orders/futuresGrid/reduce — 平掉部分仓位,同时机器人继续运行(reduceNum 是整数形式的网格线数量,而不是币种数量)

  • POST /api/v1/bot/orders/futuresGrid/cancel — 停止机器人;可选的 closeSellModel(TO_QUOTE 或 TO_USDT)决定仓位的处理方式

  • GET /api/v1/bot/orders/futuresGrid/order?buOrderId=... — 获取完整订单详情(状态、盈亏、仓位、强制平仓价格)

  • POST /api/v1/bot/orders/futuresGrid/addMargin / reduceMargin:向机器人追加或从中提取额外保证金(参数 buOrderId、coin、amount)。会改变强平价,不改变投资额和仓位。建议先调用 addMarginCheck / reduceMarginCheck 试算,会返回调整前后的预估强平价;提取时还会返回可提上限 maxAmount。

  • POST /api/v1/bot/orders/futuresGrid/pause / resume:暂停机器人,或立即重启、到触发价自动重启。可先用 pauseCheck / resumeCheck 校验。

  • POST /api/v1/bot/orders/futuresGrid/updateTriggerProfitLoss:修改运行中机器人的止盈止损。

  • 以上接口只适用于逐仓合约网格。全仓合约网格在 API 中仅可查看(参见第 2.2 节),包括保证金在内请在 App 或网页端操作。

  • 机器人规模较小时,试算会拒绝超出其规模的调整:invest_in 的金额必须不低于 adjustParamsCheck 返回的 minInvestment(LESS_THAN_MIN_INVESTMENT);仓位已是最小规模时,reduce 返回 POSITION_TOO_SMALL;reduceMargin 不能超过 maxAmount,没有可提取的额外保证金时该值为 0(EXCEEDS_MAX_AMOUNT)。

合约网格的 profitWithdrawn 只计算您提取的利润。(在现货网格中,它还包括转入自动复投的利润,见上文读取已关闭的现货网格。)提取的利润会计入 GET /api/v1/account/balances 返回的余额。

由哪个账户为机器人提供资金:futuresGrid/create 会从您的主账户扣取 quoteInvestment,而不是从您的合约账户或交易账户。请先向您的主账户转账,否则请求会被拒绝,并返回 balance insufficient。

checkParams 并不是保证:通过校验只表示您的设置格式正确,并不表示 create 一定会成功。请同时确认您的主账户余额足以覆盖 quoteInvestment。

如果 adjustParams 被拒绝,请先查看 code(参见常见问题)。您可能遇到的一种原因是机器人的未实现盈亏为负 — 网格往往恰恰在亏损时才需要调整区间。可以在仓位盈利时重试、在 Pionex App 中编辑区间,或在创建时启用移动网格(Trailing Move)。

利润复投。如需在不追加新资金的情况下将当前浮动利润加入投资额,请调用 futuresGrid/adjustParams,并传入 type=adjust_params、adjustParamsSence=reinvest(拼写如上)、isReinvest=true、quoteInvestment=0,以及当前的 top、bottom 和 row。之后,订单详情(futuresGrid/order)会显示:

  • quoteInvestment 增加了机器人的全部浮动利润,并出现新字段 profitExited,其值为加入的金额;

  • profitReinvest 等于当时的网格利润,且 adjustParamsInvestmentChanged: true;

  • gridProfit 不变,不会被清零。

这是一次性操作:之后产生的网格利润不会被加入。profitExited 和 adjustParamsInvestmentChanged 未列入公开 schema。

请在正式请求前立即执行预检。使用相同请求体调用 adjustParamsCheck,可能前一刻通过、几分钟后却以 BOT_INVALID_ARGUMENT / LESS_THAN_MIN_INVESTMENT 失败,例如利润只有几美分的小额机器人,其 estimateInvestment 低于 minInvestment。

修改运行中机器人的止盈止损(updateTriggerProfitLoss)。该接口字段使用 snake_case:传 bu_order_id 和 list,要改哪个触发条件,就在 list 里放一项。

  • 每项必填 type(stop_loss 或 stop_profit)、stop_type(price、price_limit、profit_amount 或 profit_ratio)和 value。stop_type 没有默认值,留空会被拒绝。

  • 只有 list 里列出的触发条件会被修改,没列出的保持原设置。例如只传一项 stop_loss,原有止盈不受影响。

  • 同一项里,要保留的字段都要传。一项会整体替换该触发条件的设置:没传的 limit_price、loss_stop_sell_model / profit_stop_sell_model 会被清空;没传的 stop_delay 保持原值。

  • 要取消某个触发条件,传该项并把 value 设为空字符串 ""。

  • profit_ratio = 机器人总收益 ÷ 投资额(quoteInvestment)。总收益为网格利润加未实现盈亏;额外追加的保证金不计入收益,也不计入投资额。profit_amount 直接用总收益金额比较。比例按小数填写:0.5 表示 +50%,-0.2 表示 −20%,可以填 0 或负数。

  • 止损在收益率或收益金额回落到设定值及以下时触发,止盈在升到设定值及以上时触发。止损填正数(如 0.025)时,总收益率回落到 +2.5% 或更低即平仓。如果设置时收益率已经低于设定值,下一个价格变动就会触发止损并平仓。

  • 运行中可以切换 stop_type,例如从 price 改为 profit_ratio。

  • 接口不会校验设定值与标记价格、网格区间之间的关系,也不校验止盈止损之间的关系(例如不要求止盈高于止损),请在提交前自行检查。

  • 修改为异步生效,返回成功只是回显你的请求。请调用 GET /api/v1/bot/orders/futuresGrid/order,查看 lossStopType / lossStop 和 profitStopType / profitStop 确认结果。

  • 以下情况会被拒绝:机器人正在平仓或已取消、该机器人不允许修改止盈、跟单从属机器人。使用发财金创建的机器人可以改止盈,不能改止损。被拒时返回参数错误,具体原因看 message。

9.3 Smart Copy 机器人

可通过 API 使用的第三种机器人类型 — 由信号驱动的合约仓位组合:

  • POST /api/v1/bot/orders/smartCopy/checkParams — 创建前校验投资额和杠杆上限

  • POST /api/v1/bot/orders/smartCopy/create — 注意此端点使用 snake_case 字段(bu_order_data、quote_total_investment),并且需要一个至少包含一项的 portfolio 数组(base、signal_type、leverage)

  • GET /api/v1/bot/orders/smartCopy/order?buOrderId=... — 完整订单详情,包括每一项的仓位

  • POST /api/v1/bot/orders/smartCopy/cancel — 请求体使用 bu_order_id

止盈与止损(profit_stop_ratio、loss_stop_ratio)。两者都是 smartCopy/create 中每个 portfolio 项的可选字段,以小数字符串传入。仅合约项可用;现货项设置会报错 not allowed for spot orders。

  • 比例 = 该仓位按标记价格计算的未实现盈亏 ÷ 保证金,保证金 = 持仓成本 ÷ 杠杆。不按杠杆后的仓位价值计算,也不是币价涨跌幅。

  • profit_stop_ratio 必须为正数:"0.2" 表示未实现盈利达到保证金的 20% 时触发。

  • loss_stop_ratio 必须为 0 或负数,传正数会报错 loss_stop_ratio must be <= 0。"-0.1" 表示未实现亏损达到保证金的 10% 时触发。建议取 -1 到 0 之间的值:低于 -1 时,仓位通常会先被强平,止损来不及触发。

  • 不传或传 "0" 表示不启用;可以只设置其中一项。

  • 每个 portfolio 项(币种)各自判断。触发后只平掉该币种当前的仓位,机器人继续运行,收到下一个信号时重新开仓。之前已实现的盈亏不计入,手续费和资金费也不另外计入。

  • 示例:投入 100 USDT、5 倍杠杆、全部用于 BTC,机器人约持有 500 USDT 的 BTC 仓位,保证金约 100 USDT。设置 loss_stop_ratio: "-0.1" 时,BTC 仓位未实现亏损约 10 USDT 就会平仓,对应价格反向波动约 2%(0.1 ÷ 5)。保证金按实际持仓成本计算,经过 percent 分配、复利或信号加减仓后,可能与投入额不同。

相关:POST /api/v1/bot/signal/listener 用于发布自定义交易信号来驱动这些机器人 — 它需要账户激活(请发送邮件至 service@pionex.com)以及您 API 密钥上的“Enable Reading”权限。GET /api/v1/bot/kol/selectCopyTradeList?shareCode=... 会列出精选的 KOL 跟单策略。

信号监听器面向信号提供方。它会将信号推送到 Pionex 信号平台,再由该平台转发给订阅了该 signalType(您的信号 UUID)的每一个 Smart Copy 机器人。

在 data 中:action 为 buy 表示开仓,为 sell 表示平仓。position_size 是以比例表示的目标仓位:"1" 表示 100%,"0" 表示平仓。contracts 是合约数量。

9.4 合约直接交易

请注意 /uapi/v1 路径前缀:

GET  /uapi/v1/account/balances
GET /uapi/v1/account/positions
GET /uapi/v1/account/detail
GET /uapi/v1/account/leverage?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/openOrders
GET /uapi/v1/trade/fills?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/fundingFee?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/isolatedMode?symbol=BTC_USDT_PERP

注意:上述所有 GET(读取)端点,目前任何 API 密钥均可使用。写入操作(下合约订单、更改杠杆/保证金模式)在直接合约交易仍处于开发阶段期间受到限制。

9.5 Earn — 双币投资(测试版)

GET  /api/v1/earn/dual/openProducts?symbol=BTC POST /api/v1/earn/dual/invests   { "productId": "...", "amount": "0.5" } GET  /api/v1/earn/dual/balances

订阅前请先阅读执行价、上涨 APY 和下跌 APY。资金会在产品期限内被锁定。

9.6 WebSocket 基础知识

wss://ws.pionex.com/wsPub

两类频道:

  • 公共(无需身份验证) — ticker、kline、depth、trade

  • 私有(需要身份验证) — 余额更新、订单更新、仓位更新

通过 JSON 消息订阅:

{ "op": "SUBSCRIBE", "topic": "TRADE", "symbol": "BTC_USDT" }

重要:WebSocket 连接会断开。请将您的客户端包装在“带退避的重连”循环中,并在重连时重新订阅所有主题。


10. 速率限制与可靠性

10.1 您会得到什么

Pionex 不会返回 X-RateLimit-* 响应头。限制为每个 IP 每秒 10 次请求,以及每个账户(私有端点)每秒 10 次请求,且每个端点都按权重占用该额度。超出限制会返回 HTTP 429 — 请先退避,再重试。

10.2 如何保持安全

  1. 不要全速轮询。每 200 毫秒调用一次 GET /openOrders 是不必要的;对大多数策略而言,每秒一次就足够了。

  2. 对由变化驱动的数据使用 WebSocket。不要为了获取价格跳动而轮询 — 请订阅。

  3. 对 429 和 5xx 响应实现指数退避:

import time, random  def with_backoff(fn, max_attempts=6):     for i in range(max_attempts):         r = fn()         if r.status_code not in (429, 500, 502, 503):             return r         sleep = (2 ** i) + random.random()         time.sleep(sleep)     raise RuntimeError("max retries exceeded")
  1. 尽可能批量处理。需要查询 50 个订单的状态?请使用较大的 limit 调用一次 GET /trade/allOrders,而不是进行 50 次单独查询。


11. 常见问题

开始上手

问:我需要申请 API 访问权限吗?

答:不需要 — 对于现货、Earn 和 Bot API,创建密钥即可开始使用;Bot API 只需要在密钥上启用其 Bot Reading / Bot Trading 权限。直接合约交易对任何账户均不可用,也没有申请或候补名单,但合约读取类端点对每个 API 密钥都可使用。Earn 端点处于测试阶段,可能并未面向所有地区开放。

问:API 是免费的吗?
答:是的。您只需支付正常的交易手续费(费率与网站上相同)。

问:我可以在浏览器中使用吗?
答:可以,但要小心。浏览器无法保守机密 — 任何检查您网页的人都能读取这些机密。要么将签名逻辑放在您可控的后端中运行,要么只使用只读密钥并严格设置 IP 和来源(origin)限制,并且绝不要在客户端部署具有 Trade 权限的密钥。

问:哪种编程语言最好?

答:Python 和 JavaScript 的示例最多。任何能够进行 HTTPS 和 HMAC-SHA256 的语言都可以:Go、Rust、Java、C#、PHP、Ruby。在其中任何一种语言里,签名逻辑都大约只有十行。

问:我可以使用 Pionex API 连接外部平台吗?

答:可以 — 这是一个标准的 REST/WebSocket API,因此任何能发出已签名 HTTPS 请求的工具都可以与它通信,包括您自己的脚本、服务器和第三方工具。某个特定的第三方平台是否可用,取决于该平台自身是否已构建对 Pionex 的支持 — API 不限制谁可以调用它,但双方必须使用相同的集成方式。请查阅该平台自己的文档,了解其是否列出 Pionex,以及它期望您使用哪种集成方式。在 Pionex 一侧,受支持的接入点是本指南中的 Trade/Bot/Wallet/Earn 端点,以及用于 TradingView webhook 的 Signal Bot。

问:我可以将 Pionex API 连接到 Bybit 或 Binance 等其他加密货币交易所吗?

答:不可以。Pionex API 并非用于连接 Bybit 或 Binance 等其他加密货币交易所。它仅用于与您自己的 Pionex 账户交互 — 下单/管理您自己的订单、机器人和仓位 — 而不用于在其他交易所账户之间桥接、镜像或套利交易活动。

身份验证

问:我的签名一直返回无效。该从哪里开始排查?

答:请按以下顺序检查五件事:

  1. 查询参数是否按字母顺序排序?

  2. timestamp 是否放在查询字符串中,而不是请求体中?

  3. 您签名的请求体是否与您发送的请求体完全一致(没有多余的空白字符)?

  4. 您机器的时钟是否与真实时间相差在几秒之内?

  5. PIONEX-KEY 和 PIONEX-SIGNATURE 请求头是否都存在,且没有互换?

问:为什么 POST 请求的 timestamp 也要放在查询字符串中?

答:这是 Pionex 定义标准消息规则的方式。这是一种约定,不可协商。如果您把它放在请求体中,您的签名就会不匹配。

问:我可以在不停机的情况下轮换密钥吗?
答:可以 — 创建一个新密钥,将其部署到您的代码中,然后撤销旧密钥。在重叠期间,两个密钥会同时有效。

问:我可以拥有多个密钥吗?
答:可以。请为每种用途创建一个密钥(bot-prod、dashboard-readonly、dev-laptop)。这样在出问题时,撤销操作可以做到精准。

交易

问:quantity 和 amount 有什么区别?

答:quantity 是基础币的数量(例如 0.5 BTC)。amount 是计价币的价值(例如 25,000 USDT)。来自 /common/symbols 的 minQuantity 和 minAmount 会同时强制执行这两项:订单必须同时满足两者。

问:我的订单一直因“最小名义价值”而被拒绝。

答:quantity * price 必须至少等于 minAmount。以 30,000 美元的价格下一笔 0.0001 BTC 的订单,名义价值为 3 美元,通常低于典型的 10 美元最小值。

问:如何让我的下单具备幂等性?
答:将 clientOrderId 设置为唯一值(例如 UUID)。如果您使用相同的 clientOrderId 重试,Pionex 不会重复创建订单。

问:限价单可能出现部分成交吗?

答:可以。请关注 filledQuantity 和 status(PARTIALLY_FILLED)。请使用 WebSocket 订单更新频道获取实时状态。

问:有测试或沙盒端点吗?

答:Pionex 目前没有公开的沙盒环境。通行做法是:先使用只读密钥开发,然后针对成交量较低的交易对,用 quantity = minQuantity 下极小额的真实订单作为冒烟测试。

机器人

问:我可以创建与我在 App 中看到的相同类型的机器人吗?
答:您可以通过 API 创建和管理三种机器人类型:现货网格、合约网格和 Smart Copy。全仓合约网格仅可查看:它会出现在列表中,但无法通过 API 创建、修改或关闭。App 中的所有其他机器人类型(马丁格尔、定投、再平衡、无限网格、TWAP、套利、智能交易)仅限在界面中使用,没有 API 端点。

GET /api/v1/bot/orders 只返回 API 支持的机器人类型。它们的 buOrderType 值分别为 spot_grid、futures_grid、future_hedge_grid(全仓合约网格)和 smart_copy。其他类型的机器人不会被返回,即使它们正在您的账户上运行。将不受支持的类型作为筛选条件传入,会返回 BOT_INVALID_ARGUMENT。

杠杆网格属于合约网格,会以 futures_grid 返回。

简易合约没有机器人端点。其持仓仅出现在 GET /api/v1/wallet/balancesFull 中,位于 botAccount.detail[] 下,且 type: "futures_lite"。每个条目会给出 buOrderId、baseList、investmentAmount 和 profit。不提供状态、订单或仓位详情。

Q:GET /api/v1/assets/transfers 会显示从机器人提取的利润吗?
A:不会。它只列出账户之间的手动划转(MAIN 与 TRADE)。从现货网格和合约网格机器人提取的利润不会出现,API 也没有列出过往机器人利润提取的端点。在现货网格中,profitWithdrawn 是累计总额。文档列出的参数为 status、endTime 和 limit;不支持 startTime。带 endTime 的请求可能返回早于您所传 startTime 的记录,不带 endTime 的请求可能不返回任何记录。

问:我可以调整正在运行的机器人吗?
答:可以。adjustParams 允许您在不取消的情况下更改价格区间(top/bottom)和网格数量(row),或追加投资。在现货网格上,您还可以使用 investIn(追加资金)和 profit(提取利润);在合约网格上,您可以使用 reduce 减少仓位。不存在收益率参数 — 每格利润由价格区间和网格数量决定。

问:我收到了 BOT_INTERNAL_ERROR,但看不出原因。
答:请查看 code 字段。它现在会告诉您发生了以下两种情况中的哪一种。

code

含义

处理方式

BOT_INVALID_ARGUMENT

您的请求被拒绝。message 会说明原因 — 例如 balance insufficient。

按 message 中指出的问题修正,然后重新发送。

BOT_INTERNAL_ERROR

我们这边出现了故障。message 始终为 Internal error。

请退避后重试。如果问题持续出现,请联系客服并提供您的时间戳。

futuresGrid/create 被拒绝的一个常见原因,是您的主账户中计价币不足。创建机器人会从您的主账户扣款,而不是从您的合约账户或交易账户。

如果在 message 本应给出说明的情况下仍返回 BOT_INTERNAL_ERROR,请将您的时间戳发送给客服。

问:reduce 与 cancel 有什么不同?

答:reduce 会平掉一定百分比的仓位,但机器人会继续运行。cancel 则会完全停止机器人。

问:aiStrategy 端点实际上是做什么的?
答:它会根据近期波动率,返回 Pionex 为某个交易对建议的网格参数。请把它当作起点,而不是金科玉律 — 在投入资金之前请先自行审查。

合约

问:如何获得 Futures API 的访问权限?

答:Futures API 直接交易对任何账户均不可用。它仍处于内部开发阶段,且没有申请、候补名单或抢先体验流程 — 无法申请访问权限。

问:通过 API 下合约单时出现「TRADE_TYPE_DENIED: user denied, not in whitelist」,是什么原因?
答:通过 API 直接进行合约交易(合约下单、变更杠杆或保证金模式)目前尚未向任何账户开放。此功能仍在内部开发中,也没有申请、候补名单或抢先体验的渠道,因此错误信息中的「whitelist」并不代表可以申请开通。目前也没有公布开放时间。合约的读取类端点则任何 API Key 均可使用。若想自动化合约交易,目前可以通过 Bot API 创建和管理合约网格机器人,或使用 Signal Bot 以 TradingView webhook 等外部信号触发交易。

问:逐仓与全仓保证金有什么区别?

答:

逐仓 — 只有您分配给该仓位的保证金可能亏损。

全仓 — 您的整个合约钱包都为该仓位提供担保。对初学者而言,逐仓更安全。

单向持仓与双向持仓模式?

答:

单向持仓 — 每个交易对只有一个仓位;开反方向仓位会减仓或平仓。双向持仓 — 多头和空头可以同时存在。大多数交易者应当从单向持仓开始。

问:资金费用是如何体现的?

答:定期结算(通常每八小时一次,但请查看具体交易对)。请使用 GET /uapi/v1/trade/fundingFee 拉取历史记录。

Earn

问:双币投资是否保本?

答:否。它们在收益方面有“下跌 APY”的下限,但本金存在风险。订阅前请阅读每个产品的详细说明。

问:我可以提前取消双币投资吗?
答:通常不可以。资金会在产品期限内被锁定。请据此规划您的流动性。

运维

问:我应该按什么样的速率限制来规划?
答:请按每个 IP 和每个账户每秒 10 次请求来规划(Pionex 不会返回 X-RateLimit-* 响应头)。一个保守的起点是每类端点每秒不超过五次请求,并在遇到 429 响应时采用指数退避。

问:我该如何处理 5xx 错误?

答:采用指数退避并加入抖动进行重试。关键在于,在重试 POST 之前,先查询状态以确认先前的请求是否实际成功 — 服务器错误并不总是意味着操作失败。

问:我的请求返回 HTTP 451 和一个 HTML 页面,而不是 JSON,这是什么意思?
答:HTTP 451 的意思是“因法律原因无法提供”(Unavailable For Legal Reasons)。Pionex API 的正常响应是 JSON,因此状态码为 451 且内容是 HTML 页面,通常表示请求在网络路径上受到法律或地区限制,而不是 API 本身的问题。这和前面介绍的密钥、签名或权限错误(401、403,或 HTTP 200 加 result: false)不同。请用不同的网络再发送同一个请求,例如移动数据或其他网络供应商。若换网络后正常,说明限制来自原本的网络环境,Pionex 无法更改;也请确认你所在的国家/地区是否在不支持地区清单中。若在其他网络仍返回 451,请联系 Pionex 客服,并提供请求的端点、请求时间(含时区)与完整响应内容,请勿提供 API 密钥(Secret)。

问:我的 WebSocket 一直断线。是出了什么问题吗?

答:这在网络层面是正常现象。请实现:每 30 秒 ping 一次、带退避的自动重连,以及重连时重新订阅所有主题。

问:我该如何订阅多个交易对?
答:发送多条订阅消息,或使用该频道支持的批量订阅形式。每个主题都是独立的。

安全性

问:我认为我的 Secret 泄露了。我该怎么办?

答:

  1. 打开 API 管理页面并立即撤销该密钥。

  2. 审查近期活动(订单,如已启用则包括提现)。

  3. 使用新的标签创建一个新密钥。

  4. 在您的代码库和提交历史中搜索泄露的 Secret,并轮换所有相关凭证。

问:我应该把 API Key 或 Secret 提交到 git 吗?

答:绝对不要。请使用环境变量、.env 文件(放入 .gitignore)或密钥管理工具。如果不小心提交了,请立即轮换密钥 — git 历史记录是永久保留的。

问:我可以启用充值/提现权限吗?
答:API 管理中没有充值或提现功能。目前,API 端点仅可用于交易和机器人。

问:我可以通过 IP 限制密钥吗?

答:可以 — 强烈建议对任何具有 Trade 权限的密钥这样做。请设置您的服务器或工作站的 IP 地址。

问:Pionex 能看到我的 Secret 吗?

答:Pionex 存储的是单向哈希值,而不是明文,并用它按照与您生成签名相同的方式来验证您的签名。这就是它只能向您显示一次 Secret 的原因。


12. 故障排查速查表

现象

最可能的原因

解决方法

每个请求都返回 401

密钥错误或签名不匹配

重新检查排序顺序、请求体字节和请求头

仅在 POST 时返回 401

请求体在签名后被重新序列化

将完全相同的已签名字符串作为请求体发送

result: false 并伴有时间戳错误

时钟漂移

同步您的系统时间

403

未授予权限

请重新检查密钥权限。任何账户均不可使用直接合约交易。

429

触发速率限制(自上次请求起最长 24 小时)

加入退避;降低轮询频率

订单被拒绝 — 最小名义价值

quantity * price < minAmount

增大下单量

订单被拒绝 — 精度

小数位数过多

取至 baseScale / quoteScale 位数

机器人无法启动 — BOT_INVALID_ARGUMENT

message 会指明原因,例如 balance insufficient

按 message 中指出的问题修正。如果是资金问题,请为您的主账户充值 — 合约账户和交易账户不计入

机器人无法启动 — BOT_INTERNAL_ERROR

我们这边的故障

退避后重试;如果问题持续出现,请联系客服

机器人无法启动 — P_TRADING_BOT_OPERATION_IS_FORBIDDEN,“account frozen”

账户受到限制

请联系客服。重试没有帮助

WebSocket 断线

正常现象,或防火墙空闲超时

退避后重连;每 30 秒 ping 一次

在 curl 中签名正常,在代码中却不行

库自动对请求体进行了编码

发送原始的已签名字节


13. 安全最佳实践

  1. 每种用途使用一个密钥。更容易撤销,更容易审计。

  2. 最小权限。默认只读;仅在需要时才启用 Trade。

  3. 对任何能够转移资金或下单的密钥,都应设置 IP 白名单。

  4. 绝不记录 Secret。从请求日志中去除身份验证请求头。

  5. 绝不要把 Secret 放进客户端代码。浏览器、移动应用 — 请假定任何发送到用户端的代码都是公开可读的。

  6. 定期轮换。每 90 天是合理的频率;一旦怀疑泄露,应立即轮换。

  7. 监控使用情况。Pionex 会显示 API 密钥的使用统计 — 请每周查看一次。

  8. 检查代码中是否有意外提交的内容。git-secrets、trufflehog 或 GitHub 密钥扫描等工具可以及早发现泄露。

  9. 在生产环境中使用密钥管理工具:AWS Secrets Manager、HashiCorp Vault、1Password CLI、Doppler — 任何方式都比磁盘上的明文强。

  10. 在小额账户上测试。不要在第一天就让全新的交易机器人去操作您的常用账户。


14. 词汇表

术语

定义

API Key / Secret

您用于 API 的“用户名加密码”组合。Secret 用于对请求签名;Key 用于标识您的身份。

HMAC-SHA256

一种带密钥的哈希函数。相同的输入加上相同的 Secret 会产生相同的输出,但您无法从输出中还原出 Secret。

标准消息(Canonical message)

您和 Pionex 双方为比对签名而进行哈希运算的同一个字符串。

计价币(Quote currency)

交易对中的第二个资产(BTC_USDT 中的 USDT)。

基础币(Base currency)

交易对中的第一个资产(BTC_USDT 中的 BTC)。

名义价值(Notional)

quantity × price — 一笔交易以美元(或计价资产)计算的价值。

Maker / Taker

Maker 提供流动性(您的订单挂在订单簿上)。Taker 消耗流动性(您的订单与已有订单成交)。

标记价格(Mark price)

Pionex 用于合约的参考价格,用于计算强制平仓和未实现盈亏。

资金费用(Funding fee)

永续合约中多头与空头之间的定期支付款项。

强制平仓价格(Liquidation price)

杠杆仓位被强制平仓时的价格。

幂等(Idempotent)

可以安全重试的操作 — 相同的输入产生相同的效果。请使用 clientOrderId 来实现幂等下单。

速率限制(Rate limit)

在被限流之前,每个时间窗口内允许的最大请求数。

WebSocket

一条持久的双向连接 — 非常适合用于推送通知。

执行价(Earn)

在到期时决定适用上涨 APY 还是下跌 APY 的价格门槛。


15. 接下来去哪里

建议的学习路径:

  1. 构建第 7 节中的只读投资组合脚本。

  2. 使用 clientOrderId 重试机制,下您的第一笔 10 美元限价单。

  3. 启动一个迷你现货网格机器人(投入 50 美元,窄价格区间),并观察一周。

  4. 加入 WebSocket 私有频道,实时记录成交。

  5. 请在运行现货机器人至少一个月之后,再转向合约。

Pionex 官方文档包含最新的端点列表和任何测试版通知:https://www.pionex.com/docs/。

如果您对 API 还有其他任何问题,我们诚挚邀请您加入 Telegram 群组,以获得更好的协助:https://t.me/pionexapi

最后一条提示:如果您遇到瓶颈,最有用的调试步骤几乎总是:将您的标准消息字符串和签名,与一个可正常运行的 curl 示例并排打印出来,找出那个不同的字符。那一个字符几乎总是问题所在。


API 在合约交易和交易机器人方面有哪些限制?

Pionex 提供的 API 旨在便利交易活动,但在合约交易和交易机器人的使用方面存在特定的限制。以下是对这些限制的详细说明:

  • 现货 API(手动交易)

该 API 目前仅支持现货交易。这意味着用户可以通过 API 对现货市场中可交易的资产执行交易。现货交易是指按当前市场价格即时交换资产。

  • 合约 API(手动交易)排除项

直接通过 Futures API 交易不可用 — 它仍处于内部开发阶段,尚未向任何账户开放。没有申请或候补名单流程。受支持的替代方案:

  • Bot API:包括对创建和关闭合约网格机器人的支持,可作为自动化合约策略的临时解决方案。

  • Signal Bot:您还可以利用 Signal Bot,根据外部触发条件或自定义信号来执行交易。

祝您开发顺利。

这是否解答了您的问题?