mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-07 15:59:08 +08:00
BUG: Determine valid future contracts with notice date
Since most brokers will cease accepting trades by the notice date, contracts should not be considered valid after the notice date. This commit adjusts the lookup_future_chain method to consider all contracts with notice dates on or following the current date invalid.
This commit is contained in:
+11
-12
@@ -542,19 +542,19 @@ class AssetFinderTestCase(TestCase):
|
||||
|
||||
def test_lookup_future_chain(self):
|
||||
metadata = {
|
||||
# Expires today, so should be valid
|
||||
# Notice day is today, so not valid
|
||||
2: {
|
||||
'symbol': 'ADN15',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-06-15', tz='UTC'),
|
||||
'notice_date': pd.Timestamp('2015-05-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
1: {
|
||||
'symbol': 'ADV15',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-09-14', tz='UTC'),
|
||||
'notice_date': pd.Timestamp('2015-08-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
# Starts trading today, so should be valid.
|
||||
@@ -562,8 +562,8 @@ class AssetFinderTestCase(TestCase):
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-06-15', tz='UTC')
|
||||
'notice_date': pd.Timestamp('2015-11-16', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-05-14', tz='UTC')
|
||||
},
|
||||
# Copy of the above future, but starts trading in August,
|
||||
# so it isn't valid.
|
||||
@@ -571,24 +571,23 @@ class AssetFinderTestCase(TestCase):
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'notice_date': pd.Timestamp('2015-11-16', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-08-01', tz='UTC')
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
finder = AssetFinder(metadata=metadata)
|
||||
dt = pd.Timestamp('2015-06-15', tz='UTC')
|
||||
dt = pd.Timestamp('2015-05-14', tz='UTC')
|
||||
last_year = pd.Timestamp('2014-01-01', tz='UTC')
|
||||
first_day = pd.Timestamp('2015-01-01', tz='UTC')
|
||||
|
||||
# Check that we get the expected number of contracts, in the
|
||||
# right order
|
||||
ad_contracts = finder.lookup_future_chain('AD', dt, dt)
|
||||
self.assertEqual(len(ad_contracts), 3)
|
||||
self.assertEqual(ad_contracts[0].sid, 2)
|
||||
self.assertEqual(ad_contracts[1].sid, 1)
|
||||
self.assertEqual(ad_contracts[2].sid, 0)
|
||||
self.assertEqual(len(ad_contracts), 2)
|
||||
self.assertEqual(ad_contracts[0].sid, 1)
|
||||
self.assertEqual(ad_contracts[1].sid, 0)
|
||||
|
||||
# Check that we get nothing if our knowledge date is last year
|
||||
ad_contracts = finder.lookup_future_chain('AD', dt, last_year)
|
||||
@@ -596,7 +595,7 @@ class AssetFinderTestCase(TestCase):
|
||||
|
||||
# Check that we get things that start on the knowledge date
|
||||
ad_contracts = finder.lookup_future_chain('AD', dt, first_day)
|
||||
self.assertEqual(len(ad_contracts), 2)
|
||||
self.assertEqual(len(ad_contracts), 1)
|
||||
|
||||
def test_map_identifier_index_to_sids(self):
|
||||
# Build an empty finder and some Assets
|
||||
|
||||
@@ -214,10 +214,10 @@ class AssetFinder(object):
|
||||
""" Sort by increasing expiration date the list of contracts
|
||||
for each root symbol in the future cache.
|
||||
"""
|
||||
exp_key = operator.attrgetter('expiration_date')
|
||||
notice_key = operator.attrgetter('notice_date')
|
||||
|
||||
for root_symbol in self.future_chains_cache:
|
||||
self.future_chains_cache[root_symbol].sort(key=exp_key)
|
||||
self.future_chains_cache[root_symbol].sort(key=notice_key)
|
||||
|
||||
def lookup_future_chain(self, root_symbol, as_of_date, knowledge_date):
|
||||
""" Return the futures chain for a given root symbol.
|
||||
@@ -241,7 +241,7 @@ class AssetFinder(object):
|
||||
"""
|
||||
try:
|
||||
return [c for c in self.future_chains_cache[root_symbol]
|
||||
if c.expiration_date and (as_of_date <= c.expiration_date)
|
||||
if c.notice_date and (as_of_date < c.notice_date)
|
||||
and c.start_date and (c.start_date <= knowledge_date)]
|
||||
except KeyError:
|
||||
raise RootSymbolNotFound(root_symbol=root_symbol)
|
||||
|
||||
Reference in New Issue
Block a user