Merge pull request #535 from quantopian/rename-security-to-asset

Refactor Security to Asset
This commit is contained in:
James Kirk
2015-03-19 17:09:46 -04:00
4 changed files with 140 additions and 80 deletions
+2 -2
View File
@@ -20,8 +20,8 @@ import numpy as np
ext_modules = [
Extension(
'zipline.assets._securities',
['zipline/assets/_securities.pyx'],
'zipline.assets._assets',
['zipline/assets/_assets.pyx'],
include_dirs=[np.get_include()],
),
]
+59 -19
View File
@@ -17,33 +17,73 @@
Tests for the zipline.assets package
"""
import sys
from unittest import TestCase
from zipline.assets._securities import Security
from zipline.assets._assets import Asset, Future
class SecurityTestCase(TestCase):
class AssetTestCase(TestCase):
def test_security_object(self):
self.assertEquals({5061: 'foo'}[Security(5061)], 'foo')
self.assertEquals(Security(5061), 5061)
self.assertEquals(5061, Security(5061))
def test_asset_object(self):
self.assertEquals({5061: 'foo'}[Asset(5061)], 'foo')
self.assertEquals(Asset(5061), 5061)
self.assertEquals(5061, Asset(5061))
self.assertEquals(Security(5061), Security(5061))
self.assertEquals(int(Security(5061)), 5061)
self.assertEquals(Asset(5061), Asset(5061))
self.assertEquals(int(Asset(5061)), 5061)
self.assertEquals(str(Security(5061)), 'Security(5061)')
self.assertEquals(str(Asset(5061)), 'Asset(5061)')
# TODO: we can't provide this property while subclassing
# int. Need to subclass object to fix all the following
# cases.
# assert Security(5061) != 5061.0
# with self.assertRaises(TypeError):
# assert Security(5061) + Security(5061)
class TestAssetRichCmp(TestCase):
# with self.assertRaises(TypeError):
# print float(Security(5061))
def test_lt(self):
self.assertTrue(Asset(3) < Asset(4))
self.assertFalse(Asset(4) < Asset(4))
self.assertFalse(Asset(5) < Asset(4))
# with self.assertRaises(TypeError):
# print float(Security(5061))
def test_le(self):
self.assertTrue(Asset(3) <= Asset(4))
self.assertTrue(Asset(4) <= Asset(4))
self.assertFalse(Asset(5) <= Asset(4))
def test_eq(self):
self.assertFalse(Asset(3) == Asset(4))
self.assertTrue(Asset(4) == Asset(4))
self.assertFalse(Asset(5) == Asset(4))
def test_ge(self):
self.assertFalse(Asset(3) >= Asset(4))
self.assertTrue(Asset(4) >= Asset(4))
self.assertTrue(Asset(5) >= Asset(4))
def test_gt(self):
self.assertFalse(Asset(3) > Asset(4))
self.assertFalse(Asset(4) > Asset(4))
self.assertTrue(Asset(5) > Asset(4))
def test_type_mismatch(self):
if sys.version_info.major < 3:
self.assertIsNotNone(Asset(3) < 'a')
self.assertIsNotNone('a' < Asset(3))
else:
with self.assertRaises(TypeError):
Asset(3) < 'a'
with self.assertRaises(TypeError):
'a' < Asset(3)
class testFuture(TestCase):
def test_repr(self):
future = Future(2468,
notice_date='2014-01-20',
expiration_date='2014-02-20')
rep = future.__repr__()
self.assertTrue("Future" in rep)
self.assertTrue("2468" in rep)
self.assertTrue("notice_date='2014-01-20'" in rep)
self.assertTrue("expiration_date='2014-02-20'" in rep)
-40
View File
@@ -1,40 +0,0 @@
import sys
from unittest import TestCase
from zipline.assets._securities import Security
class TestSecurityRichCmp(TestCase):
def test_lt(self):
self.assertTrue(Security(3) < Security(4))
self.assertFalse(Security(4) < Security(4))
self.assertFalse(Security(5) < Security(4))
def test_le(self):
self.assertTrue(Security(3) <= Security(4))
self.assertTrue(Security(4) <= Security(4))
self.assertFalse(Security(5) <= Security(4))
def test_eq(self):
self.assertFalse(Security(3) == Security(4))
self.assertTrue(Security(4) == Security(4))
self.assertFalse(Security(5) == Security(4))
def test_ge(self):
self.assertFalse(Security(3) >= Security(4))
self.assertTrue(Security(4) >= Security(4))
self.assertTrue(Security(5) >= Security(4))
def test_gt(self):
self.assertFalse(Security(3) > Security(4))
self.assertFalse(Security(4) > Security(4))
self.assertTrue(Security(5) > Security(4))
def test_type_mismatch(self):
if sys.version_info.major < 3:
self.assertIsNotNone(Security(3) < 'a')
self.assertIsNotNone('a' < Security(3))
else:
with self.assertRaises(TypeError):
Security(3) < 'a'
with self.assertRaises(TypeError):
'a' < Security(3)
@@ -14,22 +14,26 @@
# limitations under the License.
"""
Cythonized Security object.
Cythonized Asset object.
"""
cimport cython
import numpy as np
cimport numpy as np
cdef enum AssetType:
EQUITY = 1
FUTURE = 2
cdef class Security:
cdef class Asset:
cdef readonly int sid
# Cached hash of self.sid
cdef int sid_hash
cdef readonly object symbol
cdef readonly object security_name
cdef readonly object asset_name
cdef readonly AssetType asset_type
# TODO: Maybe declare as pandas Timestamp?
cdef readonly object start_date
@@ -41,16 +45,18 @@ cdef class Security:
def __cinit__(self,
int sid, # sid is required
object symbol="",
object security_name="",
object asset_name="",
object start_date=None,
object end_date=None,
object first_traded=None,
object exchange=""):
object exchange="",
*args,
**kwargs):
self.sid = sid
self.sid_hash = hash(sid)
self.sid_hash = hash(sid)
self.symbol = symbol
self.security_name = security_name
self.asset_name = asset_name
self.exchange = exchange
self.start_date = start_date
self.end_date = end_date
@@ -62,7 +68,7 @@ cdef class Security:
def __hash__(self):
return self.sid_hash
property security_start_date:
property asset_start_date:
"""
Alias for start_date to disambiguate from other `start_date`s in the
system.
@@ -70,7 +76,7 @@ cdef class Security:
def __get__(self):
return self.start_date
property security_end_date:
property asset_end_date:
"""
Alias for end_date to disambiguate from other `end_date`s in the
system.
@@ -92,14 +98,14 @@ cdef class Security:
"""
cdef int x_as_int, y_as_int
if isinstance(x, Security):
if isinstance(x, Asset):
x_as_int = x.sid
elif isinstance(x, int):
x_as_int = x
else:
return NotImplemented
if isinstance(y, Security):
if isinstance(y, Asset):
y_as_int = y.sid
elif isinstance(y, int):
y_as_int = y
@@ -131,18 +137,18 @@ cdef class Security:
def __str__(self):
if self.symbol:
return 'Security(%d [%s])' % (self.sid, self.symbol)
return 'Asset(%d [%s])' % (self.sid, self.symbol)
else:
return 'Security(%d)' % self.sid
return 'Asset(%d)' % self.sid
def __repr__(self):
attrs = ('symbol', 'security_name', 'exchange',
attrs = ('symbol', 'asset_name', 'exchange',
'start_date', 'end_date', 'first_traded')
tuples = ((attr, repr(getattr(self, attr, None)))
for attr in attrs)
strings = ('%s=%s' % (t[0], t[1]) for t in tuples)
params = ', '.join(strings)
return 'Security(%d, %s)' % (self.sid, params)
return 'Asset(%d, %s)' % (self.sid, params)
cpdef __reduce__(self):
"""
@@ -153,7 +159,7 @@ cdef class Security:
"""
return (self.__class__, (self.sid,
self.symbol,
self.security_name,
self.asset_name,
self.start_date,
self.end_date,
self.first_traded,
@@ -166,7 +172,7 @@ cdef class Security:
return {
'sid': self.sid,
'symbol': self.symbol,
'security_name': self.security_name,
'asset_name': self.asset_name,
'start_date': self.start_date,
'end_date': self.end_date,
'first_traded': self.first_traded,
@@ -176,6 +182,60 @@ cdef class Security:
@staticmethod
def from_dict(dict_):
"""
Build a Security instance from a dict.
Build an Asset instance from a dict.
"""
return Security(**dict_)
return Asset(**dict_)
cdef class Equity(Asset):
def __cinit__(self,
int sid, # sid is required
object symbol="",
object asset_name="",
object start_date=None,
object end_date=None,
object first_traded=None,
object exchange=""):
self.asset_type = EQUITY
def __repr__(self):
attrs = ('symbol', 'asset_name', 'exchange',
'start_date', 'end_date', 'first_traded')
tuples = ((attr, repr(getattr(self, attr, None)))
for attr in attrs)
strings = ('%s=%s' % (t[0], t[1]) for t in tuples)
params = ', '.join(strings)
return 'Equity(%d, %s)' % (self.sid, params)
cdef class Future(Asset):
cdef readonly object notice_date
cdef readonly object expiration_date
def __cinit__(self,
int sid, # sid is required
object symbol="",
object asset_name="",
object start_date=None,
object end_date=None,
object notice_date=None,
object expiration_date=None,
object first_traded=None,
object exchange=""):
self.asset_type = FUTURE
self.notice_date = notice_date
self.expiration_date = expiration_date
def __repr__(self):
attrs = ('symbol', 'asset_name', 'exchange',
'start_date', 'end_date', 'first_traded', 'notice_date',
'expiration_date')
tuples = ((attr, repr(getattr(self, attr, None)))
for attr in attrs)
strings = ('%s=%s' % (t[0], t[1]) for t in tuples)
params = ', '.join(strings)
return 'Future(%d, %s)' % (self.sid, params)