def __init__(self, order_arrival_lambda=2, initial_price=100., price_sigma=.2, quantity_mu=2, quantity_sigma=1, periods=None, traders=50, tick_size=.0001, purge_after_vol=100, open_time=dt.datetime(2017, 1, 1, 8, 0, 0), close_time=dt.datetime(2017, 1, 1, 15, 0, 0)): self.p0 = initial_price self.p = initial_price self.tick_size = tick_size self.purge_after_vol = purge_after_vol self.order_arrival_lambda = order_arrival_lambda self.price_sigma = price_sigma self.quantity_mu = quantity_mu self.quantity_sigma = quantity_sigma if periods: self.periods = periods else: self.periods = (close_time-open_time).total_seconds() if type(traders) == int: traders = range(traders) self.traders = traders self.orderbook = OrderBook() self.total_orders_submitted = 0 self.sides = np.array(['ask', 'bid']) self.sign = np.array([1., -1.]) self.time = 0 self.orders_by_vol = deque(maxlen=None)
def setup(self): self.book = OrderBook(9999, 3, 'TEST') self.book.change(3, 'Offer', 8, 8, 8) self.book.change(2, 'Offer', 7, 7, 7) self.book.change(1, 'Offer', 6, 6, 6) self.book.change(1, 'Bid', 3, 3, 3) self.book.change(2, 'Bid', 2, 2, 2) self.book.change(3, 'Bid', 1, 1, 1) self.book.instrument_sequence = 0
def setUp(self): self.order_book = OrderBook() self.limit_orders = [ { 'type': 'limit', 'side': 'ask', 'quantity': 5, 'price': 101 }, { 'type': 'limit', 'side': 'ask', 'quantity': 5, 'price': 103 }, { 'type': 'limit', 'side': 'ask', 'quantity': 5, 'price': 101 }, { 'type': 'limit', 'side': 'ask', 'quantity': 5, 'price': 101 }, { 'type': 'limit', 'side': 'bid', 'quantity': 5, 'price': 99 }, { 'type': 'limit', 'side': 'bid', 'quantity': 5, 'price': 98 }, { 'type': 'limit', 'side': 'bid', 'quantity': 5, 'price': 99 }, { 'type': 'limit', 'side': 'bid', 'quantity': 5, 'price': 97 }, ] for order in self.limit_orders: trades, order_id = self.order_book.process_order(order)
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 orderbook_demo(): import time, random ITERS = 100000 max_price = 10 ob = OrderBook("FOOBAR", max_price=max_price) start = time.clock() for i in range(ITERS): os.system("clear") buysell, qty, price, trader = random.choice([0,1]), random.randrange(1,50), \ random.randrange(1,max_price), 'trader %s' % random.randrange(1000) print "NEW ORDER: %s %s %s @ %s" % (trader, "BUY" if buysell==0 else "SELL", qty, price) ob.limit_order(buysell, qty, price, trader) print ob.render() raw_input()
def main(): # TODO: Create three agents: order_book = OrderBook() agents = [101, 102, 103] # TODO: Agents send in buy/sell orders randomly with some probablility for i in range(30): print '\nTimestep# {}: '.format(i) for a in agents: if (random.random() > 0.5): # make an order # buy or sell? # TO BE REPLACED WITH TRADING STRATEGIES tradedir = random.choice(['bid', 'ask']) # how many? ordqty = random.randint(1, 20) # market or limit? tradetype = random.choice(['market', 'limit']) # if limit, what is your bid/ask price if tradetype == 'limit': # TO BE REPLACED WITH TRADING STRATEGIES limitprice = random.uniform(90, 100) # send in the order if tradetype == 'market': agent_order = { 'type': 'market', 'side': tradedir, 'quantity': ordqty, 'trade_id': a } print 'agent {} made a market order to {} {} shares'.format( a, tradedir, ordqty) else: agent_order = { 'type': 'limit', 'side': tradedir, 'quantity': ordqty, 'price': limitprice, 'trade_id': a } print 'agent {} made a limit order at {} to {} {} shares'.format( a, limitprice, tradedir, ordqty) trades, order_in_book = order_book.process_order( agent_order, False, False) else: print 'agent {} did not trade'.format(a) # plot how the stock changes print order_book
def test_one_buy_order_book(instrument_identifier, marshaller): simple_order_book = OrderBook(instrument_identifier) buy_order = ServerOrder(Buy(), instrument_identifier, quantity=100.0, price=10.0, counterparty='Trader1') simple_order_book.add_order(buy_order) encoded_order_book = marshaller.encode_order_book(simple_order_book) message_type, body, _ = marshaller.decode_header(encoded_order_book) decoded_order_book = marshaller.decode_order_book(body) assert message_type == MessageTypes.OrderBook.value assert encoded_order_book == marshaller.encode_order_book( decoded_order_book)
class Engine: def __init__(self): self.orderbook = OrderBook() self.orderbook.on_event = self.on_event self.trades = [] self._next_order_id = 0 self.all_orders = {} def next_order_id(self): n = self._next_order_id self._next_order_id += 1 return n 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 cancel_order(self, orderid): o = self.orderbook.cancel_order(self.all_orders[orderid].price, orderid) self.validate() return o def on_event(self, name, evt): if name == 'trade': self.trades.append(evt) def validate(self): book = self.orderbook assert not book.bids or not book.asks or book.bids.max() < book.asks.min(), \ 'bids asks shouldn\'t cross' assert all(price == self.all_orders[makerid].price for _, makerid, _, price in self.trades), \ 'trade price equals to maker price' assert all(better_price(price, self.all_orders[takerid].price, self.all_orders[takerid].side) for takerid, _, _, price in self.trades), \ 'trade price equal or better than taker price' assert all(order.price == price for price, lvl in book.levels.items() for order in lvl.orders), \ 'level price is correct' assert all(sum(o.size for o in lvl.orders) == lvl.volume for price, lvl in book.levels.items()), \ 'level volume is correct'
def setUp(self): self.completed_trades = [] self.completed_orders = [] self.orders = [] self.order_book = OrderBook("KEQ") for i in range(1, 10): quote = test_quotes[str(i)] if "price" in quote: quote["price"] = Decimal(quote["price"]) order = json.loads(self.order_book.process_order(quote)) self.orders.append(order) for trades in self.order_book.completed_trades: self.completed_trades.append(trades) for orders in self.order_book.completed_orders: self.completed_orders.append(orders)
def test_empty_order_book(instrument_identifier, marshaller): empty_order_book = OrderBook(instrument_identifier) encoded_order_book = marshaller.encode_order_book(empty_order_book) message_type, body, _ = marshaller.decode_header(encoded_order_book) decoded_order_book = marshaller.decode_order_book(body) assert message_type == MessageTypes.OrderBook.value assert empty_order_book.__dict__ == decoded_order_book.__dict__
def ob(red, request): '''Returns an empty OrderBook''' def fin(): red.flushdb() request.addfinalizer(fin) return OrderBook('XBT', 'XLT', red)
def test_one_buy_order_book(self): simple_order_book = OrderBook(self.instrument_identifier) buy_order = ServerOrder(Buy(), self.instrument_identifier, quantity=100.0, price=10.0, counterparty='Trader1') simple_order_book.add_order(buy_order) encoded_order_book = self.marshaller.encode_order_book( simple_order_book) message_type, body, _ = self.marshaller.decode_header( encoded_order_book) decoded_order_book = self.marshaller.decode_order_book(body) self.assertEqual(message_type, MessageTypes.OrderBook.value) self.assertEqual(encoded_order_book, self.marshaller.encode_order_book(decoded_order_book))
def test_update_invalid(self): """ check: invalid size and update missing order""" obj = OrderBook() # invalid size self.assertRaises(AssertionError, obj.process_order, "1568390243|abbb11|u|0") # update missing order self.assertRaises(KeyError, obj.process_order, "1|abbb11|u|1")
def testOrderbook(red): '''Returns an OrderBook populated with 20 test non crossing bids/asks''' #FIXME or use ob fixture? ob = OrderBook('XBT', 'XLT', red) #ob. some bids #ob. some asks return ob
def initialize_order_books(self, referential): logger.trace("Initializing order books") # TODO: use generator for instrument in referential.instruments: self.order_books[instrument.identifier] = OrderBook( instrument.identifier) logger.trace(f"[{len(referential)}] order books are initialized")
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 initialize_order_books(self): self.logger.debug('Initializing order books') # TODO: use generator for instrument in self.referential.instruments: self.order_books[instrument.identifier] = OrderBook( instrument.identifier) self.logger.debug('[{}] order books are initialized'.format( len(self.referential)))
def test_to_json(): asks = [Ask(quantity=1, rate=2)] bids = [Bid(quantity=3, rate=4)] o = OrderBook(asks=asks, bids=bids) j = orderbook_to_json(o) assert j == '{"Asks": [{"Quantity": 1, "Rate": 2}], "Bids": [{"Quantity": 3, "Rate": 4}]}'
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_empty_order_book(self): empty_order_book = OrderBook(StaticData.get_instrument(1).identifier) encoded_order_book = self.marshaller.encode_order_book( empty_order_book) message_type, body, _ = self.marshaller.decode_header( encoded_order_book) decoded_order_book = self.marshaller.decode_order_book(body) self.assertEqual(message_type, MessageTypes.OrderBook.value) self.assertEqual(empty_order_book.__dict__, decoded_order_book.__dict__)
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_partial_fill_of_market_order2(self): book = OrderBook() limit_buy_order = Order(ID_GENERATOR, 1, 195, "LIMIT", 50) limit_buy_order2 = Order(ID_GENERATOR, 3, 200, "LIMIT", 50) 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(market_sell_order) self.assertEqual(book.bids, []) 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)
def test_add_invalid(self): """ check: invalid type , order size, order price""" obj = OrderBook() # invalid type self.assertRaises(AttributeError, obj.process_order, 11) # invalid order size self.assertRaises(AssertionError, obj.process_order, "1568390243|abbb11|a|AAPL|B|209.00000|0") # invalid order price self.assertRaises(AssertionError, obj.process_order, "1568390243|abbb11|a|AAPL|B|-209.00000|2")
def _setup_orderbook(): [redis.delete(key) for key in redis.keys()] orderbook_store = db.orderbook.find({'orderbook_id': 1}).limit(1) if path.isfile(ORDERBOOK_FILE): with open(ORDERBOOK_FILE, 'rb') as f: orderbook = pickle.load(f) elif orderbook_store.count() > 0: orderbook = pickle.loads(orderbook_store[0]["orderbook"]) else: orderbook = OrderBook(STOCK_SYMBOL) return orderbook
def test_process_order(self): """ check: order,add,update,missing parameters; unsupported action""" obj = OrderBook() # missing parameters self.assertRaises(IndexError, obj.process_order, "1568390243|abbb11") # add missing parameters self.assertRaises(AssertionError, obj.process_order, "1568390243|abbb11|a") # update missing parameters self.assertRaises(AssertionError, obj.process_order, "1568390243|abbb11|u") # unsupported action self.assertRaises(PermissionError, obj.process_order, "1568390243|abbb11|x")
def score(self, process_event_func): Ys = [] pred_probas = [] orderbook = OrderBook() for event in tqdm(self.event_player.iget_events(), total=len(self.event_player), desc="scoring"): orderbook.apply_event(event) pred_proba = process_event_func(event, orderbook) self._check_return_value(event, pred_proba) if not event.need_prediction: continue Ys.append(event.Y) pred_probas.append(pred_proba) roc_auc = roc_auc_score(Ys, pred_probas) print(f"\nroc_auc_score = {roc_auc:.3f}") return roc_auc, (Ys, pred_probas)
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')
class OnlineDA(object): def __init__(self): self.ob=OrderBook() self.day=0 self.trades=[] def nextDay(self): self.day+=1 self.trades=[] self.ob.asks=OrderTree() self.ob.bids=OrderTree() def submitOrder(self, order): trades, remOrder=self.ob.process_order(order, False, False) if len(trades)>0: self.trades.extend(trades) if not remOrder: order['isFilled']=True return trades, order if remOrder['quantity']<order['quantity']: order['isFilled']=True return trades, order order['isFilled']=False return trades, order def getOpenPrice(self): if len(self.trades)>0: return self.trades[0]['price'] return 0 def getClosePrice(self): if len(self.trades)>0: return self.trades[-1]['price'] return 0 def getHighPrice(self): if len(self.trades)>0: return np.max([t['price'] for t in self.trades]) return 0 def getLowPrice(self): if len(self.trades)>0: return np.min([t['price'] for t in self.trades]) return 0 def getVolume(self): return np.sum([t['quantity'] for t in self.trades])
def test_two_opposite_orders_in_order_book(self): order_book = OrderBook(self.instrument_identifier) orders = [ ServerOrder(Buy(), self.instrument_identifier, quantity=100.0, price=9.0, counterparty='Trader1'), ServerOrder(Sell(), self.instrument_identifier, quantity=100.0, price=10.0, counterparty='Trader2') ] for order in orders: order_book.add_order(order) encoded_order_book = self.marshaller.encode_order_book(order_book) message_type, body, _ = self.marshaller.decode_header( encoded_order_book) decoded_order_book = self.marshaller.decode_order_book(body) self.assertEqual(message_type, MessageTypes.OrderBook.value) self.assertEqual(encoded_order_book, self.marshaller.encode_order_book(decoded_order_book))
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 main(): # TODO: Create three agents: order_book = OrderBook() agents = [101, 102, 103] # TODO: Agents send in buy/sell orders randomly with some probablility for i in range(30): print '\nTimestep# {}: '.format(i) for a in agents: if (random.random() > 0.5): # make an order # buy or sell? # TO BE REPLACED WITH TRADING STRATEGIES tradedir = random.choice(['bid','ask']) # how many? ordqty = random.randint(1,20) # market or limit? tradetype = random.choice(['market', 'limit']) # if limit, what is your bid/ask price if tradetype == 'limit': # TO BE REPLACED WITH TRADING STRATEGIES limitprice = random.uniform(90,100) # send in the order if tradetype == 'market': agent_order = {'type':'market', 'side':tradedir, 'quantity':ordqty, 'trade_id':a} print 'agent {} made a market order to {} {} shares'.format(a, tradedir, ordqty) else: agent_order = {'type':'limit', 'side':tradedir, 'quantity':ordqty, 'price':limitprice, 'trade_id':a} print 'agent {} made a limit order at {} to {} {} shares'.format(a, limitprice, tradedir, ordqty) trades, order_in_book = order_book.process_order(agent_order, False, False) else: print 'agent {} did not trade'.format(a) # plot how the stock changes print order_book
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_partial_fill_of_market_buy_order_existing_unfilled_orders(self): book = OrderBook() limit_sell_order = Order(ID_GENERATOR, 1, 195, "LIMIT", -50) limit_sell_order2 = Order(ID_GENERATOR, 3, 200, "LIMIT", -50) limit_sell_order3 = Order(ID_GENERATOR, 4, 180, "LIMIT", -700) market_buy_order = Order(ID_GENERATOR, 2, None, "MARKET", 100) book.add_order(limit_sell_order) book.add_order(limit_sell_order2) book.add_order(limit_sell_order3) book.add_order(market_buy_order) self.assertEqual(book.bids, []) self.assertEqual( book.asks, [limit_sell_order3, limit_sell_order2, limit_sell_order]) self.assertEqual(market_buy_order.order_state, 'FILLED') self.assertEqual(limit_sell_order.order_size, -50) self.assertEqual(limit_sell_order2.order_size, -50) self.assertEqual(limit_sell_order3.order_size, -600)
def setUp(self): self.order_book = OrderBook() self.limit_orders = [{'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 103}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 99}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 98}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 99}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 97}, ] for order in self.limit_orders: trades, order_id = self.order_book.process_order(order)
def __init__(self): self.ob=OrderBook() self.day=0 self.trades=[]
class OrderBookTestCase(unittest.TestCase): ''' Unittest for the OrderBook module ''' def setUp(self): self.order_book = OrderBook() self.limit_orders = [{'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 103}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 99}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 98}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 99}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5, 'price' : 97}, ] for order in self.limit_orders: trades, order_id = self.order_book.process_order(order) def test_process_asks_order(self): ''' set up asks orders for unittests ''' self.assertEquals(self.order_book.asks.order_map[1].price, 101.0) self.assertEquals(self.order_book.asks.order_map[2].price, 103.0) self.assertEquals(self.order_book.asks.order_map[3].price, 101.0) self.assertEquals(self.order_book.asks.order_map[4].price, 101.0) def test_process_bids_order(self): ''' set up bids orders for unittests ''' self.assertEquals(self.order_book.bids.order_map[5].price, 99.0) self.assertEquals(self.order_book.bids.order_map[6].price, 98.0) self.assertEquals(self.order_book.bids.order_map[7].price, 99.0) self.assertEquals(self.order_book.bids.order_map[8].price, 97.0) def test_trades(self): ''' Submitting a limit order that crosses the opposing best price will result in a trade ''' crossing_limit_order = {'type': 'limit', 'side': 'bid', 'quantity': 2, 'price': 102} trades, order_in_book = self.order_book.process_order(\ crossing_limit_order) self.assertEquals(trades[0]['price'], 101) self.assertEquals(trades[0]['quantity'],2) def test_large_trades(self): ''' If a limit crosses but is only partially matched, the remaning volume will be placed in the book as an outstanding order ''' big_crossing_limit_order = {'type': 'limit', 'side': 'bid', 'quantity': 50, 'price': 102} trades, order_in_book = self.order_book.process_order(\ big_crossing_limit_order) self.assertEquals(order_in_book['price'], 102) self.assertEquals(order_in_book['quantity'], 35)
else: print(newbook) def process_line(order_book, line, output=True): tokens = line.strip().split(",") d = {"type" : "limit", "side" : "bid" if tokens[0] == 'B' else 'ask', "quantity": int(tokens[1]), "price" : Decimal(tokens[2]), "trade_id" : tokens[3]} if output: printme('external order=', pprint.pformat(d)) return order_book.process_order(d, False, False) order_book = OrderBook() if len(sys.argv) != 2 and len(sys.argv) != 3 and len(sys.argv) != 4: printme("usage: %s input.csv [algo]" % sys.argv[0]) sys.exit(0) if len(sys.argv) == 3: myalgomodule = importlib.import_module(sys.argv[2]) myalgo = myalgomodule.Algorithm(order_book) elif len(sys.argv) == 4: myalgomodule = importlib.import_module(sys.argv[2]) json_data=open(sys.argv[3]).read() data = json.loads(json_data) myalgo = myalgomodule.Algorithm(order_book, **data) else: myalgo = None try: reader = open(sys.argv[1], 'r')
class TestOrderBook: def setup(self): self.book = OrderBook(9999, 3, 'TEST') self.book.change(3, 'Offer', 8, 8, 8) self.book.change(2, 'Offer', 7, 7, 7) self.book.change(1, 'Offer', 6, 6, 6) self.book.change(1, 'Bid', 3, 3, 3) self.book.change(2, 'Bid', 2, 2, 2) self.book.change(3, 'Bid', 1, 1, 1) self.book.instrument_sequence = 0 def teardown(self): self.book = None def test_adding_level_1_entries(self): # def add(self, level, side, price, size, num_orders): self.book.add(1, 'Offer', 5, 5, 5) self.book.add(1, 'Bid', 4, 4, 4) assert_equals(self.book.offers[0].price, 5) assert_equals(self.book.offers[2].price, 7) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[2].price, 2) def test_adding_level_3_entries(self): # def add(self, level, side, price, size, num_orders): self.book.add(3, 'Offer', 9, 9, 9) self.book.add(3, 'Bid', 0, 0, 0) assert_equals(self.book.offers[0].price, 6) assert_equals(self.book.offers[2].price, 9) assert_equals(self.book.bids[0].price, 3) assert_equals(self.book.bids[2].price, 0) def test_deleting_level_1_entries(self): # def add(self, level, side, price, size, num_orders): self.book.delete(1, 'Offer') self.book.delete(1, 'Bid') assert_equals(self.book.offers[0].price, 7) assert_is_none(self.book.offers[2].price) assert_equals(self.book.bids[0].price, 2) assert_is_none(self.book.bids[2].price) def test_deleting_level_3_entries(self): # def add(self, level, side, price, size, num_orders): self.book.delete(3, 'Offer') self.book.delete(3, 'Bid') assert_equals(self.book.offers[0].price, 6) assert_is_none(self.book.offers[2].price) assert_equals(self.book.bids[0].price, 3) assert_is_none(self.book.bids[2].price) def test_change(self): self.book.change(3, 'Offer', 8, 8, 8) assert_equals(self.book.offers[2].price, 8) assert_equals(self.book.offers[2].size, 8) assert_equals(self.book.offers[2].num_orders, 8) self.book.change(1, 'Bid', 4, 4, 4) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[0].size, 4) assert_equals(self.book.bids[0].num_orders, 4) #def update(self, sending_time, received_time, stream_sequence, instrument_sequence, level, md_entry_type, md_update_action, price, size, num_orders): def test_update_book_change(self): self.book.handle_update(101, 102, 1, 1, 3, 'Offer', 'Change', 8, 8, 8) assert_equals(self.book.offers[0].price, 6) assert_equals(self.book.offers[0].size, 6) assert_equals(self.book.offers[0].num_orders, 6) assert_equals(self.book.offers[2].price, 8) assert_equals(self.book.offers[2].size, 8) assert_equals(self.book.offers[2].num_orders, 8) self.book.handle_update(101, 102, 2, 2, 1, 'Bid', 'Change', 4, 4, 4) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[0].size, 4) assert_equals(self.book.bids[0].num_orders, 4) assert_equals(self.book.bids[2].price, 1) assert_equals(self.book.bids[2].size, 1) assert_equals(self.book.bids[2].num_orders, 1) def test_update_book_add(self): self.book.handle_update(101, 102, 1, 1, 1, 'Offer', 'New', 5, 5, 5) assert_equals(self.book.offers[0].price, 5) assert_equals(self.book.offers[0].size, 5) assert_equals(self.book.offers[0].num_orders, 5) assert_equals(self.book.offers[2].price, 7) assert_equals(self.book.offers[2].size, 7) assert_equals(self.book.offers[2].num_orders, 7) self.book.handle_update(101, 102, 2, 2, 1, 'Bid', 'New', 4, 4, 4) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[0].size, 4) assert_equals(self.book.bids[0].num_orders, 4) assert_equals(self.book.bids[2].price, 2) assert_equals(self.book.bids[2].size, 2) assert_equals(self.book.bids[2].num_orders, 2) def test_update_book_delete(self): self.book.handle_update(101, 102, 1, 1, 1, 'Offer', 'Delete', None, None, None) assert_equals(self.book.offers[0].price, 7) assert_equals(self.book.offers[0].size, 7) assert_equals(self.book.offers[0].num_orders, 7) assert_is_none(self.book.offers[2].price) self.book.handle_update(101, 102, 2, 2, 1, 'Bid', 'Delete', None, None, None) assert_equals(self.book.bids[0].price, 2) assert_equals(self.book.bids[0].size, 2) assert_equals(self.book.bids[0].num_orders, 2) assert_is_none(self.book.bids[2].price) def test_update_book_old_sequence(self): self.book.instrument_sequence = 99 self.book.handle_update(101, 102, 100, 100, 1, 'Offer', 'New', 5, 5, 5) self.book.handle_update(101, 102, 99, 99, 1, 'Offer', 'New', 999, 999, 999) assert_equals(self.book.offers[0].price, 5) assert_equals(self.book.offers[0].size, 5) assert_equals(self.book.offers[0].num_orders, 5) assert_equals(self.book.offers[2].price, 7) assert_equals(self.book.offers[2].size, 7) assert_equals(self.book.offers[2].num_orders, 7) self.book.instrument_sequence = 99 self.book.handle_update(101, 102, 100, 100, 1, 'Bid', 'New', 4, 4, 4) self.book.handle_update(101, 102, 99, 99, 1, 'Bid', 'New', 999, 999, 999) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[0].size, 4) assert_equals(self.book.bids[0].num_orders, 4) assert_equals(self.book.bids[2].price, 2) assert_equals(self.book.bids[2].size, 2) assert_equals(self.book.bids[2].num_orders, 2) def test_update_book_duplicate_sequence(self): self.book.handle_update(101, 102, 1, 1, 1, 'Offer', 'New', 5, 5, 5) self.book.handle_update(101, 102, 1, 1, 1, 'Offer', 'New', 999, 999, 999) assert_equals(self.book.offers[0].price, 5) assert_equals(self.book.offers[0].size, 5) assert_equals(self.book.offers[0].num_orders, 5) assert_equals(self.book.offers[2].price, 7) assert_equals(self.book.offers[2].size, 7) assert_equals(self.book.offers[2].num_orders, 7) self.book.handle_update(101, 102, 2, 2, 1, 'Bid', 'New', 4, 4, 4) self.book.handle_update(101, 102, 2, 2, 1, 'Bid', 'New', 999, 999, 999) assert_equals(self.book.bids[0].price, 4) assert_equals(self.book.bids[0].size, 4) assert_equals(self.book.bids[0].num_orders, 4) assert_equals(self.book.bids[2].price, 2) assert_equals(self.book.bids[2].size, 2) assert_equals(self.book.bids[2].num_orders, 2) def test_update_book_gapped(self): return # not ready for testing gaps until we handle more messages
from orderbook import OrderBook # Create an order book order_book = OrderBook() # Create some limit orders limit_orders = [{'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101, 'trade_id' : 100}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 103, 'trade_id' : 101}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101, 'trade_id' : 102}, {'type' : 'limit', 'side' : 'ask', 'quantity' : 5, 'price' : 101, 'trade_id' : 103}, {'type' : 'limit', 'side' : 'bid', 'quantity' : 5,