/test/integration/test_liquid_order_book_tracker.py

https://github.com/CoinAlpha/hummingbot · Python · 128 lines · 100 code · 16 blank · 12 comment · 11 complexity · 876ca412a6337478b44346195fc847be MD5 · raw file

  1. #!/usr/bin/env python
  2. from os.path import (
  3. join,
  4. realpath
  5. )
  6. import sys; sys.path.insert(0, realpath(join(__file__, "../../../")))
  7. from hummingbot.core.event.event_logger import EventLogger
  8. from hummingbot.core.event.events import (
  9. OrderBookEvent,
  10. OrderBookTradeEvent,
  11. TradeType
  12. )
  13. import asyncio
  14. import logging
  15. import math
  16. import unittest
  17. from typing import (
  18. Dict,
  19. Optional,
  20. List)
  21. from hummingbot.connector.exchange.liquid.liquid_order_book_tracker import LiquidOrderBookTracker
  22. from hummingbot.connector.exchange.liquid.liquid_api_order_book_data_source import LiquidAPIOrderBookDataSource
  23. from hummingbot.core.data_type.order_book import OrderBook
  24. from hummingbot.core.utils.async_utils import (
  25. safe_ensure_future,
  26. safe_gather,
  27. )
  28. class LiquidOrderBookTrackerUnitTest(unittest.TestCase):
  29. order_book_tracker: Optional[LiquidOrderBookTracker] = None
  30. events: List[OrderBookEvent] = [
  31. OrderBookEvent.TradeEvent
  32. ]
  33. trading_pairs: List[str] = [
  34. 'ETH-USD',
  35. 'LCX-BTC'
  36. ]
  37. @classmethod
  38. def setUpClass(cls):
  39. cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
  40. cls.order_book_tracker: LiquidOrderBookTracker = LiquidOrderBookTracker(cls.trading_pairs)
  41. cls.order_book_tracker_task: asyncio.Task = safe_ensure_future(cls.order_book_tracker.start())
  42. cls.ev_loop.run_until_complete(cls.wait_til_tracker_ready())
  43. @classmethod
  44. async def wait_til_tracker_ready(cls):
  45. while True:
  46. if len(cls.order_book_tracker.order_books) > 0:
  47. print("Initialized real-time order books.")
  48. return
  49. await asyncio.sleep(1)
  50. async def run_parallel_async(self, *tasks, timeout=None):
  51. future: asyncio.Future = safe_ensure_future(safe_gather(*tasks))
  52. timer = 0
  53. while not future.done():
  54. if timeout and timer > timeout:
  55. raise Exception("Time out running parallel async task in tests.")
  56. timer += 1
  57. # now = time.time()
  58. # next_iteration = now // 1.0 + 1
  59. await asyncio.sleep(1.0)
  60. return future.result()
  61. def run_parallel(self, *tasks):
  62. return self.ev_loop.run_until_complete(self.run_parallel_async(*tasks))
  63. def setUp(self):
  64. self.event_logger = EventLogger()
  65. for event_tag in self.events:
  66. for trading_pair, order_book in self.order_book_tracker.order_books.items():
  67. order_book.add_listener(event_tag, self.event_logger)
  68. def test_order_book_trade_event_emission(self):
  69. """
  70. Test if order book tracker is able to retrieve order book trade message from exchange and
  71. emit order book trade events after correctly parsing the trade messages
  72. """
  73. self.run_parallel(self.event_logger.wait_for(OrderBookTradeEvent))
  74. for ob_trade_event in self.event_logger.event_log:
  75. self.assertTrue(type(ob_trade_event) == OrderBookTradeEvent)
  76. self.assertTrue(ob_trade_event.trading_pair in self.trading_pairs)
  77. self.assertTrue(type(ob_trade_event.timestamp) == float)
  78. self.assertTrue(type(ob_trade_event.amount) == float)
  79. self.assertTrue(type(ob_trade_event.price) == float)
  80. self.assertTrue(type(ob_trade_event.type) == TradeType)
  81. self.assertTrue(math.ceil(math.log10(ob_trade_event.timestamp)) == 10)
  82. self.assertTrue(ob_trade_event.amount > 0)
  83. self.assertTrue(ob_trade_event.price > 0)
  84. def test_tracker_integrity(self):
  85. # Wait 5 seconds to process some diffs.
  86. self.ev_loop.run_until_complete(asyncio.sleep(5.0))
  87. order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books
  88. ethusd_book: OrderBook = order_books["ETH-USD"]
  89. lxcbtc_book: OrderBook = order_books["LCX-BTC"]
  90. # print("ethusd_book")
  91. # print(ethusd_book.snapshot)
  92. # print("lxcbtc_book")
  93. # print(lxcbtc_book.snapshot)
  94. self.assertGreaterEqual(ethusd_book.get_price_for_volume(True, 10).result_price,
  95. ethusd_book.get_price(True))
  96. self.assertLessEqual(lxcbtc_book.get_price_for_volume(False, 10).result_price,
  97. lxcbtc_book.get_price(False))
  98. for order_book in self.order_book_tracker.order_books.values():
  99. print(order_book.last_trade_price)
  100. self.assertFalse(math.isnan(order_book.last_trade_price))
  101. def test_api_get_last_traded_prices(self):
  102. prices = self.ev_loop.run_until_complete(
  103. LiquidAPIOrderBookDataSource.get_last_traded_prices(["BTC-USD", "ETH-USD"]))
  104. for key, value in prices.items():
  105. print(f"{key} last_trade_price: {value}")
  106. self.assertGreater(prices["BTC-USD"], 1000)
  107. self.assertLess(prices["ETH-USD"], 1000)
  108. def main():
  109. logging.basicConfig(level=logging.INFO)
  110. unittest.main()
  111. if __name__ == "__main__":
  112. main()