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)
Example #2
0
    def setUp(self):
        self.scheduling_time_delay = 1
        start_date = str_to_date("2018-02-04")

        before_close = start_date + MarketCloseEvent.trigger_time(
        ) - RelativeDelta(minutes=self.scheduling_time_delay)
        self.timer = SettableTimer(initial_time=before_close)

        self.msft_ticker = BloombergTicker("MSFT US Equity")

        self.data_handler = Mock(spec=DataHandler)
        self.data_handler.frequency = Frequency.DAILY
        self.data_handler.data_provider = Mock(spec=DataProvider)

        self.scheduler = Mock(spec=Scheduler)

        self.commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = Mock(spec=AbstractMonitor)
        self.portfolio = Mock(spec=Portfolio)

        slippage_model = PriceBasedSlippage(0.0, self.data_handler)
        self.exec_handler = SimulatedExecutionHandler(
            self.data_handler, self.timer, self.scheduler, self.monitor,
            self.commission_model, self.portfolio, slippage_model,
            RelativeDelta(minutes=self.scheduling_time_delay))

        self.order_1 = Order(self.msft_ticker,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(self.msft_ticker,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(self.msft_ticker,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(self.msft_ticker,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)
Example #3
0
    def setUp(self):
        self.start_date = str_to_date("2018-02-04")
        self.msft_contract = Contract(self.MSFT_TICKER_STR,
                                      security_type='SEK',
                                      exchange='TEST')
        self.msft_ticker = BloombergTicker(self.MSFT_TICKER_STR)

        self.contracts_to_tickers_mapper = DummyBloombergContractTickerMapper()
        self.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, self.timer, self.scheduler, self.spied_monitor,
            self.commission_model, self.contracts_to_tickers_mapper,
            self.portfolio, slippage_model)

        self._set_last_msft_price(100.0)
        self.order_1 = Order(self.msft_contract,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(self.msft_contract,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(self.msft_contract,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(self.msft_contract,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)
    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 = 100000
        self._monitor_type = LightBacktestMonitor
        self._logging_level = logging.WARNING
        self._contract_ticker_mapper = DummyBloombergContractTickerMapper()
        self._commission_model = FixedCommissionModel(0.0)
        self._slippage_model = PriceBasedSlippage(0.0)
        self._position_sizer_type = SimplePositionSizer
        self._position_sizer_param = None

        self._data_provider = data_provider
        self._settings = settings
        self._pdf_exporter = pdf_exporter
        self._excel_exporter = excel_exporter
Example #5
0
    def setUp(self):
        MarketOpenEvent.set_trigger_time({"hour": 13, "minute": 30, "second": 0, "microsecond": 0})
        MarketCloseEvent.set_trigger_time({"hour": 20, "minute": 0, "second": 0, "microsecond": 0})

        self.start_date = str_to_date("2018-02-04")
        self.number_of_minutes = 5

        before_close = self.start_date + MarketCloseEvent.trigger_time() - RelativeDelta(minutes=self.number_of_minutes)
        self.msft_ticker = BloombergTicker(self.MSFT_TICKER_STR)

        self.timer = SettableTimer(initial_time=before_close)

        self.data_handler = Mock(spec=DataHandler)
        self.data_handler.data_provider = Mock(spec=DataProvider)

        scheduler = Mock(spec=Scheduler)
        ScheduleOrderExecutionEvent.clear()

        # Set the periodic bar events to intraday trading
        IntradayBarEvent.frequency = Frequency.MIN_1

        commission_model = FixedCommissionModel(commission=0.0)
        self.monitor = Mock(spec=AbstractMonitor)
        self.portfolio = Mock(spec=Portfolio)

        slippage_model = PriceBasedSlippage(0.0, self.data_handler)
        self.exec_handler = SimulatedExecutionHandler(self.data_handler, self.timer, scheduler, self.monitor,
                                                      commission_model, self.portfolio, slippage_model,
                                                      RelativeDelta(minutes=self.number_of_minutes))

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

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

        self.exec_handler.assign_order_ids([self.stop_loss_order_1, self.stop_loss_order_2, self.stop_loss_order_3])
    def __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 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]))
Example #8
0
class TestMarketOnOpenExecutionStyle(TestCase):
    MSFT_TICKER_STR = "MSFT US Equity"

    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()
        self.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, self.timer, self.scheduler, self.spied_monitor,
            self.commission_model, self.contracts_to_tickers_mapper,
            self.portfolio, slippage_model)

        self._set_last_msft_price(100.0)
        self.order_1 = Order(self.msft_contract,
                             quantity=10,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_2 = Order(self.msft_contract,
                             quantity=-5,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)
        self.order_3 = Order(self.msft_contract,
                             quantity=-7,
                             execution_style=MarketOrder(),
                             time_in_force=TimeInForce.OPG)

        self.order_4 = Order(self.msft_contract,
                             quantity=4,
                             execution_style=MarketOnCloseOrder(),
                             time_in_force=TimeInForce.DAY)

    def test_1_order_fill(self):
        self.exec_hanlder.accept_orders([self.order_1])
        self._set_price_for_now(101)
        self.exec_hanlder.on_market_open(...)

        verify(self.spied_monitor, times=1).record_transaction(...)
        verify(self.portfolio, times=1).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = []
        assert_lists_equal(expected_orders, actual_orders)

    def test_3_orders_fill(self):
        self.exec_hanlder.accept_orders(
            [self.order_1, self.order_2, self.order_3])
        self._set_price_for_now(101)
        self.exec_hanlder.on_market_open(...)

        verify(self.spied_monitor, times=3).record_transaction(...)
        verify(self.portfolio, times=3).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = []
        assert_lists_equal(expected_orders, actual_orders)

    def test_3_orders_fill_only_at_open(self):
        self.exec_hanlder.accept_orders(
            [self.order_1, self.order_2, self.order_3])
        self._set_price_for_now(101)
        self.exec_hanlder.on_market_close(...)

        verifyZeroInteractions(self.portfolio, self.spied_monitor)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = [self.order_1, self.order_2, self.order_3]
        assert_lists_equal(expected_orders, actual_orders)

    def test_fill_open_and_close(self):
        self.exec_hanlder.accept_orders([self.order_1, self.order_2])
        self.exec_hanlder.accept_orders([self.order_2, self.order_3])
        self.exec_hanlder.accept_orders([self.order_3, self.order_4])
        self.exec_hanlder.accept_orders([self.order_4, self.order_4])

        self._set_price_for_now(101)
        self.exec_hanlder.on_market_open(...)

        verify(self.spied_monitor, times=5).record_transaction(...)
        verify(self.portfolio, times=5).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = [self.order_4, self.order_4, self.order_4]
        assert_lists_equal(expected_orders, actual_orders)

        self.exec_hanlder.on_market_close(...)

        verify(self.spied_monitor, times=8).record_transaction(...)
        verify(self.portfolio, times=8).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = []
        assert_lists_equal(expected_orders, actual_orders)

    def test_fill_close_and_open(self):
        self.exec_hanlder.accept_orders([self.order_1, self.order_2])
        self.exec_hanlder.accept_orders([self.order_2, self.order_3])
        self.exec_hanlder.accept_orders([self.order_3, self.order_4])
        self.exec_hanlder.accept_orders([self.order_4, self.order_4])

        self._set_price_for_now(101)
        self.exec_hanlder.on_market_close(...)

        verify(self.spied_monitor, times=3).record_transaction(...)
        verify(self.portfolio, times=3).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = [
            self.order_1, self.order_2, self.order_2, self.order_3,
            self.order_3
        ]
        assert_lists_equal(expected_orders, actual_orders)

        self.exec_hanlder.on_market_open(...)

        verify(self.spied_monitor, times=8).record_transaction(...)
        verify(self.portfolio, times=8).transact_transaction(...)

        actual_orders = self.exec_hanlder.get_open_orders()
        expected_orders = []
        assert_lists_equal(expected_orders, actual_orders)

    def test_market_open_transaction(self):
        order = self.order_1
        price = 102
        self.exec_hanlder.accept_orders([order])
        self._set_price_for_now(price)
        self.exec_hanlder.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)

        captor = _ArgCaptor()
        verify(self.spied_monitor, times=1).record_transaction(captor)
        self.assertEqual(expected_transaction, captor.get_value())

    def test_market_close_transaction(self):
        order = self.order_4
        price = 102
        self.exec_hanlder.accept_orders([self.order_1, order])
        self._set_price_for_now(price)
        self.exec_hanlder.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)

        captor = _ArgCaptor()
        verify(self.spied_monitor, times=1).record_transaction(captor)
        self.assertEqual(expected_transaction, captor.get_value())

    def test_market_close_does_not_trade(self):
        price = None
        self.exec_hanlder.accept_orders([self.order_1, self.order_4])
        self._set_price_for_now(price)
        self.exec_hanlder.on_market_close(...)

        verifyZeroInteractions(self.portfolio, self.spied_monitor)

    def test_market_open_does_not_trade(self):
        price = None
        self.exec_hanlder.accept_orders([self.order_1, self.order_4])
        self._set_price_for_now(price)
        self.exec_hanlder.on_market_open(...)

        verifyZeroInteractions(self.portfolio, self.spied_monitor)

    def _set_last_msft_price(self, price):
        when(self.data_handler).get_last_available_price(
            [self.msft_ticker]).thenReturn(
                pd.Series(data=[price],
                          index=pd.Index([self.msft_ticker]),
                          name=self.start_date))

    def _set_price_for_now(self, price):
        when(self.data_handler).get_current_price(
            [self.msft_ticker]).thenReturn(
                pd.Series(data=[price], index=pd.Index([self.msft_ticker])))