class Market(object): def __init__(self, currency): self.name = self.__class__.__name__ self.currency = currency self.pair = config.pair pair_names = str.split(self.pair, "_") self.pair1_name = str.upper(pair_names[0]) self.pair2_name = str.upper(pair_names[1]) self.depth_updated = 0 self.update_rate = 60 self.fc = FiatConverter() self.fc.update() def get_depth(self): timediff = time.time() - self.depth_updated if timediff > self.update_rate: self.ask_update_depth() timediff = time.time() - self.depth_updated if timediff > config.market_expiration_time: logging.warn('Market: %s order book is expired' % self.name) self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ {'price': 0, 'amount': 0}]} return self.depth def convert_to_usd(self): if self.currency == "USD": return for direction in ("asks", "bids"): for order in self.depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "USD") def ask_update_depth(self): try: self.update_depth() self.convert_to_usd() self.depth_updated = time.time() except (urllib.error.HTTPError, urllib.error.URLError) as e: logging.error("HTTPError, can't update market: %s code=%d reason=%s headers=%s" % (self.name, e.code, e.reason, e.headers)) log_exception(logging.DEBUG) except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) log_exception(logging.DEBUG) def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): def __init__(self, currency): self.name = self.__class__.__name__ self.currency = currency self.depth_updated = 0 self.update_rate = 60 self.trade_fee = 0 self.fc = FiatConverter() self.fc.update() def get_depth(self): timediff = time.time() - self.depth_updated if timediff > self.update_rate: self.ask_update_depth() timediff = time.time() - self.depth_updated if timediff > config.market_expiration_time: logging.warning('Market: %s order book is expired' % self.name) self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [{'price': 0, 'amount': 0}]} if self.depth['bids'][0]['price'] > self.depth['asks'][0]['price']: logging.warning('Market: %s order book is invalid (bid>ask : quotation is stopped ?)' % self.name) self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [{'price': 0, 'amount': 0}]} return self.depth def convert_to_usd(self): if self.currency == "USD": return for direction in ("asks", "bids"): for order in self.depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "USD") def ask_update_depth(self): try: self.update_depth() self.convert_to_usd() self.depth_updated = time.time() except (urllib.error.HTTPError, urllib.error.URLError) as e: logging.error("HTTPError, can't update market: %s" % self.name) except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): def __init__(self, base_currency, market_currency, pair_code): self.name = self.__class__.__name__ self.base_currency = base_currency self.market_currency = market_currency self.pair_code = pair_code self.depth_updated = 0 self.update_rate = 1 self.fc = FiatConverter() self.fc.update() self.is_terminated = False self.request_timeout = 5 #5s def terminate(self): self.is_terminated = True def get_depth(self): timediff = time.time() - self.depth_updated # logging.warn('Market: %s order book1:(%s>%s)', self.name, timediff, self.depth_updated) if timediff > self.update_rate: # print('should update...') self.ask_update_depth() timediff = time.time() - self.depth_updated # logging.warn('Market: %s order book2:(%s>%s)', self.name, timediff, self.depth_updated) if timediff > config.market_expiration_time: # logging.warn('Market: %s order book is expired(%s>%s)', self.name, timediff, config.market_expiration_time) self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ {'price': 0, 'amount': 0}]} return self.depth def convert_to_cny(self): if self.currency == "CNY": return for direction in ("asks", "bids"): for order in self.depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "CNY") def subscribe_depth(self): if config.SUPPORT_ZMQ: t = threading.Thread(target = self.subscribe_zmq_depth) t.start() elif config.SUPPORT_WEBSOCKET: t = threading.Thread(target = self.subscribe_websocket_depth) t.start() else: pass def subscribe_zmq_depth(self): import lib.push as push push_s = push.Push(config.ZMQ_PORT) push_s.msg_server() def subscribe_websocket_depth(self): import json from socketIO_client import SocketIO def on_message(data): data = data.decode('utf8') if data[0] != '2': return data = json.loads(data[1:]) depth = data[1] logging.debug("depth coming: %s", depth['market']) self.depth_updated = int(depth['timestamp']/1000) self.depth = self.format_depth(depth) def on_connect(): logging.info('[Connected]') socketIO.emit('land', {'app': 'haobtcnotify', 'events':[self.event]}); with SocketIO(config.WEBSOCKET_HOST, port=config.WEBSOCKET_PORT) as socketIO: socketIO.on('connect', on_connect) socketIO.on('message', on_message) socketIO.wait() def ask_update_depth(self): try: self.update_depth() # self.convert_to_usd() self.depth_updated = time.time() except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) log_exception(logging.DEBUG) # traceback.print_exc() def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res def sort_and_format(self, l, reverse=False): l.sort(key=lambda x: float(x[0]), reverse=reverse) r = [] for i in l: r.append({'price': float(i[0]), 'amount': float(i[1])}) return r def format_depth(self, depth): bids = self.sort_and_format(depth['bids'], True) asks = self.sort_and_format(depth['asks'], False) return {'asks': asks, 'bids': bids} ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): def __init__(self, currency): # print("I HAVE INSTANTIATED MARKET.PY, self:", self.depth, "; CURRENCY: ", currency) self.name = self.__class__.__name__ self.currency = currency self.depth_updated = 0 self.update_rate = 60 # self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ # {'price': 0, 'amount': 0}]} self.fc = FiatConverter() self.fc.update() print("Market.py, __init completed") # def get_depth(self): # timediff = time.time() - self.depth_updated # if timediff > self.update_rate: # print("3.1 market.py, get_depth, timediff: {}, self.update_rate: {}; ".format(timediff, self.update_rate)) # self.ask_update_depth() # timediff = time.time() - self.depth_updated # print("!!!!!! market.py, get_depth, time.time(): {}; self.depth.updated(): {}, config.market_expiration_time: {}".format(time.time(), # self.depth_updated, config.market_expiration_time)) # if timediff > config.market_expiration_time: # print("3.2 market.py, get_depth, timediff > config.market_expiration_time") # logging.warning('Market: %s order book is expired' % self.name) # # TODO: Issues is with setting self.depth here - self.depth should be set in __init__ # self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ # {'price': 0, 'amount': 0}]} # print("3.3 market.py, get_depth, timediff > config.market_expiration_time; self.depth: ", self.depth) # return self.depth def convert_to_usd(self): # print("arbitrage, public_markets, market.py, convert_to_usd()") if self.currency == "USD": print( "arbitrage, public_markets, convert_to_usd, self.currency = USD" ) return for direction in ("asks", "bids"): for order in self.depth[direction]: # print("arbitrage, public_markets, market.py, convert_to_usd(), for loop nested") order["price"] = self.fc.convert(order["price"], self.currency, "USD") # def ask_update_depth(self): # print("4.0 arbitrage, public_markets, market.py, ask_update_depth()") # try: # # TODO: Market' object has no attribute 'depth' (occurs here) # import pdb; pdb.set_trace() # print("market.py, ask_update_depth, after 1st pdb") # self.update_depth() # print("market.py, ask_update_depth, self.update_depth just finished") # self.convert_to_usd() # self.depth_updated = time.time() # except (urllib.error.HTTPError, urllib.error.URLError) as e: # logging.error("4.1 arbitrage, public_markets, market.py, ask_update_depth HTTPError, can't update market: %s" % self.name) # log_exception(logging.DEBUG) # except Exception as e: # logging.error("4.2 arbitrage, public_markets, market.py, ask_update_depth(); Can't update market: %s - %s" % (self.name, str(e))) # log_exception(logging.DEBUG) def get_ticker(self): # print("!!!!!!!!!!!!!!3.0 market.py, get_ticker") depth = self.get_depth() # print("3.0 market.py, get_ticker, depth: ", depth) res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res ## Abstract methods def update_depth(self): # import pdb; pdb.set_trace() # print("arbitrage, market.py, update_depth, passing (self): ", self) pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): def __init__(self, currency): self.name = self.__class__.__name__ self.currency = currency self.depth_updated = 0 self.update_rate = 60 self.fc = FiatConverter() self.fc.update() self.converted_depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ {'price': 0, 'amount': 0}]} def get_depth(self): # note that self.ask_update_depth converts the result to USD timediff = time.time() - self.depth_updated if timediff > self.update_rate: self.ask_update_depth() timediff = time.time() - self.depth_updated if timediff > config.market_expiration_time: logging.warn('Market: %s order book is expired' % self.name) self.depth = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ {'price': 0, 'amount': 0}]} self.converted = {'asks': [{'price': 0, 'amount': 0}], 'bids': [ {'price': 0, 'amount': 0}]} return self.depth def get_converted_depth (self, currency="USD"): self.get_depth() self.convert_to_currency(currency) return self.converted_depth def convert_to_usd(self): if self.currency == "USD": return #dont get confused here, direction will take either "asks" or "bids" self.converted_depth = self.depth for direction in ("asks", "bids"): for order in self.converted_depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "USD") def convert_to_currency(self, currency="USD"): if self.currency == currency: return #dont get confused here, direction will take either "asks" or "bids" self.converted_depth = self.depth for direction in ("asks", "bids"): for order in self.converted_depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, currency) def ask_update_depth(self): try: self.update_depth() #self.convert_to_usd() self.depth_updated = time.time() #update urllib in original code to urllib2 except (urllib2.HTTPError, urllib2.URLError) as e: logging.error("HTTPError, can't update market: %s" % self.name) except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res def get_converted_ticker(self, currency = "USD"): depth = self.get_converted_depth(currency) res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): def __init__(self, currency): self.name = self.__class__.__name__ self.currency = currency self.depth_updated = 0 self.update_rate = 1 self.fc = FiatConverter() self.fc.update() def get_depth(self): timediff = time.time() - self.depth_updated if timediff > self.update_rate: self.ask_update_depth() timediff = time.time() - self.depth_updated if timediff > config.market_expiration_time: logging.warn('Market: %s order book is expired' % self.name) self.depth = { 'asks': [{ 'price': 0, 'amount': 0 }], 'bids': [{ 'price': 0, 'amount': 0 }] } return self.depth def convert_to_cny(self): if self.currency == "CNY": return for direction in ("asks", "bids"): for order in self.depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "CNY") def ask_update_depth(self): try: self.update_depth() # self.convert_to_usd() self.depth_updated = time.time() except (urllib.error.HTTPError, urllib.error.URLError) as e: logging.error("HTTPError, can't update market: %s" % self.name) log_exception(logging.DEBUG) except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) log_exception(logging.DEBUG) def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]} return res ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass
class Market(object): registered_market = {} def __init__(self): self.name = self.__class__.__name__ self.depth_updated = 0 self.update_rate = 1 self.fc = FiatConverter() self.fc.update() self.is_terminated = False def terminate(self): self.is_terminated = True #seems not used anywhere def get_depth(self): timediff = time.time() - self.depth_updated if timediff > self.update_rate: self.ask_update_depth() #order book is in valide if it updated time long time ago. timediff = time.time() - self.depth_updated if timediff > config.market_expiration_time: logging.warn('Market: %s order book is expired' % self.name) self.depth = { 'asks': [{ 'price': 0, 'amount': 0 }], 'bids': [{ 'price': 0, 'amount': 0 }] } return self.depth def gen_id(self, lu, currency_pair): return hex(int(lu.timestamp() * 1e6)) + currency_pair def convert_to_cny(self): if self.currency == "CNY": return for direction in ("asks", "bids"): for order in self.depth[direction]: order["price"] = self.fc.convert(order["price"], self.currency, "CNY") def start_websocket_depth(self): if config.SUPPORT_WEBSOCKET: t = threading.Thread(target=self.websocket_depth) t.start() def websocket_depth(self): #?? import json from socketIO_client import SocketIO def on_message(data): data = data.decode('utf8') if data[0] != '2': return data = json.loads(data[1:]) depth = data[1] logging.debug("depth coming: %s", depth['market']) self.depth_updated = int(depth['timestamp'] / 1000) self.depth = self.format_depth(depth) def on_connect(): logging.info('[Connected]') socketIO.emit('land', { 'app': 'haobtcnotify', 'events': [self.event] }) with SocketIO(config.WEBSOCKET_HOST, port=config.WEBSOCKET_PORT) as socketIO: socketIO.on('connect', on_connect) socketIO.on('message', on_message) socketIO.wait() def ask_update_depth(self): try: self.update_depth() # self.convert_to_usd() self.depth_updated = time.time() except (urllib.error.HTTPError, urllib.error.URLError) as e: logging.error("HTTPError, can't update market: %s" % self.name) traceback.print_exc() log_exception(logging.DEBUG) except Exception as e: logging.error("Can't update market: %s - %s" % (self.name, str(e))) log_exception(logging.DEBUG) traceback.print_exc() def get_ticker(self): depth = self.get_depth() res = {'ask': 0, 'bid': 0} if len(depth['asks']) > 0 and len(depth["bids"]) > 0: res = { 'date': depth['date'].strftime('%Y.%m.%d'), 'lu': depth['lu'], 'ask': depth['asks'][0], 'bid': depth['bids'][0] } return res ## Abstract methods def update_depth(self): pass def buy(self, price, amount): pass def sell(self, price, amount): pass def sort_and_format(self, l, reverse=False): l.sort(key=lambda x: float(x[0]), reverse=reverse) r = [] for i in l: r.append({'price': float(i[0]), 'amount': float(i[1])}) return r def format_depth(self, depth): bids = self.sort_and_format(depth['bids'], True) asks = self.sort_and_format(depth['asks'], False) return {'asks': asks, 'bids': bids} @staticmethod def get_market(name): return Market.registered_market[name]() @staticmethod def get_market_list(): return Market.registered_market.keys() @staticmethod def register_market(class_name): name = class_name.__name__ createfn = class_name.create if name in Market.registered_market: logging.info('conflicted market name for ' + name + ' will be skipped') else: Market.registered_market[name] = createfn logging.info(name + ' is registered')