Exemplo n.º 1
0
    async def book_callback(self, book_type: str, book: OrderBook, receipt_timestamp: float, timestamp=None, raw=None, sequence_number=None, checksum=None, delta=None):
        if self.cross_check:
            self.check_bid_ask_overlapping(book)

        book.timestamp = timestamp
        book.raw = raw
        book.sequence_number = sequence_number
        book.delta = delta
        book.checksum = checksum
        await self.callback(book_type, book, receipt_timestamp)
Exemplo n.º 2
0
    async def l2_book(self, symbol: str, retry_count=0, retry_delay=60):
        ret = OrderBook(self.id, symbol)
        symbol = self.std_symbol_to_exchange_symbol(symbol)

        data = await self.http_conn.read(
            f"{self.api}get_order_book?depth=10000&instrument_name={symbol}",
            retry_count=retry_count,
            retry_delay=retry_delay)
        data = json.loads(data, parse_float=Decimal)
        for side in ('bids', 'asks'):
            for entry_bid in data["result"][side]:
                price, amount = entry_bid
                ret.book[side][price] = amount
        return ret
Exemplo n.º 3
0
    async def _rest_book(self,
                         symbol: str,
                         l3=False,
                         retry_count=0,
                         retry_delay=60):
        ret = OrderBook(self.id, symbol)

        symbol = self.std_symbol_to_exchange_symbol(symbol)
        funding = 'f' in symbol

        precision = 'R0' if l3 is True else 'P0'
        r = await self.http_conn.read(
            f"{self.api}/book/{symbol}/{precision}?len=100",
            retry_delay=retry_delay,
            retry_count=retry_count)
        data = json.loads(r, parse_float=Decimal)

        if l3:
            for entry in data:
                if funding:
                    order_id, period, price, amount = entry
                    update = (abs(amount), period)
                else:
                    order_id, price, amount = entry
                    update = abs(amount)
                amount = Decimal(amount)
                price = Decimal(price)
                side = BID if (amount > 0 and not funding) or (
                    amount < 0 and funding) else ASK
                if price not in ret.book[side]:
                    ret.book[side][price] = {order_id: update}
                else:
                    ret.book[side][price][order_id] = update
        else:
            for entry in data:
                if funding:
                    price, period, _, amount = entry
                    update = (abs(amount), period)
                else:
                    price, _, amount = entry
                    update = abs(amount)
                price = Decimal(price)
                amount = Decimal(amount)
                side = BID if (amount > 0 and not funding) or (
                    amount < 0 and funding) else ASK
                ret.book[side][price] = update

        return ret
Exemplo n.º 4
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
                    break

        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] = OrderBook(
            self.id,
            std_pair,
            max_depth=self.max_depth,
            bids={Decimal(u[0]): Decimal(u[1])
                  for u in resp['bids']},
            asks={Decimal(u[0]): Decimal(u[1])
                  for u in resp['asks']})
        await self.book_callback(L2_BOOK,
                                 self._l2_book[std_pair],
                                 time.time(),
                                 timestamp=None,
                                 raw=resp,
                                 sequence_number=self.last_update_id[std_pair])
Exemplo n.º 5
0
 def _reset(self):
     self.partial_received = defaultdict(bool)
     self.order_id = {}
     self.open_orders = {}
     for pair in self.normalized_symbols:
         self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)
         self.order_id[pair] = defaultdict(dict)
