コード例 #1
0
 def test_market_order_cancelled(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['market_cancellation_accepted']):
         notification = ba_table.handle_order(order, order.creation_time)
     # First order is canceled
     self.assertEquals(len(notification.canceled), 1)
     self.assertEquals(len(notification.completed), 1)
コード例 #2
0
 def test_expired_order(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     order = self.orders['basic'][0]
     notification = ba_table.handle_order(order, order.expiration_time + 1)
     self.assertEquals(len(notification.rejected), 1)
     self.assertEquals(notification.rejected[0].m_orderId, order.m_orderId)
     self.assertEquals(notification.rejected[0].get_status(), OrderStatus.Rejected)
コード例 #3
0
 def test_limit_vs_market_multiple_order(self):
     ba_table = LOBTable(contract='IBM')
     for i, order in enumerate(self.orders['market_vs_limit_multiple']):
         notification = ba_table.handle_order(order, order.creation_time)
         if i == 2:
             self.assertEquals(len(notification.completed), 2)
         if i == 3:
             self.assertEquals(len(notification.completed), 2)
コード例 #4
0
 def test_stop_to_market(self):
     ba_table = LOBTable(contract='IBM')
     for i, order in enumerate(self.orders['stop_mutates_to_market']):
         notification = ba_table.handle_order(order, order.creation_time)
         if i == 2:
             self.assertEqual(len(notification.completed), 2)
             self.assertEqual(len(ba_table.stop), 0)
             self.assertEqual(len(ba_table.market_bid), 1)
コード例 #5
0
 def test_bid_ordering_1(self):
     contract = 'AAPL'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['bid_ordering_1']):
         ba_table.handle_order(order, order.creation_time)
     # Asserts
     self.assertEquals([order.m_orderId for order in heapq.nsmallest(5, ba_table.bid)], [13, 14, 15])
     self.assertEquals([order.m_orderId for order in heapq.nsmallest(5, ba_table.ask)], [16, 17, 18])
コード例 #6
0
 def test_market_vs_limit_order(self):
     ba_table = LOBTable(contract='IBM')
     order1 = self.orders['market_vs_limit'][0]
     notification1 = ba_table.handle_order(order1, order1.creation_time)
     self.assertEquals(len(notification1.accepted), 1)
     self.assertEquals(ba_table.queue_observer.market_bid_size(), 1)
     order2 = self.orders['market_vs_limit'][1]
     notification2 = ba_table.handle_order(order2, order2.creation_time)
     self.assertEquals(len(notification2.completed), 2)
