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__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 self.future_ticker.get_current_specific_ticker.return_value = BloombergTicker("ExampleN01 Comdty") futures_alpha_model_strategy = AlphaModelStrategy(self.ts, {self.alpha_model: [self.future_ticker]}, use_stop_losses=False) 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") })] futures_alpha_model_strategy.on_before_market_open() self.alpha_model.get_signal.assert_called_once_with(self.future_ticker, Exposure.LONG) 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") }), Mock(spec=BacktestPosition, **{ 'contract.return_value': Contract("ExampleZ00 Comdty", "FUT", "SIM_EXCHANGE"), 'quantity.return_value': 20, 'start_time': str_to_date("2000-01-02") })] self.assertRaises(AssertionError, futures_alpha_model_strategy.on_before_market_open)
def test__adjust_number_of_open_positions_4(self): """ Test description: - max number of positions is 1 - portfolio contains position with contract ExampleZ00 Comdty - there is signal for ExampleZ00 Comdty with suggested exposure OUT and for Example Ticker - LONG - Expected output: Example Ticker will be changed to OUT """ self.future_ticker.get_current_specific_ticker.return_value = BloombergTicker("AN01 Index") alpha_model_strategy = AlphaModelStrategy(self.ts, {self.alpha_model: [BloombergTicker("ExampleZ00 Comdty"), BloombergTicker("Example Ticker")]}, use_stop_losses=False, max_open_positions=1) exposures = { BloombergTicker("ExampleZ00 Comdty"): Exposure.OUT, BloombergTicker("Example Ticker"): Exposure.LONG, } self.alpha_model.get_signal.side_effect = lambda ticker, _: Signal(ticker, exposures[ticker], 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(BloombergTicker("ExampleZ00 Comdty"), Exposure.OUT, 1), Signal(BloombergTicker("Example Ticker"), Exposure.OUT, 1)] self.assertCountEqual(signals, expected_signals)
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.get_current_specific_ticker.return_value = 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) 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(self.future_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.on_before_market_open() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.OUT) # Open long position in the portfolio self.positions_in_portfolio = [Mock(spec=BacktestPosition, **{ 'contract.return_value': Contract("Example Ticker", "STK", "SIM_EXCHANGE"), 'quantity.return_value': 10, 'start_time': str_to_date("2000-01-01") })] alpha_model_strategy.on_before_market_open() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.LONG) # Open short position in the portfolio self.positions_in_portfolio = [Mock(spec=BacktestPosition, **{ 'contract.return_value': Contract("Example Ticker", "STK", "SIM_EXCHANGE"), 'quantity.return_value': -10, 'start_time': str_to_date("2000-01-01") })] alpha_model_strategy.on_before_market_open() self.alpha_model.get_signal.assert_called_with(self.ticker, Exposure.SHORT) # Verify if in case of two positions for the same contract an exception will be raised by the strategy self.positions_in_portfolio = [BacktestPositionFactory.create_position(c) for c in ( Contract("Example Ticker", "STK", "SIM_EXCHANGE"), Contract("Example Ticker", "STK", "SIM_EXCHANGE"))] self.assertRaises(AssertionError, alpha_model_strategy.on_before_market_open)
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()
def run_strategy(data_provider: DataProvider) -> Tuple[float, str]: """ Returns the strategy end result and checksum of the preloaded data. """ model_tickers = [BloombergFutureTicker("Corn", "C {} Comdty", 1, 10, 1)] start_date = str_to_date('2003-05-30') end_date = str_to_date('2009-01-01') initial_risk = 0.006 # ----- build trading session ----- # session_builder = container.resolve(BacktestTradingSessionBuilder) # type: BacktestTradingSessionBuilder session_builder.set_backtest_name('Simple Futures Strategy') session_builder.set_position_sizer(InitialRiskPositionSizer, initial_risk=initial_risk) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(data_provider) session_builder.set_monitor_settings(BacktestMonitorSettings.no_stats()) ts = session_builder.build(start_date, end_date) # ----- build models ----- # model = SimpleFuturesModel(fast_time_period=50, slow_time_period=100, risk_estimation_factor=3, data_handler=ts.data_handler) model_tickers_dict = {model: model_tickers} # ----- start trading ----- # AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=False) ts.use_data_preloading(model_tickers) print(ts.get_preloaded_data_checksum()) ts.start_trading() data_checksum = ts.get_preloaded_data_checksum() actual_end_value = ts.portfolio.portfolio_eod_series()[-1] return actual_end_value, data_checksum
def main(): initial_risk = 0.03 start_date = str_to_date('2016-01-01') end_date = str_to_date('2017-12-31') # ----- build trading session ----- # session_builder = container.resolve(BacktestTradingSessionBuilder) # type: BacktestTradingSessionBuilder session_builder.set_backtest_name('Moving Average Alpha Model Backtest') session_builder.set_position_sizer(InitialRiskPositionSizer, initial_risk=initial_risk) session_builder.set_contract_ticker_mapper(DummyQuandlContractTickerMapper()) session_builder.set_commission_model(IBCommissionModel) session_builder.set_frequency(Frequency.DAILY) ts = session_builder.build(start_date, end_date) # ----- build models ----- # model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_handler=ts.data_handler) model_tickers = [QuandlTicker('AAPL', 'WIKI'), QuandlTicker('AMZN', 'WIKI')] model_tickers_dict = {model: model_tickers} # ----- preload price data ----- # ts.use_data_preloading(model_tickers) # ----- start trading ----- # AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=True) ts.start_trading() # ----- use results ----- # backtest_tms = ts.portfolio.portfolio_eod_series().to_log_returns() print("mean daily log return: {}".format(backtest_tms.mean())) print("std of daily log returns: {}".format(backtest_tms.std()))
def main(): initial_risk = 0.03 start_date = str_to_date('2010-01-01') end_date = str_to_date('2011-12-31') # Use the preset daily data provider data_provider = daily_data_provider # ----- build trading session ----- # session_builder = container.resolve(BacktestTradingSessionBuilder) # type: BacktestTradingSessionBuilder session_builder.set_backtest_name('Moving Average Alpha Model Backtest') session_builder.set_position_sizer(InitialRiskPositionSizer, initial_risk=initial_risk) session_builder.set_contract_ticker_mapper(DummyTickerMapper()) session_builder.set_commission_model(IBCommissionModel) session_builder.set_data_provider(data_provider) session_builder.set_frequency(Frequency.DAILY) ts = session_builder.build(start_date, end_date) # ----- build models ----- # model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_handler=ts.data_handler) model_tickers = [DummyTicker('AAA'), DummyTicker('BBB'), DummyTicker('CCC'), DummyTicker('DDD'), DummyTicker('EEE'), DummyTicker('FFF')] model_tickers_dict = {model: model_tickers} # ----- preload price data ----- # ts.use_data_preloading(model_tickers) # Verify the checksum of preloaded data with the precomputed value ts.verify_preloaded_data("e73eed1f125ff6afa2cdc95957a703a999f41d34") # ----- start trading ----- # AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=True) ts.start_trading()
def test__get_current_exposure__future_ticker(self): """ Test the result of _get_current_exposure function for a future ticker in case of an empty portfolio and in case if a position for the given specific ticker exists. """ expected_current_exposure_values = [] # Set current specific ticker to ExampleZ00 Comdty and open position in the portfolio for the current ticker self.future_ticker.get_current_specific_ticker.return_value = BloombergTicker("ExampleZ00 Comdty") futures_alpha_model_strategy = AlphaModelStrategy(self.ts, {self.alpha_model: [self.future_ticker]}, use_stop_losses=False) # In case of empty portfolio get_signal function should have current exposure set to OUT futures_alpha_model_strategy.on_before_market_open() expected_current_exposure_values.append(Exposure.OUT) self.alpha_model.get_signal.assert_called_with(self.future_ticker, Exposure.OUT) 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") })] futures_alpha_model_strategy.on_before_market_open() self.alpha_model.get_signal.assert_called_with(self.future_ticker, Exposure.LONG) self.positions_in_portfolio = [BacktestPositionFactory.create_position(c) for c in ( Contract("ExampleZ00 Comdty", "STK", "SIM_EXCHANGE"), Contract("ExampleZ00 Comdty", "STK", "SIM_EXCHANGE"))] self.assertRaises(AssertionError, futures_alpha_model_strategy.on_before_market_open)
def test_limiting_open_positions_2_position(self): max_open_positions = 2 AlphaModelStrategy(self.ts, self.model_tickers_dict, use_stop_losses=False, max_open_positions=max_open_positions) self.ts.start_trading() number_of_assets = self._get_assets_number_series(self.ts.portfolio) number_of_assets_exceeded_the_limit = number_of_assets.where( number_of_assets > max_open_positions).any() self.assertFalse(number_of_assets_exceeded_the_limit)
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 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.end_date) risk_estimation_factor = 0.05 self.alpha_model = DummyAlphaModel(risk_estimation_factor) self.ts = self._test_trading_session_init() model_tickers_dict = {self.alpha_model: self.tickers} AlphaModelStrategy(self.ts, model_tickers_dict, use_stop_losses=True) self.ts.start_trading()
def main(): model_type = MovingAverageAlphaModel initial_risk = 0.03 commission_model = IBCommissionModel() start_date = str_to_date('2016-01-01') end_date = str_to_date('2017-12-31') # ----- build trading session ----- # session_builder = container.resolve( BacktestTradingSessionBuilder) # type: BacktestTradingSessionBuilder session_builder.set_backtest_name('Moving Average Alpha Model Backtest') session_builder.set_position_sizer(InitialRiskPositionSizer, initial_risk) session_builder.set_contract_ticker_mapper( DummyQuandlContractTickerMapper()) session_builder.set_commission_model(commission_model) session_builder.set_monitor_type(BacktestMonitor) ts = session_builder.build(start_date, end_date) # ----- build models ----- # model_factory = AlphaModelFactory(ts.data_handler) model = model_factory.make_parametrized_model(model_type) model_tickers = [ QuandlTicker('AAPL', 'WIKI'), QuandlTicker('AMZN', 'WIKI') ] model_tickers_dict = {model: model_tickers} # ----- preload price data ----- # all_tickers_used = get_all_tickers_used(model_tickers_dict) ts.use_data_preloading(all_tickers_used) # ----- start trading ----- # AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=True) ts.start_trading() # ----- use results ----- # backtest_tms = ts.portfolio.get_portfolio_timeseries().to_log_returns() print("mean daily log return: {}".format(backtest_tms.mean())) print("std of daily log returns: {}".format(backtest_tms.std()))
def get_trade_rets_values(init_risk: float, alpha_model_type: Type[AlphaModel]) -> List[float]: start_date = str_to_date('2013-01-01') end_date = str_to_date('2016-12-31') session_builder = container.resolve(BacktestTradingSessionBuilder) # type: BacktestTradingSessionBuilder session_builder.set_position_sizer(InitialRiskPositionSizer, init_risk) session_builder.set_monitor_type(BacktestMonitor) session_builder.set_backtest_name("Initial Risk Testing - {}".format(init_risk)) ts = session_builder.build(start_date, end_date) model_factory = AlphaModelFactory(ts.data_handler) model = model_factory.make_parametrized_model(alpha_model_type) model_tickers_dict = {model: [BloombergTicker('SVXY US Equity')]} AlphaModelStrategy(ts, model_tickers_dict, use_stop_losses=True) ts.use_data_preloading(get_all_tickers_used(model_tickers_dict)) ts.start_trading() trades = ts.portfolio.get_trades() returns_of_trades = [(t.exit_price / t.entry_price - 1) * np.sign(t.quantity) for t in trades] return returns_of_trades
def _set_up_trading_strategy(self, model_type_tickers_dict): # the settings below should match exactly the setting of the live trading observed session_builder = self.container.resolve(BacktestTradingSessionBuilder) session_builder.set_position_sizer(InitialRiskPositionSizer, self.initial_risk) session_builder.set_monitor_type(DummyMonitor) backtest_ts = session_builder.build(self.live_start_date, self.end_date) all_tickers = get_all_tickers_used(self.model_type_tickers_dict) backtest_ts.use_data_preloading(all_tickers) self.backtest_ts = backtest_ts model_factory = AlphaModelFactory(backtest_ts.data_handler) model_tickers_dict = {} for model_type, tickers in model_type_tickers_dict.items(): model = model_factory.make_parametrized_model(model_type) model_tickers_dict[model] = tickers strategy = AlphaModelStrategy(self.backtest_ts, model_tickers_dict) return strategy