/test/integration/test_bamboo_relay_order_book_tracker.py

https://github.com/CoinAlpha/hummingbot · Python · 117 lines · 93 code · 16 blank · 8 comment · 8 complexity · 1c77ceec5c2b5f512f77b943bf6b20c8 MD5 · raw file

  1. #!/usr/bin/env python
  2. from os.path import join, realpath
  3. import sys; sys.path.insert(0, realpath(join(__file__, "../../../")))
  4. import math
  5. import asyncio
  6. import logging
  7. import unittest
  8. from typing import (
  9. Dict,
  10. Optional,
  11. List
  12. )
  13. from hummingbot.core.event.event_logger import EventLogger
  14. from hummingbot.core.event.events import (
  15. OrderBookEvent,
  16. OrderBookTradeEvent,
  17. TradeType
  18. )
  19. from hummingbot.connector.exchange.bamboo_relay.bamboo_relay_order_book_tracker import BambooRelayOrderBookTracker
  20. from hummingbot.core.data_type.order_book import OrderBook
  21. from hummingbot.core.utils.async_utils import (
  22. safe_ensure_future,
  23. safe_gather,
  24. )
  25. class BambooRelayOrderBookTrackerUnitTest(unittest.TestCase):
  26. order_book_tracker: Optional[BambooRelayOrderBookTracker] = None
  27. events: List[OrderBookEvent] = [
  28. OrderBookEvent.TradeEvent
  29. ]
  30. trading_pairs: List[str] = [
  31. "WETH-DAI",
  32. "ZRX-WETH",
  33. "WETH-USDC",
  34. "DAI-USDC"
  35. ]
  36. @classmethod
  37. def setUpClass(cls):
  38. cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
  39. cls.order_book_tracker: BambooRelayOrderBookTracker = BambooRelayOrderBookTracker(
  40. trading_pairs=cls.trading_pairs
  41. )
  42. cls.order_book_tracker_task: asyncio.Task = safe_ensure_future(cls.order_book_tracker.start())
  43. cls.ev_loop.run_until_complete(cls.wait_til_tracker_ready())
  44. @classmethod
  45. async def wait_til_tracker_ready(cls):
  46. await cls.order_book_tracker._order_books_initialized.wait()
  47. async def run_parallel_async(self, *tasks, timeout=None):
  48. future: asyncio.Future = safe_ensure_future(safe_gather(*tasks))
  49. timer = 0
  50. while not future.done():
  51. if timeout and timer > timeout:
  52. raise Exception("Time out running parallel async task in tests.")
  53. timer += 1
  54. await asyncio.sleep(1.0)
  55. return future.result()
  56. def run_parallel(self, *tasks):
  57. return self.ev_loop.run_until_complete(self.run_parallel_async(*tasks))
  58. def setUp(self):
  59. self.event_logger = EventLogger()
  60. for event_tag in self.events:
  61. for trading_pair, order_book in self.order_book_tracker.order_books.items():
  62. order_book.add_listener(event_tag, self.event_logger)
  63. @unittest.skipUnless(any("test_order_book_trade_event_emission" in arg for arg in sys.argv),
  64. "test_order_book_trade_event_emission test requires waiting or manual trade.")
  65. def test_order_book_trade_event_emission(self):
  66. """
  67. Test if order book tracker is able to retrieve order book trade message from exchange and
  68. emit order book trade events after correctly parsing the trade messages
  69. """
  70. self.run_parallel(self.event_logger.wait_for(OrderBookTradeEvent))
  71. for ob_trade_event in self.event_logger.event_log:
  72. self.assertTrue(type(ob_trade_event) == OrderBookTradeEvent)
  73. self.assertTrue(ob_trade_event.trading_pair in self.trading_pairs)
  74. self.assertTrue(type(ob_trade_event.timestamp) in [float, int])
  75. self.assertTrue(type(ob_trade_event.amount) == float)
  76. self.assertTrue(type(ob_trade_event.price) == float)
  77. self.assertTrue(type(ob_trade_event.type) == TradeType)
  78. self.assertTrue(math.ceil(math.log10(ob_trade_event.timestamp)) == 10)
  79. self.assertTrue(ob_trade_event.amount > 0)
  80. self.assertTrue(ob_trade_event.price > 0)
  81. def test_tracker_integrity(self):
  82. # Wait 5 seconds to process some diffs.
  83. self.ev_loop.run_until_complete(asyncio.sleep(5.0))
  84. order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books
  85. weth_dai_book: OrderBook = order_books["WETH-DAI"]
  86. zrx_weth_book: OrderBook = order_books["ZRX-WETH"]
  87. # print(weth_dai_book.snapshot)
  88. # print(zrx_weth_book.snapshot)
  89. self.assertGreaterEqual(weth_dai_book.get_price_for_volume(True, 10).result_price,
  90. weth_dai_book.get_price(True))
  91. self.assertLessEqual(weth_dai_book.get_price_for_volume(False, 10).result_price,
  92. weth_dai_book.get_price(False))
  93. self.assertGreaterEqual(zrx_weth_book.get_price_for_volume(True, 10).result_price,
  94. zrx_weth_book.get_price(True))
  95. self.assertLessEqual(zrx_weth_book.get_price_for_volume(False, 10).result_price,
  96. zrx_weth_book.get_price(False))
  97. def main():
  98. logging.basicConfig(level=logging.INFO)
  99. unittest.main()
  100. if __name__ == "__main__":
  101. main()