From 705fb4e89fc03d584a0e314b0c45ca12db125cb6 Mon Sep 17 00:00:00 2001 From: jfkirk Date: Wed, 20 Apr 2016 13:26:05 -0400 Subject: [PATCH] MAINT: Removes use of partials in schedule classes --- tests/test_exchange_calendar.py | 2 +- tests/test_finance.py | 8 +- zipline/utils/calendars/calendar_helpers.py | 7 +- .../utils/calendars/cme_exchange_calendar.py | 2 - zipline/utils/calendars/exchange_calendar.py | 73 +++++++++++------- zipline/utils/calendars/trading_schedule.py | 75 ++++++++++++------- 6 files changed, 101 insertions(+), 66 deletions(-) diff --git a/tests/test_exchange_calendar.py b/tests/test_exchange_calendar.py index a80977fd..cf08de87 100644 --- a/tests/test_exchange_calendar.py +++ b/tests/test_exchange_calendar.py @@ -112,7 +112,7 @@ class ExchangeCalendarTestBase(object): def test_minute_window(self): for open in self.answers.market_open: open_tz = open.tz_localize('UTC') - window = self.calendar.market_minute_window(open_tz, 390, step=1) + window = self.calendar.trading_minute_window(open_tz, 390, step=1) self.assertEqual(len(window), 390) diff --git a/tests/test_finance.py b/tests/test_finance.py index df1cf72d..2ab293d5 100644 --- a/tests/test_finance.py +++ b/tests/test_finance.py @@ -497,7 +497,7 @@ class TradingEnvironmentTestCase(WithLogger, utc_start = pd.Timestamp(start.astimezone(utc)) # Get the next 10 minutes - minutes = self.cal.market_minute_window( + minutes = self.cal.trading_minute_window( utc_start, 10, ) self.assertEqual(len(minutes), 10) @@ -505,7 +505,7 @@ class TradingEnvironmentTestCase(WithLogger, self.assertEqual(minutes[i], utc_start + timedelta(minutes=i)) # Get the previous 10 minutes. - minutes = self.cal.market_minute_window( + minutes = self.cal.trading_minute_window( utc_start, 10, step=-1, ) self.assertEqual(len(minutes), 10) @@ -518,7 +518,7 @@ class TradingEnvironmentTestCase(WithLogger, # Today: 10:01 AM -> 4:00 PM (360 minutes) # Tomorrow: 9:31 AM -> 4:00 PM (390 minutes, 750 total) # Last Day: 9:31 AM -> 12:00 PM (150 minutes, 900 total) - minutes = self.cal.market_minute_window( + minutes = self.cal.trading_minute_window( start, 900, ) today = self.cal.trading_minutes_for_day(utc_start)[30:] @@ -540,7 +540,7 @@ class TradingEnvironmentTestCase(WithLogger, # Today: 10:01 AM -> 9:31 AM (31 minutes) # Friday: 4:00 PM -> 9:31 AM (390 minutes, 421 total) # Thursday: 4:00 PM -> 9:41 AM (380 minutes, 801 total) - minutes = self.cal.market_minute_window( + minutes = self.cal.trading_minute_window( start, 801, step=-1, ) diff --git a/zipline/utils/calendars/calendar_helpers.py b/zipline/utils/calendars/calendar_helpers.py index c660bf42..e235af77 100644 --- a/zipline/utils/calendars/calendar_helpers.py +++ b/zipline/utils/calendars/calendar_helpers.py @@ -116,9 +116,6 @@ def days_in_range(start, end, all_days): end_date = normalize_date(end) return all_days[all_days.slice_indexer(start_date, end_date)] - #mask = ((all_days >= start_date) & (all_days <= end_date)) - #return all_days[mask] - def minutes_for_days_in_range(start, end, days_in_range_hook, minutes_for_day_hook): @@ -216,8 +213,8 @@ def previous_scheduled_minute(start, is_scheduled_day_hook, return previous_open_and_close_hook(start)[1] -def minute_window(start, count, schedule, is_scheduled_minute_hook, - session_date_hook, minutes_for_date_hook, step=1): +def minute_window(start, count, step, schedule, is_scheduled_minute_hook, + session_date_hook, minutes_for_date_hook): """ Returns a DatetimeIndex containing `count` market minutes, starting with `start` and continuing `step` minutes at a time. diff --git a/zipline/utils/calendars/cme_exchange_calendar.py b/zipline/utils/calendars/cme_exchange_calendar.py index fd67511d..7b62ab0d 100644 --- a/zipline/utils/calendars/cme_exchange_calendar.py +++ b/zipline/utils/calendars/cme_exchange_calendar.py @@ -16,8 +16,6 @@ from datetime import time from itertools import chain -import numpy as np -import pandas as pd from dateutil.relativedelta import ( MO, TH, diff --git a/zipline/utils/calendars/exchange_calendar.py b/zipline/utils/calendars/exchange_calendar.py index 012bdf30..ba32f942 100644 --- a/zipline/utils/calendars/exchange_calendar.py +++ b/zipline/utils/calendars/exchange_calendar.py @@ -17,7 +17,6 @@ from abc import ( abstractproperty, abstractmethod, ) -from functools import partial import pandas as pd from pandas import ( @@ -187,64 +186,86 @@ class ExchangeCalendar(with_metaclass(ABCMeta)): self.last_trading_day = _all_days[-1] self.early_closes = _special_closes.map(self.session_date) - # Assign the partial calendar helpers - self.next_trading_day = partial( - next_scheduled_day, + def next_trading_day(self, date): + return next_scheduled_day( + date, last_trading_day=self.last_trading_day, is_scheduled_day_hook=self.is_open_on_day, ) - self.previous_trading_day = partial( - previous_scheduled_day, + + def previous_trading_day(self, date): + return previous_scheduled_day( + date, first_trading_day=self.first_trading_day, is_scheduled_day_hook=self.is_open_on_day, ) - self.next_open_and_close = partial( - next_open_and_close, + + def next_start_and_end(self, date): + return next_open_and_close( + date, open_and_close_hook=self.open_and_close, next_scheduled_day_hook=self.next_trading_day, ) - self.previous_open_and_close = partial( - previous_open_and_close, + + def previous_start_and_end(self, date): + return previous_open_and_close( + date, open_and_close_hook=self.open_and_close, previous_scheduled_day_hook=self.previous_trading_day, ) - self.trading_day_distance = partial( - scheduled_day_distance, + + def trading_day_distance(self, first_date, second_date): + return scheduled_day_distance( + first_date, second_date, all_days=self.all_trading_days, ) - self.trading_minutes_for_day = partial( - minutes_for_day, + + def trading_minutes_for_day(self, day): + return minutes_for_day( + day, open_and_close_hook=self.open_and_close, ) - self.trading_days_in_range = partial( - days_in_range, + + def trading_days_in_range(self, start, end): + return days_in_range( + start, end, all_days=self.all_trading_days, ) - self.trading_minutes_for_days_in_range = partial( - minutes_for_days_in_range, + + def trading_minutes_for_days_in_range(self, start, end): + return minutes_for_days_in_range( + start, end, days_in_range_hook=self.trading_days_in_range, minutes_for_day_hook=self.trading_minutes_for_day, ) - self.add_trading_days = partial( - add_scheduled_days, + + def add_trading_days(self, n, date): + return add_scheduled_days( + n, date, next_scheduled_day_hook=self.next_trading_day, previous_scheduled_day_hook=self.previous_trading_day, all_trading_days=self.all_trading_days, ) - self.next_market_minute = partial( - next_scheduled_minute, + + def next_trading_minute(self, start): + return next_scheduled_minute( + start, is_scheduled_day_hook=self.is_open_on_day, open_and_close_hook=self.open_and_close, next_open_and_close_hook=self.next_open_and_close, ) - self.previous_market_minute = partial( - previous_scheduled_minute, + + def previous_trading_minute(self, start): + return previous_scheduled_minute( + start, is_scheduled_day_hook=self.is_open_on_day, open_and_close_hook=self.open_and_close, previous_open_and_close_hook=self.previous_open_and_close, ) - self.market_minute_window = partial( - minute_window, + + def trading_minute_window(self, start, count, step=1): + return minute_window( + start, count, step, schedule=self.schedule, is_scheduled_minute_hook=self.is_open_on_minute, session_date_hook=self.session_date, diff --git a/zipline/utils/calendars/trading_schedule.py b/zipline/utils/calendars/trading_schedule.py index eeef9ea9..9f0d0c7d 100644 --- a/zipline/utils/calendars/trading_schedule.py +++ b/zipline/utils/calendars/trading_schedule.py @@ -18,7 +18,6 @@ from abc import ( abstractmethod, abstractproperty, ) -from functools import partial from six import with_metaclass from zipline.utils.memoize import remember_last @@ -46,65 +45,86 @@ class TradingSchedule(with_metaclass(ABCMeta)): A TradingSchedule defines the execution timing of a TradingAlgorithm. """ - def __init__(self): - # Assign the partial calendar helpers - self.next_execution_day = partial( - next_scheduled_day, + def next_execution_day(self, date): + return next_scheduled_day( + date, last_trading_day=self.last_execution_day, is_scheduled_day_hook=self.is_executing_on_day, ) - self.previous_execution_day = partial( - previous_scheduled_day, + + def previous_execution_day(self, date): + return previous_scheduled_day( + date, first_trading_day=self.first_execution_day, is_scheduled_day_hook=self.is_executing_on_day, ) - self.next_start_and_end = partial( - next_open_and_close, + + def next_start_and_end(self, date): + return next_open_and_close( + date, open_and_close_hook=self.start_and_end, next_scheduled_day_hook=self.next_execution_day, ) - self.previous_start_and_end = partial( - previous_open_and_close, + + def previous_start_and_end(self, date): + return previous_open_and_close( + date, open_and_close_hook=self.start_and_end, previous_scheduled_day_hook=self.previous_execution_day, ) - self.execution_day_distance = partial( - scheduled_day_distance, + + def execution_day_distance(self, first_date, second_date): + return scheduled_day_distance( + first_date, second_date, all_days=self.all_execution_days, ) - self.execution_minutes_for_day = partial( - minutes_for_day, + + def execution_minutes_for_day(self, day): + return minutes_for_day( + day, open_and_close_hook=self.start_and_end, ) - self.execution_days_in_range = partial( - days_in_range, + + def execution_days_in_range(self, start, end): + return days_in_range( + start, end, all_days=self.all_execution_days, ) - self.execution_minutes_for_days_in_range = partial( - minutes_for_days_in_range, + + def execution_minutes_for_days_in_range(self, start, end): + return minutes_for_days_in_range( + start, end, days_in_range_hook=self.execution_days_in_range, minutes_for_day_hook=self.execution_minutes_for_day, ) - self.add_execution_days = partial( - add_scheduled_days, + + def add_execution_days(self, n, date): + return add_scheduled_days( + n, date, next_scheduled_day_hook=self.next_execution_day, previous_scheduled_day_hook=self.previous_execution_day, all_trading_days=self.all_execution_days, ) - self.next_execution_minute = partial( - next_scheduled_minute, + + def next_execution_minute(self, start): + return next_scheduled_minute( + start, is_scheduled_day_hook=self.is_executing_on_day, open_and_close_hook=self.start_and_end, next_open_and_close_hook=self.next_start_and_end, ) - self.previous_execution_minute = partial( - previous_scheduled_minute, + + def previous_execution_minute(self, start): + return previous_scheduled_minute( + start, is_scheduled_day_hook=self.is_executing_on_day, open_and_close_hook=self.start_and_end, previous_open_and_close_hook=self.previous_start_and_end, ) - self.execution_minute_window = partial( - minute_window, + + def execution_minute_window(self, start, count, step=1): + return minute_window( + start, count, step, schedule=self.schedule, is_scheduled_minute_hook=self.is_executing_on_minute, session_date_hook=self.session_date, @@ -265,7 +285,6 @@ class TradingSchedule(with_metaclass(ABCMeta)): """ raise NotImplementedError() - @abstractmethod def session_date(self, dt): """