コード例 #7
0
 def test_expiration_before_match(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     order1 = self.orders['expiration_before_match'][0]
     ba_table.handle_order(order1, order1.creation_time)
     order2 = self.orders['expiration_before_match'][1]
     notification_order2 = ba_table.handle_order(order2, order2.creation_time)
     self.assertEquals(len(notification_order2.accepted), 1)
     self.assertEquals(len(notification_order2.expired), 1)
コード例 #8
0
 def test_bat_reject_unordered_expired_order(self):
     contract = 'IBM'
     b = LOBTable(contract=contract)
     notification1 = b.handle_order(
         self.orders['unordered'][0],
         self.orders['unordered'][0].creation_time)
     self.assertEquals(len(notification1.accepted), 1)
     self.assertRaises(Exception, b.handle_order,
                       self.orders['unordered'][1],
                       self.orders['unordered'][1].creation_time)
コード例 #9
0
 def test_accepted_and_canceled(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['single_canceled_accepted']):
         notification = ba_table.handle_order(order, order.creation_time)
     # First order is canceled
     self.assertEquals(len(notification.canceled), 1)
     self.assertEquals(len(notification.completed), 1)
     self.assertEquals(ba_table.queue_observer.bid_size(), 0)
     self.assertEquals(ba_table.queue_observer.ask_size(), 0)
コード例 #10
0
 def test_multiple_expiration_before_match(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['multiple_expiration_before_match']):
         notification = ba_table.handle_order(order, order.creation_time)
         if i <= 2:
             self.assertEqual(len(notification.accepted), 1)
         elif i == 3:
             self.assertEqual(len(notification.expired), 3)
             self.assertEqual(len(notification.accepted), 1)
コード例 #11
0
 def test_partial_direct_buy(self):
     current_time = 90
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     buy_order_1 = self.orders['partial_buy'][0]
     notification_buy_1 = ba_table.handle_order(buy_order_1, buy_order_1.creation_time)
     self.assertEquals(len(notification_buy_1.accepted), 1)
     sell_order = self.orders['partial_buy'][1]
     notification_sell = ba_table.handle_order(sell_order, sell_order.creation_time)
     self.assertEquals(len(notification_sell.partial_completed), 1)
     self.assertEquals(len(notification_sell.completed), 1)
コード例 #12
0
 def test_completed_order(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     buy_order_1 = self.orders['basic_2'][0]
     notification_buy_1 = ba_table.handle_order(buy_order_1, buy_order_1.creation_time)
     self.assertEquals(len(notification_buy_1.accepted), 1)
     sell_order = self.orders['basic_2'][1]
     notfication_sell = ba_table.handle_order(sell_order, sell_order.creation_time)
     self.assertEquals(len(notfication_sell.completed), 2)
     self.assertTrue(ba_table.queue_observer.bid_empty(), True)
     self.assertTrue(ba_table.queue_observer.ask_empty(), True)
コード例 #13
0
 def test_expired_vs_cancelled(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['expired_vs_cancelled']):
         notification = ba_table.handle_order(order, order.creation_time)
         if i == 1:
             self.assertEqual(len(notification.canceled), 1)
             self.assertEqual(len(notification.completed), 1)
         if i == 3:
             self.assertEquals(len(notification.expired), 1)
             self.assertEqual(len(notification.rejected), 1)
コード例 #14
0
 def test_price_execution_two_limit_orders(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     ba_table.handle_order(self.orders['limit'][0],
                           self.orders['limit'][0].creation_time)
     sell_notification = ba_table.handle_order(
         self.orders['limit'][1], self.orders['limit'][1].creation_time)
     self.assertEqual(len(sell_notification.completed), 2)
     for order in sell_notification.completed:
         self.assertEqual(len(order.trades), 1)
         self.assertEqual(order.trades[0][0], 0.233423432)
         self.assertEqual(order.trades[0][1], 15)
コード例 #15
0
 def test_rejected_new_order_expired(self):
     current_time = 100
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     buy_order_1 = self.orders['with_expiration'][0]
     notification_buy_1 = ba_table.handle_order(buy_order_1, buy_order_1.creation_time)
     self.assertEquals(len(notification_buy_1.accepted), 1)
     sell_order = self.orders['with_expiration'][1]
     notification_sell = ba_table.handle_order(sell_order, current_time)
     self.assertEquals(len(notification_sell.rejected), 1)
     self.assertEquals(ba_table.queue_observer.bid_size(), 1)
     self.assertEquals(ba_table.queue_observer.ask_size(), 0)
コード例 #16
0
    def test_partial_direct_sell(self):
        current_time = 90
        contract = 'IBM'
        ba_table = LOBTable(contract=contract)
        sell_order = self.orders['partial_sell'][0]
        notification_sell = ba_table.handle_order(sell_order, sell_order.creation_time)
        self.assertEquals(len(notification_sell.accepted), 1)
        buy_order = self.orders['partial_sell'][1]
        notification_buy = ba_table.handle_order(buy_order, buy_order.creation_time)
        self.assertEquals(len(notification_buy.partial_completed), 1)
        self.assertEquals(len(notification_buy.completed), 1)

        self.assertEquals(notification_buy.completed[0].direction, Direction.Buy)
        self.assertEquals(notification_buy.partial_completed[0].direction, Direction.Sell)
コード例 #17
0
 def test_accepted_and_canceled_with_noise(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(
             self.orders['single_canceled_accepted_with_noise']):
         notification = ba_table.handle_order(order, order.creation_time)
     # First order is canceled
     self.assertEquals(len(notification.canceled), 1)
     self.assertEquals(len(notification.completed), 1)
     self.assertEquals(ba_table.queue_observer.bid_size(), 3)
     # Check that the queue keeps in order
     self.assertEquals(ba_table.queue_observer.best_bid().price, 50)
     self.assertEquals(
         [order.price for order in heapq.nsmallest(3, ba_table.bid)],
         [50, 10, 1])
コード例 #18
0
 def test_price_execution_multiple(self):
     contract = 'IBM'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['limit_multiple']):
         notification = ba_table.handle_order(order, order.creation_time)
         if i == 0:
             self.assertEqual(len(notification.accepted), 1)
         elif i == 1:
             self.assertEqual(len(notification.accepted), 1)
         elif i == 2:
             self.assertEqual(len(notification.completed), 2)
         elif i == 3:
             self.assertEqual(len(notification.accepted), 1)
             self.assertEqual(len(notification.partial_completed), 0)
             self.assertEqual(len(notification.completed), 0)
コード例 #19
0
    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)
コード例 #20
0
    def __init__(self, agent, identifier, contract, delay_order,
                 delay_notification, output_ports_map):
        self.agent = agent
        self.identifier = identifier + '_strategy'
        self.last_message_id = 0
        self.output_ports_map = output_ports_map

        self.contract = contract
        self.bid_ask_table = LOBTable(contract=contract)

        # Priority queue of orders to process
        self.delay_order = delay_order
        self.delay_notification = delay_notification
        self.ready = []

        self.next_order_status_delivery = {contract: []}
        self.next_notification_delivery = {contract: []}
コード例 #21
0
 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)
コード例 #22
0
    def test_bid_ordering_4(self):
        contract = 'AAPL'
        b = LOBTable(contract=contract)
        notification1 = b.handle_order(self.orders['bid_ordering_4'][0], self.orders['bid_ordering_4'][0].creation_time)
        notification2 = b.handle_order(self.orders['bid_ordering_4'][1], self.orders['bid_ordering_4'][1].creation_time)
        notification3 = b.handle_order(self.orders['bid_ordering_4'][2], self.orders['bid_ordering_4'][2].creation_time)
        notification4 = b.handle_order(self.orders['bid_ordering_4'][3], self.orders['bid_ordering_4'][3].creation_time)
        notification5 = b.handle_order(self.orders['bid_ordering_4'][4], self.orders['bid_ordering_4'][4].creation_time)
        notification6 = b.handle_order(self.orders['bid_ordering_4'][5], self.orders['bid_ordering_4'][5].creation_time)
        # Checks
        self.assertEquals(len(notification1.accepted), 1)
        self.assertEquals(len(notification2.accepted), 1)
        self.assertEquals(len(notification3.accepted), 1)

        self.assertEquals(len(notification4.partial_completed), 0)
        self.assertEquals(len(notification4.completed), 2)

        self.assertEquals(len(notification5.partial_completed), 0)
        self.assertEquals(len(notification5.completed), 2)

        self.assertEquals(len(notification6.completed), 2)
コード例 #23
0
 def test_three_market_orders(self):
     ba_table = LOBTable(contract='IBM')
     order1 = self.orders['three_market'][0]
     notification1 = ba_table.handle_order(order1, order1.creation_time)
     self.assertEquals(len(notification1.accepted), 1)
     order2 = self.orders['three_market'][1]
     notification2 = ba_table.handle_order(order2, order2.creation_time)
     self.assertEquals(len(notification2.accepted), 1)
     order3 = self.orders['three_market'][2]
     ba_table.handle_order(order3, order3.creation_time)
     # Final state of bid ask tables
     self.assertEqual(ba_table.queue_observer.market_bid_size(), 2)
     self.assertEqual(ba_table.queue_observer.market_ask_size(), 1)
コード例 #24
0
 def test_bid_ordering_3(self):
     contract = 'AAPL'
     ba_table = LOBTable(contract=contract)
     for i, order in enumerate(self.orders['bid_ordering_3']):
         ba_table.handle_order(order, order.creation_time)
     self.assertEquals([order.m_orderId for order in heapq.nsmallest(6, ba_table.bid)], [10, 11, 12, 13, 14, 15])
コード例 #25
0
 def test_stop_accepted(self):
     ba_table = LOBTable(contract='IBM')
     order1 = self.orders['single_stop_market'][0]
     notification = ba_table.handle_order(order1, order1.creation_time)
     self.assertEquals(len(notification.accepted), 1)
コード例 #26
0
class OrderbookStrategy(Debug):
    def __init__(self, agent, identifier, contract, delay_order,
                 delay_notification, output_ports_map):
        self.agent = agent
        self.identifier = identifier + '_strategy'
        self.last_message_id = 0
        self.output_ports_map = output_ports_map

        self.contract = contract
        self.bid_ask_table = LOBTable(contract=contract)

        # Priority queue of orders to process
        self.delay_order = delay_order
        self.delay_notification = delay_notification
        self.ready = []

        self.next_order_status_delivery = {contract: []}
        self.next_notification_delivery = {contract: []}

    def get_identifier(self):
        return self.identifier

    def get_next_message_id(self):
        self.last_message_id += 1
        return self.last_message_id

    def set_initial_orders(self, initial_orders):
        return self.bid_ask_table.set_initial_orders(initial_orders)

    def set_tick_size(self, tick_size):
        self.bid_ask_table.set_tick_size(tick_size)
        return 0

    def output_function(self, current_time, elapsed):
        output = {}
        for out_port in ['out_journal']:
            # Look for a notification for each LOB table
            messages = self.next_notification_delivery[self.contract]
            if len(messages) > 0:
                next_message = heapq.heappop(messages)
                assert (current_time + elapsed <= next_message.wakeup_time)
                self.debug('Check notification: %f %f %f' %
                           (current_time, elapsed, next_message.wakeup_time))
                self.debug(str(next_message))
                if eq_rounded(current_time + elapsed,
                              next_message.wakeup_time):
                    self.debug("Notification ready")
                    bat_notification = next_message.notification
                    ob_information = OBInformation(
                        contract=self.contract,
                        best_ask=self.bid_ask_table.queue_observer.best_ask(),
                        best_bid=self.bid_ask_table.queue_observer.best_bid())
                    ob_notification = OBNotificationCreator.create_from_batable_notification(
                        bat_notification, ob_information)
                    output[out_port] = MessageForJournal(
                        current_time + elapsed, ob_notification)
                else:
                    self.debug(
                        "Notification not ready: %f %f %f" %
                        (current_time, elapsed, next_message.wakeup_time))
                    heapq.heappush(
                        self.next_notification_delivery[self.contract],
                        next_message)

        self.debug("Emit output = %s" % str(output))
        return output

    def get_smallest_wakeup_time_orders_and_notifications(self):
        smallest_wakeup_time = float('inf')
        messages = self.next_notification_delivery[self.contract]
        if len(messages) > 0:
            wakeup_time = heapq.nsmallest(1, messages)[0].wakeup_time
            if wakeup_time < smallest_wakeup_time:
                smallest_wakeup_time = wakeup_time
        # 2.
        messages = self.next_order_status_delivery[self.contract]
        if len(messages) > 0:
            wakeup_time = heapq.nsmallest(1, messages)[0].wakeup_time
            if wakeup_time < smallest_wakeup_time:
                smallest_wakeup_time = wakeup_time
        return smallest_wakeup_time

    def process_internal(self, current_time, elapsed):
        self.debug("process_internal")
        if len(self.next_order_status_delivery[self.contract]) == 0:
            self.debug("No orders missing processing")
            next_wakeup_time = self.get_smallest_wakeup_time_orders_and_notifications(
            )
            self.debug("Next wakeup time = %f" % next_wakeup_time)
            self.debug("Next waiting time = %f" %
                       (next_wakeup_time - current_time - elapsed))
            return next_wakeup_time - current_time - elapsed
        else:
            self.debug("Processing orders")
            top_order = heapq.heappop(
                self.next_order_status_delivery[self.contract])
            assert (current_time + elapsed <= top_order.wakeup_time)
            if lt_rounded(current_time + elapsed, top_order.wakeup_time):
                # Re-enqueue in order queue
                heapq.heappush(self.next_order_status_delivery[self.contract],
                               top_order)
            else:
                # Process and enqueue in notifications queue
                notification = self.bid_ask_table.handle_order(
                    top_order.order, current_time + elapsed)
                notification_wake_up = current_time + elapsed + self.delay_notification
                heapq.heappush(
                    self.next_notification_delivery[self.contract],
                    PendingNotification(self.get_next_message_id(),
                                        notification, notification_wake_up))
            next_wakeup_time = self.get_smallest_wakeup_time_orders_and_notifications(
            )
            self.debug("Next wakeup time = %f" % next_wakeup_time)
            self.debug("Next waiting time = %f" %
                       (next_wakeup_time - current_time - elapsed))
            return next_wakeup_time - current_time - elapsed

    def process_in_order(self, current_time, elapsed, message):
        self.debug("process_in_order")
        wakeup_time = current_time + elapsed + self.delay_order

        self.debug("execution_time=%f, current_time=%f, elapsed=%f, delay=%f" %
                   (wakeup_time, current_time, elapsed, self.delay_order))

        heapq.heappush(
            self.next_order_status_delivery[message.value.contract],
            PendingOrder(self.get_next_message_id(), message.value,
                         wakeup_time))
        next_wakeup_time = self.get_smallest_wakeup_time_orders_and_notifications(
        )
        self.debug("Next wakeup time = %f" % next_wakeup_time)
        self.debug("Next waiting time = %f" %
                   (next_wakeup_time - current_time - elapsed))
        return next_wakeup_time - current_time - elapsed