From a8491879ce43840cf4a80d1c236e8d3ea41a6516 Mon Sep 17 00:00:00 2001 From: Andrew Liang Date: Tue, 5 Apr 2016 15:45:22 -0400 Subject: [PATCH] FIX: time_rules should trigger only at dt specified Previously, time_rules triggered when the dt specified has passed --- tests/utils/test_events.py | 27 ++++++++++++--------------- zipline/utils/events.py | 11 +++-------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/tests/utils/test_events.py b/tests/utils/test_events.py index 16450da4..bfa0e929 100644 --- a/tests/utils/test_events.py +++ b/tests/utils/test_events.py @@ -16,7 +16,6 @@ from collections import namedtuple import datetime from functools import partial from inspect import isabstract -from itertools import islice import random from unittest import TestCase @@ -306,16 +305,12 @@ class TestStatelessRules(RuleTestCase): self.after_open.should_trigger, env=self.env, ) - for m in islice(ms, 64): - # Check the first 64 minutes of data. - # We use 64 because the offset is from market open - # at 13:30 UTC, meaning the first minute of data has an - # offset of 1. - self.assertFalse(should_trigger(m)) - - for m in islice(ms, 64, None): - # Check the rest of the day. - self.assertTrue(should_trigger(m)) + for i, m in enumerate(ms): + # Should only trigger at the 64th minute + if i != 64: + self.assertFalse(should_trigger(m)) + else: + self.assertTrue(should_trigger(m)) @subtest(minutes_for_days(ordered_days=True), 'ms') def test_BeforeClose(self, ms): @@ -324,10 +319,12 @@ class TestStatelessRules(RuleTestCase): self.before_close.should_trigger, env=self.env ) - for m in ms[0:-66]: - self.assertFalse(should_trigger(m)) - for m in ms[-66:]: - self.assertTrue(should_trigger(m)) + for m in ms: + # Should only trigger at the 65th-to-last minute + if m != ms[-66]: + self.assertFalse(should_trigger(m)) + else: + self.assertTrue(should_trigger(m)) @subtest(minutes_for_days(), 'ms') def test_NotHalfDay(self, ms): diff --git a/zipline/utils/events.py b/zipline/utils/events.py index c19e8c02..dbccb7a0 100644 --- a/zipline/utils/events.py +++ b/zipline/utils/events.py @@ -364,11 +364,7 @@ class AfterOpen(StatelessRule): ): self.calculate_dates(dt, env) - if self._period_start <= dt < self._period_end: - # haven't made it past the offset yet - return False - else: - return True + return dt == self._period_end class BeforeClose(StatelessRule): @@ -394,7 +390,7 @@ class BeforeClose(StatelessRule): # given a dt, find that day's close and period start (close - offset) self._period_end = env.get_open_and_close(dt)[1] self._period_start = \ - self._period_end - self.offset - self._one_minute + self._period_end - self.offset self._period_close = self._period_end def should_trigger(self, dt, env): @@ -413,8 +409,7 @@ class BeforeClose(StatelessRule): ): self.calculate_dates(dt, env) - # Return true if we're within the interval specified. - return self._period_start < dt <= self._period_end + return self._period_start == dt class NotHalfDay(StatelessRule):