Exemplo n.º 6
0
    async def _book(self, msg: dict, timestamp: float):
        if msg['action'] == 'partial':
            # snapshot
            for update in msg['data']:
                pair = self.exchange_symbol_to_std_symbol(update['instrument_id'])
                bids = {Decimal(price): Decimal(amount) for price, amount, *_ in update['bids']}
                asks = {Decimal(price): Decimal(amount) for price, amount, *_ in update['asks']}
                self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth, checksum_format='OKCOIN', bids=bids, asks=asks)

                if self.checksum_validation and self._l2_book[pair].book.checksum() != (update['checksum'] & 0xFFFFFFFF):
                    raise BadChecksum
                await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(update['timestamp']), raw=msg, checksum=update['checksum'] & 0xFFFFFFFF)
        else:
            # update
            for update in msg['data']:
                delta = {BID: [], ASK: []}
                pair = self.exchange_symbol_to_std_symbol(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].book[s]:
                                delta[s].append((price, 0))
                                del self._l2_book[pair].book[s][price]
                        else:
                            delta[s].append((price, amount))
                            self._l2_book[pair].book[s][price] = amount

                if self.checksum_validation and self._l2_book[pair].book.checksum() != (update['checksum'] & 0xFFFFFFFF):
                    raise BadChecksum
                await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(update['timestamp']), raw=msg, delta=delta, checksum=update['checksum'] & 0xFFFFFFFF)
Exemplo n.º 7
0
    async def _book(self, msg: dict, pair: str, timestamp: float):
        delta = {BID: [], ASK: []}
        msg = msg[1:-2]

        if 'as' in msg[0]:
            # Snapshot
            bids = {
                Decimal(update[0]): Decimal(update[1])
                for update in msg[0]['bs']
            }
            asks = {
                Decimal(update[0]): Decimal(update[1])
                for update in msg[0]['as']
            }
            self._l2_book[pair] = OrderBook(
                self.id,
                pair,
                max_depth=self.max_depth,
                bids=bids,
                asks=asks,
                checksum_format='KRAKEN',
                truncate=self.max_depth != self.valid_depths[-1])
            await self.book_callback(L2_BOOK,
                                     self._l2_book[pair],
                                     timestamp,
                                     raw=msg)
        else:
            for m in msg:
                for s, updates in m.items():
                    side = False
                    if s == 'b':
                        side = BID
                    elif s == 'a':
                        side = ASK
                    if side:
                        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].book[side]:
                                    del self._l2_book[pair].book[side][price]
                                    delta[side].append((price, 0))
                            else:
                                delta[side].append((price, size))
                                self._l2_book[pair].book[side][price] = size

            if self.checksum_validation and 'c' in msg[0] and self._l2_book[
                    pair].book.checksum() != int(msg[0]['c']):
                raise BadChecksum("Checksum validation on orderbook failed")
            await self.book_callback(
                L2_BOOK,
                self._l2_book[pair],
                timestamp,
                delta=delta,
                raw=msg,
                checksum=int(msg[0]['c']) if 'c' in msg[0] else None)
Exemplo n.º 8
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 = self.exchange_symbol_to_std_symbol(msg['ch'].split('.')[1])
        data = msg['tick']

        # 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:
            if pair not in self._l2_book:
                self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)
            self._l2_book[pair].book.bids = {Decimal(price): Decimal(amount) for price, amount in data['bids']}
            self._l2_book[pair].book.asks = {Decimal(price): Decimal(amount) for price, amount in data['asks']}

            await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(msg['ts']), raw=msg)
Exemplo n.º 9
0
    async def _book(self, msg: dict, timestamp: float):
        '''
        {
            'instrument_name': 'BTC_USDT',
            'subscription': 'book.BTC_USDT.150',
            'channel': 'book',
            'depth': 150,
            'data': [
                {
                    'bids': [
                        [Decimal('57553.03'), Decimal('0.481606'), 2],
                        [Decimal('57552.47'), Decimal('0.000418'), 1],
                        ...
                    ]
                    'asks': [
                        [Decimal('57555.44'), Decimal('0.343236'), 1],
                        [Decimal('57555.95'), Decimal('0.026062'), 1],
                        ...
                    ]
                }
            ]
        }
        '''
        pair = self.exchange_symbol_to_std_symbol(msg['instrument_name'])
        for entry in msg['data']:
            if pair not in self._l2_book:
                self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)

            self._l2_book[pair].book.bids = {price: amount for price, amount, _ in entry['bids']}
            self._l2_book[pair].book.asks = {price: amount for price, amount, _ in entry['asks']}

            await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(entry['t']), raw=entry)
