Example #1
0
    def update_matched_orders(self, attacking_order: ServerOrder,
                              matching_orders) -> OrderBookChanges:
        """
        Iterate and update attacked orders, create deals upon total and partial executions
        """
        changes = OrderBookChanges()

        for attacked_order in matching_orders:
            if self.is_attacked_order_full_executed(attacking_order,
                                                    attacked_order):
                executed_quantity = attacked_order.get_remaining_quantity()
                attacking_order.executed_quantity += executed_quantity
                attacked_order.executed_quantity += executed_quantity
                self.update_statistics(last_executed_order=attacked_order)
                logger.debug(f"Attacker [{attacking_order.counterparty}]")
                logger.debug(f"Attacked [{attacked_order.counterparty}]")
                # Create deal
                deal = ServerDeal(attacking_order, attacked_order,
                                  executed_quantity)
                changes.deals_to_add.append(deal)
                # Remove executed order
                changes.order_to_remove.append(attacked_order)
            else:
                executed_quantity = attacking_order.get_remaining_quantity()
                attacking_order.executed_quantity += executed_quantity
                attacked_order.executed_quantity += executed_quantity
                self.update_statistics(last_executed_order=attacking_order)
                # Create a deal
                deal = ServerDeal(attacking_order, attacked_order,
                                  executed_quantity)
                changes.deals_to_add.append(attacking_order)
            if attacking_order.get_remaining_quantity() == 0.0:
                break

        return changes
Example #2
0
    def on_new_order(self,
                     order: ServerOrder,
                     apply_changes=False) -> OrderBookChanges:
        """
        Entry point to process a new order in order book
        apply_changes indicates either order book changes are applied directly at the end (testing purpose)
        """
        if order.instrument_identifier != self.instrument_identifier:
            raise Exception(
                "[LOGIC FAILURE] Order instrument must match order book instrument"
            )

        quantity_before_execution = order.get_remaining_quantity()
        changes = self.match_order(order)
        # Case 1: unmatched
        if quantity_before_execution == order.get_remaining_quantity():
            logger.debug(
                f"Attacking order is unmatched, adding [{order}] to trading book"
            )
            changes.order_to_add.append(order)
        # Case 2: partially executed (existing order(s) have been executed)
        elif order.get_remaining_quantity() > 0.0:
            logger.debug(
                f"Attacking order cannot be fully executed, adding [{order}] to trading book"
            )
            changes.order_to_add.append(order)
        # Case 3: order has been fully executed
        else:
            logger.debug(
                f"Attacking order [{order}] has been totally executed")

        if apply_changes:
            self.apply_order_book_changes(changes)

        return changes
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
 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)
     self.book.on_new_order(attacking_order)
     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)
Example #6
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)
Example #7
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)
     self.book.on_new_order(attacking_order)
     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)