Exemple #1
0
    async def _book(self, pair: str, l2_book: dict, msg: dict, timestamp: float):
        """For L2 book updates."""
        if not isinstance(msg[1], list):
            if msg[1] != 'hb':
                LOG.warning('%s: Unexpected book L2 msg %s', self.id, msg)
            return

        delta = {BID: [], ASK: []}

        if isinstance(msg[1][0], list):
            # snapshot so clear book
            forced = True
            l2_book[BID] = sd()
            l2_book[ASK] = sd()
            for update in msg[1]:
                price, _, amount = update
                price = Decimal(price)
                amount = Decimal(amount)

                if amount > 0:
                    side = BID
                else:
                    side = ASK
                    amount = abs(amount)
                l2_book[side][price] = amount
        else:
            # book update
            forced = False
            price, count, amount = msg[1]
            price = Decimal(price)
            amount = Decimal(amount)

            if amount > 0:
                side = BID
            else:
                side = ASK
                amount = abs(amount)

            if count > 0:
                # change at price level
                delta[side].append((price, amount))
                l2_book[side][price] = amount
            else:
                # remove price level
                if price in l2_book[side]:
                    del l2_book[side][price]
                    delta[side].append((price, 0))

        await self.book_callback(l2_book, L2_BOOK, pair, forced, delta, timestamp, timestamp)
Exemple #2
0
    async def _book(self, msg: dict, timestamp: float):
        if msg['action'] == 'partial':
            # snapshot
            for update in msg['data']:
                pair = symbol_exchange_to_std(update['instrument_id'])
                self.l2_book[pair] = {
                    BID:
                    sd({
                        Decimal(price): Decimal(amount)
                        for price, amount, *_ in update['bids']
                    }),
                    ASK:
                    sd({
                        Decimal(price): Decimal(amount)
                        for price, amount, *_ in update['asks']
                    })
                }

                if self.checksum_validation and self.__calc_checksum(pair) != (
                        update['checksum'] & 0xFFFFFFFF):
                    raise BadChecksum
                await self.book_callback(
                    self.l2_book[pair], L2_BOOK, pair, True, None,
                    timestamp_normalize(self.id, update['timestamp']),
                    timestamp)
        else:
            # update
            for update in msg['data']:
                delta = {BID: [], ASK: []}
                pair = symbol_exchange_to_std(update['instrument_id'])
                for side in ('bids', 'asks'):
                    s = BID if side == 'bids' else ASK
                    for price, amount, *_ in update[side]:
                        price = Decimal(price)
                        amount = Decimal(amount)
                        if amount == 0:
                            if price in self.l2_book[pair][s]:
                                delta[s].append((price, 0))
                                del self.l2_book[pair][s][price]
                        else:
                            delta[s].append((price, amount))
                            self.l2_book[pair][s][price] = amount
                if self.checksum_validation and self.__calc_checksum(pair) != (
                        update['checksum'] & 0xFFFFFFFF):
                    raise BadChecksum
                await self.book_callback(
                    self.l2_book[pair], L2_BOOK, pair, False, delta,
                    timestamp_normalize(self.id, update['timestamp']),
                    timestamp)
Exemple #3
0
    async def _book(self, msg: dict, timestamp: float):
        """
        {
            'ch':'market.BTC_CW.depth.step0',
            'ts':1565857755564,
            'tick':{
                'mrid':14848858327,
                'id':1565857755,
                'bids':[
                    [  Decimal('9829.99'), 1], ...
                ]
                'asks':[
                    [ 9830, 625], ...
                ]
            },
            'ts':1565857755552,
            'version':1565857755,
            'ch':'market.BTC_CW.depth.step0'
        }
        """
        pair = symbol_std_to_exchange(msg['ch'].split('.')[1], self.id)
        data = msg['tick']
        forced = pair not in self.l2_book

        # When Huobi Delists pairs, empty updates still sent:
        # {'ch': 'market.AKRO-USD.depth.step0', 'ts': 1606951241196, 'tick': {'mrid': 50651100044, 'id': 1606951241, 'ts': 1606951241195, 'version': 1606951241, 'ch': 'market.AKRO-USD.depth.step0'}}
        # {'ch': 'market.AKRO-USD.depth.step0', 'ts': 1606951242297, 'tick': {'mrid': 50651100044, 'id': 1606951242, 'ts': 1606951242295, 'version': 1606951242, 'ch': 'market.AKRO-USD.depth.step0'}}
        if 'bids' in data and 'asks' in data:
            update = {
                BID:
                sd({
                    Decimal(price): Decimal(amount)
                    for price, amount in data['bids']
                }),
                ASK:
                sd({
                    Decimal(price): Decimal(amount)
                    for price, amount in data['asks']
                })
            }

            if not forced:
                self.previous_book[pair] = self.l2_book[pair]
            self.l2_book[pair] = update

            await self.book_callback(self.l2_book[pair], L2_BOOK, pair, forced,
                                     False,
                                     timestamp_normalize(self.id,
                                                         msg['ts']), timestamp)
