Skip to content

Commit

Permalink
ENH: Changes the default offset for time_rules.market_open to 1, and
Browse files Browse the repository at this point in the history
makes it an offset from 13:30 UTC.

This is to be more consistent with the market_close, which is an offset
from 20:00 UTC.

This also makes market_open and market_close cache the dt to offset from
for each day.
  • Loading branch information
llllllllll committed Nov 4, 2014
1 parent 1c08f60 commit 0f52162
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
9 changes: 7 additions & 2 deletions tests/utils/test_events.py
Expand Up @@ -260,9 +260,14 @@ def test_Never(self):
def test_AfterOpen(self):
should_trigger = AfterOpen(minutes=5, hours=1).should_trigger
for d in self.trading_days:
for m in islice(d, 65):
for m in islice(d, 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(d, 65, None):
for m in islice(d, 64, None):
# Check the rest of the day.
self.assertTrue(should_trigger(m))

def test_BeforeClose(self):
Expand Down
35 changes: 29 additions & 6 deletions zipline/utils/events.py
Expand Up @@ -115,11 +115,11 @@ def _td_check(td):
seconds = td.total_seconds()

# 23400 seconds is 6 hours and 30 minutes.
if 0 <= seconds <= 23400:
if 60 <= seconds <= 23400:
return td
else:
raise ValueError('offset must be in between 0 minutes and 6 hours and'
' 30 minutes')
raise ValueError('offset must be in between 1 minute and 6 hours and'
' 30 minutes inclusive')


def _build_offset(offset, kwargs, default):
Expand Down Expand Up @@ -323,11 +323,23 @@ def __init__(self, offset=None, **kwargs):
self.offset = _build_offset(
offset,
kwargs,
datetime.timedelta(), # Defaults to the first minute.
datetime.timedelta(minutes=1), # Defaults to the first minute.
)

self._dt = None

def should_trigger(self, dt):
return self.env.get_open_and_close(dt)[0] + self.offset <= dt
return self._get_open(dt) + self.offset <= dt

def _get_open(self, dt):
"""
Cache the open for each day.
"""
if self._dt is None or (self._dt.date() != dt.date()):
self._dt = self.env.get_open_and_close(dt)[0] \
- datetime.timedelta(minutes=1)

return self._dt


class BeforeClose(StatelessRule):
Expand All @@ -344,8 +356,19 @@ def __init__(self, offset=None, **kwargs):
datetime.timedelta(minutes=1), # Defaults to the last minute.
)

self._dt = None

def should_trigger(self, dt):
return self.env.get_open_and_close(dt)[1] - self.offset < dt
return self._get_close(dt) - self.offset < dt

def _get_close(self, dt):
"""
Cache the close for each day.
"""
if self._dt is None or (self._dt.date() != dt.date()):
self._dt = self.env.get_open_and_close(dt)[1]

return self._dt


class NotHalfDay(StatelessRule):
Expand Down

0 comments on commit 0f52162

Please sign in to comment.