def test_order_book_consolidation(): updater = Updater('123', '456', 'abc') updater.bids = { 'a': [500, 1], 'b': [500, 2], } updater.asks = {'c': [600, 4], 'd': [600, 6]} consolidated = updater.consolidated_order_book assert consolidated['asks'] == [[600, 10]] assert consolidated['bids'] == [[500, 3]]
def test_order_book_consolidation(self): updater = Updater('123', '456', 'abc') updater.bids = { 'a': [500, 1], 'b': [500, 2], } updater.asks = {'c': [600, 4], 'd': [600, 6]} consolidated = updater.consolidated_order_book self.assertEqual(consolidated['asks'], [[600, 10]]) self.assertEqual(consolidated['bids'], [[500, 3]])
def test_simple_updates(self): num_updates = 0 def hook(cob, t): nonlocal num_updates num_updates += 1 updater = Updater('XBTZAR', 'key', 'secret', [hook]) updater.url = 'ws://localhost:8765/simple_updates' with self.assertRaises(futures.TimeoutError): asyncio.run(asyncio.wait_for(updater.run(), 5)) self.assertEqual(num_updates, 4)
def test_broken_sequence(self): # the updater should automatically close the connection and later reconnect updater = Updater('XBTZAR', 'key', 'secret', []) updater.url = 'ws://localhost:8765/broken_sequence' async def main(): task = asyncio.create_task(updater.run()) await asyncio.sleep(1) self.assertEqual(updater.websocket.state, State.OPEN) await asyncio.sleep(2) self.assertEqual(updater.websocket.state, State.CLOSED) task.cancel() asyncio.run(main())
def test_backoff(self): updater = Updater('123', '456', 'abc') # 0 seconds should raise updater.time_last_connection_attempt = time.time() with self.assertRaises(BackoffException): updater.check_backoff() # 5 seconds should also raise updater.time_last_connection_attempt = time.time() - 5 with self.assertRaises(BackoffException): updater.check_backoff() # 12 seconds should not updater.time_last_connection_attempt = time.time() - 12 updater.check_backoff()
def test_processing(self): updater = Updater('123', '456', 'abc') self.assertDictEqual(updater.bids, {}) self.assertDictEqual(updater.asks, {}) # create a bid message = { 'create_update': { 'price': 100, 'volume': 10, 'order_id': 'a', 'type': 'BID' }, 'delete_update': {}, 'trade_updates': [] } trades = updater.process_message(message) expected_bids = {'a': [100, 10]} expected_asks = {} expected_trades = [] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades) # create an ask message = { 'create_update': { 'price': 100, 'volume': 10, 'order_id': 'b', 'type': 'ASK' }, 'delete_update': {}, 'trade_updates': [] } trades = updater.process_message(message) expected_bids = {'a': [100, 10]} expected_asks = {'b': [100, 10]} expected_trades = [] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades) # delete ask message = { 'create_update': {}, 'delete_update': { 'order_id': 'b' }, 'trade_updates': [] } trades = updater.process_message(message) expected_bids = {'a': [100, 10]} expected_asks = {} expected_trades = [] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades) # sell half of bid order message = { 'create_update': {}, 'delete_update': {}, 'trade_updates': [{ 'counter': 500, 'base': 5, 'maker_order_id': 'a' }] } trades = updater.process_message(message) expected_bids = {'a': [100, 5]} expected_asks = {} expected_trades = [{ 'type': 'sell', 'price': 100, 'base': 5, 'counter': 500, 'maker_order_id': 'a', }] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades) # sell remaining part of bid order message = { 'create_update': {}, 'delete_update': {}, 'trade_updates': [{ 'counter': 500, 'base': 5, 'maker_order_id': 'a' }] } trades = updater.process_message(message) expected_bids = {} expected_asks = {} expected_trades = [{ 'type': 'sell', 'price': 100, 'base': 5, 'counter': 500, 'maker_order_id': 'a', }] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades) # order is placed that is partially filled # first add an existing bid message = { 'create_update': { 'order_id': 'c', 'price': 150, 'volume': 10, 'type': 'BID', }, 'delete_update': {}, 'trade_updates': [] } updater.process_message(message) # buy order was placed and partially filled message = { 'create_update': { 'order_id': 'd', 'price': 150, 'volume': 50, 'type': 'ASK' }, 'delete_update': {}, 'trade_updates': [{ 'counter': 1500, 'base': 10, 'maker_order_id': 'c' }] } trades = updater.process_message(message) expected_bids = {} expected_asks = {'d': [150, 50]} expected_trades = [{ 'type': 'sell', 'price': 150, 'base': 10, 'counter': 1500, 'maker_order_id': 'c', }] self.assertDictEqual(updater.bids, expected_bids) self.assertDictEqual(updater.asks, expected_asks) self.assertListEqual(trades, expected_trades)
def test_disconnecting_server(self): # no exceptions should be raised, the coroutine just finishes updater = Updater('XBTZAR', 'key', 'secret', []) updater.url = 'ws://localhost:8765/close_connection' asyncio.run(updater.run())