def test_midday_start(self): """Tests that RealtimeClock is able to execute if started mid-day""" msc = MinuteSimulationClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(8, 45), "US/Eastern"), False) msc_events = list(msc) with patch('zipline.gens.realtimeclock.pd.to_datetime') as to_dt, \ patch('zipline.gens.realtimeclock.sleep') as sleep: rtc = RealtimeClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(8, 45), "US/Eastern"), False) to_dt.side_effect = self.get_clock sleep.side_effect = self.advance_clock self.internal_clock = pd.Timestamp("2017-04-20 15:00", tz='UTC') rtc_events = list(rtc) # Count the mid-day position in the MinuteSimulationClock's events: # Simulation Tick: 2017-04-20 00:00:00+00:00 - 1 (SESSION_START) # Simulation Tick: 2017-04-20 12:45:00+00:00 - 4 (BEFORE_TRADING_START) # Simulation Tick: 2017-04-20 13:31:00+00:00 - 0 (BAR) msc_midday_position = 2 + 90 self.assertEquals(rtc_events[0], msc_events[0]) # Session start bar # before_trading_start is fired immediately if we're after 8:45 EDT event_time, event_type = rtc_events[1] self.assertEquals(event_time, pd.Timestamp("2017-04-20 15:00", tz='UTC')) self.assertEquals(event_type, BEFORE_TRADING_START_BAR) self.assertEquals(rtc_events[2:], msc_events[msc_midday_position:])
def test_crosscheck_realtimeclock_with_minutesimulationclock(self): """Tests that RealtimeClock behaves like MinuteSimulationClock""" for minute_emission in (False, True): # MinuteSimulationClock also relies on to_datetime, shall not be # created in the patch block msc = MinuteSimulationClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(8, 45), "US/Eastern"), minute_emission) msc_events = list(msc) with patch('zipline.gens.realtimeclock.pd.to_datetime') as to_dt, \ patch('zipline.gens.realtimeclock.sleep') as sleep: rtc = iter( RealtimeClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(8, 45), "US/Eastern"), minute_emission)) self.internal_clock = \ pd.Timestamp("2017-04-20 00:00", tz='UTC') to_dt.side_effect = self.get_clock sleep.side_effect = self.advance_clock rtc_events = list(rtc) for rtc_event, msc_event in zip_longest(rtc_events, msc_events): self.assertEquals(rtc_event, msc_event) self.assertEquals(len(rtc_events), len(msc_events))
def _create_clock(self): # This method is taken from TradingAlgorithm. # The clock has been replaced to use RealtimeClock trading_o_and_c = self.trading_calendar.schedule.ix[ self.sim_params.sessions] assert self.sim_params.emission_rate == 'minute' minutely_emission = True market_opens = trading_o_and_c['market_open'] market_closes = trading_o_and_c['market_close'] # The calendar's execution times are the minutes over which we actually # want to run the clock. Typically the execution times simply adhere to # the market open and close times. In the case of the futures calendar, # for example, we only want to simulate over a subset of the full 24 # hour calendar, so the execution times dictate a market open time of # 6:31am US/Eastern and a close of 5:00pm US/Eastern. execution_opens = \ self.trading_calendar.execution_time_from_open(market_opens) execution_closes = \ self.trading_calendar.execution_time_from_close(market_closes) # FIXME generalize these values before_trading_start_minutes = days_at_time(self.sim_params.sessions, time(8, 45), "US/Eastern") return RealtimeClock(self.sim_params.sessions, execution_opens, execution_closes, before_trading_start_minutes, minute_emission=minutely_emission, time_skew=self.broker.time_skew)
def test_afterhours_start(self): """Tests that RealtimeClock returns immediately if started after RTH""" with patch('zipline.gens.realtimeclock.pd.to_datetime') as to_dt, \ patch('zipline.gens.realtimeclock.sleep') as sleep: rtc = RealtimeClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(8, 45), "US/Eastern"), False ) to_dt.side_effect = self.get_clock sleep.side_effect = self.advance_clock self.internal_clock = pd.Timestamp("2017-04-20 20:05", tz='UTC') events = list(rtc) self.assertEquals(len(events), 2) # SESSION_START & which always triggered. _, event_type = events[0] self.assertEquals(event_type, SESSION_START) event_time, event_type = events[1] self.assertEquals(event_time, pd.Timestamp("2017-04-20 20:05", tz='UTC')) self.assertEquals(event_type, BEFORE_TRADING_START_BAR)
def test_time_skew(self): """Tests that RealtimeClock's time_skew parameter behaves as expected""" for time_skew in (pd.Timedelta("2 hour"), pd.Timedelta("-120 sec")): with patch('zipline.gens.realtimeclock.pd.to_datetime') as to_dt, \ patch('zipline.gens.realtimeclock.sleep') as sleep: clock = RealtimeClock( self.sessions, self.opens, self.closes, days_at_time(self.sessions, time(11, 31), "US/Eastern"), False, time_skew) to_dt.side_effect = self.get_clock sleep.side_effect = self.advance_clock start_time = pd.Timestamp("2017-04-20 15:31", tz='UTC') self.internal_clock = start_time events = list(clock) # Event 0 is SESSION_START which always happens at 00:00. ts, event_type = events[1] self.assertEquals(ts, start_time + time_skew)
def _create_clock(self): # This method is taken from TradingAlgorithm. # The clock has been replaced to use RealtimeClock trading_o_and_c = self.trading_calendar.schedule.ix[ self.sim_params.sessions] assert self.sim_params.emission_rate == 'minute' minutely_emission = True market_opens = trading_o_and_c['market_open'] market_closes = trading_o_and_c['market_close'] # The calendar's execution times are the minutes over which we actually # want to run the clock. Typically the execution times simply adhere to # the market open and close times. In the case of the futures calendar, # for example, we only want to simulate over a subset of the full 24 # hour calendar, so the execution times dictate a market open time of # 6:31am US/Eastern and a close of 5:00pm US/Eastern. execution_opens = \ self.trading_calendar.execution_time_from_open(market_opens) execution_closes = \ self.trading_calendar.execution_time_from_close(market_closes) before_trading_start_minutes = (( pd.to_datetime(execution_opens.values).tz_localize( 'UTC').tz_convert('US/Eastern') - timedelta( minutes=_minutes_before_trading_starts)).tz_convert('UTC')) return RealtimeClock( self.sim_params.sessions, execution_opens, execution_closes, before_trading_start_minutes, minute_emission=minutely_emission, time_skew=self.broker.time_skew, is_broker_alive=self.broker.is_alive, execution_id=self.sim_params._execution_id if hasattr( self.sim_params, "_execution_id") else None, stop_execution_callback=self._stop_execution_callback)