def __init__(self, data_handler: DataHandler, timer: Timer,
                 scheduler: Scheduler, monitor: AbstractMonitor,
                 commission_model: CommissionModel,
                 contracts_to_tickers_mapper: ContractTickerMapper,
                 portfolio: Portfolio, slippage_model: Slippage) -> None:
        scheduler.subscribe(MarketOpenEvent, self)
        scheduler.subscribe(MarketCloseEvent, self)

        self.logger = qf_logger.getChild(self.__class__.__name__)

        self.data_handler = data_handler
        self.commission_model = commission_model
        self.contracts_to_tickers_mapper = contracts_to_tickers_mapper
        self.portfolio = portfolio

        order_id_generator = count(start=1)

        self._market_orders_executor = MarketOrdersExecutor(
            contracts_to_tickers_mapper, data_handler, monitor, portfolio,
            timer, order_id_generator, commission_model, slippage_model)

        self._stop_orders_executor = StopOrdersExecutor(
            contracts_to_tickers_mapper, data_handler, monitor, portfolio,
            timer, order_id_generator, commission_model, slippage_model)

        self._market_on_close_orders_executor = MarketOnCloseOrdersExecutor(
            contracts_to_tickers_mapper, data_handler, monitor, portfolio,
            timer, order_id_generator, commission_model, slippage_model)
Exemplo n.º 2
0
    def __init__(self, broker: Broker, order_factory: OrderFactory,
                 scheduler: Scheduler):
        self.order_factory = order_factory
        self.broker = broker

        self.invested = False

        scheduler.subscribe(BeforeMarketOpenEvent, listener=self)
    def __init__(self,
                 data_handler: DataHandler,
                 timer: Timer,
                 scheduler: Scheduler,
                 monitor: AbstractMonitor,
                 commission_model: CommissionModel,
                 portfolio: Portfolio,
                 slippage_model: Slippage,
                 scheduling_time_delay: RelativeDelta = RelativeDelta(
                     minutes=1),
                 frequency: Frequency = Frequency.DAILY) -> None:

        self.logger = qf_logger.getChild(self.__class__.__name__)

        # Set the intraday_trading flag in case of minutely frequency
        self.intraday_trading = frequency == Frequency.MIN_1

        # Subscribe to events
        scheduler.subscribe(MarketOpenEvent, self)
        scheduler.subscribe(MarketCloseEvent, self)
        scheduler.subscribe(AfterMarketCloseEvent, self)
        scheduler.subscribe(ScheduleOrderExecutionEvent, self)
        # In case of minutely frequency, subscribe to IntradayBarEvents
        if self.intraday_trading:
            scheduler.subscribe(IntradayBarEvent, self)

        self.data_handler = data_handler
        self.commission_model = commission_model
        self.portfolio = portfolio
        self.monitor = monitor
        self.timer = timer
        self.scheduling_time_delay = scheduling_time_delay

        order_id_generator = count(start=1)

        self._market_orders_executor = MarketOrdersExecutor(
            data_handler, monitor, portfolio, timer, order_id_generator,
            commission_model, slippage_model, frequency)

        self._stop_orders_executor = StopOrdersExecutor(
            data_handler, monitor, portfolio, timer, order_id_generator,
            commission_model, slippage_model, frequency)

        self._market_on_close_orders_executor = MarketOnCloseOrdersExecutor(
            data_handler, monitor, portfolio, timer, order_id_generator,
            commission_model, slippage_model, frequency)

        self._market_on_open_orders_executor = MarketOnOpenOrdersExecutor(
            data_handler, monitor, portfolio, timer, order_id_generator,
            commission_model, slippage_model, frequency)
