Exemplo n.º 1
0
async def handle_depth_stream(
    symbol: str,
    session: ClientSession,
    dispatcher: DiffDepthStreamDispatcher,
    database: Database,
    logger: Logger,
    loop: AbstractEventLoop,
    asset_type: AssetType,
):
    next_full_fetch = time()
    logger.log_msg(f"Connecting to {asset_type.value + symbol} stream",
                   LoggingLevel.INFO, symbol)
    prev_final_update_id = None
    while True:
        async with session.ws_connect(depth_stream_url(symbol,
                                                       asset_type)) as ws:
            async for msg in ws:
                if msg.type == aiohttp.WSMsgType.TEXT:
                    try:
                        data_raw = DiffDepthStreamMsg(**msg.json())
                    except ValidationError:
                        print(msg.data)
                        break

                    s = data_raw.E / 1000.0
                    timestamp = datetime.utcfromtimestamp(s)
                    if asset_type == AssetType.SPOT:
                        first_update_id = data_raw.U
                        final_update_id = data_raw.u
                    else:
                        first_update_id = data_raw.pu + 1
                        final_update_id = data_raw.u
                    bids_quantity = [pairs[1] for pairs in data_raw.b]
                    bids_price = [pairs[0] for pairs in data_raw.b]
                    asks_quantity = [pairs[1] for pairs in data_raw.a]
                    asks_price = [pairs[0] for pairs in data_raw.a]
                    symbol = data_raw.s
                    symbol_full = asset_type.value + symbol

                    if next_full_fetch < time():
                        logger.log_msg(
                            f"Fetching {symbol_full} full market depth",
                            LoggingLevel.INFO,
                            symbol_full,
                        )
                        next_full_fetch += CONFIG.full_fetch_interval
                        loop.create_task(
                            get_full_depth(symbol, session, database,
                                           asset_type))
                    if (prev_final_update_id
                            and prev_final_update_id + 1 != first_update_id):
                        logger.log_msg(
                            f"LOB dropped for {symbol_full}, refetching full market depth",
                            LoggingLevel.INFO,
                            symbol_full,
                        )

                    dispatcher.insert(
                        timestamp,
                        first_update_id,
                        final_update_id,
                        bids_quantity,
                        bids_price,
                        asks_quantity,
                        asks_price,
                        symbol_full,
                    )
                if msg.type == aiohttp.WSMsgType.CLOSE:
                    break
        logger.log_msg(
            f"Connection closed for {symbol_full} stream, retrying.",
            LoggingLevel.INFO,
            symbol,
        )
        next_full_fetch = time()