Exemple #4
0
    async def _book(self, msg):
        pair = pair_exchange_to_std(msg['ch'].split('.')[1])
        data = msg['tick']
        self.l2_book[pair] = {
            BID: sd({
                Decimal(price): Decimal(amount)
                for price, amount in data['bids']
            }),
            ASK: sd({
                Decimal(price): Decimal(amount)
                for price, amount in data['asks']
            })
        }

        await self.book_callback(pair, L2_BOOK, False, False, timestamp_normalize(self.id, msg['ts']))
Exemple #5
0
    def __init__(self, pairs=None, channels=None, callbacks=None):
        if len(pairs) != 1:
            LOG.error("Gemini requires a websocket per trading pair")
            raise ValueError("Gemini requires a websocket per trading pair")
        if channels is not None:
            LOG.error("Gemini does not support different channels")
            raise ValueError("Gemini does not support different channels")
        self.pair = pairs[0]

        super().__init__('wss://api.gemini.com/v1/marketdata/' +
                         pair_std_to_exchange(self.pair, 'GEMINI'),
                         pairs=None,
                         channels=None,
                         callbacks=callbacks)
        self.book = {BID: sd(), ASK: sd()}
Exemple #6
0
    async def _pair_level2_snapshot(self, msg):
        timestamp = dt.utcnow()
        timestamp = timestamp.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
        self.l2_book[msg['product_id']] = {
            BID: sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['bids']
            }),
            ASK: sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['asks']
            })
        }

        await self.book_callback(msg['product_id'], L2_BOOK, True, None, timestamp)
Exemple #7
0
def depth(book: dict, depth: int, book_type=L2_BOOK) -> dict:
    """
    Take a book and return a new dict with max `depth` levels per side
    """
    ret = {BID: sd(), ASK: sd()}
    for side in (BID, ASK):
        prices = list(book[side].keys())[:depth] if side == ASK else list(book[side].keys())[-depth:]
        if book_type == L2_BOOK:
            for price in prices:
                ret[side][price] = book[side][price]
        else:
            for price in prices:
                ret[side][price] = {order_id: size for order_id, size in ret[side][price].items()}

    return ret
Exemple #8
0
    async def _book(self, msg):
        chan_id = msg[0]
        pair = self.channel_map[chan_id]['symbol']
        pair = pair_exchange_to_std(pair)

        if isinstance(msg[1], list):
            if isinstance(msg[1][0], list):
                # snapshot so clear book
                self.l2_book[pair] = {BID: sd(), ASK: sd()}
                for update in msg[1]:
                    price, _, amount = [Decimal(x) for x in update]
                    if amount > 0:
                        side = BID
                    else:
                        side = ASK
                        amount = abs(amount)
                    self.l2_book[pair][side][price] = amount
            else:
                # book update
                price, count, amount = [Decimal(x) for x in msg[1]]

                if amount > 0:
                    side = BID
                else:
                    side = ASK
                    amount = abs(amount)

                if count > 0:
                    # change at price level
                    self.l2_book[pair][side][price] = amount
                else:
                    # remove price level
                    del self.l2_book[pair][side][price]
        elif msg[1] == 'hb':
            pass
        else:
            LOG.warning("{} - Unexpected book msg {}".format(self.id, msg))

        if L3_BOOK in self.channels:
            await self.callbacks[L3_BOOK](feed=self.id,
                                          pair=pair,
                                          timestamp=None,
                                          sequence=None,
                                          book=self.l2_book[pair])
        else:
            await self.callbacks[L2_BOOK](feed=self.id,
                                          pair=pair,
                                          book=self.l2_book[pair])