Exemplo n.º 4
0
    def __init__(self, timer: Timer):
        """
        When an Event of certain type is being dispatched by EventManager then what EventManger
        does is it finds the EventNotifier which corresponds to this type of Event. Then the EventNotifier
        notifies all its EventListeners about an Event which occurred. However there might be some EventListeners
        which are listening to the more general type of Event (super-type of the event) and they should also be
        notified.

        That's why the EventNotifier will also call an EventNotifier specific to a more general type of Events
        which will then notify all its EventListeners. The chain of calls on different
        EventNotifiers goes on until the AllEventNotifier is called. That one corresponds to the most general
        type of Events (the Event). When EventListeners subscribed to the Event are notified in the end
        the process of notifications is over.

        Because of the fact that each EventNotifier also calls the EventNotifier for Events of more general type,
        each EventNotifier must have a reference to this "more general" EventNotifier. Most of Events inherit
        directly from the Event type. That's why most of notifiers will need a reference to AllEventNotifier.
        """
        self.all_event_notifier = AllEventNotifier()
        self.empty_queue_event_notifier = EmptyQueueEventNotifier(
            self.all_event_notifier)
        self.end_trading_event_notifier = EndTradingEventNotifier(
            self.all_event_notifier)
        self.scheduler = Scheduler(timer)
Exemplo n.º 5
0
 def setUp(self):
     self.timer = SettableTimer()
     self.scheduler = Scheduler(self.timer)
