mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-04 01:56:36 +08:00
MAINT: Moved auto_close_date to Asset
Handle custom data source with non-int sids
This commit is contained in:
+15
-13
@@ -37,7 +37,7 @@ cimport numpy as np
|
||||
# IMPORTANT NOTE: You must change this template if you change
|
||||
# Asset.__reduce__, or else we'll attempt to unpickle an old version of this
|
||||
# class
|
||||
CACHE_FILE_TEMPLATE = '/tmp/.%s-%s.v5.cache'
|
||||
CACHE_FILE_TEMPLATE = '/tmp/.%s-%s.v6.cache'
|
||||
|
||||
cdef class Asset:
|
||||
|
||||
@@ -51,6 +51,7 @@ cdef class Asset:
|
||||
cdef readonly object start_date
|
||||
cdef readonly object end_date
|
||||
cdef public object first_traded
|
||||
cdef readonly object auto_close_date
|
||||
|
||||
cdef readonly object exchange
|
||||
|
||||
@@ -61,6 +62,7 @@ cdef class Asset:
|
||||
object start_date=None,
|
||||
object end_date=None,
|
||||
object first_traded=None,
|
||||
object auto_close_date=None,
|
||||
object exchange="",
|
||||
*args,
|
||||
**kwargs):
|
||||
@@ -73,6 +75,7 @@ cdef class Asset:
|
||||
self.start_date = start_date
|
||||
self.end_date = end_date
|
||||
self.first_traded = first_traded
|
||||
self.auto_close_date = auto_close_date
|
||||
|
||||
def __int__(self):
|
||||
return self.sid
|
||||
@@ -127,7 +130,7 @@ cdef class Asset:
|
||||
|
||||
def __repr__(self):
|
||||
attrs = ('symbol', 'asset_name', 'exchange',
|
||||
'start_date', 'end_date', 'first_traded')
|
||||
'start_date', 'end_date', 'first_traded', 'auto_close_date')
|
||||
tuples = ((attr, repr(getattr(self, attr, None)))
|
||||
for attr in attrs)
|
||||
strings = ('%s=%s' % (t[0], t[1]) for t in tuples)
|
||||
@@ -147,6 +150,7 @@ cdef class Asset:
|
||||
self.start_date,
|
||||
self.end_date,
|
||||
self.first_traded,
|
||||
self.auto_close_date,
|
||||
self.exchange,))
|
||||
|
||||
cpdef to_dict(self):
|
||||
@@ -160,6 +164,7 @@ cdef class Asset:
|
||||
'start_date': self.start_date,
|
||||
'end_date': self.end_date,
|
||||
'first_traded': self.first_traded,
|
||||
'auto_close_date': self.auto_close_date,
|
||||
'exchange': self.exchange,
|
||||
}
|
||||
|
||||
@@ -181,7 +186,7 @@ cdef class Equity(Asset):
|
||||
|
||||
def __repr__(self):
|
||||
attrs = ('symbol', 'asset_name', 'exchange',
|
||||
'start_date', 'end_date', 'first_traded')
|
||||
'start_date', 'end_date', 'first_traded', 'auto_close_date')
|
||||
tuples = ((attr, repr(getattr(self, attr, None)))
|
||||
for attr in attrs)
|
||||
strings = ('%s=%s' % (t[0], t[1]) for t in tuples)
|
||||
@@ -227,10 +232,8 @@ cdef class Future(Asset):
|
||||
cdef readonly object root_symbol
|
||||
cdef readonly object notice_date
|
||||
cdef readonly object expiration_date
|
||||
cdef readonly object auto_close_date
|
||||
cdef readonly object tick_size
|
||||
cdef readonly float multiplier
|
||||
cdef readonly object effective_expiration
|
||||
|
||||
def __cinit__(self,
|
||||
int sid, # sid is required
|
||||
@@ -250,16 +253,16 @@ cdef class Future(Asset):
|
||||
self.root_symbol = root_symbol
|
||||
self.notice_date = notice_date
|
||||
self.expiration_date = expiration_date
|
||||
self.auto_close_date = auto_close_date
|
||||
self.tick_size = tick_size
|
||||
self.multiplier = multiplier
|
||||
|
||||
if notice_date is None:
|
||||
self.effective_expiration = expiration_date
|
||||
elif expiration_date is None:
|
||||
self.effective_expiration = notice_date
|
||||
else:
|
||||
self.effective_expiration = min(notice_date, expiration_date)
|
||||
if auto_close_date is None:
|
||||
if notice_date is None:
|
||||
self.auto_close_date = expiration_date
|
||||
elif expiration_date is None:
|
||||
self.auto_close_date = notice_date
|
||||
else:
|
||||
self.auto_close_date = min(notice_date, expiration_date)
|
||||
|
||||
def __str__(self):
|
||||
if self.symbol:
|
||||
@@ -307,7 +310,6 @@ cdef class Future(Asset):
|
||||
super_dict['root_symbol'] = self.root_symbol
|
||||
super_dict['notice_date'] = self.notice_date
|
||||
super_dict['expiration_date'] = self.expiration_date
|
||||
super_dict['auto_close_date'] = self.auto_close_date
|
||||
super_dict['tick_size'] = self.tick_size
|
||||
super_dict['multiplier'] = self.multiplier
|
||||
return super_dict
|
||||
|
||||
@@ -19,6 +19,7 @@ from contextlib2 import ExitStack
|
||||
from logbook import Logger, Processor
|
||||
from pandas.tslib import normalize_date
|
||||
|
||||
from zipline.errors import SidsNotFound
|
||||
from zipline.finance.trading import NoFurtherDataError
|
||||
from zipline.protocol import (
|
||||
BarData,
|
||||
@@ -57,19 +58,32 @@ class AlgorithmSimulator(object):
|
||||
# Snapshot Setup
|
||||
# ==============
|
||||
|
||||
def _get_effective_expiration(sid,
|
||||
finder=self.env.asset_finder,
|
||||
default=self.sim_params.last_close
|
||||
+ timedelta(days=1)):
|
||||
asset = finder.retrieve_asset(sid)
|
||||
return getattr(asset, 'effective_expiration', None) or default
|
||||
def _get_asset_close_date(sid,
|
||||
finder=self.env.asset_finder,
|
||||
default=self.sim_params.last_close
|
||||
+ timedelta(days=1)):
|
||||
try:
|
||||
asset = finder.retrieve_asset(sid)
|
||||
except ValueError:
|
||||
# Handle sid not an int, such as from a custom source.
|
||||
# So that they don't compare equal to other sids, and we'd
|
||||
# blow up comparing strings to ints, let's give them unique
|
||||
# close dates.
|
||||
return default + timedelta(microseconds=id(sid))
|
||||
except SidsNotFound:
|
||||
return default
|
||||
# Default is used when the asset has no auto close date,
|
||||
# and is set to a time after the simulation ends, so that the
|
||||
# relevant asset isn't removed from the universe at all
|
||||
# (at least not for this reason).
|
||||
return asset.auto_close_date or default
|
||||
|
||||
self._get_expiration = _get_effective_expiration
|
||||
self._get_asset_close = _get_asset_close_date
|
||||
|
||||
# The algorithm's data as of our most recent event.
|
||||
# We want an object that will have empty objects as default
|
||||
# values on missing keys.
|
||||
self.current_data = BarData(SortedDict(self._get_expiration))
|
||||
# Maintain sids in order by asset close date, so that we can more
|
||||
# efficiently remove them when their times come...
|
||||
self.current_data = BarData(SortedDict(self._get_asset_close))
|
||||
|
||||
# We don't have a datetime for the current snapshot until we
|
||||
# receive a message.
|
||||
@@ -110,11 +124,11 @@ class AlgorithmSimulator(object):
|
||||
self.simulation_dt = date
|
||||
self.on_dt_changed(date)
|
||||
|
||||
expired = list(takewhile(
|
||||
lambda asset_id: self._get_expiration(asset_id) < date,
|
||||
closed = list(takewhile(
|
||||
lambda asset_id: self._get_asset_close(asset_id) < date,
|
||||
self.current_data
|
||||
))
|
||||
for sid in expired:
|
||||
for sid in closed:
|
||||
try:
|
||||
del self.current_data[sid]
|
||||
except KeyError:
|
||||
|
||||
Reference in New Issue
Block a user