Exemple #9
0
    async def _book(self, msg: dict, timestamp: float):
        """
        example messages:

        snapshot:
        {"channel": "orderbook", "market": "BTC/USD", "type": "partial", "data": {"time": 1564834586.3382702,
        "checksum": 427503966, "bids": [[10717.5, 4.092], ...], "asks": [[10720.5, 15.3458], ...], "action": "partial"}}

        update:
        {"channel": "orderbook", "market": "BTC/USD", "type": "update", "data": {"time": 1564834587.1299787,
        "checksum": 3115602423, "bids": [], "asks": [[10719.0, 14.7461]], "action": "update"}}
        """
        if msg['type'] == 'partial':
            # snapshot
            pair = pair_exchange_to_std(msg['market'])
            self.l2_book[pair] = {
                BID:
                sd({
                    Decimal(price): Decimal(amount)
                    for price, amount in msg['data']['bids']
                }),
                ASK:
                sd({
                    Decimal(price): Decimal(amount)
                    for price, amount in msg['data']['asks']
                })
            }
            await self.book_callback(self.l2_book[pair], L2_BOOK,
                                     pair, True, None,
                                     float(msg['data']['time']), timestamp)
        else:
            # update
            delta = {BID: [], ASK: []}
            pair = pair_exchange_to_std(msg['market'])
            for side in ('bids', 'asks'):
                s = BID if side == 'bids' else ASK
                for price, amount in msg['data'][side]:
                    price = Decimal(price)
                    amount = Decimal(amount)
                    if amount == 0:
                        delta[s].append((price, 0))
                        del self.l2_book[pair][s][price]
                    else:
                        delta[s].append((price, amount))
                        self.l2_book[pair][s][price] = amount
            await self.book_callback(self.l2_book[pair], L2_BOOK,
                                     pair, False, delta,
                                     float(msg['data']['time']), timestamp)
Exemple #10
0
    async def _book(self, msg):
        """
        For L2 book updates
        """
        timestamp = time.time()
        chan_id = msg[0]
        pair = self.channel_map[chan_id]['symbol']
        pair = pair_exchange_to_std(pair)
        delta = {BID: defaultdict(list), ASK: defaultdict(list)}
        forced = False

        if isinstance(msg[1], list):
            if isinstance(msg[1][0], list):
                # snapshot so clear book
                self.l2_book[pair] = {BID: sd(), ASK: sd()}
                for update in msg[1]:
                    price, _, amount = update
                    if amount > 0:
                        side = BID
                    else:
                        side = ASK
                        amount = abs(amount)
                    self.l2_book[pair][side][price] = amount
                forced = True
            else:
                # book update
                price, count, amount = msg[1]

                if amount > 0:
                    side = BID
                else:
                    side = ASK
                    amount = abs(amount)

                if count > 0:
                    # change at price level
                    delta[side] = {UPD: [(price, amount)]}
                    self.l2_book[pair][side][price] = amount
                else:
                    # remove price level
                    del self.l2_book[pair][side][price]
                    delta[side] = {DEL: [price]}
        elif msg[1] == 'hb':
            pass
        else:
            LOG.warning("%s: Unexpected book msg %s", self.id, msg)

        await self.book_callback(pair, L2_BOOK, forced, delta, timestamp)
Exemple #11
0
    async def _pair_level2_snapshot(self, msg: dict, timestamp: float):
        self.l2_book[msg['product_id']] = {
            BID:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['bids']
            }),
            ASK:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['asks']
            })
        }

        await self.book_callback(msg['product_id'], L2_BOOK, True, None,
                                 timestamp)
Exemple #12
0
    async def _l3_book(self, msg: dict, timestamp: float):
        data = msg['data']
        chan = msg['channel']
        ts = int(data['microtimestamp'])
        pair = pair_exchange_to_std(chan.split('_')[-1])

        book = {BID: sd(), ASK: sd()}
        for side in (BID, ASK):
            for price, size, order_id in data[side + 's']:
                price = Decimal(price)
                size = Decimal(size)
                book[side].get(price, sd())[order_id] = size
        self.l3_book[pair] = book
        await self.book_callback(self.l3_book[pair], L3_BOOK,
                                 pair, False, False,
                                 timestamp_normalize(self.id, ts), timestamp)
