Exemple #1
0
    def get_portfolio_and_data_handler(self):
        data_handler = Mock(spec=DataHandler)
        data_handler.get_last_available_price.side_effect = lambda tickers: self.data_handler_prices[tickers] \
            if tickers else None

        timer = SettableTimer()
        timer.set_current_time(self.start_time)

        portfolio = Portfolio(data_handler, self.initial_cash, timer)
        return portfolio, data_handler, timer
Exemple #2
0
class TestRules(TestCase):
    def setUp(self):
        self.timer = SettableTimer()

    def test_market_open_rule(self):
        self.timer.set_current_time(
            str_to_date("2018-01-01 00:00:00.000000", DateFormat.FULL_ISO))
        now = self.timer.now()
        next_trigger_time = MarketOpenEvent.next_trigger_time(now)
        self.assertEqual(
            str_to_date("2018-01-01 09:30:00.000000", DateFormat.FULL_ISO),
            next_trigger_time)

        self.timer.set_current_time(
            str_to_date("2018-01-01 09:29:59.999999", DateFormat.FULL_ISO))
        now = self.timer.now()
        next_trigger_time = MarketOpenEvent.next_trigger_time(now)
        self.assertEqual(
            str_to_date("2018-01-01 09:30:00.000000", DateFormat.FULL_ISO),
            next_trigger_time)

        self.timer.set_current_time(
            str_to_date("2018-01-01 09:30:00.000000", DateFormat.FULL_ISO))
        now = self.timer.now()
        next_trigger_time = MarketOpenEvent.next_trigger_time(now)
        self.assertEqual(
            str_to_date("2018-01-02 09:30:00.000000", DateFormat.FULL_ISO),
            next_trigger_time)
Exemple #3
0
    def get_portfolio_and_data_handler(self):
        data_handler = Mock(spec=DataHandler)
        data_handler.get_last_available_price.side_effect = lambda tickers: self.data_handler_prices[tickers] \
            if tickers else None

        contract_mapper = Mock(spec=ContractTickerMapper)
        contract_mapper.contract_to_ticker.side_effect = lambda contract: DummyTicker(contract.symbol)

        timer = SettableTimer()
        timer.set_current_time(self.start_time)

        portfolio = Portfolio(data_handler, self.initial_cash, timer, contract_mapper)
        return portfolio, data_handler, timer
Exemple #4
0
    def test_designated_contracts(self):
        future_ticker = PortaraFutureTicker("",
                                            "AB{}",
                                            1,
                                            1,
                                            designated_contracts="MZ")

        timer = SettableTimer()
        future_ticker.initialize_data_provider(timer, self.data_provider)

        timer.set_current_time(str_to_date("2021-06-15"))
        specific_ticker = future_ticker.get_current_specific_ticker()
        self.assertEqual(specific_ticker,
                         PortaraTicker("AB2021Z", SecurityType.FUTURE, 1))
