|
1
|
|
|
#! /usr/bin/env python |
|
2
|
|
|
"""API Wrapper for Bitcoin.de Trading API.""" |
|
3
|
|
|
|
|
4
|
|
|
import requests |
|
5
|
|
|
import time |
|
6
|
|
|
import json |
|
7
|
|
|
import hmac |
|
8
|
|
|
import hashlib |
|
9
|
|
|
import logging |
|
10
|
|
|
import codecs |
|
11
|
|
|
import decimal |
|
12
|
|
|
import inspect |
|
13
|
|
|
import urllib |
|
14
|
|
|
|
|
15
|
|
|
from urllib.parse import urlencode |
|
16
|
|
|
|
|
17
|
|
|
logging.basicConfig() |
|
18
|
|
|
log = logging.getLogger(__name__) |
|
19
|
|
|
requests_log = logging.getLogger("requests.packages.urllib3") |
|
20
|
|
|
requests_log.propagate = True |
|
21
|
|
|
|
|
22
|
|
|
__version__ = '4.0' |
|
23
|
|
|
|
|
24
|
|
|
class ParameterBuilder(object): |
|
25
|
|
|
'''To verify given parameters for API.''' |
|
26
|
|
|
def __init__(self, avail_params, given_params, uri): |
|
27
|
|
|
self.verify_keys_and_values(avail_params, given_params) |
|
28
|
|
|
self.params = given_params |
|
29
|
|
|
self.create_url(uri) |
|
30
|
|
|
|
|
31
|
|
|
def verify_keys_and_values(self, avail_params, given_params): |
|
32
|
|
|
for k, v in given_params.items(): |
|
33
|
|
|
if k not in avail_params: |
|
34
|
|
|
list_string = ', '.join(avail_params) |
|
35
|
|
|
raise KeyError("{} is not any of {}".format(k, list_string)) |
|
36
|
|
|
if k == 'trading_pair': |
|
37
|
|
|
self.error_on_invalid_value(v, self.TRADING_PAIRS) |
|
38
|
|
|
elif k == 'type': |
|
39
|
|
|
self.error_on_invalid_value(v, self.TRADE_TYPES) |
|
40
|
|
|
elif k == 'currency': |
|
41
|
|
|
self.error_on_invalid_value(v, self.CURRENCIES) |
|
42
|
|
|
elif k == 'seat_of_bank': |
|
43
|
|
|
self.error_on_invalid_value(v, self.BANK_SEATS) |
|
44
|
|
|
elif k in ['min_trust_level', 'trust_level']: |
|
45
|
|
|
self.error_on_invalid_value(v, self.TRUST_LEVELS) |
|
46
|
|
|
elif k == 'payment_option': |
|
47
|
|
|
self.error_on_invalid_value(v, self.PAYMENT_OPTIONS) |
|
48
|
|
|
elif k == 'state': |
|
49
|
|
|
caller = inspect.stack()[2][3] |
|
50
|
|
|
if caller in ["showMyOrders", "showMyOrderDetails"]: |
|
51
|
|
|
self.error_on_invalid_value(v, self.ORDER_STATES) |
|
52
|
|
|
elif caller in ["showMyTrades", "showMyTradesDetails"]: |
|
53
|
|
|
self.error_on_invalid_value(v, self.TRADE_STATES) |
|
54
|
|
|
|
|
55
|
|
|
def error_on_invalid_value(self, value, list): |
|
56
|
|
|
if value not in list: |
|
57
|
|
|
list_string = ', '.join(str(x) for x in list) |
|
58
|
|
|
raise ValueError("{} is not any of {}".format(value, list_string)) |
|
59
|
|
|
|
|
60
|
|
|
def create_url(self, uri): |
|
61
|
|
|
if self.params: |
|
62
|
|
|
self.encoded_string = urlencode(sorted(self.params.items())) |
|
63
|
|
|
self.url = uri + '?' + self.encoded_string |
|
64
|
|
|
else: |
|
65
|
|
|
self.encoded_string = '' |
|
66
|
|
|
self.url = uri |
|
67
|
|
|
|
|
68
|
|
|
|
|
69
|
|
|
TRADING_PAIRS = ['btceur', 'bcheur', 'etheur', 'btgeur', 'bsveur', 'ltceur', |
|
70
|
|
|
'iotabtc', 'dashbtc', 'gntbtc', 'ltcbtc'] |
|
71
|
|
|
ORDER_TYPES = ['buy', 'sell'] |
|
72
|
|
|
CURRENCIES = ['btc', 'bch', 'eth', 'btg', 'bsv', 'ltc', |
|
73
|
|
|
'iota', 'dash', 'gnt'] |
|
74
|
|
|
BANK_SEATS = ['AT', 'BE', 'BG', 'CH', 'CY', 'CZ', |
|
75
|
|
|
'DE', 'DK', 'EE', 'ES', 'FI', 'FR', |
|
76
|
|
|
'GB', 'GR', 'HR', 'HU', 'IE', 'IS', |
|
77
|
|
|
'IT', 'LI', 'LT', 'LU', 'LV', 'MT', |
|
78
|
|
|
'MQ', 'NL', 'NO', 'PL', 'PT', 'RO', |
|
79
|
|
|
'SE', 'SI', 'SK'] |
|
80
|
|
|
TRUST_LEVELS = ['bronze', 'silver', 'gold', 'platin'] |
|
81
|
|
|
TRADE_STATES = [-1, 0, 1] |
|
82
|
|
|
ORDER_STATES = [-2, -1, 0] |
|
83
|
|
|
PAYMENT_OPTIONS = [1, 2, 3] |
|
84
|
|
|
TRADE_TYPES = ['all', 'buy', 'sell', 'inpayment', |
|
85
|
|
|
'payout', 'affiliate', 'welcome_btc', |
|
86
|
|
|
'buy_yubikey', 'buy_goldshop', |
|
87
|
|
|
'buy_diamondshop', 'kickback', |
|
88
|
|
|
'outgoing_fee_voluntary'] |
|
89
|
|
|
|
|
90
|
|
|
def HandleRequestsException(e): |
|
91
|
|
|
"""Handle Exception from request.""" |
|
92
|
|
|
log.warning(e) |
|
93
|
|
|
|
|
94
|
|
|
|
|
95
|
|
|
def HandleAPIErrors(r): |
|
96
|
|
|
"""To handle Errors from BTCDE API.""" |
|
97
|
|
|
valid_status_codes = [200, 201, 204] |
|
98
|
|
|
if r.status_code not in valid_status_codes: |
|
99
|
|
|
content = r.json() |
|
100
|
|
|
errors = content.get('errors') |
|
101
|
|
|
log.warning('API Error Code: {}'.format(str(errors[0]['code']))) |
|
102
|
|
|
log.warning('API Error Message: {}'.format(errors[0]['message'])) |
|
103
|
|
|
log.warning('API Error URL: {}'.format(r.url)) |
|
104
|
|
|
return False |
|
105
|
|
|
else: |
|
106
|
|
|
return True |
|
107
|
|
|
|
|
108
|
|
|
class Connection(object): |
|
109
|
|
|
"""To provide connection credentials to the trading API""" |
|
110
|
|
|
def __init__(self, api_key, api_secret): |
|
111
|
|
|
self.api_key = api_key |
|
112
|
|
|
self.api_secret = api_secret |
|
113
|
|
|
# set initial self.nonce |
|
114
|
|
|
self.nonce = int(time.time() * 1000000) |
|
115
|
|
|
# Bitcoin.de API URI |
|
116
|
|
|
self.apihost = 'https://api.bitcoin.de' |
|
117
|
|
|
self.apiversion = 'v4' |
|
118
|
|
|
self.apibase = f'{self.apihost}/{self.apiversion}/' |
|
119
|
|
|
|
|
120
|
|
|
def build_hmac_sign(self, md5string, method, url): |
|
121
|
|
|
hmac_data = '#'.join([method, url, self.api_key, str(self.nonce), md5string]) |
|
122
|
|
|
hmac_signed = hmac.new(bytearray(self.api_secret.encode()), msg=hmac_data.encode(), digestmod=hashlib.sha256).hexdigest() |
|
123
|
|
|
return hmac_signed |
|
124
|
|
|
|
|
125
|
|
|
def set_header(self, url, method, encoded_string): |
|
126
|
|
|
# raise self.nonce before using |
|
127
|
|
|
self.nonce = int(time.time() * 1000000) |
|
128
|
|
|
if method == 'POST': |
|
129
|
|
|
md5_encoded_query_string = hashlib.md5(encoded_string.encode()).hexdigest() |
|
130
|
|
|
else: |
|
131
|
|
|
md5_encoded_query_string = hashlib.md5(b'').hexdigest() |
|
132
|
|
|
hmac_signed = self.build_hmac_sign(md5_encoded_query_string, |
|
133
|
|
|
method, url) |
|
134
|
|
|
# set header |
|
135
|
|
|
header = {'content-type': |
|
136
|
|
|
'application/x-www-form-urlencoded; charset=utf-8', |
|
137
|
|
|
'X-API-KEY': self.api_key, |
|
138
|
|
|
'X-API-NONCE': str(self.nonce), |
|
139
|
|
|
'X-API-SIGNATURE': hmac_signed } |
|
140
|
|
|
return header |
|
141
|
|
|
|
|
142
|
|
|
def send_request(self, url, method, header, encoded_string): |
|
143
|
|
|
if method == 'GET': |
|
144
|
|
|
r = requests.get(url, headers=(header), |
|
145
|
|
|
stream=True, verify=False) |
|
146
|
|
|
elif method == 'POST': |
|
147
|
|
|
r = requests.post(url, headers=(header), data=encoded_string, |
|
148
|
|
|
stream=True, verify=False) |
|
149
|
|
|
elif method == 'DELETE': |
|
150
|
|
|
r = requests.delete(url, headers=(header), |
|
151
|
|
|
stream=True, verify=False) |
|
152
|
|
|
return r |
|
|
|
|
|
|
153
|
|
|
|
|
154
|
|
|
def APIConnect(self, method, params): |
|
155
|
|
|
"""Transform Parameters to URL""" |
|
156
|
|
|
header = self.set_header(params.url, method, |
|
157
|
|
|
params.encoded_string) |
|
158
|
|
|
log.debug('Set Header: {}'.format(header)) |
|
159
|
|
|
try: |
|
160
|
|
|
r = self.send_request(params.url, method, header, |
|
161
|
|
|
params.encoded_string) |
|
162
|
|
|
# Handle API Errors |
|
163
|
|
|
if HandleAPIErrors(r): |
|
164
|
|
|
# get results |
|
165
|
|
|
result = r.json(parse_float=decimal.Decimal) |
|
166
|
|
|
else: |
|
167
|
|
|
result = {} |
|
168
|
|
|
except requests.exceptions.RequestException as e: |
|
169
|
|
|
HandleRequestsException(e) |
|
170
|
|
|
result = {} |
|
171
|
|
|
return result |
|
172
|
|
|
|
|
173
|
|
|
def addToAddressPool(self, currency, address, **args): |
|
174
|
|
|
"""Add address to pool""" |
|
175
|
|
|
uri = f'{self.apibase}{currency}/address' |
|
176
|
|
|
params = {'address': address} |
|
177
|
|
|
params.update(args) |
|
178
|
|
|
avail_params = ['address', 'amount_usages', 'comment'] |
|
179
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
180
|
|
|
return self.APIConnect('POST', p) |
|
181
|
|
|
|
|
182
|
|
|
def removeFromAddressPool(self, currency, address): |
|
183
|
|
|
"""Remove address from pool""" |
|
184
|
|
|
uri = f'{self.apibase}{currency}/address/{address}' |
|
185
|
|
|
params = {'currency': currency, 'address': address} |
|
186
|
|
|
avail_params = ['currency', 'address'] |
|
187
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
188
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
189
|
|
|
return self.APIConnect('DELETE', p) |
|
190
|
|
|
|
|
191
|
|
|
def listAddressPool(self, currency, **args): |
|
192
|
|
|
"""List address pool""" |
|
193
|
|
|
uri = f'{self.apibase}{currency}/address' |
|
194
|
|
|
params = args |
|
195
|
|
|
avail_params = ['usable', 'comment', 'page'] |
|
196
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
197
|
|
|
return self.APIConnect('GET', p) |
|
198
|
|
|
|
|
199
|
|
|
def showOrderbook(self, order_type, trading_pair, **args): |
|
200
|
|
|
"""Search Orderbook for offers.""" |
|
201
|
|
|
uri = f'{self.apibase}{trading_pair}/orderbook' |
|
202
|
|
|
params = {'type': order_type} |
|
203
|
|
|
params.update(args) |
|
204
|
|
|
avail_params = ['type', 'trading_pair', 'amount_currency_to_trade', 'price', |
|
205
|
|
|
'order_requirements_fullfilled', |
|
206
|
|
|
'only_kyc_full', 'only_express_orders', 'payment_option', |
|
207
|
|
|
'sepa_option', 'only_same_bankgroup', 'only_same_bic', |
|
208
|
|
|
'seat_of_bank', 'page_size'] |
|
209
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
210
|
|
|
return self.APIConnect('GET', p) |
|
211
|
|
|
|
|
212
|
|
|
def showOrderDetails(self, trading_pair, order_id): |
|
213
|
|
|
"""Show details for an offer.""" |
|
214
|
|
|
uri = f'{self.apibase}{trading_pair}/orders/public/details/{order_id}' |
|
215
|
|
|
params = {'trading_pair': trading_pair, 'order_id': order_id} |
|
216
|
|
|
avail_params = ['trading_pair', 'order_id'] |
|
217
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
218
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
219
|
|
|
return self.APIConnect('GET', p) |
|
220
|
|
|
|
|
221
|
|
|
def createOrder(self, order_type, trading_pair, max_amount_currency_to_trade, price, **args): |
|
222
|
|
|
"""Create a new Order.""" |
|
223
|
|
|
uri = f'{self.apibase}{trading_pair}/orders' |
|
224
|
|
|
# Build parameters |
|
225
|
|
|
params = {'type': order_type, |
|
226
|
|
|
'max_amount_currency_to_trade': max_amount_currency_to_trade, |
|
227
|
|
|
'price': price} |
|
228
|
|
|
params.update(args) |
|
229
|
|
|
avail_params = ['type', 'max_amount_currency_to_trade', 'price', |
|
230
|
|
|
'min_amount_currency_to_trade', 'end_datetime', |
|
231
|
|
|
'new_order_for_remaining_amount', 'trading_pair', |
|
232
|
|
|
'min_trust_level', 'only_kyc_full', 'payment_option', |
|
233
|
|
|
'sepa_option', 'seat_of_bank'] |
|
234
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
235
|
|
|
p.verify_keys_and_values(avail_params, {'trading_pair': trading_pair}) |
|
236
|
|
|
return self.APIConnect('POST', p) |
|
237
|
|
|
|
|
238
|
|
|
def deleteOrder(self, order_id, trading_pair): |
|
239
|
|
|
"""Delete an Order.""" |
|
240
|
|
|
# Build parameters |
|
241
|
|
|
uri = f'{self.apibase}{trading_pair}/orders/{order_id}' |
|
242
|
|
|
avail_params = ['order_id', 'trading_pair'] |
|
243
|
|
|
params = { 'order_id': order_id, 'trading_pair': trading_pair} |
|
244
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
245
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
246
|
|
|
return self.APIConnect('DELETE', p) |
|
247
|
|
|
|
|
248
|
|
|
def showMyOrders(self, **args): |
|
249
|
|
|
"""Query and Filter own Orders.""" |
|
250
|
|
|
# Build parameters |
|
251
|
|
|
params = args |
|
252
|
|
|
avail_params = ['type', 'trading_pair', 'state', |
|
253
|
|
|
'date_start', 'date_end', 'page'] |
|
254
|
|
|
if params.get("trading_pair"): |
|
255
|
|
|
uri = f'{self.apibase}{params["trading_pair"]}/orders' |
|
256
|
|
|
del params["trading_pair"] |
|
257
|
|
|
else: |
|
258
|
|
|
uri = f'{self.apibase}orders' |
|
259
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
260
|
|
|
return self.APIConnect('GET', p) |
|
261
|
|
|
|
|
262
|
|
|
def showMyOrderDetails(self, trading_pair, order_id): |
|
263
|
|
|
"""Details to an own Order.""" |
|
264
|
|
|
uri = f'{self.apibase}{trading_pair}/orders/{order_id}' |
|
265
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
266
|
|
|
return self.APIConnect('GET', p) |
|
267
|
|
|
|
|
268
|
|
|
def executeTrade(self, trading_pair, order_id, order_type, amount): |
|
269
|
|
|
"""Buy/Sell on a specific Order.""" |
|
270
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{order_id}' |
|
271
|
|
|
params = { 'type': order_type, |
|
272
|
|
|
'amount_currency_to_trade': amount} |
|
273
|
|
|
avail_params = ['type', 'amount_currency_to_trade'] |
|
274
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
275
|
|
|
return self.APIConnect('POST', p) |
|
276
|
|
|
|
|
277
|
|
|
def showMyTrades(self, **args): |
|
278
|
|
|
"""Query and Filter on past Trades.""" |
|
279
|
|
|
# Build parameters |
|
280
|
|
|
params = args |
|
281
|
|
|
avail_params = ['type', 'trading_pair', 'state', |
|
282
|
|
|
'only_trades_with_action_for_payment_or_transfer_required', |
|
283
|
|
|
'payment_method', 'date_start', 'date_end', 'page'] |
|
284
|
|
|
if params.get("trading_pair"): |
|
285
|
|
|
uri = f'{self.apibase}{params["trading_pair"]}/trades' |
|
286
|
|
|
del params["trading_pair"] |
|
287
|
|
|
else: |
|
288
|
|
|
uri = f'{self.apibase}trades' |
|
289
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
290
|
|
|
return self.APIConnect('GET', p) |
|
291
|
|
|
|
|
292
|
|
|
def showMyTradeDetails(self, trading_pair, trade_id): |
|
293
|
|
|
"""Details to a specific Trade.""" |
|
294
|
|
|
params = {'trading_pair': trading_pair, 'trade_id': trade_id} |
|
295
|
|
|
avail_params = [ 'trading_pair', 'trade_id' ] |
|
296
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}' |
|
297
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
298
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
299
|
|
|
return self.APIConnect('GET', p) |
|
300
|
|
|
|
|
301
|
|
|
def markCoinsAsTransferred(self, trading_pair, trade_id, amount_currency_to_trade_after_fee): |
|
302
|
|
|
"""Mark trade as transferred.""" |
|
303
|
|
|
params = {'amount_currency_to_trade_after_fee': amount_currency_to_trade_after_fee, |
|
304
|
|
|
'trading_pair': trading_pair, 'trade_id': trade_id} |
|
305
|
|
|
|
|
306
|
|
|
avail_params = [ 'trading_pair', 'trade_id', 'amount_currency_to_trade_after_fee' ] |
|
307
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}/mark_coins_as_transferred' |
|
308
|
|
|
p = ParameterBuilder(avail_params, |
|
309
|
|
|
{'amount_currency_to_trade_after_fee': amount_currency_to_trade_after_fee}, uri) |
|
310
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
311
|
|
|
return self.APIConnect('POST', p) |
|
312
|
|
|
|
|
313
|
|
|
def markTradeAsPaid(self, trading_pair, trade_id, volume_currency_to_pay_after_fee): |
|
314
|
|
|
"""Mark traded as paid.""" |
|
315
|
|
|
params = {'volume_currency_to_pay_after_fee': volume_currency_to_pay_after_fee, |
|
316
|
|
|
'trading_pair': trading_pair, 'trade_id': trade_id} |
|
317
|
|
|
|
|
318
|
|
|
avail_params = [ 'trading_pair', 'trade_id', 'volume_currency_to_pay_after_fee' ] |
|
319
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}/mark_trade_as_paid' |
|
320
|
|
|
p = ParameterBuilder(avail_params, |
|
321
|
|
|
{'volume_currency_to_pay_after_fee': volume_currency_to_pay_after_fee}, uri) |
|
322
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
323
|
|
|
return self.APIConnect('POST', p) |
|
324
|
|
|
|
|
325
|
|
|
def markCoinsAsReceived(self, trading_pair, trade_id, amount_currency_to_trade_after_fee, rating): |
|
326
|
|
|
"""Mark coins as received.""" |
|
327
|
|
|
params = {'amount_currency_to_trade_after_fee': amount_currency_to_trade_after_fee, |
|
328
|
|
|
'trading_pair': trading_pair, 'trade_id': trade_id, 'rating': rating} |
|
329
|
|
|
params_post = {'amount_currency_to_trade_after_fee': amount_currency_to_trade_after_fee, |
|
330
|
|
|
'rating': rating} |
|
331
|
|
|
avail_params = [ 'trading_pair', 'trade_id', 'amount_currency_to_trade_after_fee', 'rating' ] |
|
332
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}/mark_coins_as_received' |
|
333
|
|
|
p = ParameterBuilder(avail_params, params_post, uri) |
|
334
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
335
|
|
|
return self.APIConnect('POST', p) |
|
336
|
|
|
|
|
337
|
|
|
def markTradeAsPaymentReceived(self, trading_pair, trade_id, |
|
338
|
|
|
volume_currency_to_pay_after_fee, rating, |
|
339
|
|
|
is_paid_from_correct_bank_account): |
|
340
|
|
|
"""Mark coins as received.""" |
|
341
|
|
|
params = {'volume_currency_to_pay_after_fee': volume_currency_to_pay_after_fee, |
|
342
|
|
|
'trading_pair': trading_pair, 'trade_id': trade_id, 'rating': rating} |
|
343
|
|
|
params_post = {'volume_currency_to_pay_after_fee': volume_currency_to_pay_after_fee, |
|
344
|
|
|
'rating': rating, |
|
345
|
|
|
'is_paid_from_correct_bank_account': is_paid_from_correct_bank_account} |
|
346
|
|
|
avail_params = [ 'trading_pair', 'trade_id', 'volume_currency_to_pay_after_fee', |
|
347
|
|
|
'rating', 'is_paid_from_correct_bank_account' ] |
|
348
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}/mark_trade_as_payment_received' |
|
349
|
|
|
p = ParameterBuilder(avail_params, params_post, uri) |
|
350
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
351
|
|
|
return self.APIConnect('POST', p) |
|
352
|
|
|
|
|
353
|
|
|
def addTradeRating(self, trading_pair, trade_id, rating): |
|
354
|
|
|
"""Mark coins as received.""" |
|
355
|
|
|
params = {'trading_pair': trading_pair, 'trade_id': trade_id, 'rating': rating} |
|
356
|
|
|
params_post = {'rating': rating} |
|
357
|
|
|
avail_params = [ 'trading_pair', 'trade_id', 'rating' ] |
|
358
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/{trade_id}/add_trade_rating' |
|
359
|
|
|
p = ParameterBuilder(avail_params, params_post, uri) |
|
360
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
361
|
|
|
return self.APIConnect('POST', p) |
|
362
|
|
|
|
|
363
|
|
|
def showAccountInfo(self): |
|
364
|
|
|
"""Query on Account Infos.""" |
|
365
|
|
|
uri = f'{self.apibase}account' |
|
366
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
367
|
|
|
return self.APIConnect('GET', p) |
|
368
|
|
|
|
|
369
|
|
|
def showOrderbookCompact(self, trading_pair): |
|
370
|
|
|
"""Bids and Asks in compact format.""" |
|
371
|
|
|
params = {'trading_pair': trading_pair} |
|
372
|
|
|
avail_params = ['trading_pair'] |
|
373
|
|
|
uri = f'{self.apibase}{trading_pair}/orderbook/compact' |
|
374
|
|
|
# Build parameters |
|
375
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
376
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
377
|
|
|
return self.APIConnect('GET', p) |
|
378
|
|
|
|
|
379
|
|
|
def showPublicTradeHistory(self, trading_pair, **args): |
|
380
|
|
|
"""All successful trades of the last 24 hours.""" |
|
381
|
|
|
params = { 'trading_pair': trading_pair } |
|
382
|
|
|
params.update(args) |
|
383
|
|
|
avail_params = ['trading_pair', 'since_tid'] |
|
384
|
|
|
uri = f'{self.apibase}{trading_pair}/trades/history' |
|
385
|
|
|
if params.get('since_tid'): |
|
386
|
|
|
del params["trading_pair"] |
|
387
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
388
|
|
|
else: |
|
389
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
390
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
391
|
|
|
return self.APIConnect('GET', p) |
|
392
|
|
|
|
|
393
|
|
|
def showRates(self, trading_pair): |
|
394
|
|
|
"""Query of the average rate last 3 and 12 hours.""" |
|
395
|
|
|
uri = f'{self.apibase}{trading_pair}/rates' |
|
396
|
|
|
params = {'trading_pair': trading_pair} |
|
397
|
|
|
avail_params = ['trading_pair'] |
|
398
|
|
|
# Build parameters |
|
399
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
400
|
|
|
p.verify_keys_and_values(avail_params, params) |
|
401
|
|
|
return self.APIConnect('GET', p) |
|
402
|
|
|
|
|
403
|
|
|
def showAccountLedger(self, currency, **args): |
|
404
|
|
|
"""Query on Account statement.""" |
|
405
|
|
|
params = {'currency': currency} |
|
406
|
|
|
params.update(args) |
|
407
|
|
|
uri = f'{self.apibase}{currency}/account/ledger' |
|
408
|
|
|
avail_params = ['currency', 'type', |
|
409
|
|
|
'datetime_start', 'datetime_end', 'page'] |
|
410
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
411
|
|
|
del params['currency'] |
|
412
|
|
|
p = ParameterBuilder(avail_params, params, uri) |
|
413
|
|
|
return self.APIConnect('GET', p) |
|
414
|
|
|
|
|
415
|
|
|
def showPermissions(self): |
|
416
|
|
|
"""Show permissions that are allowed for used API key""" |
|
417
|
|
|
uri = f'{self.apibase}permissions' |
|
418
|
|
|
p = ParameterBuilder({}, {}, uri) |
|
419
|
|
|
return self.APIConnect('GET', p) |