Exemple #13
0
    async def _book_snapshot(self, msg):
        timestamp = msg["params"]["data"]["timestamp"]
        pair = msg["params"]["data"]["instrument_name"]
        self.l2_book[pair] = {
            BID: sd({
                Decimal(price): Decimal(amount)
                # _ is always 'new' for snapshot
                for _, price, amount in msg["params"]["data"]["bids"]
            }),
            ASK: sd({
                Decimal(price): Decimal(amount)
                for _, price, amount in msg["params"]["data"]["asks"]
            })
        }

        await self.book_callback(self.l2_book[pair], L2_BOOK, pair, True, None, timestamp_normalize(self.id, timestamp))
Exemple #14
0
    async def _snapshot(self, pair: str) -> None:
        url = f'{self.rest_endpoint}/depth?symbol={pair}&limit={self.book_depth}'

        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                response.raise_for_status()
                resp = await response.json()

                std_pair = symbol_exchange_to_std(pair)
                self.last_update_id[std_pair] = resp['lastUpdateId']
                self.l2_book[std_pair] = {BID: sd(), ASK: sd()}
                for s, side in (('bids', BID), ('asks', ASK)):
                    for update in resp[s]:
                        price = Decimal(update[0])
                        amount = Decimal(update[1])
                        self.l2_book[std_pair][side][price] = amount
Exemple #15
0
    async def _book(self, msg, chan_id):
        msg_type = msg[0][0]
        pair = None
        # initial update (i.e. snapshot)
        if msg_type == 'i':
            pair = msg[0][1]['currencyPair']
            pair = pair_exchange_to_std(pair)
            self.l3_book[pair] = {BID: sd(), ASK: sd()}
            # 0 is asks, 1 is bids
            order_book = msg[0][1]['orderBook']
            for key in order_book[0]:
                amount = Decimal(order_book[0][key])
                price = Decimal(key)
                self.l3_book[pair][ASK][price] = amount

            for key in order_book[1]:
                amount = Decimal(order_book[1][key])
                price = Decimal(key)
                self.l3_book[pair][BID][price] = amount
        else:
            pair = poloniex_id_pair_mapping[chan_id]
            pair = pair_exchange_to_std(pair)
            for update in msg:
                msg_type = update[0]
                # order book update
                if msg_type == 'o':
                    side = ASK if update[1] == 0 else BID
                    price = Decimal(update[2])
                    amount = Decimal(update[3])
                    if amount == 0:
                        del self.l3_book[pair][side][price]
                    else:
                        self.l3_book[pair][side][price] = amount
                elif msg_type == 't':
                    # index 1 is trade id, 2 is side, 3 is price, 4 is amount, 5 is timestamp
                    price = Decimal(update[3])
                    side = ASK if update[2] == 0 else BID
                    amount = Decimal(update[4])
                    await self.callbacks[TRADES](feed=self.id,
                                                 pair=pair,
                                                 side=side,
                                                 amount=amount,
                                                 price=price)
                else:
                    LOG.warning("{} - Unexpected message received: {}".format(self.id, msg))

        await self.callbacks[L3_BOOK](feed=self.id, pair=pair, book=self.l3_book[pair])
Exemple #16
0
 async def _book_snapshot(self, msg: dict):
     pair = pair_exchange_to_std(msg['symbol'])
     self.l2_book[pair] = {
         BID:
         sd({
             Decimal(bid['price']): Decimal(bid['size'])
             for bid in msg['bid']
         }),
         ASK:
         sd({
             Decimal(ask['price']): Decimal(ask['size'])
             for ask in msg['ask']
         })
     }
     await self.book_callback(
         self.l2_book[pair], L2_BOOK, pair, True, None,
         timestamp_normalize(self.id, msg['timestamp']))
Exemple #17
0
    async def _book(self, msg: dict, pair: str, timestamp: float):
        delta = {BID: [], ASK: []}
        msg = msg[1:-2]

        if 'as' in msg[0]:
            # Snapshot
            self.l2_book[pair] = {
                BID:
                sd({
                    Decimal(update[0]): Decimal(update[1])
                    for update in msg[0]['bs']
                }),
                ASK:
                sd({
                    Decimal(update[0]): Decimal(update[1])
                    for update in msg[0]['as']
                })
            }
            await self.book_callback(self.l2_book[pair], L2_BOOK, pair, True,
                                     delta, timestamp, timestamp)
        else:
            for m in msg:
                for s, updates in m.items():
                    side = BID if s == 'b' else ASK
                    for update in updates:
                        price, size, *_ = update
                        price = Decimal(price)
                        size = Decimal(size)
                        if size == 0:
                            # Per Kraken's technical support
                            # they deliver erroneous deletion messages
                            # periodically which should be ignored
                            if price in self.l2_book[pair][side]:
                                del self.l2_book[pair][side][price]
                                delta[side].append((price, 0))
                        else:
                            delta[side].append((price, size))
                            self.l2_book[pair][side][price] = size
            for side in (BID, ASK):
                while len(self.l2_book[pair][side]) > self.book_depth:
                    del_price = self.l2_book[pair][side].items(
                    )[0 if side == BID else -1][0]
                    del self.l2_book[pair][side][del_price]
                    delta[side].append((del_price, 0))
            await self.book_callback(self.l2_book[pair], L2_BOOK, pair, False,
                                     delta, timestamp, timestamp)
