Skip to content

Commit

Permalink
Support limited unofficial and public API v2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hanhha committed Dec 31, 2017
1 parent 60a457c commit 4ee3490
Showing 1 changed file with 148 additions and 126 deletions.
274 changes: 148 additions & 126 deletions bittrex.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,146 +7,168 @@
import hashlib

API_V1_1 = 'v1.1'
API_V2_0 = 'v2.0'

BASE_URL = 'https://bittrex.com/api/{version}/{method}?{paramvalue}'

class Bittrex (object):
def __init__ (self, api_ver):
self._api_ver = api_ver
self._ReqUrlDict = dict ()
@retry(stop_max_attempt_number=3)
def get_json (self, url, sign = None):
raw_dict = requests.get (url).json() if sign is None else requests.get(url, headers = {'apisign': sign}).json()
if raw_dict ['success'] is True:
return True, raw_dict['result']
else:
return False, raw_dict['message']
@staticmethod
def get_nonce ():
return str(int(time() * 1000))
@staticmethod
def hmac_sign (msg_str, secret_bytes):
return hmac.new (secret_bytes, msg_str.encode('utf-8'), hashlib.sha512).hexdigest()
def __init__ (self, api_ver):
self._api_ver = api_ver
self._ReqUrlDict = dict ()
@retry(stop_max_attempt_number=3)
def get_json (self, url, sign = None):
raw_dict = requests.get (url).json() if sign is None else requests.get(url, headers = {'apisign': sign}).json()
if raw_dict ['success'] is True:
return True, raw_dict['result']
else:
return False, raw_dict['message']
@staticmethod
def get_nonce ():
return str(int(time() * 1000))
@staticmethod
def hmac_sign (msg_str, secret_bytes):
return hmac.new (secret_bytes, msg_str.encode('utf-8'), hashlib.sha512).hexdigest()

class PublicAPI (Bittrex):
def __init__ (self, api_ver):
Bittrex.__init__ (self, api_ver)
self._ReqUrlDict = {'GET_MARKETS' : BASE_URL.format (version = self._api_ver, method = 'public/getmarkets', paramvalue = '') [:-1],
'GET_CURRENCIES' : BASE_URL.format (version = self._api_ver, method = 'public/getcurrencies', paramvalue = '') [:-1],
'GET_TICKER' : BASE_URL.format (version = self._api_ver, method = 'public/getticker', paramvalue = 'market={mar}'),
'GET_24HSUMALL' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummaries', paramvalue = '') [:-1],
'GET_24HSUM' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummary', paramvalue = 'market={mar}'),
'GET_ORDERBOOK' : BASE_URL.format (version = self._api_ver, method = 'public/getorderbook', paramvalue = 'market={mar}&type={typ}'),
'GET_HISTORY' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummary', paramvalue = 'market={mar}'),
}
def __init__ (self, api_ver):
Bittrex.__init__ (self, api_ver)
if api_ver == API_V1_1:
self._ReqUrlDict = {'GET_MARKETS' : BASE_URL.format (version = self._api_ver, method = 'public/getmarkets', paramvalue = '') [:-1],
'GET_CURRENCIES' : BASE_URL.format (version = self._api_ver, method = 'public/getcurrencies', paramvalue = '') [:-1],
'GET_TICKER' : BASE_URL.format (version = self._api_ver, method = 'public/getticker', paramvalue = 'market={mar}'),
'GET_24HSUMALL' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummaries', paramvalue = '') [:-1],
'GET_24HSUM' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummary', paramvalue = 'market={mar}'),
'GET_ORDERBOOK' : BASE_URL.format (version = self._api_ver, method = 'public/getorderbook', paramvalue = 'market={mar}&type={typ}'),
'GET_HISTORY' : BASE_URL.format (version = self._api_ver, method = 'public/getmarketsummary', paramvalue = 'market={mar}'),
}
elif api_ver == API_V2_0:
self._ReqUrlDict = {'GET_BTC_PRICE': BASE_URL.format (version = self._api_ver, method = 'pub/currencies/GetBTCPrice', paramvalue = '')[:-1],
'GET_TICKS': BASE_URL.format (version = self._api_ver, method = 'pub/market/GetTicks', paramvalue = 'marketName={mar}&tickInterval={itv}'),
'GET_LATESTTICK': BASE_URL.format (version = self._api_ver, method = 'pub/market/GetLatestTick', paramvalue = 'marketName={mar}&tickInterval={itv}'),
}

def get_markets (self):
reqUrl = self._ReqUrlDict['GET_MARKETS']
return self.get_json (reqUrl)
# These functions are dedicated for API_V1_1
def get_markets (self):
reqUrl = self._ReqUrlDict['GET_MARKETS']
return self.get_json (reqUrl)

def get_currencies (self):
reqUrl = self._ReqUrlDict['GET_CURRENCIES']
return self.get_json (reqUrl)
def get_currencies (self):
reqUrl = self._ReqUrlDict['GET_CURRENCIES']
return self.get_json (reqUrl)

