-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBroker.py
More file actions
174 lines (150 loc) · 6.32 KB
/
Broker.py
File metadata and controls
174 lines (150 loc) · 6.32 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# This Broker is supposed to connect to the Binance RUST API and get current market information
# All Binance requests return either a JSON object or an array
# The Binance API Docs are available here: https://binance-docs.github.io/apidocs
import requests
import time
import hmac
import hashlib
import urllib
import json
import numpy as np
class Broker:
# Initialisation - NOTE: please adjust API-Key and SecretKey
def __init__(self):
self.url = "https://api.binance.com/"
self.endpoint = self.url + "api/v3/"
self.userendpoint = self.url + "wapi/v3/"
self.apikey = ""
self.secretkey = ""
self.symbols = {}
self.get_symbols()
# Ping server to test connectivity.
# Returns True if successful, False if unsuccessful
def ping(self):
try:
test = requests.get(self.endpoint + "ping")
return True if test.text == "{}" else False
except:
return False
# Get latest price for symbol, if empty symbol, returns prices for all symbols
# Argument: Ticker symbol (str) (optional)
# Returns (True, price(s)) or (False, error_message)
def get_price(self, symbol=""):
response = 0
if symbol == "":
response = requests.get(self.endpoint + "ticker/price")
else:
response = requests.get(self.endpoint + "ticker/price?symbol=" + symbol)
if response.status_code == 200:
return (True, response.json())
elif response.status_code == 400:
return (False, response.json()["msg"])
else:
return (False, response.text)
# Get best price for symbol, if empty symbol, returns prices for all symbols
# Argument: Ticker symbol (str) (optional)
# Returns (True, price(s)) or (False, error_message)
def get_raw_best_price(self, symbol=""):
response = 0
if symbol == "":
response = requests.get(self.endpoint + "ticker/bookTicker")
else:
response = requests.get(self.endpoint + "ticker/bookTicker?symbol=" + symbol)
if response.status_code == 200:
return (True, response.json())
elif response.status_code == 400:
return (False, response.json()["msg"])
else:
return (False, response.text)
# Get best prices in dictionary form
# Returns dictionary of form price[owned_currency][new_currency]
# Dictionary entry contains direction, symbol, price and quantity
def get_best_prices(self):
api_start_time = time.time()*1000
raw_best_price = self.get_raw_best_price()[1]
api_end_time = time.time()*1000
print(f"\tAPI Time: {api_end_time - api_start_time:.2f} ms")
parsing_start_time = time.time()*1000
price = {}
for ticker in raw_best_price:
symbol = ticker["symbol"]
try:
symbol_a, symbol_b = self.symbols[symbol]
except KeyError:
continue
buy = ["buy", symbol, float(ticker["bidPrice"]), float(ticker["bidQty"])]
sell = ["sell", symbol, float(ticker["askPrice"]), float(ticker["askQty"])]
if buy[2] != 0:
try:
price[symbol_b][symbol_a] = buy
except KeyError:
price[symbol_b] = {}
price[symbol_b][symbol_a] = buy
if sell[2] != 0:
try:
price[symbol_a][symbol_b] = sell
except KeyError:
price[symbol_a] = {}
price[symbol_a][symbol_b] = sell
parsing_end_time = time.time()*1000
print(f"\tParsing Time: {parsing_end_time - parsing_start_time:.2f} ms")
return price
# Get current average price for symbol
# Argument: Ticker symbol (str)
# Returns (True, price) or (False, error_message)
def get_avg_price(self, symbol):
response = requests.get(self.endpoint + "avgPrice?symbol=" + symbol)
if response.status_code == 200:
return (True, response.json()["price"])
elif response.status_code == 400:
return (False, response.json()["msg"])
else:
return (False, response.text)
# Get orderbook information for symbol
# Arguments: Ticker symbol (str), max number of orders (int) (optional)
# Returns (True, bids, asks) or (False, error_message)
def orderbook(self, symbol, limit=500):
response = requests.get(self.endpoint + "depth?symbol=" + symbol + "&limit=" + str(limit))
info = response.json()
if response.status_code == 200:
return (True, info["bids"], info["asks"])
elif response.status_code == 400:
return (False, info["msg"])
else:
return (False, response.text)
# Get Exchange information
# Returns either (True, information (json)) or (False)
def exchange_info(self):
response = requests.get(self.endpoint + "exchangeInfo")
if response.status_code == 200:
return (True, response.json())
else:
return (False)
# Get fee information
# Returns either (True, fees (maker/taker, percent, dict)) or (False)
def get_fees(self):
params = urllib.parse.urlencode({
"signature" : hmac.new(self.secretkey.encode('utf-8'), "".encode("utf-8"), hashlib.sha256).hexdigest(),
"timestamp" : int(time.time() * 1000)})
response = requests.get(self.userendpoint + "tradeFee.html",
params = params,
headers = {
"X-MBX-APIKEY" : self.apikey,
})
if response.status_code == 200:
fees = {}
for symbol in response.json()["tradeFee"]:
fees[symbol["symbol"]] = [symbol["maker"], symbol["taker"]]
return (True, fees)
else:
return (False)
# Get all available symbols, excluding discontinued "NGN"s
def get_symbols(self):
response = requests.get(self.endpoint + "exchangeInfo")
info = response.json()
for entry in info["symbols"]:
symbol = entry["symbol"]
symbol_a = entry["baseAsset"]
symbol_b = entry["quoteAsset"]
if not (symbol_b == "NGN" and not (symbol_a == "BTC" or symbol_a == "USDT")):
self.symbols[symbol] = [symbol_a, symbol_b]