Exemplo n.º 10
0
    async def _snapshot(self, symbol: str, sequence_number: int):
        while True:
            ret, headers = await self.http_conn.read(
                f'https://api.bittrex.com/v3/markets/{symbol}/orderbook?depth={self.__depth()}',
                return_headers=True)
            seq = int(headers['Sequence'])
            if seq >= sequence_number:
                break
            await asyncio.sleep(1.0)

        self.seq_no[symbol] = seq
        data = json.loads(ret, parse_float=Decimal)
        self._l2_book[symbol] = OrderBook(self.id,
                                          symbol,
                                          max_depth=self.max_depth)
        for side, entries in data.items():
            self._l2_book[symbol].book[side] = {
                Decimal(e['rate']): Decimal(e['quantity'])
                for e in entries
            }
        await self.book_callback(L2_BOOK,
                                 self._l2_book[symbol],
                                 time.time(),
                                 raw=data,
                                 sequence_number=seq)
Exemplo n.º 11
0
    async def _book_snapshot(self, msg: dict, pair: str, timestamp: float):
        """
        {
            "feed": "book_snapshot",
            "product_id": "PI_XBTUSD",
            "timestamp": 1565342712774,
            "seq": 30007298,
            "bids": [
                {
                    "price": 11735.0,
                    "qty": 50000.0
                },
                ...
            ],
            "asks": [
                {
                    "price": 11739.0,
                    "qty": 47410.0
                },
                ...
            ],
            "tickSize": null
        }
        """
        bids = {Decimal(update['price']): Decimal(update['qty']) for update in msg['bids']}
        asks = {Decimal(update['price']): Decimal(update['qty']) for update in msg['asks']}
        if pair in self._l2_book:
            self._l2_book[pair].book.bids = bids
            self._l2_book[pair].book.asks = asks
        else:
            self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth, bids=bids, asks=asks)

        self._l2_book[pair].timestamp = self.timestamp_normalize(msg["timestamp"]) if "timestamp" in msg else None

        await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, raw=msg, sequence_number=msg['seq'])
Exemplo n.º 12
0
    async def _snapshot(self, symbol: str):
        str_to_sign = "GET" + self.rest_endpoints[0].routes.l2book.format(
            symbol)
        headers = self.generate_token(str_to_sign)
        data = await self.http_conn.read(self.rest_endpoints[0].route(
            'l2book', self.sandbox).format(symbol),
                                         header=headers)
        timestamp = time.time()
        data = json.loads(data, parse_float=Decimal)
        data = data['data']
        self.seq_no[symbol] = int(data['sequence'])
        bids = {
            Decimal(price): Decimal(amount)
            for price, amount in data['bids']
        }
        asks = {
            Decimal(price): Decimal(amount)
            for price, amount in data['asks']
        }
        self._l2_book[symbol] = OrderBook(self.id,
                                          symbol,
                                          max_depth=self.max_depth,
                                          bids=bids,
                                          asks=asks)

        await self.book_callback(L2_BOOK,
                                 self._l2_book[symbol],
                                 timestamp,
                                 raw=data,
                                 sequence_number=int(data['sequence']))
Exemplo n.º 13
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)

        urls = [self.rest_endpoints[0].route('l3book', self.sandbox).format(pair) for pair in pairs]

        results = []
        for url in urls:
            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] = OrderBook(self.id, pair, max_depth=self.max_depth)
            self.seq_no[npair] = orders['sequence']
            for side in (BID, ASK):
                for price, size, order_id in orders[side + 's']:
                    price = Decimal(price)
                    size = Decimal(size)
                    if price in self._l3_book[npair].book[side]:
                        self._l3_book[npair].book[side][price][order_id] = size
                    else:
                        self._l3_book[npair].book[side][price] = {order_id: size}
                    self.order_map[order_id] = (price, size)
            await self.book_callback(L3_BOOK, self._l3_book[npair], timestamp, raw=orders)