def get_ticker (self, market):
reqUrl = self._ReqUrlDict['GET_TICKER'].format (mar = market)
return self.get_json (reqUrl)
def get_ticker (self, market):
reqUrl = self._ReqUrlDict['GET_TICKER'].format (mar = market)
return self.get_json (reqUrl)

def get_24h_sum (self, market = ''):
reqUrl = self._ReqUrlDict['GET_24HSUMALL'] if market is '' else self._ReqUrlDict['GET_24HSUM'].format (mar = market)
return self.get_json (reqUrl)
def get_24h_sum (self, market = ''):
reqUrl = self._ReqUrlDict['GET_24HSUMALL'] if market is '' else self._ReqUrlDict['GET_24HSUM'].format (mar = market)
return self.get_json (reqUrl)

def get_order_book (self, market):
reqUrl = self._ReqUrlDict['GET_ORDERBOOK'].format (mar = market, typ = 'both')
return self.get_json (reqUrl)
def get_order_book (self, market):
reqUrl = self._ReqUrlDict['GET_ORDERBOOK'].format (mar = market, typ = 'both')
return self.get_json (reqUrl)

def get_history (self, market):
reqUrl = self._ReqUrlDict['GET_HISTORY'].format (mar = market)
return self.get_json (reqUrl)
def get_history (self, market):
reqUrl = self._ReqUrlDict['GET_HISTORY'].format (mar = market)
return self.get_json (reqUrl)

# These functions are dedicated for API_V2_0
def get_btc_price (self):
reqUrl = self._ReqUrlDict['GET_BTC_PRICE']
return self.get_json (reqUrl)

def get_ticks (self, market, interval, only_lastest = False):
"""
interval supports only ['oneMin', 'fiveMin', 'thirtyMin', 'hour', 'day']
"""
if only_lastest:
reqUrl = self._ReqUrlDict['GET_LATESTTICK'].format (mar=market, itv = interval)
else:
reqUrl = self._ReqUrlDict['GET_TICKS'].format (mar=market, itv = interval)
return self.get_json (reqUrl)

