From c6e85d08f03248850fc0c21d873cf58fba247ce3 Mon Sep 17 00:00:00 2001 From: Joe Jevnik Date: Tue, 14 Oct 2014 11:01:18 -0400 Subject: [PATCH] ENH: Does value checking for time offsets for market_open and market_close --- tests/utils/test_events.py | 10 ++++++---- zipline/utils/events.py | 35 +++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/tests/utils/test_events.py b/tests/utils/test_events.py index 960c2979..8ef27bb5 100644 --- a/tests/utils/test_events.py +++ b/tests/utils/test_events.py @@ -43,6 +43,8 @@ from zipline.utils.events import ( _build_time, EventManager, Event, + MAX_MONTH_RANGE, + MAX_WEEK_RANGE, ) @@ -276,7 +278,7 @@ class TestStatelessRules(RuleTestCase): self.assertTrue(should_trigger(FULL_DAY)) self.assertFalse(should_trigger(HALF_DAY)) - @parameterized.expand(param_range(5)) + @parameterized.expand(param_range(MAX_WEEK_RANGE)) def test_NthTradingDayOfWeek(self, n): should_trigger = NthTradingDayOfWeek(n).should_trigger prev_day = self.sept_week[0].date() @@ -291,7 +293,7 @@ class TestStatelessRules(RuleTestCase): else: self.assertNotEqual(n_tdays, n) - @parameterized.expand(param_range(5)) + @parameterized.expand(param_range(MAX_WEEK_RANGE)) def test_NDaysBeforeLastTradingDayOfWeek(self, n): should_trigger = NDaysBeforeLastTradingDayOfWeek(n).should_trigger for m in self.sept_week: @@ -306,7 +308,7 @@ class TestStatelessRules(RuleTestCase): self.assertEqual(n_tdays, n) - @parameterized.expand(param_range(30)) + @parameterized.expand(param_range(MAX_MONTH_RANGE)) def test_NthTradingDayOfMonth(self, n): should_trigger = NthTradingDayOfMonth(n).should_trigger for n_tdays, d in enumerate(self.sept_days): @@ -316,7 +318,7 @@ class TestStatelessRules(RuleTestCase): else: self.assertNotEqual(n_tdays, n) - @parameterized.expand(param_range(30)) + @parameterized.expand(param_range(MAX_MONTH_RANGE)) def test_NDaysBeforeLastTradingDayOfMonth(self, n): should_trigger = NDaysBeforeLastTradingDayOfMonth(n).should_trigger for n_days_before, d in enumerate(reversed(self.sept_days)): diff --git a/zipline/utils/events.py b/zipline/utils/events.py index ab2e12be..66ec0029 100644 --- a/zipline/utils/events.py +++ b/zipline/utils/events.py @@ -50,6 +50,10 @@ __all__ = [ ] +MAX_MONTH_RANGE = 26 +MAX_WEEK_RANGE = 5 + + def naive_to_utc(ts): """ Converts a UTC tz-naive timestamp to a tz-aware timestamp. @@ -107,6 +111,17 @@ def _out_of_range_error(a, b=None, var='offset'): ) +def _td_check(td): + seconds = td.total_seconds() + + # 23400 seconds is 6 hours and 30 minutes. + if 0 <= seconds <= 23400: + return td + else: + raise ValueError('offset must be in between 0 minutes and 6 hours and' + ' 30 minutes') + + def _build_offset(offset, kwargs, default): """ Builds the offset argument for event rules. @@ -115,11 +130,11 @@ def _build_offset(offset, kwargs, default): if not kwargs: return default # use the default. else: - return datetime.timedelta(**kwargs) + return _td_check(datetime.timedelta(**kwargs)) elif kwargs: raise ValueError('Cannot pass kwargs and an offset') elif isinstance(offset, datetime.timedelta): - return offset + return _td_check(offset) else: raise TypeError("Must pass 'hours' and/or 'minutes' as keywords") @@ -347,8 +362,8 @@ class NthTradingDayOfWeek(StatelessRule): This is zero-indexed, n=0 is the first trading day of the week. """ def __init__(self, n=0): - if n not in range(5): - raise _out_of_range_error(5) + if not 0 <= n < MAX_WEEK_RANGE: + raise _out_of_range_error(MAX_WEEK_RANGE) self.td_delta = n def should_trigger(self, dt): @@ -371,8 +386,8 @@ class NDaysBeforeLastTradingDayOfWeek(StatelessRule): A rule that triggers n days before the last trading day of the week. """ def __init__(self, n): - if n not in range(5): - raise _out_of_range_error(5) + if not 0 <= n < MAX_WEEK_RANGE: + raise _out_of_range_error(MAX_WEEK_RANGE) self.td_delta = -n self.date = None @@ -399,8 +414,8 @@ class NthTradingDayOfMonth(StatelessRule): This is zero-indexed, n=0 is the first trading day of the month. """ def __init__(self, n=0): - if n not in range(26): - raise _out_of_range_error(26) + if not 0 <= n < MAX_MONTH_RANGE: + raise _out_of_range_error(MAX_MONTH_RANGE) self.td_delta = n self.month = None self.day = None @@ -437,8 +452,8 @@ class NDaysBeforeLastTradingDayOfMonth(StatelessRule): A rule that triggers n days before the last trading day of the month. """ def __init__(self, n=0): - if n not in range(26): - raise _out_of_range_error(26) + if not 0 <= n < MAX_MONTH_RANGE: + raise _out_of_range_error(MAX_MONTH_RANGE) self.td_delta = -n self.month = None self.day = None