Exemplo n.º 14
0
    async def _snapshot(self, symbol: str):
        """
        {
            "id": 2679059670,
            "asks": [[price, amount], [...], ...],
            "bids": [[price, amount], [...], ...]
        }
        """
        url = f'https://api.gateio.ws/api/v4/spot/order_book?currency_pair={symbol}&limit=100&with_id=true'
        ret = await self.http_conn.read(url)
        data = json.loads(ret, parse_float=Decimal)

        symbol = self.exchange_symbol_to_std_symbol(symbol)
        self._l2_book[symbol] = OrderBook(self.id,
                                          symbol,
                                          max_depth=self.max_depth)
        self.last_update_id[symbol] = data['id']
        self._l2_book[symbol].book.bids = {
            Decimal(price): Decimal(amount)
            for price, amount in data['bids']
        }
        self._l2_book[symbol].book.asks = {
            Decimal(price): Decimal(amount)
            for price, amount in data['asks']
        }
        await self.book_callback(L2_BOOK,
                                 self._l2_book[symbol],
                                 time.time(),
                                 raw=data,
                                 sequence_number=data['id'])
Exemplo n.º 15
0
    async def _pair_l2_update(self, msg: str, timestamp: float):
        delta = {BID: [], ASK: []}
        pair = self.exchange_symbol_to_std_symbol(msg['symbol'])
        if msg['event'] == 'snapshot':
            # Reset the book
            self._l2_book[pair] = OrderBook(self.id,
                                            pair,
                                            max_depth=self.max_depth)

        for side in (BID, ASK):
            for update in msg[side + 's']:
                price = update['px']
                qty = update['qty']
                self._l2_book[pair].book[side][price] = qty
                if qty <= 0:
                    del self._l2_book[pair].book[side][price]
                delta[side].append((price, qty))

        await self.book_callback(
            L2_BOOK,
            self._l2_book[pair],
            timestamp,
            raw=msg,
            delta=delta if msg['event'] != 'snapshot' else None,
            sequence_number=msg['seqnum'])
Exemplo n.º 16
0
    async def _book(self, msg: dict, timestamp: float):
        sequence_number = msg['data']['seqnum']
        pair = self.exchange_symbol_to_std_symbol(msg['symbol'])
        delta = {BID: [], ASK: []}

        if msg['m'] == 'depth-snapshot':
            self.seq_no[pair] = sequence_number
            self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)
        else:
            # ignore messages while we wait for the snapshot
            if self.seq_no[pair] is None:
                return
            if self.seq_no[pair] + 1 != sequence_number:
                raise MissingSequenceNumber
            self.seq_no[pair] = sequence_number

        for side in ('bids', 'asks'):
            for price, amount in msg['data'][side]:
                s = BID if side == 'bids' else ASK
                price = Decimal(price)
                size = Decimal(amount)
                if size == 0:
                    delta[s].append((price, 0))
                    if price in self._l2_book[pair].book[s]:
                        del self._l2_book[pair].book[s][price]
                else:
                    delta[s].append((price, size))
                    self._l2_book[pair].book[s][price] = size

        await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(msg['data']['ts']), raw=msg, delta=delta if msg['m'] != 'depth-snapshot' else None, sequence_number=sequence_number)
Exemplo n.º 17
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
                    break

        resp = await self.http_conn.read(self.rest_endpoints[0].route(
            'l2book', self.sandbox).format(pair, max_depth))
        resp = json.loads(resp, parse_float=Decimal)
        timestamp = self.timestamp_normalize(
            resp['E']) if 'E' in resp else None

        std_pair = self.exchange_symbol_to_std_symbol(pair)
        self.last_update_id[std_pair] = resp['lastUpdateId']
        self._l2_book[std_pair] = OrderBook(
            self.id,
            std_pair,
            max_depth=self.max_depth,
            bids={Decimal(u[0]): Decimal(u[1])
                  for u in resp['bids']},
            asks={Decimal(u[0]): Decimal(u[1])
                  for u in resp['asks']})
        await self.book_callback(L2_BOOK,
                                 self._l2_book[std_pair],
                                 time.time(),
                                 timestamp=timestamp,
                                 raw=resp,
                                 sequence_number=self.last_update_id[std_pair])
