/test/integration/test_kucoin_order_book_tracker.py

https://github.com/CoinAlpha/hummingbot · Python · 128 lines · 103 code · 15 blank · 10 comment · 11 complexity · 08579b128073197d28a58b43c9b6d3f1 MD5 · raw file

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