Example #1
0
def test_order_book_can_add_orders():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy if i %
                   2 else OrderDirection.sell,
                   quantity=quantity,
                   price=price + (i if i % 2 else -i)) for i in range(10)
    ]

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    assert len(order_book.bids) == 4, "Test Failed: There should be 5 bids"
    assert len(order_book.asks) == 4, "Test Failed: There should be 5 asks"
    assert order_book.best_bid is not None, "Test Failed: best_bid should not be empty"
    assert order_book.best_ask is not None, "Test Failed: best_ask should not be empty"
    assert order_book.best_bid.price > order_book.best_ask.price, "Test Failed: best prices are not aligned"
    assert all(order_book.bids[i].price > order_book.asks[i].price for i in range(4)), \
        "Test Failed: prices are not aligned"
    assert not order_book.trades, "Test Failed: trades should be empty"
    assert not order_book.complete_orders, "Test Failed: complete_orders should be empty"
    assert order_book.attempt_match, "Test Failed: attempt_match should be True"
    pass
Example #2
0
def test_order_book_cannot_cancel_nothing():
    instrument_id = "AAPL"
    order_book = OrderBook()

    cancel_order = CancelOrder(instrument_id=instrument_id,
                               order_id=2,
                               order_direction=OrderDirection.sell)
    order_book.add_order(cancel_order)

    assert not cancel_order.cancel_success, "Test Failed: cancel should fail"
    pass
Example #3
0
def test_order_book_raise_exception_on_invalid_order():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_order = LimitOrder(instrument_id=instrument_id,
                             order_direction=OrderDirection.test,
                             quantity=quantity,
                             price=price)
    order_book = OrderBook()

    with pytest.raises(InvalidOrderDirectionException) as exn:
        order_book.add_order(limit_order)
    pass
Example #4
0
def test_order_book_can_handle_limit_and_market_orders_together():
    """ Here there are more asks than bids, so the bids will fill"""
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy,
                   quantity=quantity - 10 * i,
                   price=price + i) for i in range(5)
    ]

    market_order = MarketOrder(instrument_id=instrument_id,
                               order_direction=OrderDirection.sell,
                               quantity=400)

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    order_book.add_order(market_order)
    order_book.match()

    assert not order_book.asks, "Test Failed: There should be no asks after this matching"
    assert order_book.best_ask is None, "Test Failed: best_ask should be empty"
    assert not order_book.bids, "Test Failed: There should be  no bids after this matching"
    assert order_book.best_bid is None, "Test Failed: best_bid should be empty"
    assert len(order_book.trades) == 5, "Test Failed: there should be 5 trades"
    assert len(order_book.complete_orders
               ) == 6, "Test Failed: complete_orders should have 6 orders"
    assert not order_book.attempt_match, "Test Failed: attempt_match should be False"
    pass
Example #5
0
    def match(self):

        while self.orders:
            order = self.orders.popleft()
            instrument_id = order.instrument_id

            order_books = self.order_books
            if instrument_id in order_books.keys():
                order_book = order_books[instrument_id]
                order_book.add_order(order)
                order_book.match()
            else:
                order_book = OrderBook()
                order_book.add_order(order)
                order_books[instrument_id] = order_book

            self.processed_orders.append(order)
Example #6
0
def test_order_book_init():
    order_book = OrderBook()

    assert not order_book.bids, "Test Failed: bids should be empty"
    assert not order_book.asks, "Test Failed: asks should be empty"
    assert order_book.best_bid is None, "Test Failed: best_bid should be empty"
    assert order_book.best_ask is None, "Test Failed: best_ask should be empty"
    assert not order_book.trades, "Test Failed: trades should be empty"
    assert not order_book.complete_orders, "Test Failed: complete_orders should be empty"
    assert not order_book.attempt_match, "Test Failed: attempt_match should default to False"
    pass