Exemple #5
0
    def _get_prices_df(self, ticker: Ticker, start_date: datetime, end_date: datetime) -> PricesDataFrame:
        """ Returns non-adjusted open and close prices, indexed with the Market Open and Market Close time."""
        if isinstance(ticker, FutureTicker):
            ticker.initialize_data_provider(SettableTimer(end_date), self._data_provider)
            tickers_chain = ticker.get_expiration_dates()

            if start_date >= tickers_chain.index[-1] or end_date <= tickers_chain.index[0]:
                # If the futures chain starts after the _end_date or ends before the _start_date - no data available
                return PricesDataFrame()

            # Get all tickers from the chain that were valid between the start_date and expiration date of the
            # currently valid ticker
            end_date = tickers_chain[tickers_chain == ticker.get_current_specific_ticker()].index[0]
            tickers_chain = tickers_chain.loc[start_date:end_date]
            tickers = tickers_chain.values.tolist()

            open_prices = self._data_provider.get_price(tickers, PriceField.Open, start_date, end_date)
            close_prices = self._data_provider.get_price(tickers, PriceField.Close, start_date, end_date)
        else:
            open_prices = self._data_provider.get_price([ticker], PriceField.Open, start_date, end_date)
            close_prices = self._data_provider.get_price([ticker], PriceField.Close, start_date, end_date)

        open_prices.index = [dt + MarketOpenEvent.trigger_time() for dt in open_prices.index]
        close_prices.index = [dt + MarketCloseEvent.trigger_time() for dt in close_prices.index]
        prices = concat([open_prices, close_prices]).sort_index()
        return prices
    def test_event_management(self):
        timer = SettableTimer(initial_time=str_to_date("2018-04-10 00:00:00.000000", DateFormat.FULL_ISO))
        end_date = str_to_date("2018-04-10")

        notifiers = Notifiers(timer)

        event_manager = self._create_event_manager(timer, notifiers)
        BacktestTimeFlowController(
            notifiers.scheduler, event_manager, timer, notifiers.empty_queue_event_notifier, end_date
        )

        listener = DummyListener(notifiers, event_manager, timer)

        last_event = None
        while type(last_event) != EndTradingEvent:
            event_manager.dispatch_next_event()
            last_event = listener.registered_events[-1]

        expected_events = [
            (EmptyQueueEvent, str_to_date("2018-04-10 00:00:00.000000", DateFormat.FULL_ISO)),
            (BeforeMarketOpenEvent, str_to_date("2018-04-10 08:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent, str_to_date("2018-04-10 08:00:00.000000", DateFormat.FULL_ISO)),
            (MarketOpenEvent, str_to_date("2018-04-10 09:30:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent, str_to_date("2018-04-10 09:30:00.000000", DateFormat.FULL_ISO)),
            (MarketCloseEvent, str_to_date("2018-04-10 16:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent, str_to_date("2018-04-10 16:00:00.000000", DateFormat.FULL_ISO)),
            (AfterMarketCloseEvent, str_to_date("2018-04-10 18:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent, str_to_date("2018-04-10 18:00:00.000000", DateFormat.FULL_ISO)),
            (EndTradingEvent, str_to_date("2018-04-10 23:59:59.999999", DateFormat.FULL_ISO)),
        ]

        actual_events = [(type(event), event.time) for event in listener.registered_events]

        assert_lists_equal(expected_events, actual_events, absolute_tolerance=0.0)
def _get_test_case_set_up():
    timer = SettableTimer()
    tickers = [QuandlTicker("MSFT", "WIKI"), QuandlTicker("AAPL", "WIKI")]
    price_data_provider_mock = _create_price_provider_mock(tickers)
    data_handler = DailyDataHandler(price_data_provider_mock, timer)

    return timer, tickers, data_handler
Exemple #8
0
    def test_futures_chain_without_adjustment(self):
        timer = SettableTimer(self.end_date)
        self.future_ticker_1.initialize_data_provider(timer,
                                                      self.data_provider)

        futures_chain = FuturesChain(self.future_ticker_1, self.data_provider,
                                     FuturesAdjustmentMethod.NTH_NEAREST)

        # AB2021M is the current specific ticker till 2021-06-14 inclusive, afterwards the AB2021U
        start_date = str_to_date("2021-06-13")
        end_date = str_to_date("2021-06-17")
        fields = PriceField.ohlcv()
        prices = futures_chain.get_price(fields, start_date, end_date,
                                         Frequency.DAILY)

        prices_m_contract = self.data_provider.get_price(
            PortaraTicker("AB2021M", SecurityType.FUTURE, 1), fields,
            start_date, str_to_date("2021-06-14"), Frequency.DAILY)
        prices_u_contract = self.data_provider.get_price(
            PortaraTicker("AB2021U", SecurityType.FUTURE, 1), fields,
            str_to_date("2021-06-15"), end_date, Frequency.DAILY)

        assert_dataframes_equal(prices,
                                concat([prices_m_contract, prices_u_contract]),
                                check_names=False)
    def setUp(self):
        all_fields = PriceField.ohlcv()

        self._mocked_prices_arr = self._make_mock_data_array(self.tickers, all_fields)
        self._price_provider_mock = PresetDataProvider(self._mocked_prices_arr,
                                                       self.data_start_date, self.data_end_date, self.frequency)
        self.timer = SettableTimer()
        self.alpha_model_type = DummyAlphaModel
    def setUp(self):
        self.scheduling_time_delay = 1
        start_date = str_to_date("2018-02-04")

        before_close = start_date + MarketCloseEvent.trigger_time(
        ) - RelativeDelta(minutes=self.scheduling_time_delay)
        self.timer = SettableTimer(initial_time=before_close)

        contracts_to_tickers_mapper = SimulatedBloombergContractTickerMapper()
        msft_contract = Contract("MSFT US Equity",
                                 security_type='STK',
                                 exchange='TEST')
        self.msft_ticker = contracts_to_tickers_mapper.contract_to_ticker(
            msft_contract)

        self.data_handler = Mock(spec=DataHandler)
        self.scheduler = Mock(spec=Scheduler)

        self.commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = Mock(spec=AbstractMonitor)
        self.portfolio = Mock(spec=Portfolio)

        slippage_model = PriceBasedSlippage(0.0, self.data_handler,
                                            contracts_to_tickers_mapper)
        self.exec_handler = SimulatedExecutionHandler(
            self.data_handler, self.timer, self.scheduler, self.monitor,
            self.commission_model, contracts_to_tickers_mapper, self.portfolio,
            slippage_model, RelativeDelta(minutes=self.scheduling_time_delay))

        self.order_1 = Order(msft_contract,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(msft_contract,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(msft_contract,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(msft_contract,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)
Exemple #11
0
    def setUpClass(cls) -> None:
        cls.end_date = str_to_date('2015-10-08')
        cls.start_date = cls.end_date - RelativeDelta(years=2)

        cls.timer = SettableTimer(cls.end_date)

        cls.frequency = Frequency.DAILY
        cls.TICKER_1 = BloombergFutureTicker("Cotton", "CT{} Comdty", 1, 3)
        cls.TICKER_2 = BloombergFutureTicker("Corn", 'C {} Comdty', 1, 5)
Exemple #12
0
    def setUp(self):
        self.scheduling_time_delay = 1
        start_date = str_to_date("2018-02-04")

        before_close = start_date + MarketCloseEvent.trigger_time(
        ) - RelativeDelta(minutes=self.scheduling_time_delay)
        self.timer = SettableTimer(initial_time=before_close)

        self.msft_ticker = BloombergTicker("MSFT US Equity")

        self.data_handler = Mock(spec=DataHandler)
        self.data_handler.frequency = Frequency.DAILY
        self.data_handler.data_provider = Mock(spec=DataProvider)

        self.scheduler = Mock(spec=Scheduler)

        self.commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = Mock(spec=AbstractMonitor)
        self.portfolio = Mock(spec=Portfolio)

        slippage_model = PriceBasedSlippage(0.0, self.data_handler)
        self.exec_handler = SimulatedExecutionHandler(
            self.data_handler, self.timer, self.scheduler, self.monitor,
            self.commission_model, self.portfolio, slippage_model,
            RelativeDelta(minutes=self.scheduling_time_delay))

        self.order_1 = Order(self.msft_ticker,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(self.msft_ticker,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(self.msft_ticker,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(self.msft_ticker,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)
Exemple #13
0
    def setUp(self):
        self.start_date = str_to_date("2018-02-04")
        self.msft_contract = Contract(self.MSFT_TICKER_STR,
                                      security_type='SEK',
                                      exchange='TEST')
        self.msft_ticker = BloombergTicker(self.MSFT_TICKER_STR)

        self.contracts_to_tickers_mapper = DummyBloombergContractTickerMapper()
        self.timer = SettableTimer(initial_time=self.start_date)

        self.data_handler = mock(strict=True)

        self.scheduler = mock()

        self.commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = _MonitorMock()
        self.spied_monitor = spy(self.monitor)
        self.portfolio = mock()

        slippage_model = PriceBasedSlippage(0.0)
        self.exec_hanlder = SimulatedExecutionHandler(
            self.data_handler, self.timer, self.scheduler, self.spied_monitor,
            self.commission_model, self.contracts_to_tickers_mapper,
            self.portfolio, slippage_model)

        self._set_last_msft_price(100.0)
        self.order_1 = Order(self.msft_contract,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(self.msft_contract,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(self.msft_contract,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(self.msft_contract,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)
    def setUpClass(cls):
        cls.start_date = str_to_date('2008-10-08')
        cls.end_date = str_to_date('2018-12-20')

        cls.timer = SettableTimer()
        cls.timer.set_current_time(cls.end_date)

        cls.frequency = Frequency.DAILY
        cls.ticker_1 = BloombergFutureTicker("Euroswiss", "ES{} Index", 1, 3, 100, "HMUZ")
        cls.ticker_2 = BloombergFutureTicker("Corn", "C {} Comdty", 1, 3, 100, "HKNUZ")

        MarketCloseEvent.set_trigger_time({"hour": 20, "minute": 00, "second": 0, "microsecond": 0})
Exemple #15
0
    def setUp(self):
        MarketOpenEvent.set_trigger_time({"hour": 13, "minute": 30, "second": 0, "microsecond": 0})
        MarketCloseEvent.set_trigger_time({"hour": 20, "minute": 0, "second": 0, "microsecond": 0})

        self.start_date = str_to_date("2018-02-04")
        self.number_of_minutes = 5

        before_close = self.start_date + MarketCloseEvent.trigger_time() - RelativeDelta(minutes=self.number_of_minutes)
        self.msft_ticker = BloombergTicker(self.MSFT_TICKER_STR)

        self.timer = SettableTimer(initial_time=before_close)

        self.data_handler = Mock(spec=DataHandler)
        self.data_handler.data_provider = Mock(spec=DataProvider)

        scheduler = Mock(spec=Scheduler)
        ScheduleOrderExecutionEvent.clear()

        # Set the periodic bar events to intraday trading
        IntradayBarEvent.frequency = Frequency.MIN_1

        commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = Mock(spec=AbstractMonitor)
        self.portfolio = Mock(spec=Portfolio)

        slippage_model = PriceBasedSlippage(0.0, self.data_handler)
        self.exec_handler = SimulatedExecutionHandler(self.data_handler, self.timer, scheduler, self.monitor,
                                                      commission_model, self.portfolio, slippage_model,
                                                      RelativeDelta(minutes=self.number_of_minutes))

        self._set_last_available_price(100.0)
        self.stop_loss_order_1 = Order(self.msft_ticker, quantity=-1, execution_style=StopOrder(95.0),
                                       time_in_force=TimeInForce.GTC)
        self.stop_loss_order_2 = Order(self.msft_ticker, quantity=-1, execution_style=StopOrder(90.0),
                                       time_in_force=TimeInForce.GTC)

        self.stop_loss_order_3 = Order(self.msft_ticker, quantity=-1, execution_style=StopOrder(50.0),
                                       time_in_force=TimeInForce.DAY)

        self.exec_handler.assign_order_ids([self.stop_loss_order_1, self.stop_loss_order_2, self.stop_loss_order_3])
Exemple #16
0
    def setUp(self):
        try:
            self.price_data_provider = get_data_provider()
        except Exception as e:
            raise self.skipTest(e)

        self.timer = SettableTimer()
        self.data_handler = DailyDataHandler(self.price_data_provider,
                                             self.timer)

        MarketOpenEvent.set_trigger_time({
            "hour": 13,
            "minute": 30,
            "second": 0,
            "microsecond": 0
        })
        MarketCloseEvent.set_trigger_time({
            "hour": 20,
            "minute": 0,
            "second": 0,
            "microsecond": 0
        })
Exemple #17
0
    def _setup_data_handler(self, volume_value: Optional[float]) -> DataHandler:
        dates = pd.date_range(str_to_date("2019-12-01"), str_to_date("2020-01-30"), freq='D')
        prices_data_frame = QFDataFrame(data={PriceField.Volume: [volume_value] * len(dates)},
                                        index=dates)

        prices_data_array = tickers_dict_to_data_array({
            self.ticker: prices_data_frame,
        }, [self.ticker], [PriceField.Volume])

        data_provider = PresetDataProvider(prices_data_array, dates[0], dates[-1], Frequency.DAILY)
        timer = SettableTimer(dates[-1])

        return DailyDataHandler(data_provider, timer)
    def setUp(self):
        self.timer = SettableTimer()
        self.tickers = [
            QuandlTicker("MSFT", "WIKI"),
            QuandlTicker("AAPL", "WIKI")
        ]
        price_data_provider_mock = self._create_price_provider_mock(
            self.tickers)
        self.data_handler = DailyDataHandler(price_data_provider_mock,
                                             self.timer)

        MarketOpenEvent.set_trigger_time({
            "hour": 13,
            "minute": 30,
            "second": 0,
            "microsecond": 0
        })
        MarketCloseEvent.set_trigger_time({
            "hour": 20,
            "minute": 0,
            "second": 0,
            "microsecond": 0
        })
Exemple #19
0
    def test_get_current_specific_ticker(self):
        timer = SettableTimer()
        self.future_ticker_1.initialize_data_provider(timer,
                                                      self.data_provider)

        timer.set_current_time(str_to_date("2021-03-18"))
        specific_ticker = self.future_ticker_1.get_current_specific_ticker()
        self.assertEqual(specific_ticker,
                         PortaraTicker("AB2021M", SecurityType.FUTURE, 1))

        timer.set_current_time(str_to_date("2021-06-14"))
        specific_ticker = self.future_ticker_1.get_current_specific_ticker()
        self.assertEqual(specific_ticker,
                         PortaraTicker("AB2021M", SecurityType.FUTURE, 1))

        timer.set_current_time(str_to_date("2021-06-15"))
        specific_ticker = self.future_ticker_1.get_current_specific_ticker()
        self.assertEqual(specific_ticker,
                         PortaraTicker("AB2021U", SecurityType.FUTURE, 1))

        timer.set_current_time(datetime(2021, 12, 14, 23, 59))
        specific_ticker = self.future_ticker_1.get_current_specific_ticker()
        self.assertEqual(specific_ticker,
                         PortaraTicker("AB2021Z", SecurityType.FUTURE, 1))
class TestDataHandlerTimeHelper(TestCase):
    @classmethod
    def setUpClass(cls):
        cls.YESTERDAY_OPEN = str_to_date("2018-01-29 09:30:00.000000",
                                         DateFormat.FULL_ISO)
        cls.YESTERDAY_CLOSE = str_to_date("2018-01-29 16:00:00.000000",
                                          DateFormat.FULL_ISO)
        cls.TODAY_BEFORE_OPEN = str_to_date("2018-01-30 06:00:00.000000",
                                            DateFormat.FULL_ISO)
        cls.TODAY_OPEN = str_to_date("2018-01-30 09:30:00.000000",
                                     DateFormat.FULL_ISO)
        cls.TODAY_MIDDLE_DAY = str_to_date("2018-01-30 12:00:00.000000",
                                           DateFormat.FULL_ISO)
        cls.TODAY_CLOSE = str_to_date("2018-01-30 16:00:00.000000",
                                      DateFormat.FULL_ISO)
        cls.TODAY_AFTER_CLOSE = str_to_date("2018-01-30 20:00:00.000000",
                                            DateFormat.FULL_ISO)

    def setUp(self):
        self.timer = SettableTimer()
        self.time_helper = _DataHandlerTimeHelper(self.timer)

    def test_datetime_of_latest_market_event_before_market_open(self):
        self.timer.set_current_time(self.TODAY_BEFORE_OPEN)

        market_open_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketOpenEvent)
        market_close_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketCloseEvent)

        self.assertEqual(market_open_datetime, self.YESTERDAY_OPEN)
        self.assertEqual(market_close_datetime, self.YESTERDAY_CLOSE)

    def test_datetime_of_latest_market_event_during_trading_session(self):
        self.timer.set_current_time(self.TODAY_MIDDLE_DAY)

        market_open_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketOpenEvent)
        market_close_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketCloseEvent)

        self.assertEqual(market_open_datetime, self.TODAY_OPEN)
        self.assertEqual(market_close_datetime, self.YESTERDAY_CLOSE)

    def test_datetime_of_latest_market_event_after_market_close(self):
        self.timer.set_current_time(self.TODAY_AFTER_CLOSE)

        market_open_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketOpenEvent)
        market_close_datetime = self.time_helper.datetime_of_latest_market_event(
            MarketCloseEvent)

        self.assertEqual(market_open_datetime, self.TODAY_OPEN)
        self.assertEqual(market_close_datetime, self.TODAY_CLOSE)
Exemple #21
0
    def setUp(self) -> None:
        self.ticker = BloombergTicker("Example Ticker")
        self.future_ticker = MagicMock(spec=BloombergFutureTicker)
        self.future_ticker.configure_mock(name="Example", family_id="Example{} Comdty", days_before_exp_date=1,
                                          point_value=1)

        self.alpha_model = MagicMock()

        # Mock trading session
        self.ts = MagicMock()
        self.ts.contract_ticker_mapper = SimulatedBloombergContractTickerMapper()
        self.ts.timer = SettableTimer(str_to_date("2000-01-04 08:00:00.0", DateFormat.FULL_ISO))

        self.positions_in_portfolio = []  # type: List[Contract]
        """Contracts for which a position in the portfolio currently exists. This list is used to return backtest
        positions list by the broker."""

        self.ts.broker.get_positions.side_effect = lambda: self.positions_in_portfolio
def map_future_ticker_to_contract():
    mapping = {
        BloombergFutureTicker('Copper', 'HG{} Comdty', 1, 1, 250):
        IBContract("HG", SecurityType.FUTURE, "NYMEX", "25000", "USD"),
        BloombergTicker("PAH20 Comdty", SecurityType.FUTURE, 100):
        IBContract("PA", SecurityType.FUTURE, "NYMEX", "100", "",
                   str_to_date("2020-03-27"))
    }
    data_provider = container.resolve(BloombergDataProvider)

    contract_ticker_mapper = IBContractTickerMapper(mapping, data_provider)
    current_time = str_to_date("2020-12-01")

    for future_ticker in mapping.keys():
        if isinstance(future_ticker, BloombergFutureTicker):
            future_ticker.initialize_data_provider(SettableTimer(current_time),
                                                   data_provider)

    print("\nMapping PAH20 Comdty ticker to IB contract")
    ticker = BloombergTicker("PAH20 Comdty", SecurityType.FUTURE, 100)
    contract = contract_ticker_mapper.ticker_to_contract(ticker)
    print(f"Ticker mapped onto the following contract: {contract}")

    print("\nMapping IBContract onto ticker")
    contract = IBContract("PA", SecurityType.FUTURE, "NYMEX", "100", "",
                          str_to_date("2020-03-27"))
    ticker = contract_ticker_mapper.contract_to_ticker(contract)
    print(f"Contract mapped onto the following ticker: {ticker}")

    print(
        "\nMapping HGH20 Comdty ticker - Copper, March 2020 futures contracts")
    ticker = BloombergTicker("HGH20 Comdty", SecurityType.FUTURE, 250)
    contract = contract_ticker_mapper.ticker_to_contract(ticker)
    print(f"Ticker mapped onto the following contract: {contract}")

    print("\nMapping IBContract onto ticker")
    contract = IBContract("HG", SecurityType.FUTURE, "NYMEX", "25000", "USD",
                          str_to_date("2021-01-27"))
    ticker = contract_ticker_mapper.contract_to_ticker(contract)
    print(f"Contract mapped onto the following ticker: {ticker}")
    def _generate_buy_and_hold_returns(self,
                                       ticker: Ticker) -> SimpleReturnsSeries:
        """ Computes series of simple returns, which would be returned by the Buy and Hold strategy. """
        if isinstance(ticker, FutureTicker):
            try:
                ticker.initialize_data_provider(SettableTimer(self._end_date),
                                                self._data_provider)
                futures_chain = FuturesChain(
                    ticker, self._data_provider,
                    FuturesAdjustmentMethod.BACK_ADJUSTED)
                prices_series = futures_chain.get_price(
                    PriceField.Close, self._start_date, self._end_date)
            except NoValidTickerException:
                prices_series = PricesSeries()
        else:
            prices_series = self._data_provider.get_price(
                ticker, PriceField.Close, self._start_date, self._end_date)

        returns_tms = prices_series.to_simple_returns().replace(
            [-np.inf, np.inf], np.nan).fillna(0.0)
        returns_tms.name = "Buy and Hold"
        return returns_tms
class TestDailyDataHandler(TestCase):
    def setUp(self):
        self.timer = SettableTimer()
        self.tickers = [
            QuandlTicker("MSFT", "WIKI"),
            QuandlTicker("AAPL", "WIKI")
        ]
        price_data_provider_mock = self._create_price_provider_mock(
            self.tickers)
        self.data_handler = DailyDataHandler(price_data_provider_mock,
                                             self.timer)

        MarketOpenEvent.set_trigger_time({
            "hour": 13,
            "minute": 30,
            "second": 0,
            "microsecond": 0
        })
        MarketCloseEvent.set_trigger_time({
            "hour": 20,
            "minute": 0,
            "second": 0,
            "microsecond": 0
        })

    def test_before_data_starts(self):
        self._assert_last_prices_are_correct("2009-12-28 06:00:00.000000",
                                             [nan, nan])

    def test_at_market_open_when_data_available_for_every_ticker(self):
        self._assert_last_prices_are_correct("2009-12-28 13:30:00.000000",
                                             [25.0, 27.0])

    def test_at_market_open_when_data_available_for_the_first_ticker(self):
        self._assert_last_prices_are_correct("2009-12-30 13:30:00.000000",
                                             [31.0, 30.0])

    def test_during_trading_hours_when_data_available_for_every_ticker(self):
        self._assert_last_prices_are_correct("2009-12-28 14:30:00.000000",
                                             [25.0, 27.0])

    def test_during_trading_hours_when_data_available_for_the_first_ticker(
            self):
        self._assert_last_prices_are_correct("2009-12-30 14:30:00.000000",
                                             [31.0, 30.0])

    def test_at_market_close_when_data_available_for_the_first_ticker(self):
        self._assert_last_prices_are_correct("2009-12-30 20:00:00.000000",
                                             [32.0, 30.0])

    def test_after_market_close_when_data_is_not_available_for_anything_anymore(
            self):
        self._assert_last_prices_are_correct("2009-12-30 20:00:00.000000",
                                             [32.0, 30.0])

    def test_before_market_close_when_old_data_is_available(self):
        self._assert_last_prices_are_correct("2009-12-31 06:00:00.000000",
                                             [32.0, 30.0])

    def _assert_last_prices_are_correct(self, curr_time_str, expected_values):
        current_time = str_to_date(curr_time_str, DateFormat.FULL_ISO)
        self.timer.set_current_time(current_time)
        expected_series = QFSeries(data=expected_values, index=self.tickers)
        actual_series = self.data_handler.get_last_available_price(
            self.tickers)
        assert_series_equal(expected_series, actual_series, check_names=False)

    def _create_price_provider_mock(self, tickers):
        mock_data_array = QFDataArray.create(
            dates=date_range(start='2009-12-28', end='2009-12-30', freq='D'),
            tickers=tickers,
            fields=PriceField.ohlcv(),
            data=[
                # 2009-12-28
                [
                    # Open High  Low   Close Volume
                    [25.0, 25.1, 25.2, 26.0, 25.3],  # MSFT
                    [27.0, 27.1, 27.2, 28.0, 27.3]  # AAPL
                ],
                # 2009-12-29
                [
                    # Open High  Low   Close Volume
                    [None, None, None, None, None],  # MSFT
                    [29.0, 29.1, 29.2, 30.0, 29.3]  # AAPL
                ],
                # 2009-12-30
                [
                    # Open High  Low   Close Volume
                    [31.0, 31.1, 31.2, 32.0, 31.3],  # MSFT
                    [None, None, None, None, None]  # AAPL
                ]
            ])

        price_data_provider_mock = Mock(spec=DataProvider,
                                        frequency=Frequency.DAILY)
        price_data_provider_mock.get_price.side_effect = lambda t, fields, start_time, end_time, frequency: \
            mock_data_array.loc[start_time:end_time, t, fields].to_pandas()

        return price_data_provider_mock
Exemple #25
0
class TestDataHandler(TestCase):
    @classmethod
    def setUpClass(cls):
        cls.spx_index_ticker = BloombergTicker("SPX Index")
        cls.google_ticker = BloombergTicker("GOOGL US Equity")
        cls.microsoft_ticker = BloombergTicker("MSFT US Equity")

        cls.start_date = str_to_date("2018-01-02")
        cls.end_date = str_to_date("2018-01-31")
        cls.end_date_trimmed = str_to_date("2018-01-30")
        cls.get_history_field = "PX_TO_BOOK_RATIO"

    def setUp(self):
        try:
            self.price_data_provider = get_data_provider()
        except Exception as e:
            raise self.skipTest(e)

        self.timer = SettableTimer()
        self.data_handler = DailyDataHandler(self.price_data_provider,
                                             self.timer)

        MarketOpenEvent.set_trigger_time({
            "hour": 13,
            "minute": 30,
            "second": 0,
            "microsecond": 0
        })
        MarketCloseEvent.set_trigger_time({
            "hour": 20,
            "minute": 0,
            "second": 0,
            "microsecond": 0
        })

    def test_get_price_when_end_date_is_in_the_past(self):
        self.timer.set_current_time(
            str_to_date("2018-02-12 00:00:00.000000", DateFormat.FULL_ISO))
        prices_tms = self.data_handler.get_price(self.spx_index_ticker,
                                                 PriceField.Close,
                                                 self.start_date,
                                                 self.end_date)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date, prices_tms.index[-1].to_pydatetime())

    def test_get_price_when_end_date_is_today_after_market_close(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketCloseEvent.trigger_time() +
            RelativeDelta(hours=1))
        prices_tms = self.data_handler.get_price(self.spx_index_ticker,
                                                 PriceField.Close,
                                                 self.start_date,
                                                 self.end_date)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date, prices_tms.index[-1].to_pydatetime())

    def test_get_price_when_end_date_is_today_before_market_close(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        close_prices_tms = self.data_handler.get_price(self.spx_index_ticker,
                                                       PriceField.Close,
                                                       self.start_date,
                                                       self.end_date)

        self.assertEqual(self.start_date,
                         close_prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date_trimmed,
                         close_prices_tms.index[-1].to_pydatetime())

    def test_get_open_price_when_end_date_is_today_before_market_close__single_ticker(
            self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        current_date = datetime(self.timer.now().year,
                                self.timer.now().month,
                                self.timer.now().day)
        open_prices_tms = self.data_handler.get_price(self.spx_index_ticker,
                                                      PriceField.Open,
                                                      self.start_date,
                                                      self.timer.now())

        self.assertEqual(self.start_date,
                         open_prices_tms.index[0].to_pydatetime())
        self.assertEqual(current_date,
                         open_prices_tms.index[-1].to_pydatetime())

        prices_df = self.data_handler.get_price(
            self.spx_index_ticker, [PriceField.Open, PriceField.Close],
            self.start_date, self.timer.now())
        self.assertEqual(self.start_date, prices_df.index[0].to_pydatetime())
        self.assertEqual(current_date, prices_df.index[-1].to_pydatetime())

        last_bar = prices_df.iloc[-1]
        self.assertTrue(isnan(last_bar.loc[PriceField.Close]))
        self.assertIsNotNone(last_bar.loc[PriceField.Open])

    def test_get_open_price_when_end_date_is_today_before_market_close__multiple_tickers(
            self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        current_date = datetime(self.timer.now().year,
                                self.timer.now().month,
                                self.timer.now().day)

        tickers = [self.spx_index_ticker, self.microsoft_ticker]
        open_prices_tms = self.data_handler.get_price(tickers, PriceField.Open,
                                                      self.start_date,
                                                      self.timer.now())

        self.assertEqual(self.start_date,
                         open_prices_tms.index[0].to_pydatetime())
        self.assertEqual(current_date,
                         open_prices_tms.index[-1].to_pydatetime())

        prices_data_array = self.data_handler.get_price(
            tickers, [PriceField.Open, PriceField.Close], self.start_date,
            self.timer.now())
        last_bar_df = prices_data_array.loc[current_date, :, :].to_pandas()

        self.assertTrue(last_bar_df[PriceField.Close].isna().all())
        self.assertTrue(last_bar_df[PriceField.Open].notna().all())

    def test_get_price_when_end_date_is_tomorrow(self):
        self.timer.set_current_time(
            str_to_date("2018-01-30") + MarketCloseEvent.trigger_time() +
            RelativeDelta(hours=1))
        prices_tms = self.data_handler.get_price(self.spx_index_ticker,
                                                 PriceField.Close,
                                                 self.start_date,
                                                 self.end_date_trimmed)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date_trimmed,
                         prices_tms.index[-1].to_pydatetime())

    def test_get_last_price_single_ticker(self):
        # just test if getting single ticker value works, when a single ticker (not wrapped in a list) is passed
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        single_price = self.data_handler.get_last_available_price(
            self.spx_index_ticker)
        self.assertTrue(isinstance(single_price, float))

        # at market open
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time())
        at_market_open = self.data_handler.get_last_available_price(
            [self.spx_index_ticker])

        self.assertEqual(self.spx_index_ticker, at_market_open.index[0])
        self.assertEqual(single_price, at_market_open[0])

        # during the trading session
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        during_the_day_last_prices = self.data_handler.get_last_available_price(
            [self.spx_index_ticker])

        self.assertEqual(self.spx_index_ticker,
                         during_the_day_last_prices.index[0])
        self.assertEqual(single_price, during_the_day_last_prices[0])

        # after the trading session
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketCloseEvent.trigger_time() +
            RelativeDelta(hours=1))
        after_close_last_prices = self.data_handler.get_last_available_price(
            [self.spx_index_ticker])

        self.assertEqual(self.spx_index_ticker,
                         after_close_last_prices.index[0])
        self.assertNotEqual(during_the_day_last_prices[0],
                            after_close_last_prices[0])

        # before the trading session
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() -
            RelativeDelta(hours=1))
        before_trading_session_prices = self.data_handler.get_last_available_price(
            [self.spx_index_ticker])

        self.assertEqual(self.spx_index_ticker,
                         before_trading_session_prices.index[0])
        self.assertNotEqual(during_the_day_last_prices[0],
                            before_trading_session_prices[0])
        self.assertNotEqual(after_close_last_prices[0],
                            before_trading_session_prices[0])

    def test_get_last_price_with_multiple_tickers_when_current_data_is_unavailable(
            self):
        self.timer.set_current_time(
            str_to_date("2018-01-01") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        last_prices = self.data_handler.get_last_available_price(
            [self.spx_index_ticker, self.google_ticker])

        self.assertEqual(self.spx_index_ticker, last_prices.index[0])
        self.assertEqual(self.google_ticker, last_prices.index[1])

    def test_get_last_price_with_empty_tickers_list(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        last_prices = self.data_handler.get_last_available_price([])
        assert_series_equal(QFSeries(), last_prices)

    def test_get_history_when_end_date_is_in_the_past(self):
        self.timer.set_current_time(
            str_to_date("2018-02-12 00:00:00.000000", DateFormat.FULL_ISO))
        prices_tms = self.data_handler.get_history(self.spx_index_ticker,
                                                   self.get_history_field,
                                                   self.start_date,
                                                   self.end_date)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date, prices_tms.index[-1].to_pydatetime())

    def test_get_history_when_end_date_is_today_after_market_close(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketCloseEvent.trigger_time() +
            RelativeDelta(hours=1))
        prices_tms = self.data_handler.get_history(self.spx_index_ticker,
                                                   self.get_history_field,
                                                   self.start_date,
                                                   self.end_date)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date, prices_tms.index[-1].to_pydatetime())

    def test_get_history_when_end_date_is_today_before_market_close(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        prices_tms = self.data_handler.get_history(self.spx_index_ticker,
                                                   self.get_history_field,
                                                   self.start_date,
                                                   self.end_date)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date_trimmed,
                         prices_tms.index[-1].to_pydatetime())

    def test_get_history_when_end_date_is_tomorrow(self):
        self.timer.set_current_time(
            str_to_date("2018-01-30") + MarketCloseEvent.trigger_time() +
            RelativeDelta(hours=1))
        prices_tms = self.data_handler.get_history(self.spx_index_ticker,
                                                   self.get_history_field,
                                                   self.start_date,
                                                   self.end_date_trimmed)

        self.assertEqual(self.start_date, prices_tms.index[0].to_pydatetime())
        self.assertEqual(self.end_date_trimmed,
                         prices_tms.index[-1].to_pydatetime())

    def test_get_history_with_multiple_tickers(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        resilt_df = self.data_handler.get_history(
            [self.microsoft_ticker, self.google_ticker],
            self.get_history_field, self.start_date, self.end_date_trimmed)

        self.assertEqual(self.microsoft_ticker, resilt_df.columns[0])
        self.assertEqual(self.google_ticker, resilt_df.columns[1])
        self.assertEqual(self.start_date, resilt_df.index[0].to_pydatetime())
        self.assertEqual(self.end_date_trimmed,
                         resilt_df.index[-1].to_pydatetime())
        self.assertEqual(resilt_df.shape, (20, 2))

    def test_historical_price_many_tickers_many_fields(self):
        self.timer.set_current_time(
            str_to_date("2018-01-31") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        result_array = self.data_handler.historical_price(
            [self.microsoft_ticker], [PriceField.Open, PriceField.Close],
            nr_of_bars=5)

        self.assertEqual(QFDataArray, type(result_array))
        self.assertEqual((5, 1, 2), result_array.shape)

        expected_dates_str = [
            "2018-01-24", "2018-01-25", "2018-01-26", "2018-01-29",
            "2018-01-30"
        ]
        expected_dates = [
            str_to_date(date_str) for date_str in expected_dates_str
        ]
        assert_same_index(pd.DatetimeIndex(expected_dates, name=DATES),
                          result_array.dates.to_index(),
                          check_index_type=True,
                          check_names=True)

    def test_historical_price_many_tickers_one_field(self):
        self.timer.set_current_time(
            str_to_date("2018-01-04") + MarketOpenEvent.trigger_time() +
            RelativeDelta(hours=1))
        result_df = self.data_handler.historical_price([self.microsoft_ticker],
                                                       PriceField.Open,
                                                       nr_of_bars=5)

        self.assertEqual(PricesDataFrame, type(result_df))

        expected_dates_idx = pd.DatetimeIndex([
            '2017-12-27', '2017-12-28', '2017-12-29', '2018-01-02',
            '2018-01-03'
        ],
                                              name=DATES)
        assert_same_index(expected_dates_idx,
                          result_df.index,
                          check_index_type=True,
                          check_names=True)

        expected_tickers_idx = pd.Index([self.microsoft_ticker], name=TICKERS)
        assert_same_index(expected_tickers_idx,
                          result_df.columns,
                          check_index_type=True,
                          check_names=True)
    def setUp(self) -> None:
        self.contract_ticker_mapper = SimulatedBloombergContractTickerMapper()
        self.current_date = str_to_date("2017-01-01")

        self.timer = SettableTimer(self.current_date)
Exemple #27
0
 def _shift_timer_to_next_day(timer: SettableTimer):
     new_time = timer.time + RelativeDelta(days=1)
     timer.set_current_time(new_time)
    def build(self, start_date: datetime, end_date: datetime) -> BacktestTradingSession:
        self._timer = SettableTimer(start_date)
        self._notifiers = Notifiers(self._timer)
        self._events_manager = self._create_event_manager(self._timer, self._notifiers)

        self._data_handler = DataHandler(self._data_provider, self._timer)

        self._portfolio = Portfolio(self._data_handler, self._initial_cash, self._timer, self._contract_ticker_mapper)
        self._backtest_result = BacktestResult(self._portfolio, self._backtest_name, start_date, end_date)
        self._monitor = self._monitor_setup()

        self._portfolio_handler = PortfolioHandler(self._portfolio, self._monitor, self._notifiers.scheduler)
        self._execution_handler = SimulatedExecutionHandler(
            self._data_handler, self._timer, self._notifiers.scheduler, self._monitor, self._commission_model,
            self._contract_ticker_mapper, self._portfolio, self._slippage_model)

        self._time_flow_controller = BacktestTimeFlowController(
            self._notifiers.scheduler, self._events_manager, self._timer,
            self._notifiers.empty_queue_event_notifier, end_date)

        self._broker = BacktestBroker(self._portfolio, self._execution_handler)
        self._order_factory = OrderFactory(self._broker, self._data_handler, self._contract_ticker_mapper)
        self._position_sizer = self._position_sizer_setup()

        setup_logging(self._logging_level)

        self._logger.info(
            "\n".join([
                "Creating Backtest Trading Session.",
                "\tBacktest Name: {}".format(self._backtest_name),
                "\tData Provider: {}".format(self._data_provider.__class__.__name__),
                "\tContract - Ticker Mapper: {}".format(self._contract_ticker_mapper.__class__.__name__),
                "\tStart Date: {}".format(start_date),
                "\tEnd Date: {}".format(end_date),
                "\tInitial Cash: {:.2f}".format(self._initial_cash)
            ])
        )

        self._logger.info(
            "\n".join([
                "Configuration of components:",
                "\tPosition sizer: {:s}".format(self._position_sizer.__class__.__name__),
                "\tTimer: {:s}".format(self._timer.__class__.__name__),
                "\tData Handler: {:s}".format(self._data_handler.__class__.__name__),
                "\tBacktest Result: {:s}".format(self._backtest_result.__class__.__name__),
                "\tMonitor: {:s}".format(self._monitor.__class__.__name__),
                "\tExecution Handler: {:s}".format(self._execution_handler.__class__.__name__),
                "\tSlippage Model: {:s}".format(self._slippage_model.__class__.__name__),
                "\tCommission Model: {:s}".format(self._commission_model.__class__.__name__),
                "\tBroker: {:s}".format(self._broker.__class__.__name__),
            ])
        )

        ts = BacktestTradingSession(
            contract_ticker_mapper=self._contract_ticker_mapper,
            start_date=start_date,
            end_date=end_date,
            position_sizer=self._position_sizer,
            data_handler=self._data_handler,
            timer=self._timer,
            notifiers=self._notifiers,
            portfolio=self._portfolio,
            events_manager=self._events_manager,
            monitor=self._monitor,
            broker=self._broker,
            order_factory=self._order_factory
        )
        return ts
    def test_event_management(self):
        timer = SettableTimer(initial_time=str_to_date(
            "2018-04-10 00:00:00.000000", DateFormat.FULL_ISO))
        end_date = str_to_date("2018-04-10")

        notifiers = Notifiers(timer)
        event_manager = self._create_event_manager(timer, notifiers)
        BacktestTimeFlowController(notifiers.scheduler, event_manager, timer,
                                   notifiers.empty_queue_event_notifier,
                                   end_date)

        listener = DummyListener(notifiers, event_manager, timer)

        last_event = None
        while not isinstance(last_event, EndTradingEvent):
            event_manager.dispatch_next_event()
            last_event, _ = listener.registered_events[-1]

        expected_events = [
            (EmptyQueueEvent,
             str_to_date("2018-04-10 08:00:00.000000", DateFormat.FULL_ISO)),
            (BeforeMarketOpenEvent,
             str_to_date("2018-04-10 08:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 13:30:00.000000", DateFormat.FULL_ISO)),
            (MarketOpenEvent,
             str_to_date("2018-04-10 13:30:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 13:45:00.000000", DateFormat.FULL_ISO)),
            (PeriodicEvent1Hour,
             str_to_date("2018-04-10 13:45:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 13:50:00.000000", DateFormat.FULL_ISO)),
            (SingleTimeEvent,
             str_to_date("2018-04-10 13:50:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 14:45:00.000000", DateFormat.FULL_ISO)),
            (PeriodicEvent1Hour,
             str_to_date("2018-04-10 14:45:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 14:50:00.000000", DateFormat.FULL_ISO)),
            (SingleTimeEvent,
             str_to_date("2018-04-10 14:50:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 20:00:00.000000", DateFormat.FULL_ISO)),
            (MarketCloseEvent,
             str_to_date("2018-04-10 20:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 21:00:00.000000", DateFormat.FULL_ISO)),
            (AfterMarketCloseEvent,
             str_to_date("2018-04-10 21:00:00.000000", DateFormat.FULL_ISO)),
            (EmptyQueueEvent,
             str_to_date("2018-04-10 21:00:00.000000", DateFormat.FULL_ISO)),
            (EndTradingEvent,
             str_to_date("2018-04-10 21:00:00.000000", DateFormat.FULL_ISO)),
        ]

        expected_events = [
            type_of_event for type_of_event, time in expected_events
        ]
        actual_events = [
            type(event) for event, time in listener.registered_events
        ]

        assert_lists_equal(expected_events,
                           actual_events,
                           absolute_tolerance=0.0)

        expected_single_time_events_data = {
            str_to_date("2018-04-10 13:50:00.000000", DateFormat.FULL_ISO):
            str_to_date("2018-04-10 13:45:00.000000", DateFormat.FULL_ISO),
            str_to_date("2018-04-10 14:50:00.000000", DateFormat.FULL_ISO):
            str_to_date("2018-04-10 14:45:00.000000", DateFormat.FULL_ISO)
        }

        for key in expected_single_time_events_data:
            self.assertEqual(expected_single_time_events_data[key],
                             listener.registered_single_time_events[key])
    def __init__(self, data_provider: DataProvider, start_date, end_date, initial_cash,
                 frequency: Frequency = Frequency.MIN_1):
        """
        Set up the backtest variables according to what has been passed in.
        """
        super().__init__()
        self.logger = qf_logger.getChild(self.__class__.__name__)

        self.logger.info(
            "\n".join([
                "Testing the Backtester:",
                "Start date: {:s}".format(date_to_str(start_date)),
                "End date: {:s}".format(date_to_str(end_date)),
                "Initial cash: {:.2f}".format(initial_cash),
                "Frequency of the simulated execution handler: {}".format(frequency)
            ])
        )

        timer = SettableTimer(start_date)
        notifiers = Notifiers(timer)
        if frequency <= Frequency.DAILY:
            data_handler = DailyDataHandler(data_provider, timer)
        else:
            data_handler = IntradayDataHandler(data_provider, timer)

        contract_ticker_mapper = SimulatedBloombergContractTickerMapper()
        portfolio = Portfolio(data_handler, initial_cash, timer, contract_ticker_mapper)
        signals_register = BacktestSignalsRegister()
        backtest_result = BacktestResult(portfolio=portfolio, backtest_name="Testing the Backtester",
                                         start_date=start_date, end_date=end_date, signals_register=signals_register)

        monitor = Mock(spec=BacktestMonitor)
        commission_model = FixedCommissionModel(0.0)
        slippage_model = PriceBasedSlippage(0.0, data_provider, contract_ticker_mapper)

        execution_handler = SimulatedExecutionHandler(
            data_handler, timer, notifiers.scheduler, monitor, commission_model,
            contract_ticker_mapper, portfolio, slippage_model)

        broker = BacktestBroker(portfolio, execution_handler)
        order_factory = OrderFactory(broker, data_handler, contract_ticker_mapper)

        event_manager = self._create_event_manager(timer, notifiers)
        time_flow_controller = BacktestTimeFlowController(
            notifiers.scheduler, event_manager, timer, notifiers.empty_queue_event_notifier, end_date
        )
        position_sizer = SimplePositionSizer(broker, data_handler, order_factory, contract_ticker_mapper,
                                             signals_register)

        self.logger.info(
            "\n".join([
                "Configuration of components:",
                "Position sizer: {:s}".format(position_sizer.__class__.__name__),
                "Timer: {:s}".format(timer.__class__.__name__),
                "Data Provider: {:s}".format(data_provider.__class__.__name__),
                "Backtest Result: {:s}".format(backtest_result.__class__.__name__),
                "Monitor: {:s}".format(monitor.__class__.__name__),
                "Execution Handler: {:s}".format(execution_handler.__class__.__name__),
                "Commission Model: {:s}".format(commission_model.__class__.__name__),
                "Broker: {:s}".format(broker.__class__.__name__),
                "Contract-Ticker Mapper: {:s}".format(contract_ticker_mapper.__class__.__name__)
            ])
        )

        self.broker = broker
        self.notifiers = notifiers
        self.initial_cash = initial_cash
        self.start_date = start_date
        self.end_date = end_date
        self.event_manager = event_manager
        self.contract_ticker_mapper = contract_ticker_mapper
        self.data_handler = data_handler
        self.portfolio = portfolio
        self.execution_handler = execution_handler
        self.position_sizer = position_sizer
        self.orders_filters = []
        self.monitor = monitor
        self.timer = timer
        self.order_factory = order_factory
        self.time_flow_controller = time_flow_controller