Exemplo n.º 18
0
    async def l3_book(self, symbol: str, retry_count=1, retry_delay=60):
        data = await self._request('GET',
                                   f'/products/{symbol}/book?level=3',
                                   retry_count=retry_count,
                                   retry_delay=retry_delay)
        ret = OrderBook(self.id, symbol)

        for side in ('bids', 'asks'):
            for price, size, order_id in data[side]:
                price = Decimal(price)
                size = Decimal(size)
                if price in ret.book[side]:
                    ret.book[side][price][order_id] = size
                else:
                    ret.book[side][price] = {order_id: size}
        return ret
Exemplo n.º 19
0
    async def _snapshot(self, symbol: str, sequence_number: int):
        while True:
            ret, headers = await self.http_conn.read(
                self.rest_endpoints[0].route('l2book', self.sandbox).format(
                    symbol, self.__depth()),
                return_headers=True)
            seq = int(headers['Sequence'])
            if seq >= sequence_number:
                break
            await asyncio.sleep(1.0)

        self.seq_no[symbol] = seq
        data = json.loads(ret, parse_float=Decimal)
        self._l2_book[symbol] = OrderBook(self.id,
                                          symbol,
                                          max_depth=self.max_depth)
        for side, entries in data.items():
            self._l2_book[symbol].book[side] = {
                Decimal(e['rate']): Decimal(e['quantity'])
                for e in entries
            }
        await self.book_callback(L2_BOOK,
                                 self._l2_book[symbol],
                                 time.time(),
                                 raw=data,
                                 sequence_number=seq)
Exemplo n.º 20
0
    async def _book_snapshot(self, msg: dict, timestamp: float):
        """
        {
            'jsonrpc': '2.0',
            'method': 'subscription',
            'params': {
                'channel': 'book.BTC-PERPETUAL.raw',
                'data': {
                    'timestamp': 1598232105378,
                    'instrument_name': 'BTC-PERPETUAL',
                    'change_id': 21486665526, '
                    'bids': [['new', Decimal('11618.5'), Decimal('279310.0')], ..... ]
                    'asks': [[ ....... ]]
                }
            }
        }
        """
        ts = msg["params"]["data"]["timestamp"]
        pair = self.exchange_symbol_to_std_symbol(msg["params"]["data"]["instrument_name"])
        self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)
        self._l2_book[pair].book.bids = {Decimal(price): Decimal(amount) for _, price, amount in msg["params"]["data"]["bids"]}
        self._l2_book[pair].book.asks = {Decimal(price): Decimal(amount) for _, price, amount in msg["params"]["data"]["asks"]}
        self.seq_no[pair] = msg["params"]["data"]["change_id"]

        await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, timestamp=self.timestamp_normalize(ts), sequence_number=msg["params"]["data"]["change_id"], raw=msg)
