def test__adjust_number_of_open_positions_2(self, generate_close_orders): """ Test description: - max number of positions is 1 - portfolio contains position with contract ExampleZ00 Comdty - there is a signal with suggested exposure LONG for ExampleN01 Comdty - Expected output: ExampleN01 Comdty suggested exposure will be unchanged """ self.future_ticker.ticker = BloombergTicker("ExampleN01 Comdty") alpha_model_strategy = AlphaModelStrategy( self.ts, {self.alpha_model: [self.future_ticker]}, use_stop_losses=False, max_open_positions=1) self.alpha_model.get_signal.return_value = Signal( self.future_ticker, Exposure.LONG, 1, Mock(), Mock()) self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("ExampleZ00 Comdty", SecurityType.FUTURE, 1), 'quantity.return_value': -10, 'start_time': str_to_date("2000-01-01") }) ] alpha_model_strategy.calculate_and_place_orders() self.ts.position_sizer.size_signals.assert_called_with( [Signal(self.future_ticker, Exposure.LONG, 1, Mock(), Mock())], False, TimeInForce.OPG, Frequency.DAILY)
def setUp(self): self.msft_ticker = BloombergTicker("MSFT US Equity") self.google_ticker = BloombergTicker("GOOGL US Equity") self.apple_ticker = BloombergTicker("AAPL US Equity") self.start_date = datetime(2018, 2, 4) self.end_date = datetime(2018, 2, 10) self.frequency = Frequency.DAILY self.cached_tickers = [self.msft_ticker, self.google_ticker] self.cached_fields = [ PriceField.Open, PriceField.Close, PriceField.Volume ] self.cached_dates_idx = pd.date_range(self.start_date, self.end_date, name=DATES) self.cached_tickers_idx = pd.Index( [self.msft_ticker, self.google_ticker], name=TICKERS) self.cached_fields_idx = pd.Index( [PriceField.Open, PriceField.Close, PriceField.Volume], name=FIELDS) self.data_provider = self.mock_data_provider() self.prefetching_data_provider = PrefetchingDataProvider( self.data_provider, self.cached_tickers, self.cached_fields, self.start_date, self.end_date, self.frequency)
def test_get_ticker_1st_contract_6_days_before_exp_date(self): exp_dates_to_ticker_str = { str_to_date("2016-12-16"): BloombergTicker('ESZ16 Index'), str_to_date("2017-03-17"): BloombergTicker('ESH17 Index') } future_ticker = BloombergFutureTicker("Euroswiss", "ES{} Index", 1, 6, 100, "HMUZ") future_ticker.initialize_data_provider(self.timer, self.data_provider) # Check dates before 2016-12-16 self.timer.set_current_time(str_to_date('2016-11-11')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-12-16")]) self.timer.set_current_time(str_to_date('2016-12-10')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-12-16")]) self.timer.set_current_time( str_to_date('2016-12-10 23:55:00.0', DateFormat.FULL_ISO)) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-12-16")]) self.timer.set_current_time(str_to_date('2016-12-16')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2017-03-17")])
def setUp(self): msft_ticker = BloombergTicker("MSFT US Equity") aapl_ticker = BloombergTicker("AAPL US Equity") googl_ticker = BloombergTicker("GOOGL US Equity") self.tickers = [msft_ticker, aapl_ticker, googl_ticker] self.data_provider = self._create_data_provider_mock() self.orders = [ Order( ticker=msft_ticker, quantity=1250, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC ), Order( ticker=aapl_ticker, quantity=-200, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC ), Order( ticker=googl_ticker, quantity=1, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC ) ] self.market_on_close_order = [Order( ticker=msft_ticker, quantity=1250, execution_style=MarketOnCloseOrder(), time_in_force=TimeInForce.GTC )]
def test__adjust_number_of_open_positions__multiple_models_3(self, generate_close_orders): """ Test description: - max number of positions is 1 - portfolio contains position with contract ExampleZ00 Comdty - ExampleZ00 Comdty ane Example Ticker are traded by two independent alpha models - there is signal with suggested exposure LONG for Example Ticker and OUT for ExampleN00 Comdty - Expected output: Example Ticker suggested exposure will be changed to OUT """ self.future_ticker.get_current_specific_ticker.return_value = BloombergTicker("ExampleN00 Comdty") alpha_model_2 = MagicMock() alpha_model_strategy = AlphaModelStrategy(self.ts, { self.alpha_model: [self.future_ticker], alpha_model_2: [BloombergTicker("Example Ticker")] }, use_stop_losses=False, max_open_positions=1) self.alpha_model.get_signal.return_value = Signal(self.future_ticker, Exposure.OUT, 1) alpha_model_2.get_signal.return_value = Signal(BloombergTicker("Example Ticker"), Exposure.LONG, 1) self.positions_in_portfolio = [Mock(spec=BacktestPosition, **{ 'contract.return_value': Contract("ExampleZ00 Comdty", "FUT", "SIM_EXCHANGE"), 'quantity.return_value': -10, 'start_time': str_to_date("2000-01-01") })] alpha_model_strategy.on_before_market_open() self.ts.position_sizer.size_signals.assert_called_once() args, kwargs = self.ts.position_sizer.size_signals.call_args_list[0] signals, _ = args expected_signals = [Signal(self.future_ticker, Exposure.OUT, 1), Signal(BloombergTicker("Example Ticker"), Exposure.OUT, 1)] self.assertCountEqual(signals, expected_signals)
def test_tickers_dict_to_data_array(self): ticker_1 = BloombergTicker("Example 1") ticker_2 = BloombergTicker("Example 2") fields = [PriceField.Open, PriceField.Close] index = self.index[:3] data = [[[4., 1.], [nan, 5.]], [[5., 2.], [nan, 7.]], [[6., 3.], [nan, 8.]]] prices_df_1 = QFDataFrame(data={ PriceField.Close: [1., 2., 3.], PriceField.Open: [4., 5., 6.] }, index=index) prices_df_2 = QFDataFrame(data={PriceField.Close: [5., 7., 8.]}, index=index) data_array = tickers_dict_to_data_array( { ticker_1: prices_df_1, ticker_2: prices_df_2 }, [ticker_1, ticker_2], fields) self.assertEqual(dtype("float64"), data_array.dtype) expected_data_array = QFDataArray.create(index, [ticker_1, ticker_2], fields, data) assert_equal(data_array, expected_data_array)
def test_generate_close_orders__multiple_orders_close(self, future_ticker, order_factory, broker): """ There exist positions open in the portfolio for tickers, which belong to the same family as the future_ticker. Test if the order factory will be called with the necessary function and parameters to close the existing positions and if any errors have been logged (as the expiration dates did not occur, no logs should be generated). """ # Make the broker return positions with contracts_in_portfolio from the get_positions function tickers_in_portfolio = [BloombergTicker("CLG00 Comdty", SecurityType.FUTURE, 1), BloombergTicker("CLN00 Comdty", SecurityType.FUTURE, 1)] broker.get_positions.side_effect = lambda: [BacktestPositionFactory.create_position(t) for t in tickers_in_portfolio] # Set current ticker to be different then any ticker from expired_contracts future_ticker.get_current_specific_ticker.return_value = BloombergTicker("CLG01 Comdty", SecurityType.FUTURE, 1) future_ticker.get_expiration_dates.return_value = QFSeries(data=tickers_in_portfolio, index=[self.current_date - RelativeDelta(days=10), self.current_date + RelativeDelta(days=5)]) rolling_orders_generator = FuturesRollingOrdersGenerator([future_ticker], self.timer, broker, order_factory) rolling_orders_generator.logger = MagicMock() rolling_orders_generator.generate_close_orders() # The order factory should be called exactly once and in should contain all contracts from # contracts_in_portfolio order_factory.target_percent_orders.assert_called_once_with( {c: 0 for c in tickers_in_portfolio}, MarketOrder(), TimeInForce.GTC ) # The logger error function should be called only once, as only expiration date of one of the contracts in the # portfolio already passed rolling_orders_generator.logger.error.assert_called_once()
def test_compute_container_hash__data_array(self): ticker_1 = BloombergTicker("Example 1") ticker_2 = BloombergTicker("Example 2") prices_df_1 = QFDataFrame(data={ PriceField.Close: [1, 2, 3], PriceField.Open: [4, 5, 6] }) prices_df_2 = QFDataFrame(data={PriceField.Close: [5, 7, 8]}) data_array_1 = tickers_dict_to_data_array( { ticker_1: prices_df_1, ticker_2: prices_df_2 }, [ticker_1, ticker_2], [PriceField.Open, PriceField.Close]) data_array_2 = tickers_dict_to_data_array( { ticker_1: prices_df_1, ticker_2: prices_df_2, }, [ticker_1, ticker_2], [PriceField.Open, PriceField.Close]) data_array_3 = tickers_dict_to_data_array( { ticker_2: prices_df_2, ticker_1: prices_df_1, }, [ticker_1, ticker_2], [PriceField.Open, PriceField.Close]) self.assertEqual(compute_container_hash(data_array_1), compute_container_hash(data_array_2)) self.assertNotEqual(compute_container_hash(data_array_1), compute_container_hash(data_array_3))
def test_generate_close_orders__current_ticker_in_portfolio(self, future_ticker, order_factory, broker): """ There exist positions open in the portfolio for tickers, which belong to the same family as the future_ticker and for the current ticker. Test if only the expired contracts will be closed. """ expired_contract = BloombergTicker("CLG00 Comdty", SecurityType.FUTURE, 1) # Set current ticker to be different then ticker corresponding to expired_contract current_contract = BloombergTicker("CLG01 Comdty", SecurityType.FUTURE, 1) future_ticker.get_current_specific_ticker.return_value = current_contract tickers_in_portfolio = [expired_contract, current_contract] broker.get_positions.side_effect = lambda: [BacktestPositionFactory.create_position(c) for c in tickers_in_portfolio] future_ticker.get_expiration_dates.return_value = QFSeries(data=tickers_in_portfolio, index=[self.current_date + RelativeDelta(days=1), self.current_date + RelativeDelta(days=5)]) rolling_orders_generator = FuturesRollingOrdersGenerator([future_ticker], self.timer, broker, order_factory) rolling_orders_generator.logger = MagicMock() rolling_orders_generator.generate_close_orders() # The order factory should be called exactly once and in should contain all contracts from # contracts_in_portfolio order_factory.target_percent_orders.assert_called_once_with( {expired_contract: 0}, MarketOrder(), TimeInForce.GTC ) # The logger error function should not have been called rolling_orders_generator.logger.error.assert_not_called()
def test_data_arrays_concat_on_tickers(self): ticker_1 = BloombergTicker("Example 1") ticker_2 = BloombergTicker("Example 2") fields = [PriceField.Open, PriceField.Close] index = date_range(start=str_to_date("2017-01-01"), periods=5, freq="D") index_1 = index[:3] data_1 = [[[4., 1.]], [[5., 2.]], [[6., 3.]]] data_array_1 = QFDataArray.create(index_1, [ticker_1], fields, data_1) self.assertEqual(np.dtype("float64"), data_array_1.dtype) index_2 = index[3:] data_2 = [[[np.nan, 10.]], [[np.nan, 14.]]] data_array_2 = QFDataArray.create(index_2, [ticker_2], fields, data_2) self.assertEqual(np.dtype("float64"), data_array_2.dtype) data = [[[4., 1.], [np.nan, np.nan]], [[5., 2.], [np.nan, np.nan]], [[6., 3.], [np.nan, np.nan]], [[np.nan, np.nan], [np.nan, 10.]], [[np.nan, np.nan], [np.nan, 14.]]] expected_data_array = QFDataArray.create(index, [ticker_1, ticker_2], fields, data) self.assertEqual(np.dtype("float64"), expected_data_array.dtype) concatenated_data_array = QFDataArray.concat( [data_array_1, data_array_2], dim=TICKERS) self.assertEqual(np.dtype("float64"), concatenated_data_array.dtype) assert_equal(expected_data_array, concatenated_data_array)
def test_future_ticker_to_contract_mapping(self): """ Test mapping of future tickers onto IB contracts. """ mapping = { BloombergFutureTicker('Copper', 'HG{} Comdty', 1, 1, 250): IBContract("HG", SecurityType.FUTURE, "NYMEX", "25000", "USD"), } contract_ticker_mapper = IBContractTickerMapper( mapping, self.data_provider) # Map a specific ticker to contract ticker = BloombergTicker("HGH20 Comdty", SecurityType.FUTURE, 250) actual_contract = contract_ticker_mapper.ticker_to_contract(ticker) expected_contract = IBContract("HG", SecurityType.FUTURE, "NYMEX", "25000", "USD", str_to_date("2020-03-20")) self.assertEqual(actual_contract, expected_contract) # Map a future ticker to contract future_ticker = Mock(spec=BloombergFutureTicker) future_ticker.get_current_specific_ticker.return_value = BloombergTicker( "HGN20 Comdty", SecurityType.FUTURE, 250) actual_contract = contract_ticker_mapper.ticker_to_contract( future_ticker) expected_contract = IBContract("HG", SecurityType.FUTURE, "NYMEX", "25000", "USD", str_to_date("2020-06-20")) self.assertEqual(actual_contract, expected_contract)
def test_get_ticker_2nd_contract_1_day_before_exp_date(self): exp_dates_to_ticker_str = { str_to_date("2016-06-30"): BloombergTicker('C N16 Comdty'), str_to_date("2016-08-31"): BloombergTicker('C U16 Comdty'), str_to_date("2016-11-30"): BloombergTicker('C Z16 Comdty') } future_ticker = BloombergFutureTicker("Corn", "C {} Comdty", 2, 1, 100, "HKNUZ") future_ticker.initialize_data_provider(self.timer, self.data_provider) self.timer.set_current_time(str_to_date('2016-06-03')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-08-31")]) self.timer.set_current_time(str_to_date('2016-06-29')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-08-31")]) self.timer.set_current_time( str_to_date('2016-06-29 23:59:59.0', DateFormat.FULL_ISO)) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-08-31")]) self.timer.set_current_time(str_to_date('2016-06-30')) self.assertEqual(future_ticker.get_current_specific_ticker(), exp_dates_to_ticker_str[str_to_date("2016-11-30")])
def setUp(self): msft_ticker = BloombergTicker("MSFT US Equity") aapl_ticker = BloombergTicker("AAPL US Equity") googl_ticker = BloombergTicker("GOOGL US Equity") self.tickers = [msft_ticker, aapl_ticker, googl_ticker] self.data_handler = self._create_data_handler_mock() self.contract_ticker_mapper = DummyBloombergContractTickerMapper() self.orders = [ Order(contract=self.contract_ticker_mapper.ticker_to_contract( msft_ticker), quantity=1000, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC), Order(contract=self.contract_ticker_mapper.ticker_to_contract( aapl_ticker), quantity=-10, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC), Order(contract=self.contract_ticker_mapper.ticker_to_contract( googl_ticker), quantity=1, execution_style=MarketOrder(), time_in_force=TimeInForce.GTC) ] self.prices_without_slippage = [1.0, 100.0, 1000.0]
def test__adjust_number_of_open_positions_1(self, generate_close_orders): """ Test description: - max number of positions is 1 - portfolio contains position with contract ExampleZ00 Comdty - there is signal with suggested exposure LONG for Example Ticker - Expected output: Example Ticker suggested exposure will be changed to OUT In order to test the number of positions adjustment functionality, the get_signal method of alpha model and size_signals method od position sizer are mocked and the flow of signals between them is verified. """ self.future_ticker.get_current_specific_ticker.return_value = BloombergTicker( "ExampleN01 Comdty") alpha_model_strategy = AlphaModelStrategy( self.ts, {self.alpha_model: [self.ticker]}, use_stop_losses=False, max_open_positions=1) self.alpha_model.get_signal.return_value = Signal( BloombergTicker("Example Ticker"), Exposure.LONG, 1) self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'contract.return_value': Contract("ExampleZ00 Comdty", "FUT", "SIM_EXCHANGE"), 'quantity.return_value': -10, 'start_time': str_to_date("2000-01-01") }) ] alpha_model_strategy.on_before_market_open() self.ts.position_sizer.size_signals.assert_called_with( [Signal(BloombergTicker("Example Ticker"), Exposure.LONG, 1)], False)
def test__get_current_exposure(self): """ Test the result of _get_current_exposure function for a non-future ticker by inspecting the parameters passed to alpha models get_signal function. """ alpha_model_strategy = AlphaModelStrategy( self.ts, {self.alpha_model: [self.ticker]}, use_stop_losses=False) # In case of empty portfolio get_signal function should have current exposure set to OUT alpha_model_strategy.calculate_and_place_orders() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.OUT, self.ts.timer.now(), Frequency.DAILY) # Open long position in the portfolio self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("Example Ticker", SecurityType.STOCK, 1), 'quantity.return_value': 10, 'start_time': str_to_date("2000-01-01") }) ] alpha_model_strategy.calculate_and_place_orders() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.LONG, self.ts.timer.now(), Frequency.DAILY) # Open short position in the portfolio self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("Example Ticker", SecurityType.STOCK, 1), 'quantity.return_value': -10, 'start_time': str_to_date("2000-01-01") }) ] alpha_model_strategy.calculate_and_place_orders() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.SHORT, self.ts.timer.now(), Frequency.DAILY) # Verify if in case of two positions for the same ticker an exception will be raised by the strategy self.positions_in_portfolio = [ BacktestPositionFactory.create_position(c) for c in (BloombergTicker("Example Ticker", SecurityType.STOCK, 1), BloombergTicker("Example Ticker", SecurityType.STOCK, 1)) ] self.assertRaises(AssertionError, alpha_model_strategy.calculate_and_place_orders)
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")
def test__get_current_exposure__future_ticker_rolling( self, generate_close_orders): """ Test the result of _get_current_exposure function for a future ticker in case if a position for an expired contract exists in portfolio and the rolling should be performed. """ # Set the future ticker to point to a new specific ticker, different from the one in the position from portfolio current_ticker = BloombergTicker("ExampleN01 Comdty", SecurityType.FUTURE, 1) self.future_ticker.get_current_specific_ticker.return_value = current_ticker futures_alpha_model_strategy = AlphaModelStrategy( self.ts, {self.alpha_model: [self.future_ticker]}, use_stop_losses=False) self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("ExampleZ00 Comdty", SecurityType.FUTURE, 1), 'quantity.return_value': 10, 'start_time': str_to_date("2000-01-01") }) ] futures_alpha_model_strategy.calculate_and_place_orders() self.alpha_model.get_signal.assert_called_once_with( self.future_ticker, Exposure.LONG, self.ts.timer.now(), Frequency.DAILY) self.positions_in_portfolio = [ Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("ExampleZ00 Comdty", SecurityType.FUTURE, 1), 'quantity.return_value': 10, 'start_time': str_to_date("2000-01-01") }), Mock(spec=BacktestPosition, **{ 'ticker.return_value': BloombergTicker("ExampleZ00 Comdty", SecurityType.FUTURE, 1), 'quantity.return_value': 20, 'start_time': str_to_date("2000-01-02") }) ] self.assertRaises( AssertionError, futures_alpha_model_strategy.calculate_and_place_orders)
def setUp(self): self.dates = pd.date_range(start='2018-02-04', periods=3) self.spx_ticker = BloombergTicker('SPX Index') self.spy_ticker = BloombergTicker('SPY US Equity') self.tickers = [self.spx_ticker, self.spy_ticker] self.fields = [PriceField.Open, PriceField.High, PriceField.Low, PriceField.Close] self.qf_data_array = self._get_sample_data_array(self.dates, self.tickers, self.fields) self.qf_data_array.loc[str_to_date('2018-02-04'), self.spy_ticker, PriceField.Open] = np.nan self.qf_data_array.loc[str_to_date('2018-02-06'), self.spy_ticker, :] = np.nan
def test_duplicate_stock_tickers(self): bbg_ib_symbols_mapping = { BloombergTicker("Example Index"): IBContract("EXAMPLE", SecurityType.STOCK, "EXAMPLE_EXCHANGE"), BloombergTicker("Example 2 Index"): IBContract("EXAMPLE", SecurityType.STOCK, "EXAMPLE_EXCHANGE"), } with self.assertRaises(Exception): IBContractTickerMapper(bbg_ib_symbols_mapping)
def _create_tickers_dict(): # growth -> inflatoin -> tickers tickers_dict = { ChangeDirection.RISING: { ChangeDirection.RISING: [ BloombergTicker("SPGSCITR Index"), # Commodities (S&P GSCI Total Return CME) BloombergTicker("MSBIERTR Index"), # EM Debt (Morningstar Emerging Markets Corporate Bond Index TR) BloombergTicker("XAU Curncy") # Gold (XAUUSD Spot Exchange Rate - Price of 1 XAU in USD) ], ChangeDirection.FALLING: [ BloombergTicker("MXUS Index"), # Equity USA (MSCI USA) BloombergTicker("LQD US Equity") # Credit (ISHARES IBOXX investment grade corporate bond etf) ] }, ChangeDirection.FALLING: { ChangeDirection.RISING: [ # ILB (Bloomberg Barclays US Inflation Linked Bonds 1 to 10 Year TR) BloombergTicker("BCIT3T Index"), # Gold (XAUUSD Spot Exchange Rate - Price of 1 XAU in USD) BloombergTicker("XAU Curncy") ], ChangeDirection.FALLING: [ BloombergTicker("IEF US Equity"), # Gov bonds (7-10y treasury) BloombergTicker("XAU Curncy") # Gold (XAUUSD Spot Exchange Rate - Price of 1 XAU in USD) ] } } return tickers_dict
def setUp(self) -> None: self.data_provider = Mock() self.data_provider.get_futures_chain_tickers.side_effect = lambda t, _: { t: QFSeries(index=[ BloombergTicker("HGH20 Comdty", SecurityType.FUTURE, 250), BloombergTicker("HGN20 Comdty", SecurityType.FUTURE, 250) ], data= [str_to_date("2020-03-20"), str_to_date("2020-06-20")]) }
def get_trade_rets_values(ts: BacktestTradingSession, model: AlphaModel) -> List[float]: model_tickers_dict = {model: [BloombergTicker('SVXY US Equity')]} AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=True) ts.use_data_preloading([BloombergTicker('SVXY US Equity')]) ts.start_trading() trades_generator = TradesGenerator() trades = trades_generator.create_trades_from_backtest_positions( ts.portfolio.closed_positions()) returns_of_trades = [t.pnl for t in trades] return returns_of_trades
def test_generate_close_orders__multiple_future_tickers(self, future_ticker, order_factory, broker): tickers_in_portfolio = [BloombergTicker("CLG00 Comdty", SecurityType.FUTURE, 1), BloombergTicker("CLG01 Comdty", SecurityType.FUTURE, 1)] tickers_in_portfolio_2 = [BloombergTicker("CTG00 Comdty", SecurityType.FUTURE, 1), BloombergTicker("CTG01 Comdty", SecurityType.FUTURE, 1)] broker.get_positions.side_effect = lambda: [BacktestPositionFactory.create_position(c) for c in tickers_in_portfolio + tickers_in_portfolio_2] # Generate the FuturesRollingOrdersGenerator for two different Future Tickers future_ticker.get_current_specific_ticker.return_value = BloombergTicker("CLG01 Comdty", SecurityType.FUTURE, 1) future_ticker.belongs_to_family.side_effect = lambda t: t in tickers_in_portfolio future_ticker.get_expiration_dates.return_value = QFSeries(data=tickers_in_portfolio, index=[self.current_date - RelativeDelta(days=10), self.current_date + RelativeDelta(days=5)]) future_ticker2 = MagicMock() future_ticker2.get_current_specific_ticker.return_value = BloombergTicker("CTG01 Comdty") future_ticker2.belongs_to_family.side_effect = lambda t: t in tickers_in_portfolio_2 future_ticker2.get_expiration_dates.return_value = QFSeries(data=tickers_in_portfolio_2, index=[self.current_date - RelativeDelta(days=10), self.current_date + RelativeDelta(days=5)]) rolling_orders_generator = FuturesRollingOrdersGenerator([future_ticker, future_ticker2], self.timer, broker, order_factory) rolling_orders_generator.logger = MagicMock() rolling_orders_generator.generate_close_orders() order_factory.target_percent_orders.assert_called_once_with( {BloombergTicker("CLG00 Comdty", SecurityType.FUTURE, 1): 0, BloombergTicker("CTG00 Comdty", SecurityType.FUTURE, 1): 0}, MarketOrder(), TimeInForce.GTC )
def setUpClass(cls): cls.tickers = [ BloombergTicker("MSFT US Equity"), BloombergTicker("AUDUSD Curncy"), BloombergFutureTicker("Heating Oil", "HO{} Comdty", 1, 1, 100), ] cls.prices_start_date = str_to_date("2020-01-02") cls.test_start_date = str_to_date("2020-01-03") cls.test_end_date = str_to_date("2020-01-09") cls.fields = [ PriceField.Open, PriceField.High, PriceField.Low, PriceField.Close ] cls.frequency = Frequency.DAILY
def test_ticker_to_futures_contract_mapping(self): """ Test contract to ticker mapping, in case of a futures contract when the mapping between a specific futures ticker and an IBContract was provided. """ mapping = { BloombergTicker("PAH20 Comdty", SecurityType.FUTURE, 100): IBContract("PA", SecurityType.FUTURE, "NYMEX", "100", "", str_to_date("2020-03-27")) } contract_ticker_mapper = IBContractTickerMapper(mapping) ticker = BloombergTicker("PAH20 Comdty", SecurityType.FUTURE, 100) actual_contract = contract_ticker_mapper.ticker_to_contract(ticker) expected_contract = IBContract("PA", SecurityType.FUTURE, "NYMEX", "100", "", str_to_date("2020-03-27")) self.assertEqual(expected_contract, actual_contract)
class BuyAndHoldStrategy: """ A testing strategy that simply purchases (longs) an asset as soon as it starts and then holds until the completion of a backtest. """ MICROSOFT_TICKER = BloombergTicker("MSFT US Equity") def __init__(self, broker: Broker, order_factory: OrderFactory, scheduler: Scheduler): self.order_factory = order_factory self.broker = broker self.invested = False scheduler.subscribe(BeforeMarketOpenEvent, listener=self) def on_before_market_open(self, _: BeforeMarketOpenEvent): self.calculate_signals() def calculate_signals(self): if not self.invested: orders = self.order_factory.percent_orders( {self.MICROSOFT_TICKER: 1.0}, MarketOrder(), TimeInForce.GTC) self.broker.place_orders(orders) self.invested = True
def _receive_reference_response(self, tickers, fields): response_events = get_response_events(self._session) tickers_fields_container = pd.DataFrame(index=tickers, columns=fields) for ev in response_events: check_event_for_errors(ev) security_data_array = extract_security_data(ev) check_security_data_for_errors(security_data_array) for i in range(security_data_array.numValues()): security_data = security_data_array.getValueAsElement(i) check_security_data_for_errors(security_data) security_name = security_data.getElementAsString(SECURITY) ticker = BloombergTicker.from_string(security_name) field_data_array = security_data.getElement(FIELD_DATA) for field_name in fields: try: value = field_data_array.getElementAsFloat(field_name) except blpapi.exception.InvalidConversionException: value = field_data_array.getElementAsString(field_name) except blpapi.exception.NotFoundException: value = np.nan tickers_fields_container.loc[ticker, field_name] = value return tickers_fields_container
def test_generate_close_orders__no_valid_ticker(self, future_ticker, order_factory, broker): """ There exist a position open in the portfolio for tickers, which belong to the same family as the future_ticker. Currently there is no valid ticker for the FutureTicker, which means the contract corresponding to the open position expired and the position should be closed. """ contract_in_portfolio = Contract("CLG00 Comdty", "FUT", "SIM_EXCHANGE") broker.get_positions.return_value = [ BacktestPositionFactory.create_position(contract_in_portfolio) ] # No valid ticker currently exists for the future ticker future_ticker.get_current_specific_ticker.side_effect = NoValidTickerException( ) future_ticker.belongs_to_family.return_value = True future_ticker.get_expiration_dates.return_value = QFSeries( data=[BloombergTicker("CLG00 Comdty")], index=[self.current_date - RelativeDelta(days=10)]) rolling_orders_generator = FuturesRollingOrdersGenerator( [future_ticker], self.timer, broker, order_factory, self.contract_ticker_mapper) rolling_orders_generator.generate_close_orders() # The order factory should be called exactly once and in should contain all contracts from # contracts_in_portfolio order_factory.target_percent_orders.assert_called_once_with( {contract_in_portfolio: 0}, MarketOrder(), TimeInForce.GTC)
def setUp(self): tickers = [BloombergTicker("AAPL US Equity")] all_fields = PriceField.ohlcv() self._mocked_prices_arr = self._make_mock_data_array( tickers, all_fields) self._price_provider_mock = PresetDataProvider(self._mocked_prices_arr, self.data_start_date, self.data_end_date, self.frequency) risk_estimation_factor = 0.05 data_handler = Mock() data_handler.get_last_available_price.return_value = None alpha_model = self.DummyAlphaModel(risk_estimation_factor, data_handler) ts = self._test_trading_session_init() # Mock the backtest result in order to be able to compare transactions self.transactions = [] ts.monitor.record_transaction.side_effect = lambda transaction: self.transactions.append( transaction) self.portfolio = ts.portfolio AlphaModelStrategy(ts, {alpha_model: tickers}, use_stop_losses=True) ts.start_trading()
class BuyAndHoldStrategy(object): """ A testing strategy that simply purchases (longs) an asset as soon as it starts and then holds until the completion of a backtest. """ CONTRACT = Contract(symbol="SPY US Equity", security_type='STK', exchange='NASDAQ') TICKER = BloombergTicker("SPY US Equity") def __init__(self, broker: Broker, order_factory: OrderFactory, scheduler: Scheduler): self.order_factory = order_factory self.broker = broker self.invested = False scheduler.subscribe(BeforeMarketOpenEvent, listener=self) def on_before_market_open(self, _: BeforeMarketOpenEvent): self.calculate_signals() def calculate_signals(self): if not self.invested: orders = self.order_factory.percent_orders({self.CONTRACT: 1.0}, MarketOrder(), TimeInForce.GTC) self.broker.place_orders(orders) self.invested = True