La différence fondamentale entre l'API Binance Futures et l'API Spot réside dans les domaines de base et les jeux de paramètres : Spot utilise api.binance.com/api/v3/*, Futures (margé en USD) utilise fapi.binance.com/fapi/v1/*, et Futures (margé en cryptomonnaies) utilise dapi.binance.com/dapi/v1/*. Bien que l'algorithme de signature HMAC-SHA256 soit identique, les contrats exigent des paramètres supplémentaires tels que reduceOnly, positionSide ou leverage, et les règles de poids diffèrent. Cet article présente une comparaison en 10 dimensions avec des exemples de code réels pour vous aider à migrer vos stratégies de trading quantitatif du Spot vers le Futures. Si vous n'avez pas de compte Binance, veuillez d'abord vous inscrire sur le Site officiel de Binance ou utiliser le lien d' inscription gratuite.
I. Tableau comparatif général
| Dimension | Spot (Comptant) | Futures (USD-M) | Futures (COIN-M) |
|---|---|---|---|
| URL de base | api.binance.com | fapi.binance.com | dapi.binance.com |
| Préfixe de chemin | /api/v3/ | /fapi/v1/ et /fapi/v2/ | /dapi/v1/ |
| Devise de marge | — | USDT, USDC | BTC, ETH, BNB, etc. |
| Levier maximum | Non pris en charge (sauf Marge) | 125x | 125x |
| Mode Hedge | Non pris en charge | Pris en charge (HEDGE) | Pris en charge |
| URL WebSocket | stream.binance.com:9443 | fstream.binance.com | dstream.binance.com |
| Montant minimum d'ordre | 5 USDT (MIN_NOTIONAL) | 5 USDT | Selon la valeur nominale |
| Taux de financement | Aucun | Toutes les 8 heures | Toutes les 8 heures |
| Poids par minute | 6000 | 2400 | 2400 |
| Validité listenKey | 60 minutes | 60 minutes | 60 minutes |
Point clé à retenir : Les endpoints USD-M commencent toujours par fapi, et ceux COIN-M par dapi. Ne changez pas simplement l'URL dans votre code Spot sans adapter les paramètres.
II. Subtilités du mécanisme de signature
L'algorithme de signature est le même (HMAC-SHA256), mais notez deux points :
1. Valeur par défaut de recvWindow
- Spot : par défaut 5000ms, max 60000ms.
- Futures : par défaut 5000ms, max 60000ms, mais il est fortement recommandé de ne pas dépasser 5000ms.
2. Utilisation de chaînes de caractères pour les paramètres numériques
L'API Futures est plus sensible à la précision numérique. Lors du passage d'un ordre, il est recommandé de transmettre price et quantity sous forme de chaînes de caractères pour éviter les erreurs de précision de type -1111 Precision :
# Non recommandé
{"price": 60000.123456789, "quantity": 0.001}
# Recommandé
{"price": "60000.12", "quantity": "0.001"}
III. Différences pour la consultation des soldes et positions
Solde Spot
# Spot: GET /api/v3/account
# Retourne un tableau balances
{
"balances": [{"asset": "USDT", "free": "1000", "locked": "0"}]
}
Positions Futures USD-M
import hmac, hashlib, time, requests
from urllib.parse import urlencode
API_KEY = "VOTRE_CLE"
SECRET_KEY = "VOTRE_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():
"""Consultation des positions V2 : retourne toutes les positions non nulles"""
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():
"""Solde du compte Futures 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']}: Qté {p['positionAmt']}, Prix d'entrée {p['entryPrice']}, PnL non réalisé {p['unRealizedProfit']}")
IV. Comparaison des paramètres d'ordre
Un ordre Spot nécessite 4-5 paramètres ; un ordre Futures nécessite des champs supplémentaires comme le côté de la position, le mode réduction seule ou la protection contre l'auto-trading :
| Paramètre | Spot | Futures |
|---|---|---|
| symbol | Requis | Requis |
| side | BUY / SELL | BUY / SELL |
| type | LIMIT/MARKET/... | LIMIT/MARKET/STOP/TAKE_PROFIT/TRAILING_STOP_MARKET |
| quantity | Requis | Requis (ou closePosition) |
| positionSide | — | BOTH (unidirectionnel) / LONG / SHORT (mode Hedge) |
| reduceOnly | — | true pour réduire uniquement la position |
| closePosition | — | true pour clôturer la position en un clic |
| workingType | — | MARK_PRICE / CONTRACT_PRICE |
| newOrderRespType | ACK/RESULT/FULL | ACK/RESULT |
Exemple d'ordre limite sur 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()
# Ouvrir long 0.01 BTC, prix limite 60000
order = place_futures_limit("BTCUSDT", "BUY", 0.01, 60000)
print(order["orderId"])
V. Réglage du levier et du mode de marge
Deux interfaces de réglage spécifiques à Futures :
# Définir le levier
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) # Levier 10x
# Définir le mode de marge : ISOLATED (isolée) ou CROSSED (croisée)
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")
Remarque : Le mode de marge ne peut pas être modifié si des positions sont ouvertes sur la paire. Clôturez d'abord vos positions.
VI. Taux de financement (Funding Rate)
Le taux de financement est un concept exclusif aux contrats perpétuels, réglé toutes les 8 heures :
# Consulter le dernier taux de financement
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"]
}
# Consulter l'historique des taux de financement
def funding_history(symbol, limit=100):
r = requests.get(f"{FAPI}/fapi/v1/fundingRate",
params={"symbol": symbol, "limit": limit})
return r.json()
Conseil d'arbitrage : Quand le fundingRate est positif, les positions longues paient les courtes ; inversement s'il est négatif. L'arbitrage de taux de financement consiste souvent à être court sur Futures et long sur Spot lorsque les taux sont élevés.
VII. Limites de poids et de fréquence
# En-têtes de réponse Spot
X-MBX-USED-WEIGHT-1m: 45
X-MBX-ORDER-COUNT-10s: 3
# En-têtes de réponse Futures
X-MBX-USED-WEIGHT-1m: 12
X-MBX-ORDER-COUNT-1m: 5
X-MBX-ORDER-COUNT-10s: 3
Futures possède une limite supplémentaire de nombre d'ordres par minute (par défaut 1200 ordres/min), à surveiller dans les stratégies haute fréquence.
VIII. Différences WebSocket
# S'abonner aux flux de marché
import websocket, json
def on_message(ws, msg):
data = json.loads(msg)
print(data["s"], data["c"]) # symbole, prix de clôture
# Spot
ws_spot = websocket.WebSocketApp(
"wss://stream.binance.com:9443/ws/btcusdt@ticker",
on_message=on_message)
# Futures USD-M
ws_fut = websocket.WebSocketApp(
"wss://fstream.binance.com/ws/btcusdt@markPrice", # Push du prix de marque
on_message=on_message)
Sujets spécifiques à Futures : @markPrice (prix de marque), @forceOrder (liquidations forcées).
IX. Code stratégique pour opérations parallèles Spot + Futures
Les stratégies de couverture nécessitent souvent d'ouvrir simultanément une position longue sur Spot et courte sur Futures :
import asyncio, aiohttp
async def spot_buy(session, symbol, qty):
# Simplifié : nécessite une signature réelle
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())
X. Questions fréquentes FAQ
Q1 : Puis-je utiliser la même clé API pour opérer sur Spot et Futures ?
R : Oui. Il suffit de cocher Enable Spot & Margin Trading et Enable Futures dans les paramètres de la clé API. Notez que vous devez d'abord activer manuellement le compte Futures sur le site web et réussir le questionnaire avant que l'API ne fonctionne.
Q2 : Les soldes fapi.binance.com et dapi.binance.com sont-ils indépendants ?
R : Oui. Les contrats USD-M utilisent des portefeuilles USDT/USDC indépendants, et les contrats COIN-M utilisent des portefeuilles BTC/ETH indépendants. Le portefeuille Spot est également séparé. Les fonds doivent être transférés via /sapi/v1/futures/transfer.
Q3 : Quelle est la différence entre les API Futures v1 et v2 ?
R : La v2 est une version améliorée, optimisant la précision et le nommage des champs. L'utilisation de la v2 est obligatoire pour les positions et soldes (/fapi/v2/positionRisk, /fapi/v2/balance), tandis que les ordres restent en v1.
Q4 : Quel est le montant minimum d'ordre sur l'API Futures ?
R : Pour USD-M, la valeur nominale minimale est généralement de 5 USDT (ex: 0.0001 BTC si le prix est de 60000). Pour certaines paires comme BNB ou ETH, elle peut descendre à 1 USDT. Vérifiez le filtre MIN_NOTIONAL via GET /fapi/v1/exchangeInfo.
Pour plus de tutoriels sur l'API, retournez à la Navigation par catégorie dans la section « Intégration API ».