Example #7
0
def test_order_book_can_match_orders():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy if i %
                   2 else OrderDirection.sell,
                   quantity=quantity,
                   price=price + (i if i % 2 else -i)) for i in range(10)
    ]

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    order_book.match()
    assert not order_book.bids, "Test Failed: There should be no bids after complete matching"
    assert not order_book.asks, "Test Failed: There should be no asks after complete matching"
    assert order_book.best_bid is None, "Test Failed: best_bid should be empty"
    assert order_book.best_ask is None, "Test Failed: best_ask should be empty"
    assert len(
        order_book.trades) == 5, "Test Failed: trades should have 5 orders"
    assert len(order_book.complete_orders
               ) == 10, "Test Failed: complete_orders should have all orders"
    assert not order_book.attempt_match, "Test Failed: attempt_match should be False"
    pass
Example #8
0
def test_order_book_can_cancel_sell_other_than_best_ask():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy if i %
                   2 else OrderDirection.sell,
                   quantity=quantity - 10 * i,
                   price=price + (i if i % 2 else -i)) for i in range(10)
    ]
    for i, l in enumerate(limit_orders):
        l.order_id = i
        limit_orders[i] = l

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    cancel_order = CancelOrder(instrument_id=instrument_id,
                               order_id=2,
                               order_direction=OrderDirection.sell)
    order_book.add_order(cancel_order)

    assert len(order_book.bids) > len(
        order_book.asks), "Test Failed: should be more buys than sells"
    assert cancel_order.cancel_success, "Test Failed: cancel should succeed"
    pass
Example #9
0
def test_order_book_can_match_incomplete_more_bids():
    """ Here there are more asks than bids, so the bids will fill"""
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy
                   if not i % 2 else OrderDirection.sell,
                   quantity=quantity - 10 * i,
                   price=price + (i if not i % 2 else -i)) for i in range(10)
    ]

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    order_book.match()

    assert not order_book.asks, "Test Failed: There should be no asks after this matching"
    assert order_book.best_ask is None, "Test Failed: best_ask should be empty"
    assert not order_book.bids, "Test Failed: There should be  no bids after this matching"
    assert order_book.best_bid is not None, "Test Failed: best_bid should not be empty"
    assert len(
        order_book.trades) > 5, "Test Failed: trades should more than 5 trades"
    assert len(
        order_book.complete_orders
    ) < 10, "Test Failed: complete_orders should have fewer than 10 orders"
    assert not order_book.attempt_match, "Test Failed: attempt_match should be False"
    pass
Example #10
0
def test_order_book_can_generate_execution_plot():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy
                   if not i % 2 else OrderDirection.sell,
                   quantity=quantity - 10 * i,
                   price=price + (i if not i % 2 else -2 * i))
        for i in range(10)
    ]

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    order_book.match()
    order_book.plot_executions()
    pass
Example #11
0
def test_order_book_can_cancel_sell():
    """ Here there are more asks than bids, so the bids will fill"""
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy if i %
                   2 else OrderDirection.sell,
                   quantity=quantity - 10 * i,
                   price=price + (i if i % 2 else -i)) for i in range(10)
    ]
    for i, l in enumerate(limit_orders):
        l.order_id = i
        limit_orders[i] = l

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    cancel_order = CancelOrder(instrument_id=instrument_id,
                               order_id=0,
                               order_direction=OrderDirection.sell)
    order_book.match()
    order_book.add_order(cancel_order)

    assert not order_book.asks, "Test Failed: There should be no asks after this matching"
    assert order_book.best_ask is None, "Test Failed: best_ask should be empty"
    assert not order_book.bids, "Test Failed: There should be  no bids after this matching"
    assert order_book.best_bid is None, "Test Failed: best_bid should be empty"
    assert len(
        order_book.trades) > 5, "Test Failed: trades should more than 5 trades"
    assert len(order_book.complete_orders
               ) == 10, "Test Failed: complete_orders should have 10 orders"
    assert cancel_order.cancel_success, "Test Failed: cancel should succeed"
    pass
Example #12
0
def test_order_book_can_generate_order_book_plot():
    instrument_id = "AAPL"
    quantity = 100
    price = 10
    limit_orders = [
        LimitOrder(instrument_id=instrument_id,
                   order_direction=OrderDirection.buy if i %
                   2 else OrderDirection.sell,
                   quantity=quantity,
                   price=price + (-i if i % 2 else i)) for i in range(10)
    ]

    order_book = OrderBook()

    for order in limit_orders:
        order_book.add_order(order)
    order_book.plot_order_book()
    pass