Пример #1
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
Пример #2
0
    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
Пример #4
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
Пример #6
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)
Пример #7
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
Пример #8
0
    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})
Пример #9
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
Пример #10
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)
Пример #11
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))
    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)
Пример #13
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
Пример #14
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()
        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, timer, self.scheduler, self.spied_monitor,
            self.commission_model, self.contracts_to_tickers_mapper,
            self.portfolio, slippage_model)

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

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

        self.exec_hanlder.accept_orders([
            self.stop_loss_order_1, self.stop_loss_order_2,
            self.stop_loss_order_3
        ])
Пример #15
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)
Пример #16
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])
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}")
Пример #18
0
    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
Пример #19
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
        })
Пример #20
0
    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
        })
Пример #21
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))
    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
Пример #23
0
def future_ticker_example(path_to_data_files: str):
    """
    In order to run the example you need to provide the path to the top directory, containing your data files. The
    example below will:

    1. initialize the Silver FutureTicker
    2. return the list of tickers belonging to the futures chain
    3. return the current specific ticker
    4. check for some tickers, if they belong to the Silver futures family
    5. return Open, High, Low, Close and Volume pricing data for the current specific ticker

    Parameters
    -----------
    path_to_data_files: str
        path to the top directory, which contains all your Portara data files
    """

    start_date = str_to_date('2020-12-02')
    end_date = str_to_date('2021-02-01')
    fields = PriceField.ohlcv()
    # Use the front contract (N = 1)
    # Roll the tickers 1 day before the expiration (days_before_exp_date = 1)
    # Set the point value to 50 (value for each of the contracts can be checked in Portara)
    future_ticker = PortaraFutureTicker('Silver',
                                        'SIA{}',
                                        1,
                                        1,
                                        50,
                                        designated_contracts="HKNUZ")
    daily_freq = Frequency.DAILY

    if path_to_data_files is None:
        raise ValueError(
            "Please provide a correct path to the Portara data and assign it to the "
            "path_to_data_files variable.")

    dp = PortaraDataProvider(path_to_data_files, future_ticker, fields,
                             start_date, end_date, daily_freq)

    # Initialize the future ticker with the data provider and timer. Timer is used to identify the current front ticker.
    timer = SettableTimer()
    future_ticker.initialize_data_provider(timer, dp)

    print(
        '\nCurrent individual contract (front contract) as of 10th December 2020:'
    )
    timer.set_current_time(str_to_date('2020-12-10'))
    current_ticker = future_ticker.get_current_specific_ticker()
    print(f'> {current_ticker}')

    print(
        '\nCurrent individual contract (front contract) as of 10th January 2021:'
    )
    timer.set_current_time(str_to_date('2021-01-10'))
    current_ticker = future_ticker.get_current_specific_ticker()
    print(f'> {current_ticker}')

    print(
        '\nCheck if the following tickers belong to the Silver futures chain:')
    ticker = PortaraTicker('SIA2017H', SecurityType.FUTURE, 50)
    print(f'- {ticker}: {future_ticker.belongs_to_family(ticker)}')
    ticker = PortaraTicker('OH2017H', SecurityType.FUTURE, 50)
    print(f'- {ticker}: {future_ticker.belongs_to_family(ticker)}')
    ticker = PortaraTicker('SIA2017', SecurityType.FUTURE, 50)
    print(f'- {ticker}: {future_ticker.belongs_to_family(ticker)}')
    ticker = PortaraTicker('SIA1999Z', SecurityType.FUTURE, 50)
    print(f'- {ticker}: {future_ticker.belongs_to_family(ticker)}')

    print(
        '\nOpen, High, Low, Close and Volume pricing data for the current specific ticker (as of 10th January 2021)'
    )
    prices = dp.get_price(current_ticker, PriceField.ohlcv(), start_date,
                          end_date, daily_freq)
    print(prices)
    def setUp(self) -> None:
        self.contract_ticker_mapper = SimulatedBloombergContractTickerMapper()
        self.current_date = str_to_date("2017-01-01")

        self.timer = SettableTimer(self.current_date)
    def build(self, start_date: datetime,
              end_date: datetime) -> BacktestTradingSession:
        """Builds a backtest trading session.

        Parameters
        -----------
        start_date: datetime
            starting date of the backtest
        end_date: datetime
            last date of the backtest

        Returns
        ---------
        BacktestTradingSession
            trading session containing all the necessary parameters
        """
        self._timer = SettableTimer(start_date)
        self._notifiers = Notifiers(self._timer)
        self._events_manager = self._create_event_manager(
            self._timer, self._notifiers)

        self._data_handler = self._create_data_handler(self._data_provider,
                                                       self._timer)
        signals_register = self._signals_register if self._signals_register else BacktestSignalsRegister(
        )

        self._portfolio = Portfolio(self._data_handler, self._initial_cash,
                                    self._timer, self._contract_ticker_mapper)

        self._backtest_result = BacktestResult(self._portfolio,
                                               signals_register,
                                               self._backtest_name, start_date,
                                               end_date, self._initial_risk)
        self._monitor = self._monitor_setup()

        self._slippage_model = self._slippage_model_setup()
        self._commission_model = self._commission_model_setup()
        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,
            scheduling_time_delay=self._scheduling_time_delay,
            frequency=self._frequency)

        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(signals_register)
        self._orders_filters = self._orders_filter_setup()

        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,
            orders_filters=self._orders_filters,
            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,
            frequency=self._frequency,
            backtest_result=self._backtest_result)

        return ts
 def setUp(self) -> None:
     self.current_date = str_to_date("2017-01-01")
     self.timer = SettableTimer(self.current_date)
Пример #27
0
 def setUp(self):
     self.timer = SettableTimer()
Пример #28
0
    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])
Пример #29
0
 def setUp(self):
     self.timer = SettableTimer()
     self.scheduler = Scheduler(self.timer)
Пример #30
0
    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