API の概要
APIの種別
- REST API
- WebSocket
REST API
Endpoint の種類
- Spot Market
- USDT Futures
- COIN Futures
Weightの概念
APIすべてにWeightが指定されている。
グローバルIPごとにレート制限があり、一定時間における累積Weightがレート制限を超えた場合、APIが利用できなくなる。
自分のレート制限は、以下APIにて確認できる。
https://api.binance.com/api/v3/exchangeInfo
rateLimits
が該当箇所。
{
"timezone": "UTC",
"serverTime": 1615020505034,
"rateLimits": [
{
"rateLimitType": "REQUEST_WEIGHT",
"interval": "MINUTE",
"intervalNum": 1,
"limit": 1200
},
{
"rateLimitType": "ORDERS",
"interval": "SECOND",
"intervalNum": 10,
"limit": 100
},
{
"rateLimitType": "ORDERS",
"interval": "DAY",
"intervalNum": 1,
"limit": 200000
}
],
"exchangeFilters": [],
"symbols": [
{
"symbol": "ETHBTC",
"status": "TRADING",
"baseAsset": "ETH",
"baseAssetPrecision": 8,
"quoteAsset": "BTC",
"quotePrecision": 8,
"quoteAssetPrecision": 8,
"baseCommissionPrecision": 8,
"quoteCommissionPrecision": 8,
"orderTypes": [
"LIMIT",
"LIMIT_MAKER",
"MARKET",
"STOP_LOSS_LIMIT",
"TAKE_PROFIT_LIMIT"
],
"icebergAllowed": true,
"ocoAllowed": true,
"quoteOrderQtyMarketAllowed": true,
"isSpotTradingAllowed": true,
"isMarginTradingAllowed": true,
"filters": [
{
"filterType": "PRICE_FILTER",
"minPrice": "0.00000100",
"maxPrice": "100000.00000000",
"tickSize": "0.00000100"
},
{
"filterType": "PERCENT_PRICE",
"multiplierUp": "5",
"multiplierDown": "0.2",
"avgPriceMins": 5
},
{
"filterType": "LOT_SIZE",
"minQty": "0.00100000",
"maxQty": "100000.00000000",
"stepSize": "0.00100000"
},
{
"filterType": "MIN_NOTIONAL",
"minNotional": "0.00010000",
"applyToMarket": true,
"avgPriceMins": 5
},
{
"filterType": "ICEBERG_PARTS",
"limit": 10
},
{
"filterType": "MARKET_LOT_SIZE",
"minQty": "0.00000000",
"maxQty": "3102.16030493",
"stepSize": "0.00000000"
},
{
"filterType": "MAX_NUM_ORDERS",
"maxNumOrders": 200
},
{
"filterType": "MAX_NUM_ALGO_ORDERS",
"maxNumAlgoOrders": 5
}
],
"permissions": [
"SPOT",
"MARGIN"
]
},{
// 実際には、大量に続く。9万行くらい。
}
]
}
これを見ると、以下の3種ある。
"rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE","intervalNum": 1, "limit": 1200
"rateLimitType": "ORDERS", "interval": "SECOND", "intervalNum": 10, "limit": 100
"rateLimitType": "ORDERS", "interval": "DAY", "intervalNum": 1, "limit": 200000
rateLimitType
APIのジャンル?
interval
恐らくレート制限のリセット間隔(単位)。
intervalNum
恐らくレート制限のリセット周期。
interval
がMINUTE
でintervalNum
が1ならば、1分間でリセットという計算。
例
-
/api/v3/depth?limit=5000
は、weightが50である。 -
REQUEST_WEIGTH
のlimit
は1200である。
ということは、1200 = 50x ・・・x = 24
24回まで一分間に呼べるということ。
実際に試してみる。確かに25回目にエラーレスポンスがあった。
エラーメッセージもわかりやすく、そういう旨のことを示している。
{
"code": -1003,
"msg": "Too much request weight used; current limit is 1200 request weight per 1 MINUTE. Please use the websocket for live updates to avoid polling the API."
}
Response Headerにもレート使用状態が付加されている
x-mbx-used-weight
やx-mbx-used-weight-1m
ヘッダに付加されている。
先程の/api/v2/depth?limit=5000
を呼ぶと、
x-mbx-used-weight-1m
は、50。
もう一度呼ぶと、x-mbx-used-weight-1m
は、100に増える。
1分経てばサーバ側では0になるため、再度呼び出すと、50が設定されて帰ってくる。
機能開発時には、こちらのヘッダのused値を常に確認してからリクエストを送るべきだろう。
レート制限の対応方針
- レート制限下の有無の保持
- ping apiによる事前チェック
レート制限下の有無の保持
エラーが起きた際は、稼働しているアプリケーションコンテキストにエラー状態とエラー発生時刻を保持し、制限解除時刻を計算して保持して不要なAPI呼び出しを重ねないようにすべき。
binanceのAPIはレート制限下で呼べば呼ぶほど、制限解除時刻が伸びる。最長3日制限される。。
ping apiによる事前チェック
/api/v3/ping
を呼べば、ヘッダーで現在のレート制限状況が把握できる。
これを例えば、10sごとに呼び出してWeightを把握すればよい。毎回1Weight消費してしまうが。
POST系APIについて
signatureについて
signature以外の必須・任意パラメータを文字列化したもの(queryString or urlencodedString)にHMAC SHA256
変換を掛けたもの。
APIの説明欄に「HMAC SHA256
」が登場したらsignature付きリクエストは必須。
application/x-www-form-urlencoded
しか受け付けない?
application/json
は受け付けてくれなそうだった(自信なし)
エラー
罠メモ
-2014 BAD_API_KEY_FMT: API-key format invalid.
POST時に、API-key format invalid.
が返ることがあるが、bodyの送り方が間違っていても返却されるケースがある。要注意。
WebSocket
SPOT/MARGIN/etc...
基本構造
POSTでSubscribeするためのパラメータlistenKey
を払い出す。
WebSocketでlistenKey
をパスパラメータに利用して、Subscribeする。
何もしなければ、60分で切断。
keepAliveするなら、PINGエンドポイントへPUT。
UnSubscribeは、DELETEでlistenKey
を指定して削除。