コード例 #1
0
 def test_market_data_check_max_ask_print_size_limiter(self):
     order_book = OrderBook(DEFAULT_TRADING_PAIR, 2, 2)
     orders = [generate_order_obj(type=OrderType.ASK) for _ in range(5)]
     for ord in orders:
         order_book.add_order(ord)
     old_market_data = order_book.market_data
     orders = sorted(orders, key=lambda i: i.price)
     delete_order = orders[0]
     order_book.remove_order(delete_order.id)
     assert order_book.market_data != old_market_data
     expected_data = self.expected_market_data(
         asks=self.aggregate_orders(orders[1:3]))
     assert order_book.market_data == expected_data
コード例 #2
0
class Engine(object):
    def __init__(self):
        self.order_book = OrderBook()
        self.ts = 0

    def execute(self, message):
        self.ts += 1
        try:
            order_action = parse_input_message(message, self.ts)
            if order_action.action_type == ACTION_TYPE_ADD_ORDER:
                trades = self.order_book.add_order(order_action.order)
                for trade in trades:
                    output_trade(trade)
            elif order_action.action_type == ACTION_TYPE_CANCEL_ORDER:
                self.order_book.cancel_order(order_action.order_id)
        except WrongInputFormatException:
            sys.stderr.write('Wrong input format: {}\n'.format(message))
        except WrongMessageTypeException:
            sys.stderr.write('Wrong message type: {}\n'.format(message))
        except UnknownOrderException:
            sys.stderr.write('Unknown order: {}\n'.format(message))
        except DuplicateOrderException:
            sys.stderr.write('Duplicate order: {}\n'.format(message))