Exemple #18
0
    async def _pair_level2_snapshot(self, msg: dict, timestamp: float):
        pair = self.exchange_symbol_to_std_symbol(msg['product_id'])
        self.l2_book[pair] = {
            BID:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['bids']
            }),
            ASK:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in msg['asks']
            })
        }

        await self.book_callback(self.l2_book[pair], L2_BOOK, pair, True, None,
                                 timestamp, timestamp)
Exemple #19
0
    async def _book(self, msg: dict, timestamp: float):
        """
        {
            'ch':'market.BTC_CW.depth.step0',
            'ts':1565857755564,
            'tick':{
                'mrid':14848858327,
                'id':1565857755,
                'bids':[
                    [  Decimal('9829.99'), 1], ...
                ]
                'asks':[
                    [ 9830, 625], ...
                ]
            },
            'ts':1565857755552,
            'version':1565857755,
            'ch':'market.BTC_CW.depth.step0'
        }
        """
        pair = pair_std_to_exchange(msg['ch'].split('.')[1], self.id)
        data = msg['tick']
        forced = pair not in self.l2_book

        update = {
            BID:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in data['bids']
            }),
            ASK:
            sd({
                Decimal(price): Decimal(amount)
                for price, amount in data['asks']
            })
        }

        if not forced:
            self.previous_book[pair] = self.l2_book[pair]
        self.l2_book[pair] = update

        await self.book_callback(self.l2_book[pair], L2_BOOK, pair,
                                 forced, False,
                                 timestamp_normalize(self.id,
                                                     msg['ts']), timestamp)
Exemple #20
0
    def __init__(self, pairs=None, channels=None, callbacks=None, **kwargs):
        if len(pairs) != 1:
            LOG.error("Gemini requires a websocket per trading pair")
            raise ValueError("Gemini requires a websocket per trading pair")
        if channels is not None:
            LOG.error("Gemini does not support different channels")
            raise ValueError("Gemini does not support different channels")
        self.pair = pairs[0]

        super().__init__('wss://api.gemini.com/v1/marketdata/',
                         pairs=None,
                         channels=None,
                         callbacks=callbacks,
                         **kwargs)

        self.address += pair_std_to_exchange(self.pair, self.id)
        self.l2_book = {self.pair: {BID: sd(), ASK: sd()}}
        self.seq_no = None
Exemple #21
0
    def __init__(self, pairs=None, channels=None, callbacks=None, **kwargs):
        self.channels = None
        if pairs and len(pairs) == 1:
            self.pair = pairs[0]
            super().__init__('wss://api.gemini.com/v1/marketdata/',
                            pairs=None,
                            channels=None,
                            callbacks=callbacks,
                            **kwargs)

            self.address += pair_std_to_exchange(self.pair, self.id)
            self.l2_book = {self.pair: {BID: sd(), ASK: sd()}}
            self.seq_no = None
            self.pairs = pairs
        else:
            self.pairs = pairs
            self.config = kwargs.get('config', None)
            self.callbacks = callbacks
Exemple #22
0
    async def _snapshot(self, pairs: list, conn: AsyncConnection):
        await asyncio.sleep(5)
        urls = [
            f'https://www.bitstamp.net/api/v2/order_book/{sym}'
            for sym in pairs
        ]
        results = [await conn.get(url) for url in urls]
        results = [json.loads(resp, parse_float=Decimal) for resp in results]

        for r, pair in zip(results, pairs):
            std_pair = symbol_exchange_to_std(pair) if pair else 'BTC-USD'
            self.last_update_id[std_pair] = r['timestamp']
            self.l2_book[std_pair] = {BID: sd(), ASK: sd()}
            for s, side in (('bids', BID), ('asks', ASK)):
                for update in r[s]:
                    price = Decimal(update[0])
                    amount = Decimal(update[1])
                    self.l2_book[std_pair][side][price] = amount
