def test_logger_yes_remove(self): new_log_file = f'{TESTS_FOLDER_NAME}/{self._testMethodName}.log' order_book = OrderBook(new_log_file) bid = self.create_bid(100, 5) order_book.add_order(bid, random_str()) ask = self.create_ask(90, 7) order_book.add_order(ask, random_str()) with self.assertRaises(KeyError) as e: order_book.remove_order(bid.id, bid.sender_id) err_regex = r'^Tried to remove order but no such order exists\.\\nOrder id: \d{15}\. Order key: \(100, 5\)$' self.assertRegex(e.args[0], err_regex) order_book.remove_order(ask.id, ask.sender_id) with open(new_log_file, 'r') as f: lines = f.readlines() # the data in the now created log file is expected to match the following regex expressions regex = list(map(re.compile, [ r'BID \| timestamp: \d{10}\.\d{5,7}, side: b, price: 100, size: 5, id: \d{15}, sender_id: "[a-zA-Z0-9]{8}"', r'ASK \| timestamp: \d{10}\.\d{5,7}, side: a, price: 90, size: 7, id: \d{15}, sender_id: "[a-zA-Z0-9]{8}"', r'TRADE \| timestamp: \d{10}\.\d{5,7}, price: 100, size: 5, buyer_id: "[a-zA-Z0-9]{8}", seller_id: "[a-zA-Z0-9]{8}"', r'\t--> ASK id: \d{15} now has size: 2', r'\t--> BID id: \d{15} now has been exhausted', r'ASK (rm) | timestamp: \d{10}\.\d{5,7}, side: a, price: 90, size: 2, id: \d{15}, sender_id: "[a-zA-Z0-9]{8}"' ] )) for i, line in enumerate(lines): self.assertRegex(line, regex[i])
def create_mock_orderbook(self, logfile_full_path): """ Creates a mock orderbook which contains 4 bids (price, size): - (100, 10) - (70, 15) - (99, 7) - (101, 9) These hardcoded values are tested throughout the testing functions, don't change """ order_book = OrderBook(logfile_full_path) order_book.add_order(self.create_bid(100, 10), sender_id=random_str()) order_book.add_order(self.create_bid(70, 15), random_str()) order_book.add_order(self.create_bid(99, 7), random_str()) order_book.add_order(self.create_bid(101, 9), random_str()) return order_book
def test_get_levels_general(self): book1 = OrderBook() book1.update_level(2, 4, True) book1.update_level(3, 4, True) book1.update_level(5, 2, False) book1.update_level(3, 1, False) assert book1.get_levels() == (([(3,4)], [(2, 4)]),([(3,1)],[(5, 2)]))
def test_get_best_bbo_general_extended(self): book1 = OrderBook() book1.update_level(2, 4, True) book1.update_level(8, 6, True) book1.update_level(3, 5, False) book1.update_level(1, 2, False) assert book1.get_best_bbo() == (8, 6, 3, 5)
def test_logger_no_remove(self): new_log_file = f'{TESTS_FOLDER_NAME}/{self._testMethodName}.log' order_book = OrderBook(new_log_file) order_book.add_order(self.create_bid(100, 5), random_str()) order_book.add_order(self.create_ask(90, 7), random_str()) with open(new_log_file, 'r') as f: lines = f.readlines() # the data in the now created log file is expected to match the following regex expressions regex = [ r'BID \| timestamp: \d{10}\.\d{5,7}, side: b, price: 100, size: 5, id: \d{15}, sender_id: "[a-zA-Z0-9]{8}"', r'ASK \| timestamp: \d{10}\.\d{5,7}, side: a, price: 90, size: 7, id: \d{15}, sender_id: "[a-zA-Z0-9]{8}"', r'TRADE \| timestamp: \d{10}\.\d{5,7}, price: 100, size: 5, buyer_id: "[a-zA-Z0-9]{8}", seller_id: "[a-zA-Z0-9]{8}"', r'\t--> ASK id: \d{15} now has size: 2', r'\t--> BID id: \d{15} now has been exhausted', ] for i, line in enumerate(lines): self.assertRegex(line, regex[i])
def test_get_best_bbo_empty_buy_list(self): book1 = OrderBook() book1.update_level(2, 4, False) assert book1.get_best_bbo() == (None, None, 2, 4)
def test_get_best_bbo_empty_sell_list(self): book1 = OrderBook() book1.update_level(2, 4, True) assert book1.get_best_bbo() == (2, 4, None, None)
def test_get_best_bbo_empty_lists(self): book1 = OrderBook() book1.update_level(2, 0, True) book1.update_level(3, 0, False) assert book1.get_best_bbo() == (None, None, None, None)
def test_update_level_add(self): book1 = OrderBook() book1.update_level(2, 4, True) assert book1.levels_buy == [[(2,4)]]
def test_show_top(self): new_log_file = f'{TESTS_FOLDER_NAME}/{self._testMethodName}.log' order_book = OrderBook(new_log_file) order_book.add_order(self.create_ask(100, 30), random_str()) order_book.add_order(self.create_ask(100, 29), random_str()) order_book.add_order(self.create_bid(10, 3), random_str()) order_book.add_order(self.create_bid(10, 4), random_str()) highest_bid, lowest_ask = order_book.show_top() # Test overridden Order comparison functions (by _key()) self.assertTrue((highest_bid.price, highest_bid.size), (10, 4)) self.assertTrue((lowest_ask.price, lowest_ask.size), (100, 29)) order_book.add_order(self.create_ask(99, 28), random_str()) order_book.add_order(self.create_bid(11, 5), random_str()) highest_bid, lowest_ask = order_book.show_top() self.assertTrue((highest_bid.price, highest_bid.size), (11, 5)) self.assertTrue((lowest_ask.price, lowest_ask.size), (99, 28))
def test_update_level_delete(self): book1 = OrderBook() book1.update_level(3, 1, True) book1.update_level(2, 4, True) book1.update_level(2, 0, True) assert book1.levels_buy == [[(3,1)]]
def test_update_level_change(self): book1 = OrderBook() book1.update_level(2, 4, True) book1.update_level(2, 3, True) assert book1.levels_buy == [[(2,3)]]
def test_update_level_add_zero_volume(self): book1 = OrderBook() book1.update_level(2, 0, True) assert book1.levels_buy == []
def test_update_level_add_to_sell_list(self): book1 = OrderBook() book1.update_level(2, 4, False) assert book1.levels_buy == [] assert book1.levels_sell == [[(2, 4)]]
def test_get_levels_general_empty_sell_list(self): book1 = OrderBook() book1.update_level(2, 4, True) book1.update_level(3, 4, True) assert book1.get_levels() == (([(3, 4)],[(2, 4)]), ())
def test_get_best_bbo_general(self): book1 = OrderBook() book1.update_level(2, 4, True) book1.update_level(3, 5, False) assert book1.get_best_bbo() == (2, 4, 3, 5)
def test_get_levels_general_empty_buy_list(self): book1 = OrderBook() book1.update_level(2, 4, False) book1.update_level(3, 4, False) assert book1.get_levels() == ((), ([(2, 4)],[(3, 4)]))
def book(): book = OrderBook() return book