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