Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
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
Пример #4
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
Пример #5
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 = {}
Пример #6
0
 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
Пример #7
0
 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
Пример #8
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()
Пример #9
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.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()
Пример #11
0
 def __init__(self):
     self.bid = OrderTree()
     self.ask = OrderTree()
     self.time = 0
Пример #12
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")
Пример #13
0
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()
Пример #14
0
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()