def test_has_both_active(self): book = OrderBook() self.assertEqual(book.has_active_bids(), False) limit_buy_order = Order(ID_GENERATOR, 1, 100, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 105, "LIMIT", -100) book.add_order(limit_buy_order) book.add_order(limit_sell_order) self.assertEqual(book.has_active_asks(), True) self.assertEqual(book.has_active_bids(), True)
def test_cancelled_orders_in_spread_calc(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 195, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 200, "LIMIT", -50) book.add_order(limit_sell_order) book.add_order(limit_buy_order) self.assertEqual(book.current_spread(), 5) limit_sell_order.cancel() self.assertEqual(book.current_spread(), 0)
def test_fill_with_partial_limit_order(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 200, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 200, "LIMIT", -50) book.add_order(limit_buy_order) book.add_order(limit_sell_order) self.assertEqual(book.bids, [limit_buy_order]) self.assertEqual(book.asks, []) self.assertEqual(book.bids[0].order_size, 50) self.assertEqual(limit_sell_order.order_size, 0)
def test_should_give_correct_bid_ask(self): book = OrderBook() self.assertEqual(book.current_spread(), 0) limit_buy_order = Order(ID_GENERATOR, 1, 100, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 105, "LIMIT", -100) book.add_order(limit_buy_order) book.add_order(limit_sell_order) self.assertEqual(book.current_spread(), 5) limit_buy_order2 = Order(ID_GENERATOR, 3, 102, "LIMIT", 100) book.add_order(limit_buy_order2) self.assertEqual(book.current_spread(), 3)
def test_should_not_allow_two_same_agent_orders(self): book = OrderBook() order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", -100) order2 = Order(ID_GENERATOR, AGENT_ID, PRICE + 5, "LIMIT", -100) book.add_order(order) self.assertEqual(book.asks, [order]) book.add_order(order2) self.assertEqual(book.asks, [order2]) self.assertEqual(book.agent_orders[AGENT_ID], [order, order2]) self.assertEqual(order.order_state, 'CANCELLED') self.assertEqual(order2.order_state, 'ACTIVE')
def test_partial_fill_of_market_order(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 195, "LIMIT", 50) market_sell_order = Order(ID_GENERATOR, 2, None, "MARKET", -100) book.add_order(limit_buy_order) book.add_order(market_sell_order) self.assertEqual(book.bids, []) self.assertEqual(book.asks, []) self.assertEqual(market_sell_order.order_state, 'CANCEL_PARTIAL_UNFILLED') self.assertEqual(limit_buy_order.order_size, 0)
def test_prevent_market_order_no_orders(self): order = Order(ID_GENERATOR, AGENT_ID, None, "MARKET", 100) book = OrderBook() with self.assertRaises(Exception) as context: book.add_order(order) self.assetEqual(context, "No available liquidity to fill market order") sell_order = Order(ID_GENERATOR, AGENT_ID, None, "MARKET", -100) with self.assertRaises(Exception) as context: book.add_order(order) self.assetEqual(context, "No available liquidity to fill market order")
def test_fill_with_partial_limit_order_multiple_and_diff_prices(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 200, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 205, "LIMIT", -50) limit_sell_order2 = Order(ID_GENERATOR, 2, 200, "LIMIT", -25) book.add_order(limit_buy_order) book.add_order(limit_sell_order) book.add_order(limit_sell_order2) self.assertEqual(book.bids, [limit_buy_order]) self.assertEqual(book.asks, []) self.assertEqual(book.bids[0].order_size, 75) self.assertEqual(limit_sell_order.order_size, -50) self.assertEqual(limit_sell_order2.order_size, 0)
def test_fill_with_limit_orders(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 200, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 200, "LIMIT", -100) book.add_order(limit_buy_order) self.assertEqual(book.bids, [limit_buy_order]) book.add_order(limit_sell_order) self.assertEqual(book.bids, []) self.assertEqual(book.asks, []) self.assertEqual(limit_sell_order.partial_execution_log, [PartialExecution(100, 200)]) self.assertEqual(limit_buy_order.partial_execution_log, [PartialExecution(100, 200)]) self.assertEqual(limit_buy_order.order_state, 'FILLED')
def test_lazy_cleanup(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 100, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 105, "LIMIT", -100) book.add_order(limit_buy_order) book.add_order(limit_sell_order) book.cancel_order(limit_buy_order.id) book.cancel_order(limit_sell_order.id) self.assertEqual(limit_buy_order.order_state, 'CANCELLED') self.assertEqual(limit_sell_order.order_state, 'CANCELLED') self.assertEqual(len(book.bids), 1) self.assertEqual(len(book.asks), 1) book._OrderBook__lazy_remove_completed_orders() self.assertEqual(len(book.bids), 0) self.assertEqual(len(book.asks), 0)
def test_cancel_order(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 100, "LIMIT", 100) book.add_order(limit_buy_order) self.assertEqual(limit_buy_order.order_state, 'ACTIVE') book.cancel_order(limit_buy_order.id) self.assertEqual(limit_buy_order.order_state, 'CANCELLED')
def test_has_active_bids(self): book = OrderBook() self.assertEqual(book.has_active_bids(), False) order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", 100) book.add_order(order) self.assertEqual(book.has_active_bids(), True) self.assertEqual(book.has_active_asks(), False)
def test_partial_fill_of_market_sell_order_existing_unfilled_orders(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 195, "LIMIT", 50) limit_buy_order2 = Order(ID_GENERATOR, 3, 200, "LIMIT", 50) limit_buy_order3 = Order(ID_GENERATOR, 4, 180, "LIMIT", 700) market_sell_order = Order(ID_GENERATOR, 2, None, "MARKET", -100) book.add_order(limit_buy_order) book.add_order(limit_buy_order2) book.add_order(limit_buy_order3) book.add_order(market_sell_order) self.assertEqual(book.bids, [limit_buy_order3]) self.assertEqual(book.asks, []) self.assertEqual(market_sell_order.order_state, 'FILLED') self.assertEqual(limit_buy_order.order_size, 0) self.assertEqual(limit_buy_order2.order_size, 0) self.assertEqual(limit_buy_order3.order_size, 700)
def test_add_basic_buy_order(self): order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", 100) book = OrderBook() book.add_order(order) self.assertEqual(book.bids, [order]) order1 = Order(ID_GENERATOR, 2, PRICE + 1, "LIMIT", 100) book.add_order(order1) self.assertEqual(book.bids, [order1, order]) all_orders = {} all_orders[order1.id] = order1 all_orders[order.id] = order agent_orders = {} agent_orders[order1.agent_id] = [order1] agent_orders[order.agent_id] = [order] self.assertEqual(book.agent_orders, agent_orders) self.assertEqual(book.all_orders, all_orders)
def test_fill_with_partial_limit_order_multiple_and_price_matching_order2( self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 200, "LIMIT", 100) limit_sell_order = Order(ID_GENERATOR, 2, 195, "LIMIT", -50) limit_sell_order2 = Order(ID_GENERATOR, 2, 200, "LIMIT", -25) book.add_order(limit_sell_order) book.add_order(limit_buy_order) book.add_order(limit_sell_order2) self.assertEqual(book.bids, [limit_buy_order]) self.assertEqual(book.asks, []) self.assertEqual(book.bids[0].order_size, 25) self.assertEqual(limit_sell_order.order_size, 0) self.assertEqual( limit_buy_order.partial_execution_log, [PartialExecution(50, 195), PartialExecution(25, 200)])
def setUp(self): self.orders = [] for i in range(1, 5): self.orders.append(Order(test_quotes[str(i)])) self.buyOrderList = OrderList("BUY", self.orders[0].price) self.sellOrderList = OrderList("SELL", self.orders[1].price) self.buyOrderList.add_order(self.orders[0]) self.sellOrderList.add_order(self.orders[1]) self.buyOrderList.add_order(self.orders[2]) self.sellOrderList.add_order(self.orders[3])
def execute_orders(conn): c = conn.cursor() orders = [] day_ago = datetime.now() - timedelta(hours=24) for is_buy, address, usd_rate, price in c.execute( "SELECT * FROM orders \ WHERE created_at >= ? ORDER BY created_at", day_ago): orders.append(Order(is_buy, address, usd_rate, price)) c.execute("UPDATE orders SET is_buy = -1 WHERE created_at >= ?", day_ago) return orders
class test_order(unittest.TestCase): def setUp(self): self.order = Order(test_quotes[str(1)]) self.order2 = Order(test_quotes[str(7)]) def test_add_order(self): self.assertEqual(self.order.price, 100.00) self.assertEqual(self.order.side, "BUY") self.assertEqual(self.order.order_type, 'LIMIT') self.assertEqual(self.order.symbol, 'KEQ') self.assertEqual(self.order.quantity, 50) self.assertEqual(self.order.account_id, "1") self.assertEqual(self.order2.price, None) self.assertEqual(self.order2.side, "BUY") self.assertEqual(self.order2.order_type, 'MARKET') self.assertEqual(self.order2.symbol, 'KEQ') self.assertEqual(self.order2.quantity, 100) self.assertEqual(self.order2.account_id, "7") def test_update_order(self): self.order.update(75) self.assertEqual(self.order.quantity, 75)
def test_partial_execution(self): order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", -100) self.assertEqual(order.order_state, "ACTIVE") self.assertEqual(order.order_size, -100) order.partial_execute(20, 4) self.assertEqual(order.order_size, -80) self.assertEqual(order.order_state, "PARTIAL_EXECUTION") self.assertEqual(order.partial_execution_log, [PartialExecution(20, 4)]) order.partial_execute(20, 4) self.assertEqual(order.order_size, -60) self.assertEqual(order.order_state, "PARTIAL_EXECUTION") self.assertEqual(order.partial_execution_log, [PartialExecution(20, 4), PartialExecution(20, 4)]) order.partial_execute(60, 4) self.assertEqual(order.order_size, 0) self.assertEqual(order.order_state, "FILLED") self.assertEqual(order.partial_execution_log, [ PartialExecution(20, 4), PartialExecution(20, 4), PartialExecution(60, 4) ])
def bench(n): book = OrderBook() length = len(tests) for i in range(n): o = tests[i % length] book.limit_order(Order(o.id, o.side, o.price, o.original_size))
def gen_random_order(i): return Order(i, random.choice([BUY, SELL]), random.randrange(50, 150), random.randrange(1, 1000))
def setUp(self): self.order = Order(test_quotes[str(1)]) self.order2 = Order(test_quotes[str(7)])
def test_must_add_price_to_limit_order(self): with self.assertRaises(Exception) as context: Order(ID_GENERATOR, AGENT_ID, None, "LIMIT", -100) self.assetEqual(context, "Limit order requires a price to be input")
def setUp(self): self.order = Order(test_quotes[str(4)]) self.order2 = Order(test_quotes[str(5)]) self.trade = Trade(self.order, self.order2, 75)
def test_cannot_add_price_to_market_order(self): with self.assertRaises(Exception) as context: Order(ID_GENERATOR, AGENT_ID, PRICE, "MARKET", -100) self.assetEqual(context, "Unable to provide price with market order")
def limit_order(self, side, price, amount): o = Order(self.next_order_id(), side, price, amount) self.all_orders[o.id] = o self.orderbook.limit_order(o) self.validate() return o
def test_buy_or_sell(self): order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", -100) self.assertEqual(order.buy_or_sell(), 'SELL') order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", 100) self.assertEqual(order.buy_or_sell(), 'BUY')
def test_change_to_fill(self): order = Order(ID_GENERATOR, AGENT_ID, PRICE, "LIMIT", -100) self.assertEqual(order.order_state, "ACTIVE") order.fill() self.assertEqual(order.order_state, "FILLED")