mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-14 11:15:09 +08:00
BUG: Fixes issues with AssetFinder future lookups
Contracts must have been trading at the as_of_date to be considered valid, and a contract's position in the chain is now zero-indexed.
This commit is contained in:
+30
-12
@@ -581,19 +581,22 @@ class AssetFinderTestCase(TestCase):
|
||||
'symbol': 'ADN15',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-06-15', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-06-15', 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')
|
||||
'expiration_date': pd.Timestamp('2015-09-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
0: {
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
|
||||
}
|
||||
@@ -602,13 +605,12 @@ class AssetFinderTestCase(TestCase):
|
||||
dt = pd.Timestamp('2015-06-19', tz='UTC')
|
||||
|
||||
# Check that the primary and secondary contracts are as expected
|
||||
primary = finder.lookup_future_in_chain('AD', dt, 1)
|
||||
secondary = finder.lookup_future_in_chain('AD', dt, 2)
|
||||
primary = finder.lookup_future_in_chain('AD', dt, 0)
|
||||
secondary = finder.lookup_future_in_chain('AD', dt, 1)
|
||||
self.assertEqual(primary.sid, 1)
|
||||
self.assertEqual(secondary.sid, 0)
|
||||
|
||||
# Check that we get None for an invalid contract num
|
||||
self.assertIsNone(finder.lookup_future_in_chain('AD', dt, 0))
|
||||
self.assertIsNone(finder.lookup_future_in_chain('AD', dt, -10))
|
||||
self.assertIsNone(finder.lookup_future_in_chain('AD', dt, 10))
|
||||
self.assertIsNone(finder.lookup_future_in_chain('CL', dt, 1))
|
||||
@@ -619,19 +621,32 @@ class AssetFinderTestCase(TestCase):
|
||||
'symbol': 'ADN15',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-06-15', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-06-15', 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')
|
||||
'expiration_date': pd.Timestamp('2015-09-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
# Starts trading today, so should be valid.
|
||||
0: {
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-06-19', tz='UTC')
|
||||
},
|
||||
# Copy of the above future, but starts trading in August,
|
||||
# so it isn't valid.
|
||||
3: {
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-08-01', tz='UTC')
|
||||
},
|
||||
|
||||
}
|
||||
@@ -652,19 +667,22 @@ class AssetFinderTestCase(TestCase):
|
||||
'symbol': 'ADN15',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-06-15', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-06-15', 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')
|
||||
'expiration_date': pd.Timestamp('2015-09-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
0: {
|
||||
'symbol': 'ADF16',
|
||||
'root_symbol': 'AD',
|
||||
'asset_type': 'future',
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC')
|
||||
'expiration_date': pd.Timestamp('2015-12-14', tz='UTC'),
|
||||
'start_date': pd.Timestamp('2015-01-01', tz='UTC')
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -247,7 +247,8 @@ class AssetFinder(object):
|
||||
"""
|
||||
try:
|
||||
return [c for c in self.future_chains_cache[root_symbol]
|
||||
if c.expiration_date > as_of_date]
|
||||
if c.expiration_date and (c.expiration_date > as_of_date)
|
||||
and c.start_date and (c.start_date <= as_of_date)]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@@ -269,7 +270,7 @@ class AssetFinder(object):
|
||||
as_of_date = normalize_date(as_of_date)
|
||||
return self._valid_contracts(root_symbol, as_of_date)
|
||||
|
||||
def lookup_future_in_chain(self, root_symbol, as_of_date, contract_num=1):
|
||||
def lookup_future_in_chain(self, root_symbol, as_of_date, contract_num=0):
|
||||
""" Find a specific contract in the futures chain for a given
|
||||
root symbol.
|
||||
|
||||
@@ -293,11 +294,10 @@ class AssetFinder(object):
|
||||
as_of_date = normalize_date(as_of_date)
|
||||
|
||||
valid_contracts = self._valid_contracts(root_symbol, as_of_date)
|
||||
contract_index = contract_num - 1
|
||||
|
||||
if valid_contracts and contract_index >= 0:
|
||||
if valid_contracts and contract_num >= 0:
|
||||
try:
|
||||
return valid_contracts[contract_index]
|
||||
return valid_contracts[contract_num]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user