def process_internal(self, current_time, elapsed): # Initialize parameters of order size = 5 price = self.price_distribution() self.next_wakeup_time = current_time + elapsed + self.wakeup_distribution( ) next_id = np.random.randint(0, 1000) self.debug("Creating order %i at t=%f" % (next_id, current_time + elapsed)) if self.next_wakeup_time > self.end_time: return float('inf') else: self.next_order = OrderCreator.create_order_from_dict({ 'contract': self.contract, 'creator_id': self.identifier, 'order_id': next_id, 'price': price, 'size': size, 'direction': self.direction, 'exec_type': self.exec_type, 'creation_time': current_time, 'expiration_time': float('inf') }) return self.next_wakeup_time - current_time - elapsed
def __init__(self, *args, **kwargs): super(BATStopOrderTest, self).__init__(*args, **kwargs) self.colnames = [ 'contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time' ] self.data_with_error = {} self.data_ok = { 'single_stop_market': [['AAPL', 1.23456, 10, 1, 1, 10, 1, 100]], # Stop order. should have price = None 'stop_mutates_to_market': [ ['AAPL', 1.23456, 11, 1, 1, 10, 1, 100], # Stop ['AAPL', 2.23456, 12, 1, 0, 9, 1, 100], # Limit ['AAPL', 3.23456, 13, -1, 0, 9, 1, 100] ], # Limit => (11,12){10}{C,C} => (10){Stop=>Market} } self.orders = dict() for k, v in self.data_ok.items(): orders = [] for i, ls in enumerate(v): d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def test_handle_order_expired_raises_exception(self): contract = 'IBM' ba_table = LOBTable(contract=contract) ls = self.data_with_errors['single_canceled_rejected'][0] d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' order1 = OrderCreator.create_order_from_dict(d) ba_table.handle_order(order1, order1.creation_time) # Second ls2 = self.data_with_errors['single_canceled_rejected'][1] d2 = {self.colnames[j]: ls2[j] for j, _ in enumerate(ls2)} d2['creation_time'] = ba_table.current_time - 1 d2['creator_id'] = 'false_agent' order2 = OrderCreator.create_order_from_dict(d2) self.assertRaises(Exception, ba_table.handle_order, order2, order2.creation_time)
def test_handle_expired_order_raise_exception(self): ls = self.data_ok['ordered'][0] d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' order = OrderCreator.create_order_from_dict(d) order.creation_time = order.expiration_time + 1 contract = 'IBM' ba_table = LOBTable(contract=contract) self.assertRaises(Exception, ba_table.handle_order, order)
def __init__(self, *args, **kwargs): super(BidAskTableOrdersTestTableOrdering, self).__init__(*args, **kwargs) self.colnames = ['contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time'] # Exectype = Limit / Stop / StopLimit / Market self.data = { 'limit': [['AAPL', 0.117459617, 10, 1, 0, 15, 1, 100], # Buy Limit $15 ['AAPL', 0.233423432, 11, -1, 0, 10, 1, 100]], # Sell Limit $10 => execute at $15 (prioritize creation_time) 'bid_ordering_0': [['AAPL', 0.444444444, 13, 1, 0, 60, 1, 100], ['AAPL', 0.555555555, 14, 1, 0, 70, 1, 100], ['AAPL', 0.666666666, 15, 1, 0, 80, 1, 100], # => bid ordering: [15, 14, 13] ['AAPL', 0.777777777, 16, -1, 0, 180, 1, 100], ['AAPL', 0.888888888, 17, -1, 0, 160, 1, 100], ['AAPL', 0.999999999, 18, -1, 0, 170, 1, 100]], # => ordering: [17, 18, 16] 'bid_ordering_1': [['AAPL', 0.444444444, 13, 1, 0, 60, 1, 100], ['AAPL', 0.555555555, 14, 1, 0, 60, 3, 100], ['AAPL', 0.666666666, 15, 1, 0, 60, 2, 100], # => bid ordering: [14, 15, 13] ['AAPL', 0.777777777, 16, -1, 0, 80, 1, 100], ['AAPL', 0.888888888, 17, -1, 0, 80, 3, 100], ['AAPL', 0.999999999, 18, -1, 0, 80, 2, 100]], # => ordering: [17, 18, 16] 'bid_ordering_3': [['AAPL', 0.444444444, 10, 1, 0, 90, 1, 100], ['AAPL', 0.555555555, 11, 1, 0, 80, 3, 100], ['AAPL', 0.666666666, 12, 1, 0, 80, 5, 100], ['AAPL', 0.777777777, 13, 1, 0, 80, 4, 100], ['AAPL', 0.888888888, 14, 1, 0, 60, 10, 100], ['AAPL', 0.999999999, 15, 1, 0, 60, 10, 100]], # => bid ordering: [10, 12, 14, 11, 14, 15] 'bid_ordering_4': [['AAPL', 0.444444444, 13, 1, 0, 60, 3, 100], ['AAPL', 0.555555555, 14, 1, 0, 60, 1, 100], ['AAPL', 0.666666666, 15, 1, 0, 60, 2, 100], ['AAPL', 0.777777777, 16, -1, 0, 60, 3, 100], ['AAPL', 0.888888888, 17, -1, 0, 60, 1, 100], ['AAPL', 0.999999999, 18, -1, 0, 60, 2, 100]] } self.orders = dict() for k, v in self.data.items(): orders = [] for i, ls in enumerate(v): d = { self.colnames[j]: ls[j] for j, _ in enumerate(ls) } d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def process_internal(self, current_time, elapsed): self.debug("process_internal") # TODO: standarize this to all transitions (internal and external) if current_time + elapsed >= self.end_time or current_time + elapsed > self.next_wakeup_time: return float('inf') size = self.get_size(current_time + elapsed) price = self.get_price(current_time + elapsed) # Propose wakeup time. If there is a cancellation before, first cancel and then propose again next_order_wakeup_time = current_time + elapsed + self.wakeup_distribution() self.debug('setea next wakeup = %f' % next_order_wakeup_time) self.debug("%f %f" % (current_time, elapsed)) # TODO: consider cancellations # if len(self.can) # next_cancellation_wakeup = heapq.nsmallest(1, ) # Get next wakeup time # Finish if next_order_wakeup_time > self.end_time: # self.debug("YYY %f" % self.next_wakeup_time) # self.next_wakeup_time = float('inf') # return float('inf') return float('inf') else: self.next_wakeup_time = next_order_wakeup_time self.debug("Wakeup (1) = %f, current=%f, elapsed=%f" % (self.next_wakeup_time, current_time, elapsed)) next_id = np.random.randint(0, 1000) self.debug("Creating order %i at t=%f" % (next_id, current_time + elapsed)) self.next_order = OrderCreator.create_order_from_dict({ 'contract': self.contract, 'creator_id': self.identifier, 'order_id': next_id, 'price': price, 'size': size, 'direction': self.direction, 'exec_type': self.exec_type, 'creation_time': current_time, # Option 1: set expiration time for automatic cancellations 'expiration_time': current_time + elapsed + self.cancellation_timeout }) # Important self.orders_sent.append(self.next_order.m_orderId) return self.next_wakeup_time - current_time - elapsed
def process_internal(self, current_time, elapsed): size = 5 price = self.get_price(current_time + elapsed) # Propose wakeup time. If there is a cancellation before, first cancel and then propose again next_order_wakeup_time = current_time + elapsed + self.wakeup_distribution( ) # if len(self.can) # next_cancellation_wakeup = heapq.nsmallest(1, ) # Get next wakeup time self.next_wakeup_time = next_order_wakeup_time # Finish if self.next_wakeup_time > self.end_time: return float('inf') else: next_id = np.random.randint(0, 1000) self.debug("Creating order %i at t=%f" % (next_id, current_time + elapsed)) self.next_order = OrderCreator.create_order_from_dict({ 'contract': self.contract, 'creator_id': self.identifier, 'order_id': next_id, 'price': price, 'size': size, 'direction': self.direction, 'exec_type': self.exec_type, 'creation_time': current_time, # Option 1: set expiration time for automatic cancellations 'expiration_time': current_time + elapsed + self.cancellation_timeout }) return self.next_wakeup_time - current_time - elapsed
def __init__(self, *args, **kwargs): super(BidAskTableTestCancelations, self).__init__(*args, **kwargs) self.colnames = [ 'contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time' ] self.data_with_errors = { 'single_canceled_rejected': [['TSLA', 0.017459617, 10, 1, 0, 10, 1, 100], ['TSLA', None, 11, 0, 0, 10, 1, 100]], # => is updated in test } self.data = { 'single_canceled_accepted': [['TSLA', 12, 10, 1, 0, 10, 1, 100], ['TSLA', 90, 10, 0, 0, 10, 1, 100]], 'single_canceled_accepted_with_noise': [ ['TSLA', 0.017459617, 10, 1, 0, 10, 1, 100], ['TSLA', 0.117459617, 21, 1, 0, 50, 1, 100], # noise ['TSLA', 0.217459617, 22, 1, 0, 10, 1, 100], # noise ['TSLA', 0.317459617, 23, 1, 0, 1, 1, 100], # noise ['TSLA', 0.433423432, 10, 0, 0, 10, 1, 100] ], 'market_cancellation_accepted': [['TSLA', 1, 10, 1, 3, None, 1, 100], ['TSLA', 2, 10, 0, 0, 10, 1, 100]], 'expired_vs_cancelled': [ ['TSLA', 1, 10, 1, 3, None, 1, 100], # => market order ['TSLA', 5, 10, 0, 0, 10, 1, 100], # => cancelation ok => (Canceled, Complete) ['TSLA', 10, 11, 1, 3, None, 1, 14], # => market order (11) ['TSLA', 15, 11, 0, 0, 10, 1, 100] ], # => market order (11) expired at t=14 => (Expired, Rejected) } self.orders = dict() for k, v in self.data.items(): orders = [] for i, ls in enumerate(v): d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def __init__(self, *args, **kwargs): super(BidAskTableOrdersTestLimitOrder, self).__init__(*args, **kwargs) self.colnames = [ 'contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time' ] # Exectype = Limit / Stop / StopLimit / Market self.data = { 'limit': [ ['AAPL', 0.117459617, 10, 1, 0, 15, 1, 100], # Buy Limit $15 ['AAPL', 0.233423432, 11, -1, 0, 10, 1, 100] ], # => Order executes at 15 'limit_multiple': [ ['AAPL', 0.117459617, 10, 1, 0, 20, 1, 100], # Buy Limit 20 => (Accepted) ['AAPL', 0.217459617, 11, -1, 0, 30, 1, 100], # Sell Limit 30 => (Accepted) ['AAPL', 0.317459617, 12, 1, 0, 40, 1, 100], # Buy Limit 40 => (Completed, Completed) ['AAPL', 0.433423432, 13, -1, 0, 50, 1, 100] ], # Sell Limit 50 => (Accepted) 'limit_multiple_partial': [ ['AAPL', 0.117459617, 10, 1, 0, 20, 1, 100], # Buy Limit 20 => (Accepted) ['AAPL', 0.217459617, 11, -1, 0, 30, 1, 100], # Sell Limit 30 => (Accepted) ['AAPL', 0.317459617, 12, 1, 0, 40, 5, 100], # Buy Limit 40 => (Completed, Partial) ['AAPL', 0.433423432, 13, -1, 0, 50, 1, 100] ] # Sell Limit 50 => (Accepted) } self.orders = dict() for k, v in self.data.items(): orders = [] for i, ls in enumerate(v): d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def __init__(self, *args, **kwargs): super(BATMarketOrderTest, self).__init__(*args, **kwargs) self.colnames = [ 'contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time' ] self.data_with_error = { 'single_market': [['AAPL', 0.017459617, 10, 1, 3, 10, 1, 100]], } self.data_ok = { 'single_market': [['AAPL', 0.017459617, 10, 1, 3, None, 1, 100]], 'three_market': [['AAPL', 0.017459617, 10, 1, 3, None, 1, 100], ['AAPL', 0.027459617, 11, 1, 3, None, 1, 100], ['AAPL', 0.038934456, 12, -1, 3, None, 1, 100]], 'market_vs_limit': [['AAPL', 0.017459617, 10, 1, 3, None, 1, 100], ['AAPL', 0.018934456, 11, -1, 0, 10, 1, 100]], 'market_vs_limit_multiple': [ ['AAPL', 0.17459617, 10, 1, 0, 10, 1, 100], ['AAPL', 0.27459617, 11, -1, 0, 20, 1, 100], ['AAPL', 0.37459617, 12, 1, 3, None, 1, 100], # => executes (11,12) at 20 (Complete, Complete) ['AAPL', 0.48934456, 13, -1, 0, 10, 1, 100] ], # => executes (10,13) at 10 (Complete, Complete) 'market_vs_limit_multiple_partial': [ ['AAPL', 0.17459617, 10, -1, 0, 10, 1, 100], ['AAPL', 0.27459617, 11, -1, 0, 20, 1, 100], ['AAPL', 0.37459617, 12, 1, 3, None, 5, 100], # => executes (10,12){10}{C,P}+(11,12){20}{C,P} ['AAPL', 0.48934456, 13, -1, 0, 10, 3, 100] ], # => executes (10,13){10}{C,C} } self.orders = dict() for k, v in self.data_ok.items(): orders = [] for i, ls in enumerate(v): d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def __init__(self, *args, **kwargs): super(BATOrderCreationTest, self).__init__(*args, **kwargs) self.colnames = [ 'contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time' ] self.data_with_error = { 'expired_order': [['AAPL', 25, 12, 0, 0, 10, 1, 5]], # creation_time = 25 > 5 = expiration } self.data_ok = { 'ordered': [['AAPL', None, 12, 0, 0, 10, 1, 5]], 'unordered': [['AAPL', 10, 10, 1, 0, 10, 1, 11], ['AAPL', 5, 11, 1, 0, 10, 1, 6]], # => unordered } self.orders = dict() for k, v in self.data_ok.items(): orders = [] for i, ls in enumerate(v): d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def __init__(self, *args, **kwargs): super(BidAskTableTest, self).__init__(*args, **kwargs) self.colnames = ['contract', 'creation_time', 'order_id', 'direction', 'exec_type', 'price', 'size', 'expiration_time'] self.data = { 'basic': [['AAPL', None, 10, 1, 0, 10, 1, 100]], 'basic_2': [['AAPL', 0.017459617, 10, 1, 0, 10, 1, 100], ['AAPL', 90.2342343, 11, -1, 0, 10, 1, 100]], 'with_expiration': [['AAPL', 0.017459617, 10, 1, 0, 10, 1, 110], ['AAPL', 0.018934456, 11, -1, 0, 10, 1, 90]], 'partial_buy': # selling 1 order and buying 2 (Partial Buy, Completed Sell) [['AAPL', 0.017459617, 10, 1, 0, 10, 1, 100], ['AAPL', 0.018934456, 11, -1, 0, 10, 2, 100]], 'partial_sell': # selling 2 orders and buying 1 (Partial Sell, Completed Buy) [['AAPL', 0.017459617, 10, -1, 0, 10, 2, 100], ['AAPL', 0.018934456, 11, 1, 0, 10, 1, 100]], 'expiration_before_match': [['AAPL', 0.1, 10, -1, 0, 10, 2, 1], # order expires at t = 1.0 ['AAPL', 2.1, 11, 1, 0, 10, 2, 100]], # order arrives at t = 2.1 => no match (+1 expiration) 'multiple_expiration_before_match': [['AAPL', 0.1, 10, -1, 0, 10, 2, 1], # order expires at t = 1.0 ['AAPL', 0.2, 11, -1, 0, 10, 2, 1], ['AAPL', 0.3, 12, -1, 0, 10, 2, 1], ['AAPL', 2.1, 13, 1, 0, 10, 2, 100]], # order arrives at t = 2.1 => no match (+3 expirations) } self.orders = dict() for k, v in self.data.items(): orders = [] for i, ls in enumerate(v): d = { self.colnames[j]: ls[j] for j, _ in enumerate(ls) } d['creator_id'] = 'false_agent' orders.append(OrderCreator.create_order_from_dict(d)) self.orders[k] = orders
def prepare_next_order_if_necessary(self, current_time, elapsed, active_leg): self.debug("prepare_next_order_if_necessary. Leg = %i" % active_leg) assert (self.leg_status[self.active_leg] is False) spread = self.bid_ask_history['INTC']['ask'][ 'price'] - self.bid_ask_history['IBM']['bid']['price'] # => buy INTC, sell IBM self.debug("Leg: %i. Checking spread = %f" % (active_leg, spread)) self.debug(str(self.bid_ask_history)) if spread < 10: price_intc = self.bid_ask_history['INTC']['ask']['price'] size_intc = self.bid_ask_history['INTC']['ask']['size'] order_intc = OrderCreator.create_order_from_dict({ 'contract': 'INTC', 'creator_id': self.identifier, 'order_id': np.random.randint(0, 1000), 'price': price_intc, 'size': size_intc, 'direction': 1, 'exec_type': 0, 'creation_time': current_time, 'expiration_time': float('inf') }) pending_order_intc = PendingOrder(identifier=order_intc.m_orderId, order=order_intc, wakeup_time=current_time + elapsed) # IMMEDIATE SEND price_ibm = self.bid_ask_history['IBM']['bid']['price'] size_ibm = self.bid_ask_history['IBM']['bid']['size'] order_ibm = OrderCreator.create_order_from_dict({ 'contract': 'IBM', 'creator_id': self.identifier, 'order_id': np.random.randint(0, 1000), 'price': price_ibm, 'size': size_ibm, 'direction': -1, 'exec_type': 0, 'creation_time': current_time, 'expiration_time': float('inf') }) pending_order_ibm = PendingOrder(identifier=order_intc.m_orderId, order=order_ibm, wakeup_time=current_time + elapsed) # IMMEDIATE SEND # Enqueue self.debug("Enqueue orders: %i %i" % (order_intc.m_orderId, order_ibm.m_orderId)) heapq.heappush(self.next_orders_delivery['INTC'], pending_order_intc) heapq.heappush(self.next_orders_delivery['IBM'], pending_order_ibm) self.active_leg_status_orders = { order_intc.m_orderId: order_intc.status, order_ibm.m_orderId: order_ibm.status } return None
def prepare_order(self): row = self.history.iloc[self.n_order_to_send - 1].copy() row['creator_id'] = self.get_devs_model().identifier next_order = OrderCreator.create_order_from_dict(row) return next_order
def prepare_next_order_if_necessary(self, current_time, elapsed, active_leg): self.debug("prepare_next_order_if_necessary. Leg = %i" % active_leg) # SET PRICES price_intc_ask = self.bid_ask_history['INTC']['bid'][ 'price'] - self.delta_price # size_intc_ask = self.bid_ask_history['INTC']['ask']['size'] size_intc_ask = self.size_orders price_intc_bid = self.bid_ask_history['INTC']['ask'][ 'price'] + self.delta_price # size_intc_bid = self.bid_ask_history['INTC']['bid']['size'] size_intc_bid = self.size_orders self.last_price_ask = price_intc_ask self.last_price_bid = price_intc_bid # ORDER 1 order_intc_ask = OrderCreator.create_order_from_dict({ 'contract': 'INTC', 'creator_id': self.identifier, 'order_id': np.random.randint(0, 1000), 'price': price_intc_ask, 'size': size_intc_ask, 'direction': -1, 'exec_type': 0, 'creation_time': current_time + elapsed, 'expiration_time': float('inf') }) pending_order_intc_ask = PendingOrder( identifier=order_intc_ask.m_orderId, order=order_intc_ask, wakeup_time=current_time + elapsed) # IMMEDIATE SEND # ORDER 2 order_intc_bid = OrderCreator.create_order_from_dict({ 'contract': 'INTC', 'creator_id': self.identifier, 'order_id': np.random.randint(0, 1000), 'price': price_intc_bid, 'size': size_intc_bid, 'direction': 1, 'exec_type': 0, 'creation_time': current_time + elapsed, 'expiration_time': float('inf') }) pending_order_intc_bid = PendingOrder( identifier=order_intc_ask.m_orderId, order=order_intc_bid, wakeup_time=current_time + elapsed) # IMMEDIATE SEND # Enqueue ORDER 1 + 2 self.debug("Enqueue orders: %i %i" % (order_intc_bid.m_orderId, order_intc_ask.m_orderId)) heapq.heappush(self.next_orders_delivery['INTC'], pending_order_intc_ask) heapq.heappush(self.next_orders_delivery['INTC'], pending_order_intc_bid) self.active_leg_status_orders = { order_intc_ask.m_orderId: order_intc_ask.status, order_intc_bid.m_orderId: order_intc_bid.status } return None
def process_internal(self, current_time, elapsed): self.debug("process_internal") # TODO: standarize this to all transitions (internal and external) if current_time + elapsed >= self.end_time or current_time + elapsed > self.next_wakeup_time: return float('inf') size = self.get_size(current_time + elapsed) price = self.get_price(current_time + elapsed) # Propose wake up time. If there is a cancellation before, first cancel and then propose again next_order_wakeup_time = current_time + elapsed + self.wakeup_distribution( ) self.debug('setea next wakeup = %f' % next_order_wakeup_time) self.debug("%f %f" % (current_time, elapsed)) # Finish: RUN OUT OF CASH OR RUN OUT OF TIME if (self.direction == Direction.Buy or self.direction == 1) and self.remaining_cash - price * size < 0: return float('inf') elif next_order_wakeup_time > self.end_time: return float('inf') elif len(self.orders_sent) >= self.max_orders: return float('inf') else: self.next_wakeup_time = next_order_wakeup_time self.debug("Wakeup (1) = %f, current=%f, elapsed=%f" % (self.next_wakeup_time, current_time, elapsed)) next_id = np.random.randint(0, 1000) self.debug("Creating order %i at t=%f" % (next_id, current_time + elapsed)) self.next_order = OrderCreator.create_order_from_dict({ 'contract': self.contract, 'creator_id': self.identifier, 'order_id': next_id, 'price': price, 'size': size, 'direction': self.direction, 'exec_type': self.exec_type, 'creation_time': current_time, # Option 1: set expiration time for automatic cancellations 'expiration_time': current_time + elapsed + self.cancellation_timeout }) if self.next_order.direction in [Direction.Buy, 1]: self.remaining_cash -= self.next_order.price * self.next_order.size elif self.next_order.direction in [Direction.Sell, -1]: self.remaining_cash += self.next_order.price * self.next_order.size else: raise Exception() # Important self.orders_sent.append(self.next_order.m_orderId) return self.next_wakeup_time - current_time - elapsed
def test_market_order_with_none(self): ls = self.data_ok['single_market'][0] d = {self.colnames[j]: ls[j] for j, _ in enumerate(ls)} d['creator_id'] = 'false_agent' order = OrderCreator.create_order_from_dict(d) self.assertEquals(order.get_exec_type(), Exectype.Market)