def __init__(self, data_provider: GeneralPriceProvider, settings: Settings, pdf_exporter: PDFExporter, excel_exporter: ExcelExporter): self._logger = qf_logger.getChild(self.__class__.__name__) self._backtest_name = "Backtest Results" self._initial_cash = 10000000 self._initial_risk = None self._benchmark_tms = None self._monitor_settings = None self._contract_ticker_mapper = SimulatedBloombergContractTickerMapper() self._commission_model_type = FixedCommissionModel self._commission_model_kwargs = {"commission": 0.0} self._slippage_model_type = PriceBasedSlippage self._slippage_model_kwargs = { "slippage_rate": 0.0, "max_volume_share_limit": None } self._position_sizer_type = SimplePositionSizer self._position_sizer_kwargs = dict() self._orders_filter_types_params = [ ] # type: List[Tuple[Type[OrdersFilter], Dict]] self._signals_register = None self._data_provider = data_provider self._settings = settings self._pdf_exporter = pdf_exporter self._excel_exporter = excel_exporter self._frequency = None self._scheduling_time_delay = RelativeDelta(minutes=1) BeforeMarketOpenEvent.set_trigger_time({ "hour": 8, "minute": 0, "second": 0, "microsecond": 0 }) MarketOpenEvent.set_trigger_time({ "hour": 13, "minute": 30, "second": 0, "microsecond": 0 }) MarketCloseEvent.set_trigger_time({ "hour": 20, "minute": 0, "second": 0, "microsecond": 0 }) AfterMarketCloseEvent.set_trigger_time({ "hour": 23, "minute": 00, "second": 0, "microsecond": 0 })
def setUp(self): BeforeMarketOpenEvent.set_trigger_time({ "hour": 8, "minute": 0, "second": 0, "microsecond": 0 }) MarketOpenEvent.set_trigger_time({ "hour": 13, "minute": 30, "second": 0, "microsecond": 0 }) MarketCloseEvent.set_trigger_time({ "hour": 20, "minute": 0, "second": 0, "microsecond": 0 }) AfterMarketCloseEvent.set_trigger_time({ "hour": 21, "minute": 0, "second": 0, "microsecond": 0 })
def setUpClass(cls): cls.YESTERDAY_OPEN = str_to_date("2018-01-29 13:30:00.000000", DateFormat.FULL_ISO) cls.YESTERDAY_CLOSE = str_to_date("2018-01-29 20:00:00.000000", DateFormat.FULL_ISO) cls.TODAY_BEFORE_OPEN = str_to_date("2018-01-30 06:00:00.000000", DateFormat.FULL_ISO) cls.TODAY_OPEN = str_to_date("2018-01-30 13:30:00.000000", DateFormat.FULL_ISO) cls.TODAY_MIDDLE_DAY = str_to_date("2018-01-30 15:00:00.000000", DateFormat.FULL_ISO) cls.TODAY_CLOSE = str_to_date("2018-01-30 20:00:00.000000", DateFormat.FULL_ISO) cls.TODAY_AFTER_CLOSE = str_to_date("2018-01-30 20:00:00.000000", DateFormat.FULL_ISO) 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, self.tickers, self.data_handler = _get_test_case_set_up() 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, self.tickers, self.data_handler = _get_test_case_set_up() self.tickers_index = pd.Index(self.tickers, name='tickers') self.fields_index = pd.Index(PriceField.ohlcv(), name='fields') 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 __init__(self, tickers: Union[Ticker, Sequence[Ticker]], start_date: datetime, end_date: datetime, data_handler: DataHandler, alpha_models: Union[AlphaModel, Sequence[AlphaModel]], settings: Settings, pdf_exporter: PDFExporter, only_entry_signals: bool = True, title: str = "Signals Plotter"): super().__init__(settings, pdf_exporter, title) # Set the market open and close events in order to use the data handler (necessary to e.g. compute the market # close time of the previous day) 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.tickers, _ = convert_to_list(tickers, Ticker) self.alpha_models, _ = convert_to_list(alpha_models, AlphaModel) self.start_date = start_date self.end_date = end_date self.data_handler = data_handler assert isinstance(self.data_handler.timer, SettableTimer) self.timer: SettableTimer = self.data_handler.timer self.only_entry_signals = only_entry_signals for ticker in tickers: if isinstance(ticker, FutureTicker): ticker.initialize_data_provider( self.timer, self.data_handler.data_provider)
def test_get_price_aggregation_single_ticker(self): MarketOpenEvent.set_trigger_time({"hour": 17, "minute": 13, "second": 0, "microsecond": 0}) dp = PortaraDataProvider(self.futures_path, self.ticker, PriceField.Close, self.start_date, self.end_date, Frequency.MIN_1) prices = dp.get_price(self.ticker, PriceField.Close, self.start_date, self.end_date, Frequency.MIN_1) prices5 = dp.get_price(self.ticker, PriceField.Close, self.start_date, self.end_date, Frequency.MIN_5) prices15 = dp.get_price(self.ticker, PriceField.Close, self.start_date, self.end_date, Frequency.MIN_15) self.assertTrue(len(prices5)) self.assertEqual(type(prices5), PricesSeries) self.assertEqual(Frequency.infer_freq(prices5.index), Frequency.MIN_5) assert_series_equal(prices5, prices.resample('5T', origin=datetime(2021, 6, 17, 17, 13)).last().dropna(), check_names=False) self.assertTrue(len(prices15)) self.assertEqual(type(prices15), PricesSeries) self.assertEqual(Frequency.infer_freq(prices15.index), Frequency.MIN_15) assert_series_equal(prices15, prices.resample('15T', origin=datetime(2021, 6, 17, 17, 13)).last().dropna(), check_names=False)
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 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 })
class TradingSessionForTests(TradingSession): """ Encapsulates the settings and components for carrying out a backtest session. Pulls for data every day. """ # initialise market time BeforeMarketOpenEvent.set_trigger_time({"hour": 7, "minute": 30, "second": 0, "microsecond": 0}) MarketOpenEvent.set_trigger_time({"hour": 13, "minute": 30, "second": 0, "microsecond": 0}) MarketCloseEvent.set_trigger_time({"hour": 20, "minute": 0, "second": 0, "microsecond": 0}) AfterMarketCloseEvent.set_trigger_time({"hour": 21, "minute": 0, "second": 0, "microsecond": 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
class TestFastAlphaModelsTester(TestCase): apple_ticker = QuandlTicker("AAPL", "WIKI") ibm_ticker = QuandlTicker("IBM", "WIKI") tickers = [apple_ticker, ibm_ticker] test_start_date = str_to_date("2015-01-01") test_end_date = str_to_date("2015-01-31") data_start_date = str_to_date("2014-12-25") data_end_date = test_end_date frequency = Frequency.DAILY 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): 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.contract_ticker_mapper = DummyQuandlContractTickerMapper() self.alpha_model_type = DummyAlphaModel @classmethod def _make_mock_data_array(cls, tickers, fields): all_dates_index = pd.bdate_range(start=cls.data_start_date, end=cls.test_end_date) num_of_dates = len(all_dates_index) num_of_tickers = len(tickers) num_of_fields = len(fields) start_value = 100.0 values = np.arange( start_value, num_of_dates * num_of_tickers * num_of_fields + start_value) reshaped_values = np.reshape( values, (num_of_dates, num_of_tickers, num_of_fields)) mocked_result = QFDataArray.create(all_dates_index, tickers, fields, data=reshaped_values) mocked_result.loc[:, :, PriceField.Low] -= 50.0 mocked_result.loc[:, :, PriceField.High] += 50.0 return mocked_result def test_alpha_models_tester(self): first_param_set = (10, Exposure.LONG) second_param_set = (5, Exposure.SHORT) data_handler = FastDataHandler(self._price_provider_mock, self.timer) params = [ FastAlphaModelTesterConfig( self.alpha_model_type, { "period_length": 10, "first_suggested_exposure": Exposure.LONG, "risk_estimation_factor": None }, ("period_length", "first_suggested_exposure")), FastAlphaModelTesterConfig( self.alpha_model_type, { "period_length": 5, "first_suggested_exposure": Exposure.SHORT, "risk_estimation_factor": None }, ("period_length", "first_suggested_exposure")) ] tester = FastAlphaModelTester(params, self.tickers, self.contract_ticker_mapper, self.test_start_date, self.test_end_date, data_handler, self.timer) backtest_summary = tester.test_alpha_models() self.assertEqual(self.tickers, backtest_summary.tickers) self.assertEqual(DummyAlphaModel, backtest_summary.alpha_model_type) backtest_summary_elements = backtest_summary.elements_list self.assertEqual(2 * (len(self.tickers) + 1), len(backtest_summary_elements)) # check first backtest summary element - trades first_elem = backtest_summary_elements[2] self.assertEqual(first_param_set, first_elem.model_parameters) expected_trades_data = [[ self.apple_ticker, str_to_date("2015-01-02"), str_to_date("2015-01-16"), (260.0 / 160.0 - 1), 1.0 ], [ self.ibm_ticker, str_to_date("2015-01-02"), str_to_date("2015-01-16"), (265.0 / 165.0 - 1), 1.0 ]] generated_trades_data = [[ self.contract_ticker_mapper.contract_to_ticker(t.contract), t.start_time, t.end_time, t.pnl, t.direction ] for t in first_elem.trades] self.assertCountEqual(generated_trades_data, expected_trades_data) # check first backtest summary element - returns all_dates_index = pd.bdate_range(start=self.test_start_date + BDay(2), end=self.test_end_date) expected_returns = SimpleReturnsSeries( index=all_dates_index, data=[ 0.0615530, 0.0579832, 0.0548048, 0.0519568, 0.0493902, 0.0470653, 0.0449495, 0.0430157, 0.0412415, 0.0396078, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000 ]) assert_series_equal(expected_returns, first_elem.returns_tms) # check second backtest summary element second_elem = backtest_summary_elements[5] self.assertEqual(second_param_set, second_elem.model_parameters) expected_trades_data = [[ self.apple_ticker, str_to_date("2015-01-02"), str_to_date("2015-01-09"), (1 - 210.0 / 160.0), -1.0 ], [ self.apple_ticker, str_to_date("2015-01-16"), str_to_date("2015-01-23"), (310.0 / 260.0 - 1), 1.0 ], [ self.apple_ticker, str_to_date("2015-01-23"), str_to_date("2015-01-30"), (1 - 360.0 / 310.0), -1.0 ], [ self.ibm_ticker, str_to_date("2015-01-02"), str_to_date("2015-01-09"), (1 - 215.0 / 165.0), -1.0 ], [ self.ibm_ticker, str_to_date("2015-01-16"), str_to_date("2015-01-23"), (315.0 / 265.0 - 1), 1.0 ], [ self.ibm_ticker, str_to_date("2015-01-23"), str_to_date("2015-01-30"), (1 - 365.0 / 315.0), -1.0 ]] generated_trades_data = [[ self.contract_ticker_mapper.contract_to_ticker(t.contract), t.start_time, t.end_time, t.pnl, t.direction ] for t in second_elem.trades] self.assertCountEqual(expected_trades_data, generated_trades_data) # check second backtest summary element - returns all_dates_index = pd.bdate_range(start=self.test_start_date + BDay(2), end=self.test_end_date) expected_returns = SimpleReturnsSeries( index=all_dates_index, data=[ -0.0615530, -0.0579832, -0.0548048, -0.0519568, -0.0493902, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0380987, 0.0367003, 0.0354010, 0.0341905, 0.0330601, -0.0320020, -0.0310096, -0.0300769, -0.0291986, -0.0283702 ]) assert_series_equal(expected_returns, second_elem.returns_tms)
class TestMarketOnOpenExecutionStyle(TestCase): 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.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 _trigger_single_time_event(self): self.timer.set_current_time(self.timer.now() + RelativeDelta( minutes=self.scheduling_time_delay)) event = ScheduleOrderExecutionEvent() self.exec_handler.on_orders_accept(event) def test_1_order_fill(self): self.exec_handler.assign_order_ids([self.order_1]) self._set_current_price(101) self._trigger_single_time_event() self.exec_handler.on_market_open(...) self.monitor.record_transaction.assert_called_once() self.portfolio.transact_transaction.assert_called_once() actual_orders = self.exec_handler.get_open_orders() expected_orders = [] assert_lists_equal(expected_orders, actual_orders) def test_3_orders_fill(self): self.exec_handler.assign_order_ids( [self.order_1, self.order_2, self.order_3]) self._set_current_price(101) self._trigger_single_time_event() self.exec_handler.on_market_open(...) self.assertEqual(self.monitor.record_transaction.call_count, 3) self.assertEqual(self.portfolio.transact_transaction.call_count, 3) actual_orders = self.exec_handler.get_open_orders() expected_orders = [] assert_lists_equal(expected_orders, actual_orders) def test_3_orders_fill_only_at_open(self): self.exec_handler.assign_order_ids( [self.order_1, self.order_2, self.order_3]) self._set_current_price(101) self._trigger_single_time_event() self.exec_handler.on_market_close(...) self.portfolio.transact_transaction.assert_not_called() self.monitor.record_transaction.assert_not_called() actual_orders = self.exec_handler.get_open_orders() expected_orders = [self.order_1, self.order_2, self.order_3] self.assertCountEqual(expected_orders, actual_orders) def test_fill_open_and_close(self): self.exec_handler.assign_order_ids([self.order_1, self.order_2]) self.exec_handler.assign_order_ids([self.order_2, self.order_3]) self.exec_handler.assign_order_ids([self.order_3, self.order_4]) self.exec_handler.assign_order_ids([self.order_4, self.order_4]) self._set_current_price(101) self._trigger_single_time_event() self.exec_handler.on_market_open(...) self.assertEqual(self.monitor.record_transaction.call_count, 3) self.assertEqual(self.portfolio.transact_transaction.call_count, 3) actual_orders = self.exec_handler.get_open_orders() expected_orders = [self.order_4] assert_lists_equal(expected_orders, actual_orders) self.exec_handler.on_market_close(...) self.assertEqual(self.monitor.record_transaction.call_count, 4) self.assertEqual(self.portfolio.transact_transaction.call_count, 4) actual_orders = self.exec_handler.get_open_orders() expected_orders = [] assert_lists_equal(expected_orders, actual_orders) def test_fill_close_and_open(self): self.exec_handler.assign_order_ids([self.order_1, self.order_2]) self.exec_handler.assign_order_ids([self.order_2, self.order_3]) self.exec_handler.assign_order_ids([self.order_3, self.order_4]) self.exec_handler.assign_order_ids([self.order_4, self.order_4]) self._set_current_price(101) self._trigger_single_time_event() self.exec_handler.on_market_close(...) # Transaction related to order 4 will be executed only once, as only one Order object was passed self.monitor.record_transaction.assert_called_once() self.portfolio.transact_transaction.assert_called_once() actual_orders = self.exec_handler.get_open_orders() expected_orders = [self.order_1, self.order_2, self.order_3] self.assertCountEqual(expected_orders, actual_orders) self.exec_handler.on_market_open(...) self.assertEqual(self.monitor.record_transaction.call_count, 4) self.assertEqual(self.portfolio.transact_transaction.call_count, 4) actual_orders = self.exec_handler.get_open_orders() expected_orders = [] self.assertCountEqual(expected_orders, actual_orders) def test_market_open_transaction(self): order = self.order_1 price = 102 self.exec_handler.assign_order_ids([order]) self._set_current_price(price) self._trigger_single_time_event() self.exec_handler.on_market_open(...) timestamp = self.timer.now() contract = order.contract quantity = order.quantity commission = self.commission_model.calculate_commission(order, price) expected_transaction = Transaction(timestamp, contract, quantity, price, commission) self.monitor.record_transaction.assert_called_once_with( expected_transaction) def test_market_close_transaction(self): order = self.order_4 price = 102 self.exec_handler.assign_order_ids([self.order_1, order]) self._set_current_price(price) self._trigger_single_time_event() self.exec_handler.on_market_close(...) timestamp = self.timer.now() contract = order.contract quantity = order.quantity commission = self.commission_model.calculate_commission(order, price) expected_transaction = Transaction(timestamp, contract, quantity, price, commission) self.monitor.record_transaction.assert_called_once_with( expected_transaction) def test_market_close_does_not_trade(self): price = None self.exec_handler.assign_order_ids([self.order_1, self.order_4]) self._set_current_price(price) self._trigger_single_time_event() self.exec_handler.on_market_close(...) self.portfolio.transact_transaction.assert_not_called() self.monitor.record_transaction.assert_not_called() def test_market_open_does_not_trade(self): price = None self.exec_handler.assign_order_ids([self.order_1, self.order_4]) self._set_current_price(price) self._trigger_single_time_event() self.exec_handler.on_market_open(...) self.portfolio.transact_transaction.assert_not_called() self.monitor.record_transaction.assert_not_called() def _set_last_available_price(self, price): self.data_handler.get_last_available_price.side_effect = lambda t: QFSeries( data=[price], index=pd.Index([self.msft_ticker])) def _set_current_price(self, price): self.data_handler.get_current_price.side_effect = lambda t: QFSeries( data=[price], index=pd.Index([self.msft_ticker]))
def setUp(self): self.timer = SettableTimer() MarketOpenEvent.set_trigger_time({"hour": 13, "minute": 30, "second": 0, "microsecond": 0}) MarketCloseEvent.set_trigger_time({"hour": 20, "minute": 0, "second": 0, "microsecond": 0})