Example #1
0
class TestOrderBook(unittest.TestCase):
    def setUp(self):
        self.instrument = Instrument(identifier=0,
                                     name='Carrefour',
                                     isin='FR0000120172',
                                     currency_identifier=0)
        self.book = OrderBook(self.instrument.identifier)

    def test_count_bids(self):
        buy_order = ServerOrder(Buy(), self.instrument.identifier, 50, 42.0,
                                'Trader1')
        self.assertEqual(self.book.count_bids(), 0)
        self.book.on_new_order(buy_order)
        self.assertEqual(self.book.count_bids(), 1)

    def test_count_asks(self):
        sell_order = ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                                 'Trader1')
        self.assertEqual(self.book.count_asks(), 0)
        self.book.on_new_order(sell_order)
        self.assertEqual(self.book.count_asks(), 1)

    def test_get_bids(self):
        bids = self.book.get_bids()
        self.assertEqual(len(bids), 0)

    def test_get_asks(self):
        asks = self.book.get_asks()
        self.assertEqual(len(asks), 0)

    def test_two_orders_no_match(self):
        buy_order = ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                                'Trader1')
        sell_order = ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                                 'Trader2')
        self.book.on_new_order(buy_order)
        self.book.on_new_order(sell_order)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 1)

    def test_four_stacked_orders_no_match(self):
        orders = [
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                        'Trader2'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                        'Trader2')
        ]
        for order in orders:
            self.book.on_new_order(order)
        self.assertEqual(self.book.count_bids(), 2)
        self.assertEqual(self.book.count_asks(), 2)

    def test_fifo_matching_orders(self):
        """ Ensure FIFO matching is enforced """
        orders = [
            ServerOrder(Buy(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader1',
                        timestamp=1),
            ServerOrder(Buy(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader2',
                        timestamp=2),
            ServerOrder(Sell(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader3',
                        timestamp=3)
        ]
        for order in orders:
            self.book.on_new_order(order)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 0)
        self.assertEqual(self.book.get_bids()[0].timestamp, 2)
        self.assertEqual(self.book.get_bids()[0].counterparty, 'Trader2')

    def test_self_execution(self):
        """ Ensure you cannot trade with yourself """
        orders = [
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 40.0,
                        'Trader1')
        ]
        for order in orders:
            self.book.on_new_order(order)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 1)
