def start(self, instmt): """ Start the exchange gateway :param instmt: Instrument :return List of threads """ instmt.set_l2_depth(L2Depth(5)) instmt.set_prev_l2_depth(L2Depth(5)) instmt.set_instmt_snapshot_table_name(self.get_instmt_snapshot_table_name(instmt.get_exchange_name(), instmt.get_instmt_name())) self.init_instmt_snapshot_table(instmt) return [self.api_socket.connect(self.api_socket.get_link(), on_message_handler=partial(self.on_message_handler, instmt), on_open_handler=partial(self.on_open_handler, instmt), on_close_handler=partial(self.on_close_handler, instmt))]
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ l2_depth = L2Depth() raw = raw["result"] keys = list(raw.keys()) if cls.get_bids_field_name() in keys and \ cls.get_asks_field_name() in keys: # Date time l2_depth.date_time = datetime.utcnow().strftime( "%Y%m%d %H:%M:%S.%f") # Bids bids = raw[cls.get_bids_field_name()] for i in range(0, 5): l2_depth.bids[i].price = bids[i][cls.get_price_field_name()] l2_depth.bids[i].volume = bids[i][cls.get_volume_field_name()] # Asks asks = raw[cls.get_asks_field_name()] for i in range(0, 5): l2_depth.asks[i].price = asks[i][cls.get_price_field_name()] l2_depth.asks[i].volume = asks[i][cls.get_volume_field_name()] else: raise Exception('Does not contain order book keys in instmt %s-%s.\nOriginal:\n%s' % \ (instmt.get_exchange_name(), instmt.get_instmt_name(), \ raw)) return l2_depth
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ l2_depth = L2Depth() keys = list(raw.keys()) if cls.get_bids_field_name() in keys and \ cls.get_asks_field_name() in keys: # No Date time information, has update id only l2_depth.date_time = datetime.now().strftime("%Y%m%d %H:%M:%S.%f") # Bids bids = raw[cls.get_bids_field_name()] bids = sorted(bids, key=lambda x: x[0], reverse=True) for i in range(0, 5): l2_depth.bids[i].price = float(bids[i][0]) if type(bids[i][0]) != float else bids[i][0] l2_depth.bids[i].volume = float(bids[i][1]) if type(bids[i][1]) != float else bids[i][1] # Asks asks = raw[cls.get_asks_field_name()] asks = sorted(asks, key=lambda x: x[0]) for i in range(0, 5): l2_depth.asks[i].price = float(asks[i][0]) if type(asks[i][0]) != float else asks[i][0] l2_depth.asks[i].volume = float(asks[i][1]) if type(asks[i][1]) != float else asks[i][1] else: raise Exception('Does not contain order book keys in instmt %s-%s.\nOriginal:\n%s' % \ (instmt.get_exchange_name(), instmt.get_instmt_name(), \ raw)) return l2_depth
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ l2_depth = L2Depth() keys = list(raw.keys()) if cls.get_bids_field_name() in keys and \ cls.get_asks_field_name() in keys: # Bids bids = raw[cls.get_bids_field_name()] bids = sorted(bids, key=lambda x: x[0], reverse=True) for i in range(0, len(bids)): l2_depth.bids[i].price = float(bids[i][0]) if type(bids[i][0]) != float else bids[i][0] l2_depth.bids[i].volume = float(bids[i][1]) if type(bids[i][1]) != float else bids[i][1] # Asks asks = raw[cls.get_asks_field_name()] asks = sorted(asks, key=lambda x: x[0]) for i in range(0, len(asks)): l2_depth.asks[i].price = float(asks[i][0]) if type(asks[i][0]) != float else asks[i][0] l2_depth.asks[i].volume = float(asks[i][1]) if type(asks[i][1]) != float else asks[i][1] return l2_depth
def start(self, instmt): """ Start the exchange gateway :param instmt: Instrument :return List of threads """ instmt.set_prev_l2_depth(L2Depth(5)) instmt.set_l2_depth(L2Depth(5)) instmt.set_instmt_snapshot_table_name(self.get_instmt_snapshot_table_name(instmt.get_exchange_name(), instmt.get_instmt_name())) self.init_instmt_snapshot_table(instmt) t1 = threading.Thread(target=partial(self.get_order_book_worker, instmt)) t1.start() t2 = threading.Thread(target=partial(self.get_trades_worker, instmt)) t2.start() return [t1, t2]
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ keys = list(raw.keys()) if cls.get_bids_field_name() in keys and \ cls.get_asks_field_name() in keys: l2_depth = L2Depth() # Bids bids = raw[cls.get_bids_field_name()] bid_level = -1 for bid in bids: price = bid[cls.get_order_book_price_field_name()] volume = bid[cls.get_order_book_volume_field_name()] if bid_level == -1 or l2_depth.bids[bid_level].price != price: bid_level += 1 if bid_level < 5: l2_depth.bids[bid_level].price = float(price) else: break l2_depth.bids[bid_level].volume += float(volume) # Asks asks = raw[cls.get_asks_field_name()] ask_level = -1 for ask in asks: price = ask[cls.get_order_book_price_field_name()] volume = ask[cls.get_order_book_volume_field_name()] if ask_level == -1 or l2_depth.asks[ask_level].price != price: ask_level += 1 if ask_level < 5: l2_depth.asks[ask_level].price = float(price) else: break l2_depth.asks[ask_level].volume += float(volume) return l2_depth else: raise Exception('Does not contain order book keys in instmt %s-%s.\nOriginal:\n%s' % \ (instmt.get_exchange_name(), instmt.get_instmt_name(), \ raw))
:return List of threads """ instmt.set_l2_depth(L2Depth(5)) instmt.set_prev_l2_depth(L2Depth(5)) instmt.set_instmt_snapshot_table_name( self.get_instmt_snapshot_table_name(instmt.get_exchange_name(), instmt.get_instmt_name())) self.init_instmt_snapshot_table(instmt) instmt.set_recovered(False) t1 = threading.Thread( target=partial(self.get_order_book_worker, instmt)) t2 = threading.Thread(target=partial(self.get_trades_worker, instmt)) t1.start() t2.start() return [t1, t2] if __name__ == '__main__': Logger.init_log() exchange_name = 'Poloniex' instmt_name = 'BTCETH' instmt_code = 'BTC_ETH' instmt = Instrument(exchange_name, instmt_name, instmt_code) db_storage = SqlStorageTemplate() exch = ExchGwPoloniex([db_storage]) instmt.set_l2_depth(L2Depth(5)) instmt.set_prev_l2_depth(L2Depth(5)) instmt.set_recovered(False) # exch.get_order_book_worker(instmt) exch.get_trades_worker(instmt)
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ def get_order_info(data): return ( data['price'] if 'price' in data.keys() else None, (0 if data['side'] == "Buy" else 1), data['id'], data['size'] if 'size' in data.keys() else None ) if raw['action'] in ('partial', 'insert'): # Order book initialization or insertion for data in raw['data']: if data['symbol'] != instmt.get_instmt_code(): continue price, side, id, volume = get_order_info(data) instmt.realtime_order_book_ids[side][id] = price if price not in instmt.realtime_order_book_prices[side].keys(): instmt.realtime_order_book_prices[side][price] = { id: volume } else: instmt.realtime_order_book_prices[side][price][id] = volume elif raw['action'] == 'update': # Order book update for data in raw['data']: if data['symbol'] != instmt.get_instmt_code(): continue _, side, id, volume = get_order_info(data) price = instmt.realtime_order_book_ids[side][id] instmt.realtime_order_book_ids[side][id] = price instmt.realtime_order_book_prices[side][price][id] = volume elif raw['action'] == 'delete': # Order book delete for data in raw['data']: if data['symbol'] != instmt.get_instmt_code(): continue _, side, id, _ = get_order_info(data) price = instmt.realtime_order_book_ids[side][id] del instmt.realtime_order_book_prices[side][price][id] if len(instmt.realtime_order_book_prices[side][price]) == 0: del instmt.realtime_order_book_prices[side][price] # return l2_depth l2_depth = L2Depth() l2_depth.date_time = datetime.utcnow().strftime("%Y%m%d %H:%M:%S.%f") bids_px = sorted(list(instmt.realtime_order_book_prices[0].keys()), reverse=True)[:5] asks_px = sorted(list(instmt.realtime_order_book_prices[1].keys()))[:5] bids_qty = [sum(instmt.realtime_order_book_prices[0][px].values()) for px in bids_px] asks_qty = [sum(instmt.realtime_order_book_prices[1][px].values()) for px in asks_px] for i in range(0, 5): l2_depth.bids[i].price = bids_px[i] l2_depth.bids[i].volume = bids_qty[i] l2_depth.asks[i].price = asks_px[i] l2_depth.asks[i].volume = asks_qty[i] return l2_depth
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ # No order book mapping from config. Need to decode here. l2_depth = instmt.get_l2_depth() l2_depth.date_time = datetime.utcnow().strftime("%Y%m%d %H:%M:%S.%f") if isinstance(raw[0], list): # Start subscription for i in range(0, 25): bid = raw[i] ask = raw[25 + i] l2_depth.bids[i] = L2Depth.Depth(price=bid[0], count=bid[1], volume=bid[2]) l2_depth.asks[i] = L2Depth.Depth(price=ask[0], count=ask[1], volume=-ask[2]) else: price = raw[1] count = raw[2] volume = raw[3] found = False if count == 0: # Deletion if volume > 0: for i in range(0, len(l2_depth.bids)): if price == l2_depth.bids[i].price: found = True del l2_depth.bids[i] break else: for i in range(0, len(l2_depth.asks)): if price == l2_depth.asks[i].price: found = True del l2_depth.asks[i] break if not found: depth_text = "" for i in range(0, l2_depth.depth): if i < len(l2_depth.bids): depth_text += "%.4f,%d,%.4f" % \ (l2_depth.bids[i].volume, \ l2_depth.bids[i].count, \ l2_depth.bids[i].price) else: depth_text += " " depth_text += "<--->" if i < len(l2_depth.asks): depth_text += "%.4f,%d,%.4f" % \ (l2_depth.asks[i].volume, \ l2_depth.asks[i].count, \ l2_depth.asks[i].price) else: depth_text += " " depth_text += "\n" Logger.info(cls.__name__, "Cannot find the deletion of the message: %s\nDepth:\n%s\n" % \ (raw, depth_text)) else: # Insertion/Update if volume > 0: # Update for i in range(0, len(l2_depth.bids)): if price == l2_depth.bids[i].price: l2_depth.bids[i].count = count l2_depth.bids[i].volume = volume found = True break if not found: # Insertion l2_depth.bids.append( L2Depth.Depth(price=price, count=count, volume=volume)) l2_depth.sort_bids() if len(l2_depth.bids) > l2_depth.depth * 2: del l2_depth.bids[l2_depth.depth:] else: for i in range(0, len(l2_depth.asks)): # Update if price == l2_depth.asks[i].price: l2_depth.asks[i].count = count l2_depth.asks[i].volume = -volume found = True break if not found: # Insertion l2_depth.asks.append( L2Depth.Depth(price=price, count=count, volume=-volume)) l2_depth.sort_asks() if len(l2_depth.asks) > l2_depth.depth * 2: del l2_depth.asks[l2_depth.depth:] return l2_depth
def parse_l2_depth(cls, instmt, raw): """ Parse raw data to L2 depth :param instmt: Instrument :param raw: Raw data in JSON """ l2_depth = instmt.get_l2_depth() keys = list(raw.keys()) bids_field = cls.get_bids_field_name() asks_field = cls.get_asks_field_name() if bids_field in keys and asks_field in keys: # Date time l2_depth.date_time = datetime.utcnow().strftime( "%Y%m%d %H:%M:%S.%f") # Bids bids = raw[bids_field] bids_len = min(l2_depth.depth, len(bids)) for i in range(0, bids_len): l2_depth.bids[i].price = float(bids[i]['price']) \ if not isinstance(bids[i]['price'], float) else bids[i][0] l2_depth.bids[i].volume = float(bids[i]['volume']) \ if not isinstance(bids[i]['volume'], float) else bids[i][1] l2_depth.bids[i].id = bids[i]['id'] # Asks asks = raw[asks_field] asks_len = min(l2_depth.depth, len(asks)) for i in range(0, asks_len): l2_depth.asks[i].price = float(asks[i]['price']) \ if not isinstance(asks[i]['price'], float) else asks[i][0] l2_depth.asks[i].volume = float(asks[i]['volume']) \ if not isinstance(asks[i]['volume'], float) else asks[i][1] l2_depth.asks[i].id = asks[i]['id'] elif "order_id" in keys: if 'type' in keys: # Insertion order_id = raw['order_id'] price = float(raw['price']) volume = float(raw['volume']) update_type = raw['type'] if update_type == "BID": l2_depth.bids.append( L2Depth.Depth(price=price, volume=volume)) l2_depth.bids[-1].id = order_id l2_depth.sort_bids() if len(l2_depth.bids) > l2_depth.depth * 2: del l2_depth.bids[l2_depth.depth:] elif update_type == "ASK": l2_depth.asks.append( L2Depth.Depth(price=price, volume=volume)) l2_depth.asks[-1].id = order_id l2_depth.sort_asks() if len(l2_depth.asks) > l2_depth.depth * 2: del l2_depth.asks[l2_depth.depth:] elif 'base' in keys: # Update order_id = raw['order_id'] volume = float(raw['base']) price = float(raw['counter']) / float(raw['base']) for i in range(0, len(l2_depth.bids)): if l2_depth.bids[i].id == order_id: if l2_depth.bids[i].price == price: l2_depth.bids[i].volume -= volume break else: # Deletion order_id = raw['order_id'] found = False for i in range(0, len(l2_depth.bids)): if l2_depth.bids[i].id == order_id: found = True del l2_depth.bids[i] break if not found: for i in range(0, len(l2_depth.asks)): if l2_depth.asks[i].id == order_id: del l2_depth.asks[i] break else: raise Exception( 'Does not contain order book keys in instmt %s-%s.\nOriginal:\n%s' % (instmt.get_exchange_name(), instmt.get_instmt_name(), raw)) return l2_depth