Python Connect to Binance API using requests

July 2, 2019

I am using requests library to call Binance REST API. If you prefer an API library, you could try python-binance (I didn’t use this).

Binance REST API

  • There are 3 types of security endpoint:
    • NONE: can be accessed freely
    • USER_STREAM and MARKET_DATA: need API Key
    • TRADE and USER_DATA: need API Key and signature

How to get Binance API Key and Secret Key

Binance Dashboard -> Settings -> API Management: https://www.binance.com/en/usercenter/settings/api-management

Create an API Key with label (a name for you to identify the key’s usage and purpose): API Key and Secret Key is generated.

NOTE: Copy down the Secret Key immediately as you cannot retrieve the Secret Key again at later stage, unless you create another new key.

You could apply API restrictions: Read only, Enable Trading, Enable Withdrawals.

You could restrict the API from certain IPs only.

import time
import json
import hmac
import hashlib
import requests
from urllib.parse import urljoin, urlencode

API_KEY = 'UIGu...'
SECRET_KEY = 'VyX...'
BASE_URL = 'https://api.binance.com'

headers = {
    'X-MBX-APIKEY': API_KEY
}
class BinanceException(Exception):
    def __init__(self, status_code, data):

        self.status_code = status_code
        if data:
            self.code = data['code']
            self.msg = data['msg']
        else:
            self.code = None
            self.msg = None
        message = f"{status_code} [{self.code}] {self.msg}"

        # Python 2.x
        # super(BinanceException, self).__init__(message)
        super().__init__(message)

Server Time

PATH =  '/api/v1/time'
params = None

timestamp = int(time.time() * 1000)

url = urljoin(BASE_URL, PATH)
r = requests.get(url, params=params)
if r.status_code == 200:
    # print(json.dumps(r.json(), indent=2))
    data = r.json()
    print(f"diff={timestamp - data['serverTime']}ms")
else:
    raise BinanceException(status_code=r.status_code, data=r.json())

Get Price

PATH = '/api/v3/ticker/price'
params = {
    'symbol': 'BTCUSDT'
}

url = urljoin(BASE_URL, PATH)
r = requests.get(url, headers=headers, params=params)
if r.status_code == 200:
    print(json.dumps(r.json(), indent=2))
else:
    raise BinanceException(status_code=r.status_code, data=r.json())

Output

{
  "symbol": "BTCUSDT",
  "price": "10261.03000000"
}

Get Order Book

PATH = '/api/v1/depth'
params = {
    'symbol': 'BTCUSDT',
    'limit': 5
}

url = urljoin(BASE_URL, PATH)
r = requests.get(url, headers=headers, params=params)
if r.status_code == 200:
    print(json.dumps(r.json(), indent=2))
else:
    raise BinanceException(status_code=r.status_code, data=r.json())

Output

{
  "lastUpdateId": 784184836,
  "bids": [
    [
      "10229.67000000",
      "0.01954500"
    ],
    [
      "10229.58000000",
      "6.90000000"
    ],
    [
      "10229.56000000",
      "0.33099600"
    ],
    [
      "10228.54000000",
      "0.02600900"
    ],
    [
      "10227.71000000",
      "0.50000000"
    ]
  ],
  "asks": [
    [
      "10232.59000000",
      "0.01703200"
    ],
    [
      "10232.60000000",
      "3.05388400"
    ],
    [
      "10232.63000000",
      "0.25000000"
    ],
    [
      "10235.07000000",
      "0.15200000"
    ],
    [
      "10236.35000000",
      "0.25000000"
    ]
  ]
}

Create Order

PATH = '/api/v3/order'
timestamp = int(time.time() * 1000)
params = {
    'symbol': 'ETHUSDT',
    'side': 'SELL',
    'type': 'LIMIT',
    'timeInForce': 'GTC',
    'quantity': 0.1,
    'price': 500.0,
    'recvWindow': 5000,
    'timestamp': timestamp
}

query_string = urlencode(params)
params['signature'] = hmac.new(SECRET_KEY.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

url = urljoin(BASE_URL, PATH)
r = requests.post(url, headers=headers, params=params)
if r.status_code == 200:
    data = r.json()
    print(json.dumps(data, indent=2))
else:
    raise BinanceException(status_code=r.status_code, data=r.json())
{
  "symbol": "ETHUSDT",
  "orderId": 336683281,
  "clientOrderId": "IVGyfNu88LhRnpZFa56JA4",
  "transactTime": 1562252912748,
  "price": "500.00000000",
  "origQty": "0.10000000",
  "executedQty": "0.00000000",
  "cummulativeQuoteQty": "0.00000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "fills": [
    {
      "price": "500.00000000",
      "qty": "0.050000000",
      "commission": "1.00000000",
      "commissionAsset": "USDT"
    },
    {
      "price": "500.00000000",
      "qty": "0.03000000",
      "commission": "0.50000000",
      "commissionAsset": "USDT"
    },
  ]
}

Get Order

PATH = '/api/v3/order'
timestamp = int(time.time() * 1000)
params = {
    'symbol': 'ETHUSDT',
    'orderId': '336683281',
    'recvWindow': 5000,
    'timestamp': timestamp
}

query_string = urlencode(params)
params['signature'] = hmac.new(SECRET_KEY.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

url = urljoin(BASE_URL, PATH)
r = requests.get(url, headers=headers, params=params)
if r.status_code == 200:
    data = r.json()
    print(json.dumps(data, indent=2))
else:
    raise BinanceException(status_code=r.status_code, data=r.json())
{
  "symbol": "ETHUSDT",
  "orderId": 336683281,
  "clientOrderId": "IVGyfNu88LhRnpZFa56JA4",
  "price": "500.00000000",
  "origQty": "0.10000000",
  "executedQty": "0.00000000",
  "cummulativeQuoteQty": "0.00000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "stopPrice": "0.00000000",
  "icebergQty": "0.00000000",
  "time": 1562252912748,
  "updateTime": 1562252912748,
  "isWorking": true
}

Delete Order

PATH = '/api/v3/order'
timestamp = int(time.time() * 1000)
params = {
    'symbol': 'ETHUSDT',
    'orderId': '336683281',
    'recvWindow': 5000,
    'timestamp': timestamp
}

query_string = urlencode(params)
params['signature'] = hmac.new(SECRET_KEY.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

url = urljoin(BASE_URL, PATH)
r = requests.delete(url, headers=headers, params=params)
if r.status_code == 200:
    data = r.json()
    print(json.dumps(data, indent=2))
else:
    raise BinanceException(status_code=r.status_code, data=r.json())
{
  "symbol": "ETHUSDT",
  "origClientOrderId": "IVGyfNu88LhRnpZFa56JA4",
  "orderId": 336683281,
  "clientOrderId": "2Fh1EdAmHU8ZUR0TwjrQAR",
  "price": "500.00000000",
  "origQty": "0.10000000",
  "executedQty": "0.00000000",
  "cummulativeQuoteQty": "0.00000000",
  "status": "CANCELED",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL"
}

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.