Example #2
0
class TestOrderBook(unittest.TestCase):
    def setUp(self):
        self.instrument = Instrument(identifier=0,
                                     name='Carrefour',
                                     isin='FR0000120172',
                                     currency_identifier=0)
        self.book = OrderBook(self.instrument.identifier)

    def test_count_bids(self):
        buy_order = ServerOrder(Buy(), self.instrument.identifier, 50, 42.0,
                                'Trader1')
        self.assertEqual(self.book.count_bids(), 0)
        self.book.on_new_order(buy_order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 1)

    def test_count_asks(self):
        sell_order = ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                                 'Trader1')
        self.assertEqual(self.book.count_asks(), 0)
        self.book.on_new_order(sell_order, apply_changes=True)
        self.assertEqual(self.book.count_asks(), 1)

    def test_get_bids(self):
        bids = self.book.get_bids()
        self.assertEqual(len(bids), 0)

    def test_get_asks(self):
        asks = self.book.get_asks()
        self.assertEqual(len(asks), 0)

    def test_self_execution(self):
        """
        Ensure you cannot trade against yourself
        """
        orders = [
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 40.0,
                        'Trader1')
        ]
        for order in orders:
            self.book.on_new_order(order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 1)

    def test_two_orders_no_match(self):
        """
        Two orders not matching (different price)
        """
        buy_order = ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                                'Trader1')
        sell_order = ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                                 'Trader2')
        self.book.on_new_order(buy_order, apply_changes=True)
        self.book.on_new_order(sell_order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 1)

    def test_four_stacked_orders_no_match(self):
        orders = [
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Buy(), self.instrument.identifier, 50, 40.0,
                        'Trader1'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                        'Trader2'),
            ServerOrder(Sell(), self.instrument.identifier, 50, 42.0,
                        'Trader2')
        ]
        for order in orders:
            self.book.on_new_order(order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 2)
        self.assertEqual(self.book.count_asks(), 2)

    def validate_one_matching(self, attacking_order, attacked_order):
        self.book.on_new_order(attacked_order, apply_changes=True)
        matching_orders = self.book.get_matching_orders(attacking_order)
        self.assertEqual(len(matching_orders), 1)
        self.assertEqual(matching_orders[0].__dict__, attacked_order.__dict__)

    def test_buy_price_greater_than_sell(self):
        attacking_order = ServerOrder(Buy(), self.instrument.identifier, 10,
                                      40.0, 'Trader1')
        attacked_order = ServerOrder(Sell(), self.instrument.identifier, 10,
                                     38.0, 'Trader2')
        self.validate_one_matching(attacking_order, attacked_order)
        self.assertEqual(attacking_order.get_remaining_quantity(), 10)
        self.assertEqual(attacked_order.get_remaining_quantity(), 10)

    def test_buy_price_equal_to_sell(self):
        attacking_order = ServerOrder(Buy(), self.instrument.identifier, 10,
                                      40.0, 'Trader1')
        attacked_order = ServerOrder(Sell(), self.instrument.identifier, 10,
                                     40.0, 'Trader2')
        self.book.on_new_order(attacked_order, apply_changes=True)
        self.book.on_new_order(attacking_order, apply_changes=True)
        self.assertEqual(attacking_order.get_remaining_quantity(), 0)
        self.assertEqual(attacked_order.get_remaining_quantity(), 0)

    def test_sell_price_greater_than_buy(self):
        attacking_order = ServerOrder(Sell(), self.instrument.identifier, 10,
                                      40.0, 'Trader1')
        attacked_order = ServerOrder(Buy(), self.instrument.identifier, 10,
                                     42.0, 'Trader2')
        self.validate_one_matching(attacking_order, attacked_order)

    def test_sell_price_equal_to_buy(self):
        attacking_order = ServerOrder(Sell(), self.instrument.identifier, 10,
                                      40.0, 'Trader1')
        attacked_order = ServerOrder(Buy(), self.instrument.identifier, 10,
                                     40.0, 'Trader2')
        self.validate_one_matching(attacking_order, attacked_order)

    def test_fifo_matching_orders(self):
        """
        Ensure FIFO matching is enforced
        """
        orders = [
            ServerOrder(Buy(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader1',
                        timestamp=1),
            ServerOrder(Buy(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader2',
                        timestamp=2),
            ServerOrder(Sell(),
                        self.instrument.identifier,
                        50,
                        40.0,
                        'Trader3',
                        timestamp=3)
        ]
        for order in orders:
            self.book.on_new_order(order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 0)
        self.assertEqual(self.book.get_bids()[0].timestamp, 2)
        self.assertEqual(self.book.get_bids()[0].counterparty, 'Trader2')

    def test_one_full_execution(self):
        quantity = 10
        price = 42.0
        attacking_order = ServerOrder(Sell(), self.instrument.identifier,
                                      quantity, price, 'Trader1')
        attacked_order = ServerOrder(Buy(), self.instrument.identifier,
                                     quantity, price, 'Trader2')
        self.book.on_new_order(attacked_order, apply_changes=True)
        self.book.on_new_order(attacking_order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 0)
        self.assertEqual(self.book.count_asks(), 0)
        self.assertEqual(attacking_order.executed_quantity, quantity)
        self.assertEqual(attacked_order.executed_quantity, quantity)
        self.assertEqual(attacking_order.get_remaining_quantity(), 0)
        self.assertEqual(attacked_order.get_remaining_quantity(), 0)

    def test_one_partial_execution(self):
        attacking_quantity = 20
        attacked_quantity = 10
        price = 42.0
        attacking_order = ServerOrder(Buy(), self.instrument.identifier,
                                      attacking_quantity, price, 'Trader1')
        attacked_order = ServerOrder(Sell(), self.instrument.identifier,
                                     attacked_quantity, price, 'Trader2')
        self.book.on_new_order(attacked_order, apply_changes=True)
        self.book.on_new_order(attacking_order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 1)
        self.assertEqual(self.book.count_asks(), 0)
        self.assertEqual(attacking_order.executed_quantity,
                         attacking_quantity - attacked_quantity)
        self.assertEqual(attacked_order.executed_quantity, attacked_quantity)
        self.assertEqual(attacking_order.get_remaining_quantity(),
                         attacking_quantity - attacked_quantity)
        self.assertEqual(attacked_order.get_remaining_quantity(), 0)

    def test_multiple_partial_executions(self):
        attacking_quantity = 50
        attacked_quantity = 10
        price = 42.0
        attacking_order = ServerOrder(Buy(), self.instrument.identifier,
                                      attacking_quantity, price, 'Trader1')
        attacked_orders = []
        for _ in list(range(5)):
            attacked_order = ServerOrder(Sell(), self.instrument.identifier,
                                         attacked_quantity, price, 'Trader2')
            attacked_orders.append(attacked_order)
            self.book.on_new_order(attacked_order, apply_changes=True)
        self.book.on_new_order(attacking_order, apply_changes=True)
        self.assertEqual(self.book.count_bids(), 0)
        self.assertEqual(self.book.count_asks(), 0)
        self.assertEqual(attacking_order.executed_quantity, attacking_quantity)
        self.assertEqual(attacking_order.get_remaining_quantity(), 0)
        for attacked_order in attacked_orders:
            self.assertEqual(attacked_order.executed_quantity,
                             attacked_quantity)
            self.assertEqual(attacked_order.get_remaining_quantity(), 0)