Exemplo n.º 6
0
class TestScheduler(TestCase):
    class _CustomTimeEvent(TimeEvent):
        def next_trigger_time(self, now: datetime) -> datetime:
            return now + RelativeDelta(days=2)

        def notify(self, listener) -> None:
            listener.on_custom_time_event(self)

    class _AnotherCustomTimeEvent(TimeEvent):
        def next_trigger_time(self, now: datetime) -> datetime:
            return now + RelativeDelta(day=4)

        def notify(self, listener) -> None:
            listener.on_another_custom_time_event(self)

    class PeriodicEvent15Minutes(PeriodicEvent):
        frequency = Frequency.MIN_15
        start_time = {"hour": 9, "minute": 45, "second": 0}
        end_time = {"hour": 11, "minute": 15, "second": 0}

        def notify(self, _) -> None:
            pass

    class PeriodicEvent30Minutes(PeriodicEvent):
        frequency = Frequency.MIN_30
        start_time = {"hour": 9, "minute": 30, "second": 0}
        end_time = {"hour": 10, "minute": 30, "second": 0}

        def notify(self, _) -> None:
            pass

    def setUp(self):
        self.timer = SettableTimer()
        self.scheduler = Scheduler(self.timer)

    def test_get_next_time_event(self):
        listener = Mock()
        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.timer.set_current_time(str_to_date("2018-01-01"))

        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(str_to_date("2018-01-03"), time)

    def test_get_multiple_next_time_events(self):
        listener = Mock()

        self.timer.set_current_time(str_to_date("2018-01-01"))
        self.scheduler.subscribe(self._AnotherCustomTimeEvent, listener)

        self.timer.set_current_time(str_to_date("2018-01-02"))
        self.scheduler.subscribe(self._CustomTimeEvent, listener)

        time_events_list, time = self.scheduler.get_next_time_events()
        expected_time_events = [
            self._CustomTimeEvent(),
            self._AnotherCustomTimeEvent()
        ]

        self.assertCountEqual(time_events_list, expected_time_events)

    def test_get_next_time_event_is_not_changing_state_of_scheduler(self):
        listener = Mock()

        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.timer.set_current_time(str_to_date("2018-01-01"))

        self.scheduler.get_next_time_events()
        self.scheduler.get_next_time_events()
        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(str_to_date("2018-01-03"), time)

    def test_correct_time_event_is_returned(self):
        self.timer.set_current_time(str_to_date("2018-01-01"))

        listener = Mock()
        another_listener = Mock()

        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.scheduler.subscribe(self._AnotherCustomTimeEvent,
                                 another_listener)

        actual_time_events_list, time = self.scheduler.get_next_time_events()
        expected_time_event = self._CustomTimeEvent()
        self.assertIn(expected_time_event, actual_time_events_list)

        self.timer.set_current_time(str_to_date("2018-01-03"))
        another_actual_time_events_list, time = self.scheduler.get_next_time_events(
        )
        another_expected_time_event = self._AnotherCustomTimeEvent()
        self.assertIn(another_expected_time_event,
                      another_actual_time_events_list)

    def test_callback_method_called(self):
        self.timer.set_current_time(str_to_date("2018-01-01"))

        # create custom time events of two kinds
        custom_event = self._CustomTimeEvent()
        another_custom_event = self._AnotherCustomTimeEvent()

        listener = Mock()
        another_listener = Mock()

        # subscribe listeners to corresponding time events
        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.scheduler.subscribe(self._AnotherCustomTimeEvent,
                                 another_listener)

        # test behaviour
        self.scheduler.notify_all(custom_event)

        listener.on_custom_time_event.assert_called_once()

        self.scheduler.notify_all(another_custom_event)
        another_listener.on_another_custom_time_event.assert_called_once()

    def test_get_next_time_event_single_time_events(self):
        self.timer.set_current_time(
            str_to_date("2018-01-02 10:00:00.000000", DateFormat.FULL_ISO))

        listener = Mock()
        self.scheduler.subscribe(SingleTimeEvent, listener)

        trigger_time = str_to_date("2018-01-02 13:00:00.000000",
                                   DateFormat.FULL_ISO)
        SingleTimeEvent.schedule_new_event(trigger_time, {})

        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(trigger_time, time)

    def test_get_next_time_event_periodic_events(self):
        self.timer.set_current_time(
            str_to_date("2018-01-01 10:00:00.000000", DateFormat.FULL_ISO))

        listener = Mock()

        self.scheduler.subscribe(self.PeriodicEvent15Minutes, listener)
        self.scheduler.subscribe(self.PeriodicEvent30Minutes, listener)

        # There will be exactly one event scheduled for 10:15:00
        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(
            str_to_date("2018-01-01 10:15:00.000000", DateFormat.FULL_ISO),
            time)
        self.assertEqual(1, len(time_events_list))

        self.timer.set_current_time(
            str_to_date("2018-01-01 10:15:00.000000", DateFormat.FULL_ISO))

        # There will be two events scheduled for 10:30:00
        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(
            str_to_date("2018-01-01 10:30:00.000000", DateFormat.FULL_ISO),
            time)
        self.assertEqual(2, len(time_events_list))

    def test_get_next_time_event_periodic_and_single_time_events(self):
        self.timer.set_current_time(
            str_to_date("2018-01-01 10:00:00.000000", DateFormat.FULL_ISO))

        listener_periodic = Mock()
        listener_single = Mock()

        self.scheduler.subscribe(self.PeriodicEvent15Minutes,
                                 listener_periodic)
        self.scheduler.subscribe(SingleTimeEvent, listener_single)

        trigger_time = str_to_date("2018-01-01 10:15:00.000000",
                                   DateFormat.FULL_ISO)
        SingleTimeEvent.schedule_new_event(trigger_time, {})

        # There will be two events scheduled for 10:15:00
        time_events_list, time = self.scheduler.get_next_time_events()
        self.assertEqual(
            str_to_date("2018-01-01 10:15:00.000000", DateFormat.FULL_ISO),
            time)
        self.assertEqual(2, len(time_events_list))

        time_events_list_types = [type(event) for event in time_events_list]
        self.assertCountEqual(time_events_list_types,
                              [self.PeriodicEvent15Minutes, SingleTimeEvent])
