11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

binance api メモ

Last updated at Posted at 2021-03-10

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

恐らくレート制限のリセット周期。

intervalMINUTEintervalNumが1ならば、1分間でリセットという計算。

  • /api/v3/depth?limit=5000は、weightが50である。
  • REQUEST_WEIGTHlimitは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-weightx-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を指定して削除。

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?