做量化交易或加密货币程序化交易,第一步就是搞懂订单数据结构。很多新手卡在这一步,不知道订单状态怎么判断、字段代表什么意思、签名怎么生成。今天我用 3000 字把 Binance 现货和合约订单的每一个关键字段讲透,代码可以直接复制运行。
一、Binance API 基础概念速成
在开始之前,先了解三个核心概念,没有技术背景也能看懂:
- API Key:相当于你的身份证,Binance 用它识别"是谁在操作"
- 签名(Signature):相当于你的指纹,用于证明"这次请求确实是你本人发起"
- Endpoint:API 接口地址,比如下单、查订单、撤销订单都有不同的地址
国内开发者推荐使用 HolySheep AI 作为中转服务,微信/支付宝直接充值,汇率 ¥1=$1 无损,比官方省 85% 以上,且国内延迟 <50ms,适合高频交易场景。
二、Binance 订单数据结构详解
2.1 订单类型一览
| 订单类型 | 说明 | 适用场景 |
|---|---|---|
| LIMIT | 限价单,需指定价格 | 挂单等待成交 |
| MARKET | 市价单,立即以最优价成交 | 急买急卖 |
| STOP_LOSS | 止损单 | 风控止损 |
| STOP_LOSS_LIMIT | 限价止损单 | 止损并挂单 |
| TAKE_PROFIT | 止盈单 | 锁定利润 |
| TAKE_PROFIT_LIMIT | 限价止盈单 | 止盈并挂单 |
| STOP | 跟踪止损单 | 动态止损 |
2.2 现货订单核心字段解析
当我们调用 Binance 的下单接口时,返回的数据结构如下:
{
"symbol": "BTCUSDT", // 交易对,如 BTC/USDT
"orderId": 12345678, // 订单唯一ID,由Binance生成
"orderListId": -1, // OCO订单组ID,普通限价单为-1
"clientOrderId": "my_order_1", // 你自定义的订单ID(可选)
"transactTime": 1678901234567, // 成交时间戳(毫秒)
"price": "50000.00", // 下单价格(字符串,避免精度丢失)
"origQty": "0.001", // 原始下单数量
"executedQty": "0.000", // 已成交数量
"cummulativeQuoteQty": "0.00",// 累计成交金额(USDT)
"status": "NEW", // 订单状态:NEW/PARTIALLY_FILLED/FILLED/CANCELED/REJECTED/EXPIRED
"type": "LIMIT", // 订单类型
"side": "BUY", // 方向:BUY/SELL
"timeInForce": "GTC" // 有效期:GTC/IOC/FOK
}
关键字段说明:
- orderId:系统生成的订单唯一标识,后续查询和撤销都要用到
- status:NEW 表示已挂单未成交,FILLED 表示完全成交,PARTIALLY_FILLED 表示部分成交
- price/origQty:注意这两个是字符串类型,直接做数值运算可能丢失精度
- executedQty:已成交数量,可据此判断订单是否完全成交
2.3 合约订单结构差异
U本位合约(USDT-M Futures)的数据结构与现货略有不同:
{
"orderId": 987654321,
"symbol": "BTCUSDT",
"side": "BUY",
"positionSide": "LONG", // 持仓方向:LONG/SHORT/BOTH(双向持仓)
"type": "LIMIT",
"origType": "LIMIT",
"timeInForce": "GTC",
"qty": "0.001", // 合约数量(注意不是origQty)
"price": "50000.00",
"stopPrice": "0.00", // 止损止盈触发价
"workingType": "CONTRACT_PRICE", // 触发价格类型
"avgPrice": "0.00", // 平均成交价(成交后返回)
"status": "NEW",
"reduceOnly": false, // 是否只减仓
"closePosition": false, // 是否触发平仓
"workingTime": 1678901234567,
"selfTradePreventionMode": "NONE"
}
合约特有字段重点注意:
- positionSide:双向持仓模式下必须指定 LONG/SHORT
- reduceOnly:true 时这单只能平仓不能开仓
- closePosition:true 时会触发市价全平
- workingType:标记价格触发还是最新价格触发
三、Python 实战代码
3.1 基础下单与查询
import requests
import time
import hashlib
import hmac
class BinanceClient:
def __init__(self, api_key, api_secret, base_url="https://api.binance.com"):
self.api_key = api_key
self.api_secret = api_secret
self.base_url = base_url
def _sign(self, params):
"""生成HMAC SHA256签名"""
query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
signature = hmac.new(
self.api_secret.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def create_order(self, symbol, side, order_type, quantity, price=None, stop_price=None):
"""下单函数"""
endpoint = "/api/v3/order"
params = {
"symbol": symbol,
"side": side,
"type": order_type,
"quantity": quantity,
"timestamp": int(time.time() * 1000)
}
# 限价单必须指定价格
if price:
params["price"] = price
params["timeInForce"] = "GTC"
# 止损单必须指定触发价
if stop_price:
params["stopPrice"] = stop_price
# 生成签名
params["signature"] = self._sign(params)
headers = {"X-MBX-APIKEY": self.api_key}
response = requests.post(
f"{self.base_url}{endpoint}",
params=params,
headers=headers
)
return response.json()
def get_order(self, symbol, order_id):
"""查询指定订单"""
endpoint = "/api/v3/order"
params = {
"symbol": symbol,
"orderId": order_id,
"timestamp": int(time.time() * 1000)
}
params["signature"] = self._sign(params)
headers = {"X-MBX-APIKEY": self.api_key}
response = requests.get(
f"{self.base_url}{endpoint}",
params=params,
headers=headers
)
return response.json()
使用示例
client = BinanceClient(
api_key="YOUR_API_KEY",
api_secret="YOUR_API_SECRET"
)
下一个限价买单:50000 USDT 买 0.001 BTC
result = client.create_order(
symbol="BTCUSDT",
side="BUY",
order_type="LIMIT",
quantity="0.001",
price="50000.00"
)
print(f"下单结果: {result}")
查询订单状态
if "orderId" in result:
order_info = client.get_order("BTCUSDT", result["orderId"])
print(f"订单状态: {order_info['status']}")
3.2 批量撤销订单
def cancel_all_orders(self, symbol):
"""撤销某交易对所有挂单"""
endpoint = "/api/v3/openOrders"
params = {
"symbol": symbol,
"timestamp": int(time.time() * 1000)
}
params["signature"] = self._sign(params)
headers = {"X-MBX-APIKEY": self.api_key}
response = requests.delete(
f"{self.base_url}{endpoint}",
params=params,
headers=headers
)
return response.json()
撤销 BTCUSDT 所有挂单
cancel_result = client.cancel_all_orders("BTCUSDT")
print(f"撤销结果: {cancel_result}")
3.3 订单状态监控轮询
def monitor_order_until_fill(self, symbol, order_id, timeout=60, interval=1):
"""
监控订单直到成交或超时
:param timeout: 超时时间(秒)
:param interval: 查询间隔(秒)
"""
start_time = time.time()
while time.time() - start_time < timeout:
order_info = self.get_order(symbol, order_id)
status = order_info.get("status")
if status == "FILLED":
print(f"订单 {order_id} 已完全成交")
print(f"成交均价: {order_info['avgPrice']}")
print(f"成交数量: {order_info['executedQty']}")
return order_info
elif status in ["CANCELED", "REJECTED", "EXPIRED"]:
print(f"订单异常结束,状态: {status}")
return order_info
else:
print(f"订单进行中,当前状态: {status}")
time.sleep(interval)
print(f"监控超时,订单 {order_id} 仍未成交")
return self.get_order(symbol, order_id)
四、实战案例:网格交易订单管理
网格交易需要同时管理多个订单,下面展示如何批量下单并追踪:
def create_grid_orders(self, symbol, base_price, grid_count, grid_spacing, quantity):
"""
创建网格交易订单
:param base_price: 基准价格
:param grid_count: 网格数量(上下各一半)
:param grid_spacing: 网格间距(百分比,如0.01代表1%)
:param quantity: 每格下单量
"""
orders = []
# 在基准价上下各创建网格
for i in range(-grid_count, grid_count + 1):
if i == 0:
continue
price = base_price * (1 + i * grid_spacing)
if i < 0:
# 下方网格:挂卖出单(低价买高价卖)
order = self.create_order(
symbol=symbol,
side="BUY",
order_type="LIMIT",
quantity=str(quantity),
price=f"{price:.2f}"
)
else:
# 上方网格:挂卖出单
order = self.create_order(
symbol=symbol,
side="SELL",
order_type="LIMIT",
quantity=str(quantity),
price=f"{price:.2f}"
)
orders.append(order)
print(f"网格{i}: 价格={price}, 方向={'买' if i<0 else '卖'}, 订单ID={order.get('orderId')}")
return orders
创建 BTC 网格策略
基准价 50000,10格网格,1%间距,每格 0.001 BTC
grid_orders = client.create_grid_orders(
symbol="BTCUSDT",
base_price=50000,
grid_count=5,
grid_spacing=0.01,
quantity="0.001"
)
五、常见报错排查
5.1 签名验证失败 (Error Code: -1022)
# ❌ 错误原因:签名参数名写错或排序不对
params["sign"] = signature # 应该是 "signature"
✅ 正确写法
params["signature"] = signature
❌ 错误原因:参数没有排序
query_string = "&".join([f"{k}={v}" for k, v in params.items()])
✅ 正确写法:参数必须按 ASCII 码排序
sorted_params = sorted(params.items())
query_string = "&".join([f"{k}={v}" for k, v in sorted_params])
5.2 余额不足 (Error Code: -2010)
# 错误信息:{"code":-2010,"msg":"Account has insufficient balance for requested action."}
✅ 解决方案1:先查询账户余额
def get_balance(self, asset="USDT"):
endpoint = "/api/v3/account"
params = {"timestamp": int(time.time() * 1000)}
params["signature"] = self._sign(params)
headers = {"X-MBX-APIKEY": self.api_key}
response = requests.get(
f"{self.base_url}{endpoint}",
params=params,
headers=headers
)
balances = response.json().get("balances", [])
for b in balances:
if b["asset"] == asset:
return float(b["free"])
return 0
✅ 解决方案2:降低下单数量
balance = client.get_balance("USDT")
order_amount = float(price) * float(quantity)
if balance >= order_amount:
result = client.create_order(symbol, side, order_type, quantity, price)
else:
# 改为全额下单
adjusted_qty = balance / float(price)
result = client.create_order(symbol, side, order_type, f"{adjusted_qty:.6f}", price)
5.3 价格精度错误 (Error Code: -1015)
# 错误信息:{"code":-1015,"msg":"Too many new orders."}
❌ 错误:价格小数位数不符合要求
BTCUSDT 要求价格精度 2 位,你写了 5 位
price = "50000.12345"
✅ 正确:根据交易对精度格式化
def format_price(symbol, price):
# 不同交易对精度不同
precision_map = {
"BTCUSDT": 2,
"ETHUSDT": 2,
"BNBUSDT": 2,
"DOGEUSDT": 4,
"SHIBUSDT": 6
}
precision = precision_map.get(symbol, 2)
return f"{price:.{precision}f}"
formatted_price = format_price("BTCUSDT", 50000.12345) # "50000.12"
5.4 订单不存在 (Error Code: -2013)
# 错误信息:{"code":-2013,"msg":"Order does not exist."}
✅ 排查步骤:
1. 确认订单ID正确
2. 确认 symbol 参数完全匹配(包括大小写)
3. 确认订单是在当前 API Key 下创建的
✅ 安全查询方式:使用 clientOrderId 查询
def get_order_by_client_id(self, symbol, client_order_id):
endpoint = "/api/v3/order"
params = {
"symbol": symbol,
"origClientOrderId": client_order_id, # 用这个查询
"timestamp": int(time.time() * 1000)
}
params["signature"] = self._sign(params)
headers = {"X-MBX-APIKEY": self.api_key}
response = requests.get(
f"{self.base_url}{endpoint}",
params=params,
headers=headers
)
return response.json()
使用自定义订单ID查询
order_info = client.get_order_by_client_id("BTCUSDT", "my_order_1")
六、价格与回本测算
如果你是量化交易者或做套利策略,Binance API 调用本身免费,但以下成本需要考虑:
| 成本项 | Binance 官方 | 通过 HolySheep 中转 | 节省比例 |
|---|---|---|---|
| 汇率 | ¥7.3 = $1(银行坑价) | ¥1 = $1(无损) | 87% |
| 充值方式 | 需购汇、跨境汇款 | 微信/支付宝直充 | 省时省力 |
| API 稳定性 | 境外服务器,200-500ms | 国内节点 <50ms | 延迟降低 80% |
| 首次注册 | 无赠额 | 送免费额度 | 白嫖体验 |
七、为什么选 HolySheep
对于国内量化开发者,使用 HolySheep 有三个核心优势:
- 极速响应:上海/深圳节点部署,延迟 <50ms,比直连 Binance 快 5-10 倍,适合高频策略
- 零损耗充值:微信/支付宝 ¥1 充 $1,官方渠道要 ¥7.3 才能换 $1,节省 85%
- 全币种支持:不仅支持 Binance,还覆盖 Bybit、OKX、Deribit 等主流合约交易所
八、适合谁与不适合谁
| 场景 | 推荐使用 Binance API | 建议使用 HolySheep 中转 |
|---|---|---|
| 日均订单 <100 单 | ✅ | ✅ |
| 高频/量化策略(>1000单/日) | ❌ 延迟高 | ✅ 50ms内 |
| 套利策略(多交易所) | ❌ 需分别对接 | ✅ 统一接口 |
| 个人学习测试 | ✅ | ✅ 有赠额 |
| 机构级量化 | ⚠️ 需专线 | ✅ 稳定优先 |
九、总结与 CTA
本文覆盖了 Binance 订单数据的所有核心字段,从基础概念到 Python 实战代码,再到 4 个高频报错解决方案。记住三个关键点:
- 订单状态 status 是核心判断依据:NEW → PARTIALLY_FILLED → FILLED
- 签名必须对参数按 ASCII 排序后计算
- 价格和数量必须符合交易对的精度要求
如果你是国内开发者做量化交易,想要更低延迟、更便捷充值,立即注册 HolySheep AI 获取首月赠额度,体验 ¥1=$1 的无损汇率和 <50ms 的极速响应。
👉 免费注册 HolySheep AI,获取首月赠额度