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))
        t1.start()
        t2 = threading.Thread(target=partial(self.get_trades_worker, instmt))
        t2.start()
        return [t1, t2]


if __name__ == '__main__':
    Logger.init_log()
    exchange_name = 'Gatecoin'
    instmt_name = 'BTCHKD'
    instmt_code = 'BTCHKD'
    instmt = Instrument(exchange_name, instmt_name, instmt_code)
    db_client = SqlClientTemplate()
    exch = ExchGwGatecoin([db_client])
    instmt.set_l2_depth(L2Depth(5))
    instmt.set_prev_l2_depth(L2Depth(5))
    instmt.set_order_book_table_name(
        exch.get_order_book_table_name(instmt.get_exchange_name(),
                                       instmt.get_instmt_name()))
    instmt.set_trades_table_name(
        exch.get_trades_table_name(instmt.get_exchange_name(),
                                   instmt.get_instmt_name()))
    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