def __init__(self, rest_book): self.bids = OrderTree() self.asks = OrderTree() for bid in rest_book.bids: self.bids.insert_price(bid.price, bid.amount, bid.oid) for ask in rest_book.asks: self.asks.insert_price(ask.price, ask.amount, ask.oid)
def __init__(self, tick_size=0.0001): self.tape = deque(maxlen=None) # Index[0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.last_tick = None self.last_timestamp = 0 self.tick_size = tick_size self.time = 0 self.next_order_id = 0
def __init__(self, tick_size = 0.0001): self.tape = deque(maxlen=None) # Index[0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.last_tick = None self.last_timestamp = 0 self.tick_size = tick_size self.time = 0 self.next_order_id = 0
def __init__(self, tick_size = 0.0001): self.tape = deque(maxlen=None) # Index [0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.lastTick = None self.lastTimestamp = 0 self.tickSize = tick_size self.time = 0 self.nextQuoteID = 0 self.traderPool = {}
def __init__(self): ''' @summary: initialization of OrderBook @mem bids: an ordertree for bids orders @mem asks: an ordertree for asks orders @mem time: maintain the current time in the orderbook ''' self.bids = OrderTree() self.asks = OrderTree() self.last_timestamp = 0 self.time = 0 self.next_order_id = 0
class OrderBook(object): def __init__(self, tick_size=0.0001): self.tape = deque(maxlen=None) # Index[0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.last_tick = None self.last_timestamp = 0 self.tick_size = tick_size self.time = 0 self.next_order_id = 0 def clip_price(self, price): '''Clips the price according to the tick size. May not make sense if not a currency''' return round(price, int(math.log10(1 / self.tick_size))) def update_time(self): self.time += 1 def process_order(self, quote, from_data, verbose): order_type = quote['type'] order_in_book = None if from_data: self.time = quote['timestamp'] else: self.update_time() quote['timestamp'] = self.time if quote['quantity'] <= 0: sys.exit('process_order() given order of quantity <= 0') if not from_data: self.next_order_id += 1 if order_type == 'market': trades = self.process_market_order(quote, verbose) elif order_type == 'limit': quote['price'] = self.clip_price(quote['price']) trades, order_in_book = self.process_limit_order( quote, from_data, verbose) else: sys.exit( "order_type for process_order() is neither 'market' or 'limit'" ) return trades, order_in_book def process_order_list(self, side, order_list, quantity_still_to_trade, quote, verbose): ''' Takes an OrderList (stack of orders at one price) and an incoming order and matches appropriate trades given the order's quantity. ''' trades = [] quantity_to_trade = quantity_still_to_trade while len(order_list) > 0 and quantity_to_trade > 0: head_order = order_list.get_head_order() traded_price = head_order.price counter_party = head_order.trade_id if quantity_to_trade < head_order.quantity: traded_quantity = quantity_to_trade # Do the transaction new_book_quantity = head_order.quantity - quantity_to_trade head_order.update_quantity(new_book_quantity, head_order.timestamp) quantity_to_trade = 0 elif quantity_to_trade == head_order.quantity: traded_quantity = quantity_to_trade if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade = 0 else: # quantity to trade is larger than the head order traded_quantity = head_order.quantity if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade -= traded_quantity if verbose: print( "TRADE: Time - %d, Price - %f, Quantity - %d, TradeID - %d, Matching TradeID - %d" % (self.time, traded_price, traded_quantity, counter_party, quote['trade_id'])) transaction_record = { 'timestamp': self.time, 'price': traded_price, 'quantity': traded_quantity, 'time': self.time } if side == 'bid': transaction_record['party1'] = [ counter_party, 'bid', head_order.order_id ] transaction_record['party2'] = [quote['trade_id'], 'ask', None] else: transaction_record['party1'] = [ counter_party, 'ask', head_order.order_id ] transaction_record['party2'] = [quote['trade_id'], 'bid', None] self.tape.append(transaction_record) trades.append(transaction_record) return quantity_to_trade, trades def process_market_order(self, quote, verbose): trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] if side == 'bid': while quantity_to_trade > 0 and self.asks: best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list( 'ask', best_price_asks, quantity_to_trade, quote, verbose) trades += new_trades elif side == 'ask': while quantity_to_trade > 0 and self.bids: best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list( 'bid', best_price_bids, quantity_to_trade, quote, verbose) trades += new_trades else: sys.exit('process_market_order() recieved neither "bid" nor "ask"') return trades def process_limit_order(self, quote, from_data, verbose): order_in_book = None trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] price = quote['price'] if side == 'bid': while (self.asks and price > self.asks.min_price() and quantity_to_trade > 0): best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list( 'ask', best_price_asks, quantity_to_trade, quote, verbose) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: if not from_data: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.bids.insert_order(quote) order_in_book = quote elif side == 'ask': while (self.bids and price < self.bids.max_price() and quantity_to_trade > 0): best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list( 'bid', best_price_bids, quantity_to_trade, quote, verbose) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: if not from_data: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.asks.insert_order(quote) order_in_book = quote else: sys.exit('process_limit_order() given neither "bid" nor "ask"') return trades, order_in_book def cancel_order(self, side, order_id, time=None): if time: self.time = time else: self.update_time() if side == 'bid': if self.bids.order_exists(order_id): self.bids.remove_order_by_id(order_id) elif side == 'ask': if self.asks.order_exists(order_id): self.bids.remove_order_by_id(order_id) else: sys.exit('cancel_order() given neither "bid" nor "ask"') def modify_order(self, order_id, order_update, time=None): if time: self.time = time else: self.update_time() side = order_update['side'] order_update['order_id'] = order_id order_update['timestamp'] = self.time if side == 'bid': if self.bids.order_exists(order_update['order_id']): self.bids.update_order(order_update) elif side == 'ask': if self.asks.order_exists(order_update['order_id']): self.asks.update_order(order_update) else: sys.exit('modify_order() given neither "bid" nor "ask"') def get_volume_at_price(self, side, price): price = self.clip_price(price) if side == 'bid': volume = 0 if self.bids.price_exists(price): volume = self.bids.get_price(price).volume return volume elif side == 'ask': volume = 0 if self.asks.price_exists(price): volume = self.asks.get_price(price).volume return volume else: sys.exit('get_volume_at_price() given neither "bid" nor "ask"') def get_best_bid(self): return self.bids.max_price() def get_worst_bid(self): return self.bids.min_price() def get_best_ask(self): return self.asks.min_price() def get_worst_ask(self): return self.asks.max_price() def tape_dump(self, filename, filemode, tapemode): dumpfile = open(filename, filemode) for tapeitem in self.tape: dumpfile.write( 'Time: %s, Price: %s, Quantity: %s\n' % (tapeitem['time'], tapeitem['price'], tapeitem['quantity'])) dumpfile.close() if tapemode == 'wipe': self.tape = [] def __str__(self): tempfile = StringIO() tempfile.write("***Bids***\n") if self.bids != None and len(self.bids) > 0: for key, value in self.bids.price_tree.items(reverse=True): tempfile.write('%s' % value) tempfile.write("\n***Asks***\n") if self.asks != None and len(self.bids) > 0: for key, value in self.asks.price_tree.items(): tempfile.write('%s' % value) tempfile.write("\n***Trades***\n") if self.tape != None and len(self.tape) > 0: num = 0 for entry in self.tape: if num < 5: # get last 5 entries tempfile.write( str(entry['quantity']) + " @ " + str(entry['price']) + " (" + str(entry['timestamp']) + ")\n") num += 1 else: break tempfile.write("\n") return tempfile.getvalue()
class OrderBook(object): def __init__(self, tick_size = 0.0001): self.tape = deque(maxlen=None) # Index[0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.last_tick = None self.last_timestamp = 0 self.tick_size = tick_size self.time = 0 self.next_order_id = 0 def clip_price(self, price): '''Clips the price according to the tick size. May not make sense if not a currency''' return round(price, int(math.log10(1 / self.tick_size))) def update_time(self): self.time += 1 def process_order(self, quote, from_data, verbose): order_type = quote['type'] order_in_book = None if from_data: self.time = quote['timestamp'] else: self.update_time() quote['timestamp'] = self.time if quote['quantity'] <= 0: sys.exit('process_order() given order of quantity <= 0') if not from_data: self.next_order_id += 1 if order_type == 'market': trades = self.process_market_order(quote, verbose) elif order_type == 'limit': quote['price'] = self.clip_price(quote['price']) trades, order_in_book = self.process_limit_order(quote, from_data, verbose) else: sys.exit("order_type for process_order() is neither 'market' or 'limit'") return trades, order_in_book def process_order_list(self, side, order_list, quantity_still_to_trade, quote, verbose): ''' Takes an OrderList (stack of orders at one price) and an incoming order and matches appropriate trades given the order's quantity. ''' trades = [] quantity_to_trade = quantity_still_to_trade while len(order_list) > 0 and quantity_to_trade > 0: head_order = order_list.get_head_order() traded_price = head_order.price counter_party = head_order.trade_id if quantity_to_trade < head_order.quantity: traded_quantity = quantity_to_trade # Do the transaction new_book_quantity = head_order.quantity - quantity_to_trade head_order.update_quantity(new_book_quantity, head_order.timestamp) quantity_to_trade = 0 elif quantity_to_trade == head_order.quantity: traded_quantity = quantity_to_trade if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade = 0 else: # quantity to trade is larger than the head order traded_quantity = head_order.quantity if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade -= traded_quantity if verbose: print ("TRADE: Time - %d, Price - %f, Quantity - %d, TradeID - %d, Matching TradeID - %d" % (self.time, traded_price, traded_quantity, counter_party, quote['trade_id'])) transaction_record = { 'timestamp': self.time, 'price': traded_price, 'quantity': traded_quantity, 'time': self.time } if side == 'bid': transaction_record['party1'] = [counter_party, 'bid', head_order.order_id] transaction_record['party2'] = [quote['trade_id'], 'ask', None] else: transaction_record['party1'] = [counter_party, 'ask', head_order.order_id] transaction_record['party2'] = [quote['trade_id'], 'bid', None] self.tape.append(transaction_record) trades.append(transaction_record) return quantity_to_trade, trades def process_market_order(self, quote, verbose): trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] if side == 'bid': while quantity_to_trade > 0 and self.asks: best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list('ask', best_price_asks, quantity_to_trade, quote, verbose) trades += new_trades elif side == 'ask': while quantity_to_trade > 0 and self.bids: best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list('bid', best_price_bids, quantity_to_trade, quote, verbose) trades += new_trades else: sys.exit('process_market_order() recieved neither "bid" nor "ask"') return trades def process_limit_order(self, quote, from_data, verbose): order_in_book = None trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] price = quote['price'] if side == 'bid': while (self.asks and price > self.asks.min_price() and quantity_to_trade > 0): best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list('ask', best_price_asks, quantity_to_trade, quote, verbose) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: if not from_data: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.bids.insert_order(quote) order_in_book = quote elif side == 'ask': while (self.bids and price < self.bids.max_price() and quantity_to_trade > 0): best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list('bid', best_price_bids, quantity_to_trade, quote, verbose) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: if not from_data: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.asks.insert_order(quote) order_in_book = quote else: sys.exit('process_limit_order() given neither "bid" nor "ask"') return trades, order_in_book def cancel_order(self, side, order_id, time=None): if time: self.time = time else: self.update_time() if side == 'bid': if self.bids.order_exists(order_id): self.bids.remove_order_by_id(order_id) elif side == 'ask': if self.asks.order_exists(order_id): self.bids.remove_order_by_id(order_id) else: sys.exit('cancel_order() given neither "bid" nor "ask"') def modify_order(self, order_id, order_update, time=None): if time: self.time = time else: self.update_time() side = order_update['side'] order_update['order_id'] = order_id order_update['timestamp'] = self.time if side == 'bid': if self.bids.order_exists(order_update['order_id']): self.bids.update_order(order_update) elif side == 'ask': if self.asks.order_exists(order_update['order_id']): self.asks.update_order(order_update) else: sys.exit('modify_order() given neither "bid" nor "ask"') def get_volume_at_price(self, side, price): price = self.clip_price(price) if side == 'bid': volume = 0 if self.bids.price_exists(price): volume = self.bids.get_price(price).volume return volume elif side == 'ask': volume = 0 if self.asks.price_exists(price): volume = self.asks.get_price(price).volume return volume else: sys.exit('get_volume_at_price() given neither "bid" nor "ask"') def get_best_bid(self): return self.bids.max_price() def get_worst_bid(self): return self.bids.min_price() def get_best_ask(self): return self.asks.min_price() def get_worst_ask(self): return self.asks.max_price() def tape_dump(self, filename, filemode, tapemode): dumpfile = open(filename, filemode) for tapeitem in self.tape: dumpfile.write('Time: %s, Price: %s, Quantity: %s\n' % (tapeitem['time'], tapeitem['price'], tapeitem['quantity'])) dumpfile.close() if tapemode == 'wipe': self.tape = [] def __str__(self): tempfile = StringIO() tempfile.write("***Bids***\n") if self.bids != None and len(self.bids) > 0: for key, value in self.bids.price_tree.items(reverse=True): tempfile.write('%s' % value) tempfile.write("\n***Asks***\n") if self.asks != None and len(self.bids) > 0: for key, value in self.asks.price_tree.items(): tempfile.write('%s' % value) tempfile.write("\n***Trades***\n") if self.tape != None and len(self.tape) > 0: num = 0 for entry in self.tape: if num < 5: # get last 5 entries tempfile.write(str(entry['quantity']) + " @ " + str(entry['price']) + " (" + str(entry['timestamp']) + ")\n") num += 1 else: break tempfile.write("\n") return tempfile.getvalue()
class OrderBook(object): def __init__(self, tick_size = 0.0001): self.tape = deque(maxlen=None) # Index [0] is most recent trade self.bids = OrderTree() self.asks = OrderTree() self.lastTick = None self.lastTimestamp = 0 self.tickSize = tick_size self.time = 0 self.nextQuoteID = 0 def clipPrice(self, price): """ Clips the price according to the ticksize """ return round(price, int(math.log10(1 / self.tickSize))) def updateTime(self): self.time+=1 def processOrder(self, quote, fromData, verbose): orderType = quote['type'] orderInBook = None if fromData: self.time = quote['timestamp'] else: self.updateTime() quote['timestamp'] = self.time if quote['qty'] <= 0: sys.exit('processLimitOrder() given order of qty <= 0') if not fromData: self.nextQuoteID += 1 if orderType=='market': trades = self.processMarketOrder(quote, verbose) elif orderType=='limit': quote['price'] = self.clipPrice(quote['price']) trades, orderInBook = self.processLimitOrder(quote, fromData, verbose) else: sys.exit("processOrder() given neither 'market' nor 'limit'") return trades, orderInBook def processOrderList(self, side, orderlist, qtyStillToTrade, quote, verbose): ''' Takes an order list (stack of orders at one price) and an incoming order and matches appropriate trades given the orders quantity. ''' trades = [] qtyToTrade = qtyStillToTrade while len(orderlist) > 0 and qtyToTrade > 0: headOrder = orderlist.getHeadOrder() tradedPrice = headOrder.price counterparty = headOrder.tid if qtyToTrade < headOrder.qty: tradedQty = qtyToTrade # Amend book order newBookQty = headOrder.qty - qtyToTrade headOrder.updateQty(newBookQty, headOrder.timestamp) # Incoming done with qtyToTrade = 0 elif qtyToTrade == headOrder.qty: tradedQty = qtyToTrade if side=='bid': # Hit the bid self.bids.removeOrderById(headOrder.idNum) else: # Lift the ask self.asks.removeOrderById(headOrder.idNum) # Incoming done with qtyToTrade = 0 else: tradedQty = headOrder.qty if side=='bid': # Hit the bid self.bids.removeOrderById(headOrder.idNum) else: # Lift the ask self.asks.removeOrderById(headOrder.idNum) # We need to keep eating into volume at this price qtyToTrade -= tradedQty if verbose: print('>>> TRADE \nt=%d $%f n=%d p1=%d p2=%d' % (self.time, tradedPrice, tradedQty, counterparty, quote['tid'])) transactionRecord = {'timestamp': self.time, 'price': tradedPrice, 'qty': tradedQty, 'time': self.time} if side == 'bid': transactionRecord['party1'] = [counterparty, 'bid', headOrder.idNum] transactionRecord['party2'] = [quote['tid'], 'ask', None] else: transactionRecord['party1'] = [counterparty, 'ask', headOrder.idNum] transactionRecord['party2'] = [quote['tid'], 'bid', None] self.tape.append(transactionRecord) trades.append(transactionRecord) return qtyToTrade, trades def processMarketOrder(self, quote, verbose): trades = [] qtyToTrade = quote['qty'] side = quote['side'] if side == 'bid': while qtyToTrade > 0 and self.asks: bestPriceAsks = self.asks.minPriceList() qtyToTrade, newTrades = self.processOrderList('ask', bestPriceAsks, qtyToTrade, quote, verbose) trades += newTrades elif side == 'ask': while qtyToTrade > 0 and self.bids: bestPriceBids = self.bids.maxPriceList() qtyToTrade, newTrades = self.processOrderList('bid', bestPriceBids, qtyToTrade, quote, verbose) trades += newTrades else: sys.exit('processMarketOrder() received neither "bid" nor "ask"') return trades def processLimitOrder(self, quote, fromData, verbose): orderInBook = None trades = [] qtyToTrade = quote['qty'] side = quote['side'] price = quote['price'] if side == 'bid': while (self.asks and price >= self.asks.minPrice() and qtyToTrade > 0): bestPriceAsks = self.asks.minPriceList() qtyToTrade, newTrades = self.processOrderList('ask', bestPriceAsks, qtyToTrade, quote, verbose) trades += newTrades # If volume remains, add to book if qtyToTrade > 0: if not fromData: quote['idNum'] = self.nextQuoteID quote['qty'] = qtyToTrade self.bids.insertOrder(quote) orderInBook = quote elif side == 'ask': while (self.bids and price <= self.bids.maxPrice() and qtyToTrade > 0): bestPriceBids = self.bids.maxPriceList() qtyToTrade, newTrades = self.processOrderList('bid', bestPriceBids, qtyToTrade, quote, verbose) trades += newTrades # If volume remains, add to book if qtyToTrade > 0: if not fromData: quote['idNum'] = self.nextQuoteID quote['qty'] = qtyToTrade self.asks.insertOrder(quote) orderInBook = quote else: sys.exit('processLimitOrder() given neither bid nor ask') return trades, orderInBook def cancelOrder(self, side, idNum, time = None): if time: self.time = time else: self.updateTime() if side == 'bid': if self.bids.orderExists(idNum): self.bids.removeOrderById(idNum) elif side == 'ask': if self.asks.orderExists(idNum): self.asks.removeOrderById(idNum) else: sys.exit('cancelOrder() given neither bid nor ask') def modifyOrder(self, idNum, orderUpdate, time=None): if time: self.time = time else: self.updateTime() side = orderUpdate['side'] orderUpdate['idNum'] = idNum orderUpdate['timestamp'] = self.time if side == 'bid': if self.bids.orderExists(orderUpdate['idNum']): self.bids.updateOrder(orderUpdate) elif side == 'ask': if self.asks.orderExists(orderUpdate['idNum']): self.asks.updateOrder(orderUpdate) else: sys.exit('modifyOrder() given neither bid nor ask') def getVolumeAtPrice(self, side, price): price = self.clipPrice(price) if side =='bid': vol = 0 if self.bids.priceExists(price): vol = self.bids.getPrice(price).volume return vol elif side == 'ask': vol = 0 if self.asks.priceExists(price): vol = self.asks.getPrice(price).volume return vol else: sys.exit('getVolumeAtPrice() given neither bid nor ask') def getBestBid(self): return self.bids.maxPrice() def getWorstBid(self): return self.bids.minPrice() def getBestAsk(self): return self.asks.minPrice() def getWorstAsk(self): return self.asks.maxPrice() def tapeDump(self, fname, fmode, tmode): dumpfile = open(fname, fmode) for tapeitem in self.tape: dumpfile.write('%s, %s, %s\n' % (tapeitem['time'], tapeitem['price'], tapeitem['qty'])) dumpfile.close() if tmode == 'wipe': self.tape = [] def __str__(self): fileStr = StringIO() fileStr.write("------ Bids -------\n") if self.bids != None and len(self.bids) > 0: for k, v in self.bids.priceTree.items(reverse=True): fileStr.write('%s' % v) fileStr.write("\n------ Asks -------\n") if self.asks != None and len(self.asks) > 0: for k, v in self.asks.priceTree.items(): fileStr.write('%s' % v) fileStr.write("\n------ Trades ------\n") if self.tape != None and len(self.tape) > 0: num = 0 for entry in self.tape: if num < 5: fileStr.write(str(entry['qty']) + " @ " + str(entry['price']) + " (" + str(entry['timestamp']) + ")\n") num += 1 else: break fileStr.write("\n") return fileStr.getvalue()
def __init__(self): self.bid = OrderTree() self.ask = OrderTree() self.time = 0
class Orderbook(object): def __init__(self): self.bid = OrderTree() self.ask = OrderTree() self.time = 0 def update_time(self): self.time += 1 def process_order_list(self, side, order_list, quantity_still_to_trade, quote, output): trades = [] quantity_to_trade = quantity_still_to_trade while len(order_list) and quantity_to_trade > 0: head_order = order_list.get_head_order() traded_price = head_order.price if quantity_to_trade < head_order.quantity: traded_quantity = quantity_to_trade new_book_quantity = head_order.quantity - quantity_to_trade ''' section for output ''' print('{},{},{}'.format(output['trade_event'], traded_quantity, traded_price)) print('{},{}'.format(output['fully_filled'], quote['order_id'])) print('{},{},{},{}'.format(output['partial_filled'], head_order.order_id, head_order.side, new_book_quantity)) head_order.update_quantity(new_book_quantity, head_order.timestamp) quantity_to_trade = 0 elif quantity_to_trade == head_order.quantity: traded_quantity = quantity_to_trade print('{},{},{}'.format(output['trade_event'], traded_quantity, traded_price)) print('{},{}'.format(output['fully_filled'], quote['order_id'])) print('{},{}'.format(output['fully_filled'], head_order.order_id)) if side == '0': self.bid.remove_order_by_order_id(head_order.order_id) else: self.ask.remove_order_by_order_id(head_order.order_id) quantity_to_trade = 0 else: traded_quantity = head_order.quantity quantity_to_trade -= traded_quantity print('{},{},{}'.format(output['trade_event'], traded_quantity, traded_price)) print('{},{},{},{}'.format(output['partial_filled'], quote['order_id'], quote['side'], quantity_to_trade)) print('{},{}'.format(output['fully_filled'], head_order.order_id)) if side == '0': self.bid.remove_order_by_order_id(head_order.order_id) else: self.ask.remove_order_by_order_id(head_order.order_id) return quantity_to_trade def process_order(self, quote, output): order_in_book = None self.update_time() quote['timestamp'] = self.time if quote['quantity'] < 0: print("BADMESSAGE : Quantity is less than 0") return quantity_to_trade = quote['quantity'] side = quote['side'] price = quote['price'] if side == '0': while self.ask and price > self.ask.min_price( ) and quantity_to_trade > 0: best_price_ask = self.ask.min_price_list() quantity_to_trade = self.process_order_list( 'ask', best_price_ask, quantity_to_trade, quote, output) if quantity_to_trade > 0: quote['quantity'] = quantity_to_trade self.bid.insert_order(quote) print("Order added in book") else: while self.bid and price < self.bid.max_price( ) and quantity_to_trade > 0: best_price_bid = self.bid.min_price_list() quantity_to_trade = self.process_order_list( 'bid', best_price_bid, quantity_to_trade, quote, output) if quantity_to_trade > 0: quote['quantity'] = quantity_to_trade self.ask.insert_order(quote) print("Order added in book") def cancel_order(self, order_id): self.update_time() if self.bid.order_exist(order_id): self.bid.remove_order_by_order_id(order_id) print("Order removed from order book") elif self.ask.order_exist(order_id): self.ask.remove_order_by_order_id(order_id) print("Order removed from order book") else: print("Given Order does not exist")
class OrderBook(object): ''' Orderbook utilizing all the other modules ''' def __init__(self): ''' @summary: initialization of OrderBook @mem bids: an ordertree for bids orders @mem asks: an ordertree for asks orders @mem time: maintain the current time in the orderbook ''' self.bids = OrderTree() self.asks = OrderTree() self.last_timestamp = 0 self.time = 0 self.next_order_id = 0 def update_time(self): ''' update time automatically ''' self.time += 1 def process_order(self, quote): ''' @summary: add order given quote @quote: a dictionary containing order information @return trades: return trades if there exists for the order added @return order_in_book: containing all orders in orderbook ''' order_type = quote['type'] order_in_book = None self.update_time() quote['timestamp'] = self.time if quote['quantity'] <= 0: sys.exit('process_order() given order of quantity <= 0') self.next_order_id += 1 trades, order_in_book = self.process_limit_order(quote) return trades, order_in_book def process_order_list(self, side, order_list, quantity_still_to_trade, quote): ''' Takes an OrderList (stack of orders at one price) and an incoming order and matches appropriate trades given the order's quantity. ''' trades = [] quantity_to_trade = quantity_still_to_trade while len(order_list) > 0 and quantity_to_trade > 0: head_order = order_list.get_head_order() traded_price = head_order.price #counter_party = head_order.trade_id if quantity_to_trade < head_order.quantity: traded_quantity = quantity_to_trade # Do the transaction new_book_quantity = head_order.quantity - quantity_to_trade head_order.update_quantity(new_book_quantity, head_order.timestamp) quantity_to_trade = 0 elif quantity_to_trade == head_order.quantity: traded_quantity = quantity_to_trade if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade = 0 else: # quantity to trade is larger than the head order traded_quantity = head_order.quantity if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade -= traded_quantity transaction_record = { 'timestamp': self.time, 'price': traded_price, 'quantity': traded_quantity, 'time': self.time } if side == 'bid': transaction_record['party1'] = ['bid', head_order.order_id] transaction_record['party2'] = ['ask', None] else: transaction_record['party1'] = ['ask', head_order.order_id] transaction_record['party2'] = ['bid', None] trades.append(transaction_record) return quantity_to_trade, trades def process_limit_order(self, quote): ''' @summary: process limit order given quote as the new order @param: a dictionary containing order infos @return trades: if causing any trade opportunites @return order_in_book: remaining orders in the orderBook ''' order_in_book = None trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] price = quote['price'] if side == 'bid': while (self.asks and price > self.asks.min_price() and quantity_to_trade > 0): best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list('ask', best_price_asks, quantity_to_trade, quote) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.bids.insert_order(quote) order_in_book = quote elif side == 'ask': while (self.bids and price < self.bids.max_price() and quantity_to_trade > 0): best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list('bid', best_price_bids, quantity_to_trade, quote) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.asks.insert_order(quote) order_in_book = quote else: sys.exit('process_limit_order() given neither "bid" nor "ask"') return trades, order_in_book def cancel_order(self, side, order_id, time=None): ''' @summary: cancel order by order_id @param side: bid or ask @param order_id: id of such order ''' if time: self.time = time else: self.update_time() if side == 'bid': if self.bids.order_exists(order_id): self.bids.remove_order_by_id(order_id) elif side == 'ask': if self.asks.order_exists(order_id): self.asks.remove_order_by_id(order_id) else: sys.exit('cancel_order() given neither "bid" nor "ask"') def get_volume_at_price(self, side, price): ''' @summary: get the volume at some price @param side: bid or ask, choose which side to get that volume @param price: the price specified to get its volume @return: the volume ''' if side == 'bid': volume = 0 if self.bids.price_exists(price): volume = self.bids.get_price_list(price).volume return volume elif side == 'ask': volume = 0 if self.asks.price_exists(price): volume = self.asks.get_price_list(price).volume return volume else: sys.exit('get_volume_at_price() given neither "bid" nor "ask"') def get_best_bid(self): ''' return best bid price in the orderbook ''' return self.bids.max_price() def get_best_ask(self): ''' return best ask price in the orderbook ''' return self.asks.min_price()
class OrderBook(object): ''' Orderbook utilizing all the other modules ''' def __init__(self): ''' @summary: initialization of OrderBook @mem bids: an ordertree for bids orders @mem asks: an ordertree for asks orders @mem time: maintain the current time in the orderbook ''' self.bids = OrderTree() self.asks = OrderTree() self.last_timestamp = 0 self.time = 0 self.next_order_id = 0 def update_time(self): ''' update time automatically ''' self.time += 1 def process_order(self, quote): ''' @summary: add order given quote @quote: a dictionary containing order information @return trades: return trades if there exists for the order added @return order_in_book: containing all orders in orderbook ''' order_type = quote['type'] order_in_book = None self.update_time() quote['timestamp'] = self.time if quote['quantity'] <= 0: sys.exit('process_order() given order of quantity <= 0') self.next_order_id += 1 trades, order_in_book = self.process_limit_order(quote) return trades, order_in_book def process_order_list(self, side, order_list, quantity_still_to_trade, quote): ''' Takes an OrderList (stack of orders at one price) and an incoming order and matches appropriate trades given the order's quantity. ''' trades = [] quantity_to_trade = quantity_still_to_trade while len(order_list) > 0 and quantity_to_trade > 0: head_order = order_list.get_head_order() traded_price = head_order.price #counter_party = head_order.trade_id if quantity_to_trade < head_order.quantity: traded_quantity = quantity_to_trade # Do the transaction new_book_quantity = head_order.quantity - quantity_to_trade head_order.update_quantity(new_book_quantity, head_order.timestamp) quantity_to_trade = 0 elif quantity_to_trade == head_order.quantity: traded_quantity = quantity_to_trade if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade = 0 else: # quantity to trade is larger than the head order traded_quantity = head_order.quantity if side == 'bid': self.bids.remove_order_by_id(head_order.order_id) else: self.asks.remove_order_by_id(head_order.order_id) quantity_to_trade -= traded_quantity transaction_record = { 'timestamp': self.time, 'price': traded_price, 'quantity': traded_quantity, 'time': self.time } if side == 'bid': transaction_record['party1'] = ['bid', head_order.order_id] transaction_record['party2'] = ['ask', None] else: transaction_record['party1'] = ['ask', head_order.order_id] transaction_record['party2'] = ['bid', None] trades.append(transaction_record) return quantity_to_trade, trades def process_limit_order(self, quote): ''' @summary: process limit order given quote as the new order @param: a dictionary containing order infos @return trades: if causing any trade opportunites @return order_in_book: remaining orders in the orderBook ''' order_in_book = None trades = [] quantity_to_trade = quote['quantity'] side = quote['side'] price = quote['price'] if side == 'bid': while (self.asks and price > self.asks.min_price() and quantity_to_trade > 0): best_price_asks = self.asks.min_price_list() quantity_to_trade, new_trades = self.process_order_list( 'ask', best_price_asks, quantity_to_trade, quote) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.bids.insert_order(quote) order_in_book = quote elif side == 'ask': while (self.bids and price < self.bids.max_price() and quantity_to_trade > 0): best_price_bids = self.bids.max_price_list() quantity_to_trade, new_trades = self.process_order_list( 'bid', best_price_bids, quantity_to_trade, quote) trades += new_trades # If volume remains, need to update the book with new quantity if quantity_to_trade > 0: quote['order_id'] = self.next_order_id quote['quantity'] = quantity_to_trade self.asks.insert_order(quote) order_in_book = quote else: sys.exit('process_limit_order() given neither "bid" nor "ask"') return trades, order_in_book def cancel_order(self, side, order_id, time=None): ''' @summary: cancel order by order_id @param side: bid or ask @param order_id: id of such order ''' if time: self.time = time else: self.update_time() if side == 'bid': if self.bids.order_exists(order_id): self.bids.remove_order_by_id(order_id) elif side == 'ask': if self.asks.order_exists(order_id): self.asks.remove_order_by_id(order_id) else: sys.exit('cancel_order() given neither "bid" nor "ask"') def get_volume_at_price(self, side, price): ''' @summary: get the volume at some price @param side: bid or ask, choose which side to get that volume @param price: the price specified to get its volume @return: the volume ''' if side == 'bid': volume = 0 if self.bids.price_exists(price): volume = self.bids.get_price_list(price).volume return volume elif side == 'ask': volume = 0 if self.asks.price_exists(price): volume = self.asks.get_price_list(price).volume return volume else: sys.exit('get_volume_at_price() given neither "bid" nor "ask"') def get_best_bid(self): ''' return best bid price in the orderbook ''' return self.bids.max_price() def get_best_ask(self): ''' return best ask price in the orderbook ''' return self.asks.min_price()