/test/integration/test_bittrex_order_book_tracker.py

https://github.com/CoinAlpha/hummingbot · Python · 105 lines · 79 code · 17 blank · 9 comment · 9 complexity · 3285d58a3cbd6a2104d1fe8c18ffe6a6 MD5 · raw file

  1. #!/usr/bin/env python
  2. import math
  3. import time
  4. from os.path import join, realpath
  5. import sys
  6. from hummingbot.core.event.event_logger import EventLogger
  7. from hummingbot.core.event.events import OrderBookEvent, OrderBookTradeEvent, TradeType
  8. import asyncio
  9. import logging
  10. from typing import Dict, Optional, List
  11. import unittest
  12. from hummingbot.connector.exchange.bittrex.bittrex_order_book_tracker import BittrexOrderBookTracker
  13. from hummingbot.core.data_type.order_book import OrderBook
  14. from hummingbot.core.utils.async_utils import safe_ensure_future
  15. sys.path.insert(0, realpath(join(__file__, "../../../")))
  16. class BittrexOrderBookTrackerUnitTest(unittest.TestCase):
  17. order_book_tracker: Optional[BittrexOrderBookTracker] = None
  18. events: List[OrderBookEvent] = [
  19. OrderBookEvent.TradeEvent
  20. ]
  21. # TODO: Update trading pair format to V3 WebSocket API
  22. trading_pairs: List[str] = [ # Trading Pair in v1.1 format(Quote-Base)
  23. "LTC-BTC",
  24. "LTC-ETH"
  25. ]
  26. @classmethod
  27. def setUpClass(cls):
  28. cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
  29. cls.order_book_tracker: BittrexOrderBookTracker = BittrexOrderBookTracker(trading_pairs=cls.trading_pairs)
  30. cls.order_book_tracker_task: asyncio.Task = safe_ensure_future(cls.order_book_tracker.start())
  31. cls.ev_loop.run_until_complete(cls.wait_til_tracker_ready())
  32. @classmethod
  33. async def wait_til_tracker_ready(cls):
  34. while True:
  35. if len(cls.order_book_tracker.order_books) > 0:
  36. print("Initialized real-time order books.")
  37. return
  38. await asyncio.sleep(1)
  39. async def run_parallel_async(self, *tasks, timeout=None):
  40. future: asyncio.Future = asyncio.ensure_future(asyncio.gather(*tasks))
  41. timer = 0
  42. while not future.done():
  43. if timeout and timer > timeout:
  44. raise Exception("Timeout running parallel async tasks in tests")
  45. timer += 1
  46. now = time.time()
  47. _next_iteration = now // 1.0 + 1 # noqa: F841
  48. await asyncio.sleep(1.0)
  49. return future.result()
  50. def run_parallel(self, *tasks):
  51. return self.ev_loop.run_until_complete(self.run_parallel_async(*tasks))
  52. def setUp(self):
  53. self.event_logger = EventLogger()
  54. for event_tag in self.events:
  55. for trading_pair, order_book in self.order_book_tracker.order_books.items():
  56. order_book.add_listener(event_tag, self.event_logger)
  57. def test_order_book_trade_event_emission(self):
  58. """
  59. Tests if the order book tracker is able to retrieve order book trade message from exchange and emit order book
  60. trade events after correctly parsing the trade messages
  61. """
  62. self.run_parallel(self.event_logger.wait_for(OrderBookTradeEvent))
  63. for ob_trade_event in self.event_logger.event_log:
  64. self.assertTrue(type(ob_trade_event) == OrderBookTradeEvent)
  65. self.assertTrue(ob_trade_event.trading_pair in self.trading_pairs)
  66. self.assertTrue(type(ob_trade_event.timestamp) in [float, int])
  67. self.assertTrue(type(ob_trade_event.amount) == float)
  68. self.assertTrue(type(ob_trade_event.price) == float)
  69. self.assertTrue(type(ob_trade_event.type) == TradeType)
  70. # Bittrex datetime is in epoch milliseconds
  71. self.assertTrue(math.ceil(math.log10(ob_trade_event.timestamp)) == 13)
  72. self.assertTrue(ob_trade_event.amount > 0)
  73. self.assertTrue(ob_trade_event.price > 0)
  74. def test_tracker_integrity(self):
  75. # Wait 5 seconds to process some diffs.
  76. self.ev_loop.run_until_complete(asyncio.sleep(5.0))
  77. order_books: Dict[str, OrderBook] = self.order_book_tracker.order_books
  78. ltcbtc_book: OrderBook = order_books["LTC-BTC"]
  79. # print(ltcbtc_book)
  80. self.assertGreaterEqual(ltcbtc_book.get_price_for_volume(True, 10).result_price,
  81. ltcbtc_book.get_price(True))
  82. self.assertLessEqual(ltcbtc_book.get_price_for_volume(False, 10).result_price,
  83. ltcbtc_book.get_price(False))
  84. def main():
  85. logging.basicConfig(level=logging.INFO)
  86. unittest.main()
  87. if __name__ == "__main__":
  88. main()