Exemple #23
0
    async def _l3_book(self, msg):
        data = msg['data']
        chan = msg['channel']
        timestamp = data['timestamp']
        pair = pair_exchange_to_std(chan.split('_')[-1])

        book = {BID: sd(), ASK: sd()}
        for side in (BID, ASK):
            for price, size, order_id in data[side + 's']:
                price = Decimal(price)
                size = Decimal(size)
                book[side].get(price, sd())[order_id] = size
        self.l3_book[pair] = book
        await self.book_callback(pair=pair,
                                 book_type=L3_BOOK,
                                 forced=False,
                                 delta=False,
                                 timestamp=timestamp)
Exemple #24
0
    async def _book_snapshot(self, pairs: list):
        # Coinbase needs some time to send messages to us
        # before we request the snapshot. If we don't sleep
        # the snapshot seq no could be much earlier than
        # the subsequent messages, causing a seq no mismatch.
        await asyncio.sleep(2)

        url = 'https://api.pro.coinbase.com/products/{}/book?level=3'
        urls = [url.format(pair) for pair in pairs]

        results = []
        for url in urls:
            # getting whole book on a initial request
            ret = await self.http_conn.read(url)
            results.append(ret)
            # rate limit - 3 per second
            await asyncio.sleep(0.3)

        timestamp = time.time()
        for res, pair in zip(results, pairs):
            orders = json.loads(res, parse_float=Decimal)
            npair = self.exchange_symbol_to_std_symbol(pair)
            self.l3_book[npair] = {BID: sd(), ASK: sd()}
            self.seq_no[npair] = orders['sequence']
            for side in (BID, ASK):
                # orders:
                # {'bid':['36805.81', '0.03757999', '3b69b4e9-12f0-4a8a-b97f-66f6253db226']}
                # {'ask':['36805.82', '0.008421', 'e1bf1be9-c323-40ca-97db-87d239ff8a96']}
                for price, size, order_id in orders[side + 's']:
                    price = Decimal(price)
                    size = Decimal(size)
                    if price in self.l3_book[npair][side]:
                        self.l3_book[npair][side][price][order_id] = size
                    else:
                        self.l3_book[npair][side][price] = {order_id: size}
                    #  self.l3_book
                    # 'bids': {Decimal('36804.93'): {'f0ad3603-cafc-484a-bac5-6fde4c12cedf': Decimal('0.09719021'), 'c2061f36-11fd-4d77-a315-2398021930c6': Decimal('2.97219063')}}
                    # 'asks': {Decimal('36804.93'): {'f0ad3603-cafc-484a-bac5-6fde4c12cedf': Decimal('0.09719021'), 'c2061f36-11fd-4d77-a315-2398021930c6': Decimal('2.97219063')}}
                    self.order_map[order_id] = (price, size)
                    # self.order_map:
                    # '07e01fbf-448c-4544-9547-7f531ce86351': (Decimal('1000000000'), Decimal('0.001'))
            # def book_callback(self, book: dict, book_type: str, symbol: str, forced: bool, delta: dict, timestamp: float, receipt_timestamp: float):
            await self.book_callback(self.l3_book[npair], L3_BOOK, npair, True,
                                     None, timestamp, timestamp)
Exemple #25
0
    async def _snapshot(self, pair: str) -> None:
        max_depth = self.max_depth if self.max_depth else 1000
        if max_depth not in self.valid_depths:
            for d in self.valid_depths:
                if d > max_depth:
                    max_depth = d

        url = f'{self.rest_endpoint}/depth?symbol={pair}&limit={max_depth}'
        resp = await self.http_conn.read(url)
        resp = json.loads(resp, parse_float=Decimal)

        std_pair = self.exchange_symbol_to_std_symbol(pair)
        self.last_update_id[std_pair] = resp['lastUpdateId']
        self.l2_book[std_pair] = {BID: sd(), ASK: sd()}
        for s, side in (('bids', BID), ('asks', ASK)):
            for update in resp[s]:
                price = Decimal(update[0])
                amount = Decimal(update[1])
                self.l2_book[std_pair][side][price] = amount