Exemplo n.º 21
0
    async def _book(self, msg: dict, timestamp: float):
        """
        {
            "jsonrpc":"2.0",
            "method":"channelMessage",
            "params":{
                "channel":"lightning_board_BTC_JPY",
                "message":{
                    "mid_price":2534243.0,
                    "bids":[

                    ],
                    "asks":[
                        {
                        "price":2534500.0,
                        "size":0.0
                        },
                        {
                        "price":2536101.0,
                        "size":0.0
                        }
                    ]
                }
            }
        }
        """
        snapshot = msg['params']['channel'].startswith('lightning_board_snapshot')
        if snapshot:
            pair = msg['params']['channel'].split("lightning_board_snapshot")[1][1:]
        else:
            pair = msg['params']['channel'].split("lightning_board")[1][1:]
        pair = self.exchange_symbol_to_std_symbol(pair)

        # Ignore deltas until a snapshot is received
        if pair not in self._l2_book and not snapshot:
            return

        delta = None
        if snapshot:
            self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth)
        else:
            delta = {BID: [], ASK: []}

        data = msg['params']['message']
        for side in ('bids', 'asks'):
            s = BID if side == 'bids' else ASK
            if snapshot:
                self._l2_book[pair].book[side] = {d['price']: d['size'] for d in data[side]}
            else:
                for entry in data[side]:
                    if entry['size'] == 0:
                        if entry['price'] in self._l2_book[pair].book[side]:
                            del self._l2_book[pair].book[side][entry['price']]
                            delta[s].append((entry['price'], Decimal(0.0)))
                    else:
                        self._l2_book[pair].book[side][entry['price']] = entry['size']
                        delta[s].append((entry['price'], entry['size']))

        await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, raw=msg, delta=delta)
Exemplo n.º 22
0
 async def l2_book(self, symbol: str, retry_count=1, retry_delay=60):
     ret = OrderBook(self.id, symbol)
     sym = self.std_symbol_to_exchange_symbol(symbol)
     data = await self.http_conn.read(f"{self.api}/markets/{sym}/orderbook?depth=100", retry_count=retry_count, retry_delay=retry_delay)
     data = json.loads(data, parse_float=Decimal)['result']
     ret.book.bids = {u[0]: u[1] for u in data['bids']}
     ret.book.asks = {u[0]: u[1] for u in data['asks']}
     return ret
Exemplo n.º 23
0
 async def l2_book(self, symbol: str, retry_count=1, retry_delay=60):
     ret = OrderBook(self.id, symbol)
     sym = self.std_symbol_to_exchange_symbol(symbol).replace("/", "")
     data = await self._post_public("/public/Depth", {'pair': sym, 'count': 200}, retry_count=retry_count, retry_delay=retry_delay)
     for _, val in data['result'].items():
         ret.book.bids = {Decimal(u[0]): Decimal(u[1]) for u in val['bids']}
         ret.book.asks = {Decimal(u[0]): Decimal(u[1]) for u in val['asks']}
         return ret
Exemplo n.º 24
0
    async def l2_book(self, symbol: str, retry_count=1, retry_delay=60):
        ret = OrderBook(self.id, symbol)

        data = await self._get('orderBook/L2', self.std_symbol_to_exchange_symbol(symbol), retry_count, retry_delay)
        for update in data:
            side = ASK if update['side'] == 'Sell' else BID
            ret.book[side][decimal.Decimal(update['price'])] = decimal.Decimal(update['size'])
        return ret
