-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbinance_api.py
124 lines (107 loc) · 7.64 KB
/
binance_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import ssl
import time
import json
import urllib
import hmac, hashlib
import requests
from urllib.parse import urlparse, urlencode
from urllib.request import Request, urlopen
class Binance():
methods = {
# public methods
'ping': {'url':'api/v1/ping', 'method': 'GET', 'private': False},
'time': {'url':'api/v1/time', 'method': 'GET', 'private': False},
'exchangeInfo': {'url':'api/v1/exchangeInfo', 'method': 'GET', 'private': False},
'depth': {'url': 'api/v1/depth', 'method': 'GET', 'private': False},
'trades': {'url': 'api/v1/trades', 'method': 'GET', 'private': False},
'historicalTrades': {'url': 'api/v1/historicalTrades', 'method': 'GET', 'private': False},
'aggTrades': {'url': 'api/v1/aggTrades', 'method': 'GET', 'private': False},
'klines': {'url': 'api/v1/klines', 'method': 'GET', 'private': False},
'ticker24hr': {'url': 'api/v1/ticker/24hr', 'method': 'GET', 'private': False},
'tickerPrice': {'url': 'api/v3/ticker/price', 'method': 'GET', 'private': False},
'tickerBookTicker': {'url': 'api/v3/ticker/bookTicker', 'method': 'GET', 'private': False},
# private methods
'createOrder': {'url': 'api/v3/order', 'method': 'POST', 'private': True},
'testOrder': {'url': 'api/v3/order/test', 'method': 'POST', 'private': True},
'orderInfo': {'url': 'api/v3/order', 'method': 'GET', 'private': True},
'cancelOrder': {'url': 'api/v3/order', 'method': 'DELETE', 'private': True},
'openOrders': {'url': 'api/v3/openOrders', 'method': 'GET', 'private': True},
'allOrders': {'url': 'api/v3/allOrders', 'method': 'GET', 'private': True},
'account': {'url': 'api/v3/account', 'method': 'GET', 'private': True},
'myTrades': {'url': 'api/v3/myTrades', 'method': 'GET', 'private': True},
# wapi
'depositAddress': {'url': 'wapi/v3/depositAddress.html', 'method':'GET', 'private':True},
'withdraw': {'url': 'wapi/v3/withdraw.html', 'method':'POST', 'private':True},
'depositHistory': {'url': 'wapi/v3/depositHistory.html', 'method':'GET', 'private':True},
'withdrawHistory': {'url': 'wapi/v3/withdrawHistory.html', 'method':'GET', 'private':True},
'assetDetail': {'url': 'wapi/v3/assetDetail.html', 'method':'GET', 'private':True},
'tradeFee': {'url': 'wapi/v3/tradeFee.html', 'method':'GET', 'private':True},
'accountStatus': {'url': 'wapi/v3/accountStatus.html', 'method':'GET', 'private':True},
'systemStatus': {'url': 'wapi/v3/systemStatus.html', 'method':'GET', 'private':True},
'assetDust': {'url': 'sapi/v1/asset/dust', 'method':'POST', 'private':True},
'dustLog': {'url': 'wapi/v3/userAssetDribbletLog.html', 'method':'GET', 'private':True},
'assetAssetDividend': {'url': 'sapi/v1/asset/assetDividend', 'method':'GET', 'private':True},
#sapi
'marginTransfer': {'url': 'sapi/v1/margin/transfer', 'method': 'POST', 'private':True},
'marginLoan': {'url': 'sapi/v1/margin/loan', 'method': 'POST', 'private': True},
'marginLoanGet': {'url': 'sapi/v1/margin/loan', 'method': 'GET', 'private': True},
'marginRepay': {'url': 'sapi/v1/margin/repay', 'method': 'POST', 'private': True},
'marginRepayGet': {'url': 'sapi/v1/margin/repay', 'method': 'GET', 'private': True},
'marginCreateOrder': {'url': 'sapi/v1/margin/order', 'method': 'POST', 'private':True},
'marginCancelOrder': {'url': 'sapi/v1/margin/order', 'method': 'DELETE', 'private':True},
'marginOrderInfo': {'url': 'sapi/v1/margin/order', 'method': 'GET', 'private':True},
'marginAccount': {'url': 'sapi/v1/margin/account', 'method': 'POST', 'private':True},
'marginOpenOrders': {'url': 'sapi/v1/margin/openOrders', 'method': 'GET', 'private':True},
'marginAllOrders': {'url': 'sapi/v1/margin/allOrders', 'method': 'GET', 'private':True},
'marginAsset': {'url': 'sapi/v1/margin/asset', 'method': 'POST', 'private':True},
'marginPair': {'url': 'sapi/v1/margin/pair', 'method': 'POST', 'private':True},
'marginPriceIndex': {'url': 'sapi/v1/margin/priceIndex', 'method': 'POST', 'private':True},
'marginMyTrades': {'url': 'sapi/v1/margin/myTrades', 'method': 'GET', 'private':True},
'marginMaxBorrowable': {'url': 'sapi/v1/margin/maxBorrowable', 'method': 'GET', 'private':True},
'marginmaxTransferable': {'url': 'sapi/v1/margin/maxTransferable', 'method': 'GET', 'private':True},
#futures
'futuresExchangeInfo': {'url': 'fapi/v1/exchangeInfo', 'method': 'GET', 'private': False, 'futures': True},
'futuresKlines': {'url': 'fapi/v1/klines', 'method': 'GET', 'private': False, 'futures': True},
'futuresCreateOrder': {'url': 'fapi/v1/order', 'method': 'POST', 'private': True, 'futures': True},
'futuresAccount': {'url': 'fapi/v1/account', 'method': 'POST', 'private': True, 'futures': True},
'futuresBalance': {'url': 'fapi/v1/balance', 'method': 'GET', 'private': True, 'futures': True},
'futuresSymbolPriceTicker': {'url': 'fapi/v1/ticker/price', 'method': 'GET', 'private': True, 'futures': True},
'futuresOrderInfo': {'url': 'fapi/v1/order', 'method': 'GET', 'private': True, 'futures': True},
'futuresCancelOrder': {'url': 'fapi/v1/order', 'method': 'DELETE', 'private': True, 'futures': True},
}
def __init__(self, API_KEY, API_SECRET):
self.API_KEY = API_KEY
self.API_SECRET = bytearray(API_SECRET, encoding='utf-8')
self.shift_seconds = 0
def __getattr__(self, name):
def wrapper(*args, **kwargs):
kwargs.update(command=name)
return self.call_api(**kwargs)
return wrapper
def set_shift_seconds(self, seconds):
self.shift_seconds = seconds
def call_api(self, **kwargs):
command = kwargs.pop('command')
base_url ='https://api.binance.com/'
if self.methods[command].get('futures'):
base_url = 'https://fapi.binance.com/'
api_url = base_url + self.methods[command]['url']
payload = kwargs
headers = {}
payload_str = urllib.parse.urlencode(payload)
if self.methods[command]['private']:
payload.update({'timestamp': int(time.time() + self.shift_seconds - 1) * 1000})
payload_str = urllib.parse.urlencode(payload).encode('utf-8')
sign = hmac.new(
key=self.API_SECRET,
msg=payload_str,
digestmod=hashlib.sha256
).hexdigest()
payload_str = payload_str.decode("utf-8") + "&signature="+str(sign)
headers = {"X-MBX-APIKEY": self.API_KEY, "Content-Type":"application/x-www-form-urlencoded"}
if self.methods[command]['method'] == 'GET' or self.methods[command]['url'].startswith('sapi'):
api_url += '?' + payload_str
response = requests.request(method=self.methods[command]['method'], url=api_url, data="" if self.methods[command]['method'] == 'GET' else payload_str, headers=headers)
if 'code' in response.text:
raise Exception(response.text)
return response.json()