币安 Futures API 与 Spot API 的根本差异是 基础域名 和 参数集:Spot 使用 api.binance.com/api/v3/*,Futures U 本位使用 fapi.binance.com/fapi/v1/*,Futures 币本位使用 dapi.binance.com/dapi/v1/*,虽然签名算法同为 HMAC-SHA256,但合约额外要求传 reduceOnly、positionSide、leverage 等参数,且权重规则不同。本文按 10 个维度给出对比表与真实代码,帮你把现货量化策略平滑迁移到合约。没有币安账号的请先到 币安官网 完成注册,新用户可以通过 免费注册 通道开户。
一、基础对比总览表
| 维度 | Spot 现货 | Futures U 本位 | Futures 币本位 |
|---|---|---|---|
| 基础 URL | api.binance.com | fapi.binance.com | dapi.binance.com |
| 路径前缀 | /api/v3/ | /fapi/v1/ 和 /fapi/v2/ | /dapi/v1/ |
| 保证金币种 | — | USDT, USDC | BTC, ETH, BNB 等币本位 |
| 最大杠杆 | 不支持(仅杠杆借贷) | 125x | 125x |
| 双向持仓 | 不支持 | 支持(HEDGE 模式) | 支持 |
| WebSocket URL | stream.binance.com:9443 | fstream.binance.com | dstream.binance.com |
| 下单最低金额 | 5 USDT (MIN_NOTIONAL) | 5 USDT | 币本位按名义价值计 |
| 资金费率 | 无 | 每 8 小时 | 每 8 小时 |
| 每分钟权重 | 6000 | 2400 | 2400 |
| listenKey 有效期 | 60 分钟 | 60 分钟 | 60 分钟 |
关键记忆点:U 本位的端点永远以 fapi 开头,币本位以 dapi 开头,千万不要把 Spot 的代码直接改 URL 就用。
二、签名机制的细微差别
签名算法完全一致(HMAC-SHA256),但两点需要注意:
1. recvWindow 默认值不同
- Spot:默认 5000ms,最大 60000ms
- Futures:默认 5000ms,最大 60000ms,但官方强烈建议不超过 5000ms
2. 所有数值参数建议用字符串
Futures API 对数值精度更敏感,下单时 price 和 quantity 推荐以字符串形式传递,避免浮点精度导致的 -1111 Precision 错误:
# 不推荐
{"price": 60000.123456789, "quantity": 0.001}
# 推荐
{"price": "60000.12", "quantity": "0.001"}
三、查询持仓与余额的接口差异
Spot 余额
# Spot: GET /api/v3/account
# 返回 balances 数组
{
"balances": [{"asset": "USDT", "free": "1000", "locked": "0"}]
}
Futures U 本位持仓
import hmac, hashlib, time, requests
from urllib.parse import urlencode
API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
FAPI = "https://fapi.binance.com"
def _sign(params):
params["timestamp"] = int(time.time() * 1000)
query = urlencode(params)
params["signature"] = hmac.new(SECRET_KEY.encode(), query.encode(), hashlib.sha256).hexdigest()
return params
def get_positions():
"""V2 持仓查询:返回所有非零持仓"""
params = _sign({})
r = requests.get(f"{FAPI}/fapi/v2/positionRisk", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return [p for p in r.json() if float(p["positionAmt"]) != 0]
def get_futures_balance():
"""V2 合约账户余额"""
params = _sign({})
r = requests.get(f"{FAPI}/fapi/v2/balance", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
positions = get_positions()
for p in positions:
print(f"{p['symbol']}: 数量 {p['positionAmt']}, 入场价 {p['entryPrice']}, 未实现盈亏 {p['unRealizedProfit']}")
四、下单参数对比
Spot 下单只需 4-5 个参数;Futures 需要额外的 持仓方向、是否只减仓、自成交防护 等字段:
| 参数 | Spot | Futures |
|---|---|---|
| symbol | 必填 | 必填 |
| side | BUY / SELL | BUY / SELL |
| type | LIMIT/MARKET/... | LIMIT/MARKET/STOP/TAKE_PROFIT/TRAILING_STOP_MARKET |
| quantity | 必填 | 必填(或用 closePosition) |
| positionSide | — | BOTH(单向)/ LONG / SHORT(双向) |
| reduceOnly | — | true 表示只减仓 |
| closePosition | — | true 一键平仓 |
| workingType | — | MARK_PRICE / CONTRACT_PRICE |
| newOrderRespType | ACK/RESULT/FULL | ACK/RESULT |
Futures 限价单完整示例
def place_futures_limit(symbol, side, quantity, price, position_side="BOTH"):
params = _sign({
"symbol": symbol,
"side": side,
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": str(quantity),
"price": str(price),
"positionSide": position_side,
})
r = requests.post(f"{FAPI}/fapi/v1/order", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
# 开多 0.01 BTC,限价 60000
order = place_futures_limit("BTCUSDT", "BUY", 0.01, 60000)
print(order["orderId"])
五、杠杆与保证金模式设置
Futures 独有的两个设置接口:
# 设置杠杆倍数
def set_leverage(symbol: str, leverage: int):
params = _sign({"symbol": symbol, "leverage": leverage})
r = requests.post(f"{FAPI}/fapi/v1/leverage", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
set_leverage("BTCUSDT", 10) # 设置 10 倍杠杆
# 设置保证金模式:ISOLATED(逐仓)或 CROSSED(全仓)
def set_margin_type(symbol: str, margin_type: str):
params = _sign({"symbol": symbol, "marginType": margin_type})
r = requests.post(f"{FAPI}/fapi/v1/marginType", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
set_margin_type("BTCUSDT", "ISOLATED")
注意:同一交易对有持仓时无法切换保证金模式,需先平仓再切换。
六、资金费率(Funding Rate)
Funding Rate 是合约独有概念,每 8 小时结算一次:
# 查询最新资金费率
def get_funding_rate(symbol="BTCUSDT"):
r = requests.get(f"{FAPI}/fapi/v1/premiumIndex",
params={"symbol": symbol})
data = r.json()
return {
"markPrice": data["markPrice"],
"fundingRate": data["lastFundingRate"],
"nextFundingTime": data["nextFundingTime"]
}
# 查询历史资金费率
def funding_history(symbol, limit=100):
r = requests.get(f"{FAPI}/fapi/v1/fundingRate",
params={"symbol": symbol, "limit": limit})
return r.json()
套利提示:当 fundingRate 为正,多头支付给空头;为负相反。连续数日维持高正费率时,空 U 本位 + 多现货是常见的资金费率套利策略。
七、权重和限频差异
# Spot 响应头
X-MBX-USED-WEIGHT-1m: 45
X-MBX-ORDER-COUNT-10s: 3
# Futures 响应头
X-MBX-USED-WEIGHT-1m: 12
X-MBX-ORDER-COUNT-1m: 5
X-MBX-ORDER-COUNT-10s: 3
Futures 多了一个 1 分钟下单上限(默认 1200 单/分钟),需要在高频策略中重点监控。
八、WebSocket 差异
# Spot 订阅行情
import websocket, json
def on_message(ws, msg):
data = json.loads(msg)
print(data["s"], data["c"]) # symbol, close price
# Spot
ws_spot = websocket.WebSocketApp(
"wss://stream.binance.com:9443/ws/btcusdt@ticker",
on_message=on_message)
# Futures U 本位
ws_fut = websocket.WebSocketApp(
"wss://fstream.binance.com/ws/btcusdt@markPrice", # 标记价推送
on_message=on_message)
Futures 独有的订阅主题:@markPrice(标记价)、@forceOrder(强平推送)、@liquidation。
九、并行操作 Spot + Futures 的策略代码
套保策略常常需要同时开 Spot 多仓 + Futures 空仓:
import asyncio, aiohttp
async def spot_buy(session, symbol, qty):
# 简化:实际需签名
async with session.post("https://api.binance.com/api/v3/order",
params={"symbol": symbol, "side": "BUY",
"type": "MARKET", "quantity": qty}) as r:
return await r.json()
async def futures_short(session, symbol, qty):
async with session.post("https://fapi.binance.com/fapi/v1/order",
params={"symbol": symbol, "side": "SELL",
"type": "MARKET", "quantity": qty}) as r:
return await r.json()
async def hedge():
async with aiohttp.ClientSession() as s:
results = await asyncio.gather(
spot_buy(s, "BTCUSDT", 0.01),
futures_short(s, "BTCUSDT", 0.01)
)
print(results)
asyncio.run(hedge())
十、常见问题 FAQ
Q1: 能不能只用一套 API Key 同时操作 Spot 和 Futures?
A: 可以。API Key 在权限页分别勾选 Enable Spot & Margin Trading 和 Enable Futures 即可,但要记住 Futures 必须在 Web 端单独开通合约账户 并通过测试题,否则 API 调用会报 -2015 Invalid API-key, IP, or permissions。
Q2: fapi.binance.com 和 dapi.binance.com 是独立账户余额吗?
A: 是的。U 本位合约使用独立的 USDT/USDC 钱包,币本位使用独立的 BTC/ETH 钱包,Spot 钱包完全独立。资金需要通过 /sapi/v1/futures/transfer 在账户间划转。
Q3: Futures v1 和 v2 有什么区别?
A: v2 是增强版,主要优化了精度和字段命名。持仓、余额强制用 v2(/fapi/v2/positionRisk, /fapi/v2/balance),下单、撤单仍在 v1(/fapi/v1/order)。
Q4: 统一账户(Portfolio Margin)要改代码吗?
A: 统一账户使用 papi.binance.com/papi/v1/* 作为独立域名,端点与 fapi 类似但参数略有不同。只有 VIP 或高净值账户才支持,普通账户不用担心。
Q5: 合约 API 下单最低金额是多少?
A: U 本位默认 5 USDT 名义价值(例如 BTC 价 60000 时最低数量约 0.0001 BTC);BNBUSDT、ETHUSDT 等热门对最低可能降至 1 USDT。具体用 GET /fapi/v1/exchangeInfo 的 MIN_NOTIONAL filter 查。
更多合约 API 专题请回到 分类导航 的「API接入」分类查看。