class MarketAPI (Bittrex):
def __init__ (self, api_ver, api_key, api_secret):
Bittrex.__init__ (self, api_ver)
self._api_key = api_key
self._secret = api_secret
self._ReqUrlDict ['BUY_LIMIT'] = BASE_URL.format (version = self._api_ver, method = 'market/buylimit', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}&quantity={qty}&rate={rate}')
self._ReqUrlDict ['SELL_LIMIT'] = BASE_URL.format (version = self._api_ver, method = 'market/selllimit', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}&quantity={qty}&rate={rate}')
self._ReqUrlDict ['CANCEL'] = BASE_URL.format (version = self._api_ver, method = 'market/cancel', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&uuid={o_uuid}')
self._ReqUrlDict ['GET_OPENORDERS'] = BASE_URL.format (version = self._api_ver, method = 'market/getopenorders', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}')
self._ReqUrlDict ['GET_OPENALLORDERS'] = BASE_URL.format (version = self._api_ver, method = 'market/getopenorders', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
def buy_limit (self, market, quantity, rate):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['BUY_LIMIT'].format (no = nonce, mar = market, qty = quantity, rate = rate)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def sell_limit (self, market, quantity, rate):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['SELL_LIMIT'].format (no = nonce, mar = market, qty = quantity, rate = rate)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def cancel (self, uuid):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['CANCEL'].format (no = nonce, o_uuid = uuid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_open_orders (self, market = ''):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_OPENORDERS'].format (no = nonce, mar = market) if market is not '' else self._ReqUrlDict['GET_OPENALLORDERS'].format(no = nonce)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def __init__ (self, api_ver, api_key, api_secret):
Bittrex.__init__ (self, api_ver)
self._api_key = api_key
self._secret = api_secret
self._ReqUrlDict ['BUY_LIMIT'] = BASE_URL.format (version = self._api_ver, method = 'market/buylimit', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}&quantity={qty}&rate={rate}')
self._ReqUrlDict ['SELL_LIMIT'] = BASE_URL.format (version = self._api_ver, method = 'market/selllimit', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}&quantity={qty}&rate={rate}')
self._ReqUrlDict ['CANCEL'] = BASE_URL.format (version = self._api_ver, method = 'market/cancel', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&uuid={o_uuid}')
self._ReqUrlDict ['GET_OPENORDERS'] = BASE_URL.format (version = self._api_ver, method = 'market/getopenorders', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}')
self._ReqUrlDict ['GET_OPENALLORDERS'] = BASE_URL.format (version = self._api_ver, method = 'market/getopenorders', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
def buy_limit (self, market, quantity, rate):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['BUY_LIMIT'].format (no = nonce, mar = market, qty = quantity, rate = rate)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def sell_limit (self, market, quantity, rate):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['SELL_LIMIT'].format (no = nonce, mar = market, qty = quantity, rate = rate)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def cancel (self, uuid):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['CANCEL'].format (no = nonce, o_uuid = uuid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_open_orders (self, market = ''):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_OPENORDERS'].format (no = nonce, mar = market) if market is not '' else self._ReqUrlDict['GET_OPENALLORDERS'].format(no = nonce)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
class AccountAPI (Bittrex):
def __init__ (self, api_ver, api_key, api_secret):
Bittrex.__init__ (self, api_ver)
self._api_key = api_key
self._secret = api_secret
self._ReqUrlDict ['GET_BALANCES'] = BASE_URL.format (version = self._api_ver, method = 'account/getbalances', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
self._ReqUrlDict ['GET_BALANCE'] = BASE_URL.format (version = self._api_ver, method = 'account/getbalance', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['GET_DEPOSITADDR'] = BASE_URL.format (version = self._api_ver, method = 'account/getdepositaddress', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['WITHDRAW'] = BASE_URL.format (version = self._api_ver, method = 'account/withdraw', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}&quantity={qty}&address={addr}&paymentid={pid}')
self._ReqUrlDict ['GET_ORDER'] = BASE_URL.format (version = self._api_ver, method = 'account/getorder', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&uuid={o_uuid}')
self._ReqUrlDict ['GET_ALLORDERHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getorderhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
self._ReqUrlDict ['GET_ORDERHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getorderhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}')
self._ReqUrlDict ['GET_WITHDRAWALHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getwithdrawalhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['GET_DEPOSITHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getdeposithistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
def __init__ (self, api_ver, api_key, api_secret):
Bittrex.__init__ (self, api_ver)
self._api_key = api_key
self._secret = api_secret
self._ReqUrlDict ['GET_BALANCES'] = BASE_URL.format (version = self._api_ver, method = 'account/getbalances', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
self._ReqUrlDict ['GET_BALANCE'] = BASE_URL.format (version = self._api_ver, method = 'account/getbalance', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['GET_DEPOSITADDR'] = BASE_URL.format (version = self._api_ver, method = 'account/getdepositaddress', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['WITHDRAW'] = BASE_URL.format (version = self._api_ver, method = 'account/withdraw', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}&quantity={qty}&address={addr}&paymentid={pid}')
self._ReqUrlDict ['GET_ORDER'] = BASE_URL.format (version = self._api_ver, method = 'account/getorder', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&uuid={o_uuid}')
self._ReqUrlDict ['GET_ALLORDERHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getorderhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}')
self._ReqUrlDict ['GET_ORDERHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getorderhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&market={mar}')
self._ReqUrlDict ['GET_WITHDRAWALHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getwithdrawalhistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')
self._ReqUrlDict ['GET_DEPOSITHIS'] = BASE_URL.format (version = self._api_ver, method = 'account/getdeposithistory', paramvalue = 'apikey=' + self._api_key.decode() + '&nonce={no}&currency={cur}')

def get_balance (self, cur = ''):
nonce = self.get_nonce()
reqUrl = self._ReqUrlDict['GET_BALANCES'].format(no = nonce) if cur is '' else self._ReqUrlDict['GET_BALANCE'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_deposit_addr (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_DEPOSITADDR'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def withdraw (self, cur, qty, addr, pid):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['WITHDRAW'].format (no = nonce, cur = cur, qty = qty, addr = addr, pid = pid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_order (self, uuid):
nonce = self.get_nonce()
reqUrl = self._ReqUrlDict ['GET_ORDER'].format (no = nonce, o_uuid = uuid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_order_history (self, market = ''):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_ALLORDERHIS'].format (no = nonce) if market is '' else self._ReqUrlDict ['GET_ORDERHIS'].format (no = nonce, mar = market)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_withdrawal_history (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_WITHDRAWALHIS'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_deposit_history (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_DEPOSITHIS'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_balance (self, cur = ''):
nonce = self.get_nonce()
reqUrl = self._ReqUrlDict['GET_BALANCES'].format(no = nonce) if cur is '' else self._ReqUrlDict['GET_BALANCE'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_deposit_addr (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_DEPOSITADDR'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def withdraw (self, cur, qty, addr, pid):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['WITHDRAW'].format (no = nonce, cur = cur, qty = qty, addr = addr, pid = pid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_order (self, uuid):
nonce = self.get_nonce()
reqUrl = self._ReqUrlDict ['GET_ORDER'].format (no = nonce, o_uuid = uuid)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_order_history (self, market = ''):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_ALLORDERHIS'].format (no = nonce) if market is '' else self._ReqUrlDict ['GET_ORDERHIS'].format (no = nonce, mar = market)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_withdrawal_history (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_WITHDRAWALHIS'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))
def get_deposit_history (self, cur):
nonce = self.get_nonce ()
reqUrl = self._ReqUrlDict ['GET_DEPOSITHIS'].format (no = nonce, cur = cur)
return self.get_json (reqUrl, self.hmac_sign (reqUrl, self._secret))

0 comments on commit 4ee3490

Please sign in to comment.