async def _liquidations(self, msg: dict, timestamp: float): """ { "e":"forceOrder", // Event Type "E":1568014460893, // Event Time "o":{ "s":"BTCUSDT", // Symbol "S":"SELL", // Side "o":"LIMIT", // Order Type "f":"IOC", // Time in Force "q":"0.014", // Original Quantity "p":"9910", // Price "ap":"9910", // Average Price "X":"FILLED", // Order Status "l":"0.014", // Order Last Filled Quantity "z":"0.014", // Order Filled Accumulated Quantity "T":1568014460893, // Order Trade Time } } """ pair = self.exchange_symbol_to_std_symbol(msg['o']['s']) liq = Liquidation(self.id, pair, SELL if msg['o']['S'] == 'SELL' else BUY, Decimal(msg['o']['q']), Decimal(msg['o']['p']), None, FILLED if msg['o']['X'] == 'FILLED' else UNFILLED, self.timestamp_normalize(msg['E']), raw=msg) await self.callback(LIQUIDATIONS, liq, receipt_timestamp=timestamp)
async def _trade(self, msg: dict, timestamp: float): """ example message: {"channel": "trades", "market": "BTC-PERP", "type": "update", "data": [{"id": null, "price": 10738.75, "size": 0.3616, "side": "buy", "liquidation": false, "time": "2019-08-03T12:20:19.170586+00:00"}]} """ for trade in msg['data']: t = Trade(self.id, self.exchange_symbol_to_std_symbol(msg['market']), BUY if trade['side'] == 'buy' else SELL, Decimal(trade['size']), Decimal(trade['price']), float(self.timestamp_normalize(trade['time'])), id=str(trade['id']), raw=trade) await self.callback(TRADES, t, timestamp) if bool(trade['liquidation']): liq = Liquidation( self.id, self.exchange_symbol_to_std_symbol(msg['market']), BUY if trade['side'] == 'buy' else SELL, Decimal(trade['size']), Decimal(trade['price']), str(trade['id']), FILLED, float(self.timestamp_normalize(trade['time'])), raw=trade) await self.callback(LIQUIDATIONS, liq, timestamp)
async def _liquidation(self, msg: dict, timestamp: float): ''' { 'topic': 'liquidation.EOSUSDT', 'data': { 'symbol': 'EOSUSDT', 'side': 'Buy', 'price': '3.950', 'qty': '58.0', 'time': 1632586154956 } } ''' liq = Liquidation( self.id, self.exchange_symbol_to_std_symbol(msg['data']['symbol']), BUY if msg['data']['side'] == 'Buy' else SELL, Decimal(msg['data']['qty']), Decimal(msg['data']['price']), None, None, self.timestamp_normalize(msg['data']['time']), raw=msg ) await self.callback(LIQUIDATIONS, liq, timestamp)
def test_liquidation(): t = Liquidation( 'BINANCE_FUTURES', 'BTC-USD-PERP', BUY, Decimal(10), Decimal(100), '1234-abcd-6789-1234', UNFILLED, time(), ) d = t.to_dict(numeric_type=str) d = json.dumps(d) d = json.loads(d) t2 = Liquidation.from_dict(d) assert t == t2
async def _liquidation(self, msg: dict, timestamp: float): """ liquidation msg example { 'orderID': '9513c849-ca0d-4e11-8190-9d221972288c', 'symbol': 'XBTUSD', 'side': 'Buy', 'price': 6833.5, 'leavesQty': 2020 } """ if msg['action'] == 'insert': for data in msg['data']: liq = Liquidation( self.id, self.exchange_symbol_to_std_symbol(data['symbol']), BUY if data['side'] == 'Buy' else SELL, Decimal(data['leavesQty']), Decimal(data['price']), data['orderID'], UNFILLED, None, raw=data ) await self.callback(LIQUIDATIONS, liq, timestamp)
async def _trade(self, msg: dict, timestamp: float): """ { "params": { "data": [ { "trade_seq": 933, "trade_id": "9178", "timestamp": 1550736299753, "tick_direction": 3, "price": 3948.69, "instrument_name": "BTC-PERPETUAL", "index_price": 3930.73, "direction": "sell", "amount": 10 } ], "channel": "trades.BTC-PERPETUAL.raw" }, "method": "subscription", "jsonrpc": "2.0" } """ for trade in msg["params"]["data"]: t = Trade( self.id, self.exchange_symbol_to_std_symbol(trade["instrument_name"]), BUY if trade['direction'] == 'buy' else SELL, Decimal(trade['amount']), Decimal(trade['price']), self.timestamp_normalize(trade['timestamp']), id=trade['trade_id'], raw=trade ) await self.callback(TRADES, t, timestamp) if 'liquidation' in trade: liq = Liquidation( self.id, self.exchange_symbol_to_std_symbol(trade["instrument_name"]), BUY if trade['direction'] == 'buy' else SELL, Decimal(trade['amount']), Decimal(trade['price']), trade['trade_id'], FILLED, self.timestamp_normalize(trade['timestamp']), raw=trade ) await self.callback(LIQUIDATIONS, liq, timestamp)
async def _liquidations(self, pairs: list): last_update = defaultdict(dict) """ for PERP liquidations, the following arguments are required: uly, state for FUTURES liquidations, the following arguments are required: uly, state, alias FUTURES, MARGIN and OPTION liquidation request not currently supported by the below """ while True: for pair in pairs: if 'SWAP' in pair: instrument_type = 'SWAP' uly = pair.split("-")[0] + "-" + pair.split("-")[1] else: continue for status in (FILLED, UNFILLED): data = await self.http_conn.read( self.rest_endpoints[0].route( 'liquidations', sandbox=self.sandbox).format( instrument_type, status, uly)) data = json.loads(data, parse_float=Decimal) timestamp = time.time() if len(data['data'][0]['details']) == 0 or ( len(data['data'][0]['details']) > 0 and last_update.get(pair) == data['data'][0]['details'][0]): continue for entry in data['data'][0]['details']: if pair in last_update: if entry == last_update[pair].get(status): break liq = Liquidation( self.id, pair, BUY if entry['side'] == 'buy' else SELL, Decimal(entry['sz']), Decimal(entry['bkPx']), None, status, self.timestamp_normalize(int(entry['ts'])), raw=data) await self.callback(LIQUIDATIONS, liq, timestamp) last_update[pair][status] = data['data'][0]['details'][0] await asyncio.sleep(0.1) await asyncio.sleep(60)
async def _liquidations(self, pairs: list): last_update = defaultdict(dict) """ for PERP liquidations, the following arguments are required: uly, state for FUTURES liquidations, the following arguments are required: uly, state, alias FUTURES, MARGIN and OPTION liquidation request not currently supported by the below """ while True: for pair in pairs: if 'PERP' in pair: instrument_type = 'SWAP' uly = pair.split("-")[0] + "-" + pair.split("-")[1] else: continue for status in (FILLED, UNFILLED): end_point = f"{self.api}v5/public/liquidation-orders?instType={instrument_type}&limit=100&state={status}&uly={uly}" data = await self.http_conn.read(end_point) data = json.loads(data, parse_float=Decimal) timestamp = time.time() if len(data['data'][0]['details']) == 0 or ( len(data['data'][0]['details']) > 0 and last_update.get(pair) == data['data'][0]['details'][0]): continue for entry in data['data'][0]['details']: if pair in last_update: if entry == last_update[pair].get(status): break liq = Liquidation( self.id, pair, BUY if entry['side'] == 'buy' else SELL, None, Decimal(entry['bkPx']), status, None, raw=data) await self.callback(LIQUIDATIONS, liq, timestamp) last_update[pair][status] = data['data'][0]['details'][0] await asyncio.sleep(0.1) await asyncio.sleep(60)