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
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 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)
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
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})
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
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 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)
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 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 ])
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)
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}")
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
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 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_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
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)
def setUp(self): self.timer = SettableTimer()
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 setUp(self): self.timer = SettableTimer() self.scheduler = Scheduler(self.timer)
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