コード例 #3
0
class OrderBookTest(unittest.TestCase):

    def setUp(self):
        self.events = queue.Queue()
        self.order_book = OrderBook(self.events)

    def test_sell_order_is_added(self):
        order = OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5'))
        self.order_book.add_order(order)

        self.assertEqual(self.order_book.sell_orders(), [order])
        self.assertEqual(self.order_book.buy_orders(), [])

    def test_buy_order_is_added(self):
        order = OrderBookOrder(1, 'buy', Decimal('500'), Decimal('5'))
        self.order_book.add_order(order)

        self.assertEqual(self.order_book.buy_orders(), [order])
        self.assertEqual(self.order_book.sell_orders(), [])

    def test_sell_and_buy_orders_are_matched(self):
        sell_order = OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5'))
        self.order_book.add_order(sell_order)

        buy_order = OrderBookOrder(2, 'buy', Decimal('500'), Decimal('5'))
        self.order_book.add_order(buy_order)

        self.assertEqual(self.order_book.buy_orders(), [])
        self.assertEqual(self.order_book.sell_orders(), [])

        self.assertEqual({
            'name': 'match',
            'amount': Decimal('500'),
            'order_id': 2,
            'matched_order_id': 1,
        }, self.events.get(block=False))

        self.assertEqual({
            'name': 'complete',
            'order_id': 1,
        }, self.events.get(block=False))

        self.assertEqual({
            'name': 'complete',
            'order_id': 2,
        }, self.events.get(block=False))

    def test_cancelled_order_is_removed_from_the_order_book(self):
        self.order_book.add_order(OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5')))

        self.order_book.cancel_order_by_id(1)

        self.assertEqual(self.order_book.buy_orders(), [])
        self.assertEqual(self.order_book.sell_orders(), [])

        self.assertEqual({
            'name': 'cancelled',
            'order_id': 1,
            'remaining_amount': Decimal('500'),
        }, self.events.get(block=False))

    def test_cancelled_partially_matched_order_has_a_correct_remaining_amount(self):
        self.order_book.add_order(OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5')))
        self.order_book.add_order(OrderBookOrder(2, 'buy', Decimal('300'), Decimal('5')))

        self.order_book.cancel_order_by_id(1)

        self.assertEqual(self.order_book.buy_orders(), [])
        self.assertEqual(self.order_book.sell_orders(), [])

        self.expect_event('match')
        self.expect_event('complete')

        self.assertEqual({
            'name': 'cancelled',
            'order_id': 1,
            'remaining_amount': Decimal('200'),
        }, self.events.get(block=False))

    def test_sell_and_buy_orders_are_matched_incompletely(self):
        self.order_book.add_order(OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5')))

        self.order_book.add_order(OrderBookOrder(2, 'buy', Decimal('300'), Decimal('5')))

        self.assertEqual(self.order_book.buy_orders(), [])
        self.assertEqual(self.order_book.sell_orders(), [
            self.with_matched_amount(OrderBookOrder(1, 'sell', Decimal('500'), Decimal('5')), Decimal('300'))])

        self.assertEqual({
            'name': 'match',
            'amount': Decimal('300'),
            'order_id': 2,
            'matched_order_id': 1,
        }, self.events.get(block=False))

        self.order_book.add_order(OrderBookOrder(3, 'buy', Decimal('500'), Decimal('5')))

        self.assertEqual([self.with_matched_amount(OrderBookOrder(3, 'buy', Decimal('500'), Decimal('5')), Decimal('200'))],
                         self.order_book.buy_orders())
        self.assertEqual(self.order_book.sell_orders(), [])

        self.assertEqual({
            'name': 'complete',
            'order_id': 2,
        }, self.events.get(block=False))

        self.assertEqual({
            'name': 'match',
            'amount': Decimal('200'),
            'order_id': 3,
            'matched_order_id': 1,
        }, self.events.get(block=False))

    def test_orders_are_matched_in_fifo_order(self):
        self.order_book.add_order(OrderBookOrder(1, 'sell', Decimal('10'), Decimal('3.5')))
        self.order_book.add_order(OrderBookOrder(2, 'sell', Decimal('30'), Decimal('3.5')))

        self.order_book.add_order(OrderBookOrder(3, 'buy', Decimal('15'), Decimal('3.5')))

        self.assertEqual([], self.order_book.buy_orders())
        self.assertEqual([self.with_matched_amount(OrderBookOrder(2, 'sell', Decimal('30'), Decimal('3.5')), Decimal('5'))],
                         self.order_book.sell_orders())

    def test_sell_orders_are_matched_until_they_are_filled_up_to_the_price_level(self):
        self.order_book.add_order(OrderBookOrder(1, 'sell', Decimal('10'), Decimal('3.6')))
        self.order_book.add_order(OrderBookOrder(2, 'sell', Decimal('30'), Decimal('3.5')))
        self.order_book.add_order(OrderBookOrder(3, 'sell', Decimal('15'), Decimal('3.5')))
        self.order_book.add_order(OrderBookOrder(4, 'sell', Decimal('5'), Decimal('3.4')))

        self.order_book.add_order(OrderBookOrder(5, 'buy', Decimal('60'), Decimal('3.5')))

        self.assertEqual([self.with_matched_amount(OrderBookOrder(5, 'buy', Decimal('60'), Decimal('3.5')), Decimal('50'))],
                         self.order_book.buy_orders())
        self.assertEqual([self.with_matched_amount(OrderBookOrder(1, 'sell', Decimal('10'), Decimal('3.6')), Decimal('0'))],
                         self.order_book.sell_orders())

    def test_buy_orders_are_matched_until_they_are_filled_up_to_the_price_level(self):
        self.order_book.add_order(OrderBookOrder(1, 'buy', Decimal('10'), Decimal('3.6')))
        self.order_book.add_order(OrderBookOrder(2, 'buy', Decimal('30'), Decimal('3.5')))
        self.order_book.add_order(OrderBookOrder(3, 'buy', Decimal('15'), Decimal('3.5')))
        self.order_book.add_order(OrderBookOrder(4, 'buy', Decimal('5'), Decimal('3.4')))

        self.order_book.add_order(OrderBookOrder(5, 'sell', Decimal('60'), Decimal('3.5')))

        self.assertEqual([self.with_matched_amount(OrderBookOrder(4, 'buy', Decimal('5'), Decimal('3.4')), Decimal('0'))],
                         self.order_book.buy_orders())
        self.assertEqual([self.with_matched_amount(OrderBookOrder(5, 'sell', Decimal('60'), Decimal('3.5')), Decimal('55'))],
                         self.order_book.sell_orders())

    def test_unmatched_buy_and_sell_orders_are_added(self):
        self.order_book.add_order(OrderBookOrder(1, 'buy', Decimal('10'), Decimal('1.0')))
        self.order_book.add_order(OrderBookOrder(2, 'sell', Decimal('20'), Decimal('1.1')))
        self.order_book.add_order(OrderBookOrder(3, 'buy', Decimal('30'), Decimal('0.9')))
        self.order_book.add_order(OrderBookOrder(4, 'sell', Decimal('40'), Decimal('1.2')))

        self.assertEqual([OrderBookOrder(3, 'buy', Decimal('30'), Decimal('0.9')),
                          OrderBookOrder(1, 'buy', Decimal('10'), Decimal('1.0'))], self.order_book.buy_orders())
        self.assertEqual([OrderBookOrder(2, 'sell', Decimal('20'), Decimal('1.1')),
                          OrderBookOrder(4, 'sell', Decimal('40'), Decimal('1.2'))], self.order_book.sell_orders())

    def expect_event(self, event_name):
        self.assertEqual(event_name, self.events.get(block=False)['name'])

    @staticmethod
    def with_matched_amount(order, matcher_amount):
        order.matched_amount = matcher_amount
        return order
コード例 #4
0
def test_order_book():
    order_book = OrderBook()
    assert len(order_book.sell_orders) == 0
    assert len(order_book.buy_orders) == 0
    trades = order_book.add_order(Order(100000, ORDER_SELL_SIDE, 1, 1075, 1))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 1
    assert len(order_book.buy_orders) == 0
    assert order_book.sell_orders[0].order_id == 100000
    trades = order_book.add_order(Order(100001, ORDER_BUY_SIDE, 9, 1000, 2))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 1
    assert len(order_book.buy_orders) == 1
    assert order_book.sell_orders[0].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    trades = order_book.add_order(Order(100002, ORDER_BUY_SIDE, 30, 975, 3))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 1
    assert len(order_book.buy_orders) == 2
    assert order_book.sell_orders[0].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100002
    trades = order_book.add_order(Order(100003, ORDER_SELL_SIDE, 10, 1050, 3))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 2
    assert len(order_book.buy_orders) == 2
    assert order_book.sell_orders[0].order_id == 100003
    assert order_book.sell_orders[1].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100002
    trades = order_book.add_order(Order(100004, ORDER_BUY_SIDE, 10, 950, 4))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 2
    assert len(order_book.buy_orders) == 3
    assert order_book.sell_orders[0].order_id == 100003
    assert order_book.sell_orders[1].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100002
    assert order_book.buy_orders[2].order_id == 100004
    trades = order_book.add_order(Order(100005, ORDER_SELL_SIDE, 2, 1025, 5))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 3
    assert len(order_book.buy_orders) == 3
    assert order_book.sell_orders[0].order_id == 100005
    assert order_book.sell_orders[1].order_id == 100003
    assert order_book.sell_orders[2].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100002
    assert order_book.buy_orders[2].order_id == 100004
    trades = order_book.add_order(Order(100006, ORDER_BUY_SIDE, 1, 1000, 6))
    assert len(trades) == 0
    assert len(order_book.sell_orders) == 3
    assert len(order_book.buy_orders) == 4
    assert order_book.sell_orders[0].order_id == 100005
    assert order_book.sell_orders[1].order_id == 100003
    assert order_book.sell_orders[2].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100006
    assert order_book.buy_orders[2].order_id == 100002
    assert order_book.buy_orders[3].order_id == 100004
    order_book.cancel_order(100004)
    assert len(order_book.sell_orders) == 3
    assert len(order_book.buy_orders) == 3
    assert order_book.sell_orders[0].order_id == 100005
    assert order_book.sell_orders[1].order_id == 100003
    assert order_book.sell_orders[2].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100006
    assert order_book.buy_orders[2].order_id == 100002
    trades = order_book.add_order(Order(100007, ORDER_SELL_SIDE, 5, 1025, 8))
    assert len(trades) == 0
    assert order_book.sell_orders[0].order_id == 100005
    assert order_book.sell_orders[1].order_id == 100007
    assert order_book.sell_orders[2].order_id == 100003
    assert order_book.sell_orders[3].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100006
    assert order_book.buy_orders[2].order_id == 100002
    trades = order_book.add_order(Order(100008, ORDER_BUY_SIDE, 3, 1050, 9))
    assert len(trades) == 2
    assert trades[0].quantity == 2
    assert trades[0].price == 1025
    assert trades[0].aggressive_fill == FILL_TYPE_PARTIAL
    assert trades[0].aggressive_quantity == 1
    assert trades[0].aggressive_id == 100008
    assert trades[0].resting_fill == FILL_TYPE_FULL
    assert trades[0].resting_id == 100005
    assert trades[1].quantity == 1
    assert trades[1].price == 1025
    assert trades[1].aggressive_fill == FILL_TYPE_FULL
    assert trades[1].aggressive_id == 100008
    assert trades[1].resting_fill == FILL_TYPE_PARTIAL
    assert trades[1].resting_id == 100007
    assert trades[1].resting_quantity == 4
    assert order_book.sell_orders[0].order_id == 100007
    assert order_book.sell_orders[1].order_id == 100003
    assert order_book.sell_orders[2].order_id == 100000
    assert order_book.buy_orders[0].order_id == 100001
    assert order_book.buy_orders[1].order_id == 100006
    assert order_book.buy_orders[2].order_id == 100002
    with pytest.raises(UnknownOrderException):
        order_book.cancel_order(1000004)
    with pytest.raises(DuplicateOrderException):
        order_book.add_order(Order(100007, ORDER_SELL_SIDE, 5, 1025, 11))