Exemple #26
0
    async def _book(self, msg: dict, timestamp: float):
        pair = self.exchange_symbol_to_std_symbol(msg['id'])
        delta = {BID: [], ASK: []}
        forced = False

        if msg['type'] == 'channel_data':
            for side, data in msg['contents'].items():
                if side == 'offset':
                    offset = int(data)
                    continue
                side = BID if side == 'bids' else ASK
                for entry in data:
                    price = Decimal(entry[0])
                    amount = Decimal(entry[1])

                    if price in self.offsets[
                            pair] and offset <= self.offsets[pair][price]:
                        continue

                    self.offsets[pair][price] = offset
                    if amount == 0:
                        if price in self.l2_book[pair]:
                            del self.l2_book[pair][side][price]
                        delta[side].append((price, 0))
                    else:
                        self.l2_book[pair][side][price] = amount
                        delta[side].append((price, amount))
        else:
            # snapshot
            self.l2_book[pair] = {BID: sd(), ASK: sd()}
            self.offsets[pair] = {}
            forced = True

            for side, data in msg['contents'].items():
                side = BID if side == 'bids' else ASK
                for entry in data:
                    self.offsets[pair][Decimal(entry['price'])] = int(
                        entry['offset'])
                    self.l2_book[pair][side][Decimal(
                        entry['price'])] = Decimal(entry['size'])

        await self.book_callback(self.l2_book[pair], L2_BOOK, pair, forced,
                                 delta, timestamp, timestamp)
Exemple #27
0
    async def _snapshot(self, pairs: list):
        urls = [f'{self.rest_endpoint}/depth?symbol={sym}&limit={self.book_depth}' for sym in pairs]
        async def fetch(session, url):
            async with session.get(url) as response:
                response.raise_for_status()
                return await response.json()

        async with aiohttp.ClientSession() as session:
            results = await asyncio.gather(*[fetch(session, url) for url in urls])

        for r, pair in zip(results, pairs):
            std_pair = pair_exchange_to_std(pair)
            self.last_update_id[pair] = r['lastUpdateId']
            self.l2_book[std_pair] = {BID: sd(), ASK: sd()}
            for s, side in (('bids', BID), ('asks', ASK)):
                for update in r[s]:
                    price = Decimal(update[0])
                    amount = Decimal(update[1])
                    self.l2_book[std_pair][side][price] = amount
Exemple #28
0
    async def _l2_book(self, msg):
        """
        top 10 orders from each side
        """
        timestamp = msg['data'][0]['timestamp']
        pair = None

        for update in msg['data']:
            pair = update['symbol']
            self.l2_book[pair][BID] = sd({
                Decimal(price): Decimal(amount)
                for price, amount in update['bids']
            })
            self.l2_book[pair][ASK] = sd({
                Decimal(price): Decimal(amount)
                for price, amount in update['asks']
            })

        await self.callbacks[L2_BOOK](feed=self.id, pair=pair, book=self.l2_book[pair], timestamp=timestamp)
Exemple #29
0
    async def _l2_book(self, msg):
        data = msg['data']
        chan = msg['channel']
        timestamp = data['timestamp']
        pair = pair_exchange_to_std(chan.split('_')[-1])

        book = {}
        for side in (BID, ASK):
            book[side] = sd({Decimal(price): Decimal(size) for price, size in data[side + 's']})
        self.l2_book[pair] = book
        await self.book_callback(pair=pair, book_type=L2_BOOK, forced=False, delta=False, timestamp=timestamp)
Exemple #30
0
    async def _snapshot(self, pairs: list):
        await asyncio.sleep(5)
        urls = [f'https://www.bitstamp.net/api/v2/order_book/{sym}' for sym in pairs]

        async def fetch(session, url):
            async with session.get(url) as response:
                response.raise_for_status()
                return await response.json()

        async with aiohttp.ClientSession() as session:
            results = await asyncio.gather(*[fetch(session, url) for url in urls])

        for r, pair in zip(results, pairs):
            std_pair = pair_exchange_to_std(pair) if pair else 'BTC-USD'
            self.last_update_id[std_pair] = r['timestamp']
            self.l2_book[std_pair] = {BID: sd(), ASK: sd()}
            for s, side in (('bids', BID), ('asks', ASK)):
                for update in r[s]:
                    price = Decimal(update[0])
                    amount = Decimal(update[1])
                    self.l2_book[std_pair][side][price] = amount