Exemplo n.º 25
0
    async def _book(self, msg: dict, chan_id: int, timestamp: float):
        delta = {BID: [], ASK: []}
        msg_type = msg[0][0]
        pair = None
        # initial update (i.e. snapshot)
        if msg_type == 'i':
            delta = None
            pair = msg[0][1]['currencyPair']
            pair = self.exchange_symbol_to_std_symbol(pair)
            self._l2_book[pair] = OrderBook(self.id,
                                            pair,
                                            max_depth=self.max_depth)
            # 0 is asks, 1 is bids
            order_book = msg[0][1]['orderBook']
            for index, side in enumerate([ASK, BID]):
                for key in order_book[index]:
                    amount = Decimal(order_book[index][key])
                    price = Decimal(key)
                    self._l2_book[pair].book[side][price] = amount
        else:
            pair = self._channel_map[chan_id]
            pair = self.exchange_symbol_to_std_symbol(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:
                        delta[side].append((price, 0))
                        del self._l2_book[pair].book[side][price]
                    else:
                        delta[side].append((price, amount))
                        self._l2_book[pair].book[side][price] = amount
                elif msg_type == 't':
                    # index 1 is trade id, 2 is side, 3 is price, 4 is amount, 5 is timestamp, 6 is timestamp ms
                    _, order_id, _, price, amount, server_ts, _ = update
                    price = Decimal(price)
                    amount = Decimal(amount)
                    t = Trade(self.id,
                              pair,
                              BUY if update[2] == 1 else SELL,
                              amount,
                              price,
                              float(server_ts),
                              id=order_id,
                              raw=msg)
                    await self.callback(TRADES, t, timestamp)
                else:
                    LOG.warning("%s: Unexpected message received: %s", self.id,
                                msg)

        await self.book_callback(L2_BOOK,
                                 self._l2_book[pair],
                                 timestamp,
                                 delta=delta,
                                 raw=msg)
Exemplo n.º 26
0
 async def l2_book(self, symbol: str, retry_count=1, retry_delay=60):
     data = await self._request('GET',
                                f'/products/{symbol}/book?level=2',
                                retry_count=retry_count,
                                retry_delay=retry_delay)
     ret = OrderBook(self.id, symbol)
     ret.book.bids = {Decimal(u[0]): Decimal(u[1]) for u in data['bids']}
     ret.book.asks = {Decimal(u[0]): Decimal(u[1]) for u in data['asks']}
     return ret
Exemplo n.º 27
0
    async def _process_l3_book(self, msg: dict, timestamp: float):
        data = msg['data']
        chan = msg['channel']
        ts = int(data['microtimestamp'])
        pair = self.exchange_symbol_to_std_symbol(chan.split('_')[-1])

        book = OrderBook(self.id, pair, max_depth=self.max_depth)
        for side in (BID, ASK):
            for price, size, order_id in data[side + 's']:
                price = Decimal(price)
                size = Decimal(size)
                if price in book.book[side]:
                    book.book[side][price][order_id] = size
                else:
                    book.book[side][price] = {order_id: size}

        self._l3_book[pair] = book
        await self.book_callback(L3_BOOK, self._l3_book[pair], timestamp, timestamp=self.timestamp_normalize(ts), raw=msg)
Exemplo n.º 28
0
 async def l2_book(self, symbol: str, retry_count=1, retry_delay=60):
     ret = OrderBook(self.id, symbol)
     sym = self.std_symbol_to_exchange_symbol(symbol)
     data = await self._get("returnOrderBook",
                            params=f"&currencyPair={sym}",
                            retry_count=retry_count,
                            retry_delay=retry_delay)
     ret.book.bids = {Decimal(u[0]): Decimal(u[1]) for u in data['bids']}
     ret.book.asks = {Decimal(u[0]): Decimal(u[1]) for u in data['asks']}
     return ret
Exemplo n.º 29
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 self.http_conn.read(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 = self.exchange_symbol_to_std_symbol(pair) if pair else 'BTC-USD'
            self.last_update_id[std_pair] = r['timestamp']
            self._l2_book[std_pair] = OrderBook(self.id, std_pair, max_depth=self.max_depth, asks={Decimal(u[0]): Decimal(u[1]) for u in r['asks']}, bids={Decimal(u[0]): Decimal(u[1]) for u in r['bids']})
            await self.book_callback(L2_BOOK, self._l2_book[std_pair], time.time(), timestamp=float(r['timestamp']), raw=r)
Exemplo n.º 30
0
    async def _pair_level2_snapshot(self, msg: dict, timestamp: float):
        pair = self.exchange_symbol_to_std_symbol(msg['product_id'])
        bids = {Decimal(price): Decimal(amount) for price, amount in msg['bids']}
        asks = {Decimal(price): Decimal(amount) for price, amount in msg['asks']}
        if pair not in self._l2_book:
            self._l2_book[pair] = OrderBook(self.id, pair, max_depth=self.max_depth, bids=bids, asks=asks)
        else:
            self._l2_book[pair].book.bids = bids
            self._l2_book[pair].book.asks = asks

        await self.book_callback(L2_BOOK, self._l2_book[pair], timestamp, raw=msg)