Exemplo n.º 7
0
class TestScheduler(TestCase):
    class _CustomTimeEvent(TimeEvent):
        @classmethod
        def next_trigger_time(cls, now: datetime) -> datetime:
            return now + RelativeDelta(days=2)

        def notify(self, listener) -> None:
            listener.on_custom_time_event(self)

    class _AnotherCustomTimeEvent(TimeEvent):
        @classmethod
        def next_trigger_time(cls, now: datetime) -> datetime:
            return now + RelativeDelta(day=4)

        def notify(self, listener) -> None:
            listener.on_another_custom_time_event(self)

    def setUp(self):
        self.timer = SettableTimer()
        self.scheduler = Scheduler(self.timer)

    def test_get_next_time_event(self):
        listener = self._get_listeners_mock()

        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.timer.set_current_time(str_to_date("2018-01-01"))

        time_event = self.scheduler.get_next_time_event()
        self.assertEqual(str_to_date("2018-01-03"), time_event.time)

    def test_get_next_time_event_is_not_changing_state_of_scheduler(self):
        listener = self._get_listeners_mock()

        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.timer.set_current_time(str_to_date("2018-01-01"))

        self.scheduler.get_next_time_event()
        self.scheduler.get_next_time_event()
        time_event = self.scheduler.get_next_time_event()
        self.assertEqual(str_to_date("2018-01-03"), time_event.time)

    def test_correct_time_event_is_returned(self):
        self.timer.set_current_time(str_to_date("2018-01-01"))

        listener = self._get_listeners_mock()
        another_listener = self._get_listeners_mock()

        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.scheduler.subscribe(self._AnotherCustomTimeEvent,
                                 another_listener)

        actual_time_event = self.scheduler.get_next_time_event()
        expected_time_event = self._CustomTimeEvent(str_to_date("2018-01-03"))
        self.assertEqual(expected_time_event, actual_time_event)

        self.timer.set_current_time(str_to_date("2018-01-03"))
        another_actual_time_event = self.scheduler.get_next_time_event()
        another_expected_time_event = self._AnotherCustomTimeEvent(
            str_to_date("2018-01-04"))
        self.assertEqual(another_expected_time_event,
                         another_actual_time_event)

    def test_callback_method_called(self):
        self.timer.set_current_time(str_to_date("2018-01-01"))

        # create custom time events of two kinds
        custom_event_1 = self._CustomTimeEvent(str_to_date("2018-01-03"))
        custom_event_2 = self._CustomTimeEvent(str_to_date("2018-01-05"))
        another_custom_event_1 = self._AnotherCustomTimeEvent(
            str_to_date("2018-01-04"))
        another_custom_event_2 = self._AnotherCustomTimeEvent(
            str_to_date("2018-01-05"))
        another_custom_event_3 = self._AnotherCustomTimeEvent(
            str_to_date("2018-01-06"))

        # create listener's mock
        listener = mock(strict=True)
        when(listener).on_custom_time_event(custom_event_1)
        when(listener).on_custom_time_event(custom_event_2)

        # create another listener's mock
        another_listener = mock(strict=True)
        when(another_listener).on_another_custom_time_event(
            another_custom_event_1)
        when(another_listener).on_another_custom_time_event(
            another_custom_event_2)
        when(another_listener).on_another_custom_time_event(
            another_custom_event_3)

        # subscribe listeners to corresponding time events
        self.scheduler.subscribe(self._CustomTimeEvent, listener)
        self.scheduler.subscribe(self._AnotherCustomTimeEvent,
                                 another_listener)

        # test behaviour
        self.scheduler.notify_all(custom_event_1)
        verify(listener).on_custom_time_event(custom_event_1)

        self.scheduler.notify_all(another_custom_event_1)
        verify(another_listener).on_another_custom_time_event(
            another_custom_event_1)

        self.scheduler.notify_all(custom_event_2)
        verify(listener).on_custom_time_event(custom_event_2)

        self.scheduler.notify_all(another_custom_event_2)
        verify(another_listener).on_another_custom_time_event(
            another_custom_event_2)

        self.scheduler.notify_all(another_custom_event_3)
        verify(another_listener).on_another_custom_time_event(
            another_custom_event_3)

    @staticmethod
    def _get_listeners_mock():
        listener = mock(strict=True)
        when(listener).on_custom_time_event(ANY(TimeEvent))

        return listener
Exemplo n.º 8
0
    def __init__(self, portfolio: Portfolio, monitor: AbstractMonitor,
                 scheduler: Scheduler):
        self.portfolio = portfolio
        self.monitor = monitor

        scheduler.subscribe(AfterMarketCloseEvent, listener=self)