Le chemin le plus court pour débuter avec l'API Binance Spot est le suivant : une fois vos clés API Key + Secret prêtes, appelez d'abord /api/v3/ping pour vérifier la connectivité, puis utilisez /api/v3/time pour synchroniser l'heure du serveur, et enfin récupérez votre solde via /api/v3/account (interface signée) pour confirmer que vos permissions sont correctes. L'ensemble du processus prend environ 10 minutes pour effectuer votre premier passage d'ordre. Cet article fournit le code complet en curl et Python pour chaque étape, tous les points de terminaison (endpoints) étant des adresses réelles sur https://api.binance.com. Si vous n'avez pas encore préparé vos clés API, veuillez d'abord effectuer le KYC sur le Site officiel de Binance ; si vous n'avez pas de compte Binance, vous pouvez vous inscrire gratuitement.
I. Hiérarchie des interfaces de l'API Spot
L'API REST Binance Spot est divisée en trois catégories selon le niveau d'authentification :
| Catégorie | Exemple de préfixe d'endpoint | Signature requise | En-tête (Header) requis | Interface typique |
|---|---|---|---|---|
| NONE | /api/v3/ping, /api/v3/time | Non | Aucun | Heure serveur, statut système |
| MARKET_DATA | /api/v3/depth, /api/v3/klines | Non | Aucun | Prix, profondeur, K-lines |
| USER_DATA | /api/v3/account, /api/v3/order | Oui | X-MBX-APIKEY + signature | Ordres, annulations, solde |
| TRADE | /api/v3/order (POST) | Oui | X-MBX-APIKEY + signature | Achat/Vente d'ordres |
| USER_STREAM | /api/v3/userDataStream | API Key uniquement | X-MBX-APIKEY | WebSocket listenKey |
Les interfaces authentifiées doivent inclure signature=<signature HMAC-SHA256> à la fin des paramètres de requête et porter l'en-tête X-MBX-APIKEY.
II. Préparation de l'environnement et test de connectivité
1. Installation des dépendances
# Python 3.8+
pip install requests python-dotenv
# Ou utiliser le SDK officiel
pip install python-binance
2. Choix de l'URL de base
Binance Spot propose 5 miroirs d'entrée. Il est conseillé d'utiliser api.binance.com dans votre code, avec un repli sur api-gcp.binance.com en cas d'échec :
ENDPOINTS = [
"https://api.binance.com", # Par défaut
"https://api-gcp.binance.com", # Ligne Google Cloud
"https://api1.binance.com",
"https://api2.binance.com",
"https://api3.binance.com",
]
3. Première requête : ping
curl -X GET "https://api.binance.com/api/v3/ping"
# Renvoie {} si la connexion est établie
4. Synchronisation de l'heure du serveur
curl -X GET "https://api.binance.com/api/v3/time"
# {"serverTime":1713027384562}
Si l'écart entre votre heure locale et serverTime dépasse 1000ms, l'interface signée renverra l'erreur -1021. Les serveurs de trading doivent impérativement activer le protocole NTP.
III. Consultation du solde du compte (Interface signée)
Voici une encapsulation Python complète gérant la signature, les tentatives et le décalage d'horodatage :
import hmac, hashlib, time, requests
from urllib.parse import urlencode
API_KEY = "VOTRE_API_KEY"
SECRET_KEY = "VOTRE_SECRET_KEY"
BASE_URL = "https://api.binance.com"
def _sign(params: dict) -> dict:
params["timestamp"] = int(time.time() * 1000)
params["recvWindow"] = 5000
query = urlencode(params)
params["signature"] = hmac.new(
SECRET_KEY.encode(),
query.encode(),
hashlib.sha256
).hexdigest()
return params
def _request(method: str, path: str, params: dict = None, signed: bool = False):
params = params or {}
headers = {"X-MBX-APIKEY": API_KEY} if signed else {}
if signed:
params = _sign(params)
url = f"{BASE_URL}{path}"
r = requests.request(method, url, params=params, headers=headers, timeout=10)
r.raise_for_status()
return r.json()
def get_account():
return _request("GET", "/api/v3/account", signed=True)
# Appel
balances = get_account()["balances"]
non_zero = [b for b in balances if float(b["free"]) > 0]
for b in non_zero:
print(f"{b['asset']}: {b['free']} (Bloqué {b['locked']})")
Exemple de structure de réponse :
{
"makerCommission": 10,
"takerCommission": 10,
"canTrade": true,
"canWithdraw": true,
"canDeposit": true,
"accountType": "SPOT",
"balances": [
{"asset": "BTC", "free": "0.00123456", "locked": "0.00000000"},
{"asset": "USDT", "free": "128.45", "locked": "0.00"}
]
}
IV. Consultation du prix et des K-lines (Interfaces publiques)
Les interfaces de données de marché ne nécessitent pas de signature, mais sont soumises à des limites de poids (weight) :
def get_price(symbol: str) -> float:
r = _request("GET", "/api/v3/ticker/price", {"symbol": symbol})
return float(r["price"])
def get_depth(symbol: str, limit: int = 20) -> dict:
return _request("GET", "/api/v3/depth", {"symbol": symbol, "limit": limit})
def get_klines(symbol: str, interval: str = "1h", limit: int = 500):
return _request("GET", "/api/v3/klines", {
"symbol": symbol,
"interval": interval, # 1m, 5m, 15m, 1h, 4h, 1d
"limit": limit
})
print(get_price("BTCUSDT")) # 68420.12
Conseil de performance : Utilisez /ticker/price (poids 1) pour un seul prix, mais utilisez /ticker/24hr (poids 40) pour obtenir toutes les paires d'un coup afin d'économiser 99% du poids par rapport à une boucle.
V. Passage et annulation d'ordres (Interfaces TRADE)
Le point de terminaison pour passer un ordre au comptant est POST /api/v3/order. Les paramètres requis varient selon le type d'ordre :
1. Ordre à cours limité (LIMIT)
def place_limit_order(symbol: str, side: str, quantity: float, price: float):
return _request("POST", "/api/v3/order", {
"symbol": symbol,
"side": side, # BUY ou SELL
"type": "LIMIT",
"timeInForce": "GTC", # GTC / IOC / FOK
"quantity": quantity,
"price": price,
}, signed=True)
order = place_limit_order("BTCUSDT", "BUY", 0.001, 60000.00)
print(order["orderId"], order["status"])
2. Ordre au marché (MARKET)
Un ordre au marché peut être passé selon la quantité (quantity) ou le montant (quoteOrderQty) :
# Acheter selon la quantité de BTC (consomme l'USDT correspondant)
_request("POST", "/api/v3/order", {
"symbol": "BTCUSDT",
"side": "BUY",
"type": "MARKET",
"quantity": 0.001
}, signed=True)
# Acheter selon le montant en USDT (plus courant pour éviter les problèmes de slippage)
_request("POST", "/api/v3/order", {
"symbol": "BTCUSDT",
"side": "BUY",
"type": "MARKET",
"quoteOrderQty": 100 # Acheter pour 100 USDT de BTC
}, signed=True)
3. Consultation du statut de l'ordre
def get_order(symbol: str, order_id: int):
return _request("GET", "/api/v3/order", {
"symbol": symbol,
"orderId": order_id
}, signed=True)
status = get_order("BTCUSDT", 12345678)
# status["status"] peut être NEW / PARTIALLY_FILLED / FILLED / CANCELED / REJECTED
4. Annulation d'un ordre
def cancel_order(symbol: str, order_id: int):
return _request("DELETE", "/api/v3/order", {
"symbol": symbol,
"orderId": order_id
}, signed=True)
cancel_order("BTCUSDT", 12345678)
VI. Utilisation du Testnet (Éviter les erreurs coûteuses)
Binance propose un Spot Testnet indépendant avec des jetons de test gratuits :
# Configuration du Testnet
BASE_URL = "https://testnet.binance.vision"
# La clé API doit être générée séparément sur testnet.binance.vision
Le passage d'ordre, l'annulation et la consultation du solde sur le Testnet simulent parfaitement le comportement du réseau principal (Mainnet), bien que les prix des actifs ne soient pas synchronisés avec le marché réel. Il est recommandé de faire tourner tout nouveau code sur le Testnet pendant 24 heures avant de passer au Mainnet.
VII. Questions fréquentes FAQ
Q1 : Pourquoi l'erreur "filter failure: LOT_SIZE" apparaît-elle lors du passage d'un ordre ?
R : La quantité ne respecte pas le stepSize (pas minimal) de la paire de trading. Par exemple, si le stepSize de BTCUSDT est 0.00001, vous ne pouvez pas commander 0.000005. Appelez /api/v3/exchangeInfo pour vérifier les règles LOT_SIZE / MIN_NOTIONAL / PRICE_FILTER de chaque paire et arrondissez vos valeurs en conséquence.
Q2 : L'API Spot permet-elle d'annuler tous les ordres ouverts ?
R : Oui. DELETE /api/v3/openOrders?symbol=BTCUSDT annulera d'un coup tous les ordres non exécutés pour cette paire (poids 1), mais l'annulation multi-paires n'est pas supportée dans un seul appel.
Q3 : Comment passer des ordres en masse ?
R : L'API Spot n'a pas d'interface native de passage d'ordres en masse ; vous pouvez appeler POST /api/v3/order plusieurs fois de manière concurrente, en respectant la limite de 100 ordres par 10 secondes. Pour les Futures, il existe /fapi/v1/batchOrders (max 5 ordres par appel).
Q4 : Quelles stratégies d'ordres peuvent être combinées via SIDE et type ?
R : Les types principaux sont LIMIT, MARKET, STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT, LIMIT_MAKER. Les ordres de type stop (stop loss/take profit) nécessitent de passer un paramètre stopPrice supplémentaire.
Q5 : La limite de 500 ordres historiques est-elle suffisante ?
R : /api/v3/allOrders renvoie 500 ordres par défaut. En utilisant les paramètres startTime/endTime/fromId, vous pouvez paginer pour récupérer tout l'historique. Pour un trading haute fréquence, il est conseillé de s'abonner au flux WebSocket userDataStream pour suivre les changements d'ordres en temps réel et économiser du poids d'API.
Pour plus de contenu sur l'API des contrats (Futures), retournez à la Navigation par catégorie pour consulter la liste complète de la catégorie « Intégration API ».