diff --git a/tests/test_assets.py b/tests/test_assets.py index 376659c9..9dfd2cec 100644 --- a/tests/test_assets.py +++ b/tests/test_assets.py @@ -18,6 +18,7 @@ Tests for the zipline.assets package """ from contextlib import contextmanager from datetime import datetime, timedelta +from functools import partial import pickle import sys from types import GetSetDescriptorType @@ -25,7 +26,6 @@ from unittest import TestCase import uuid import warnings -from nose.tools import raises from nose_parameterized import parameterized from numpy import full, int32, int64 import pandas as pd @@ -483,6 +483,97 @@ class AssetFinderTestCase(WithTradingCalendar, ZiplineTestCase): self.assertEqual(2, finder.lookup_symbol('BRK_A', None, fuzzy=True)) self.assertEqual(2, finder.lookup_symbol('BRK_A', dt, fuzzy=True)) + def test_lookup_symbol_change_ticker(self): + T = partial(pd.Timestamp, tz='utc') + metadata = pd.DataFrame.from_records( + [ + # sid 0 + { + 'symbol': 'A', + 'start_date': T('2014-01-01'), + 'end_date': T('2014-01-05'), + }, + { + 'symbol': 'B', + 'start_date': T('2014-01-06'), + 'end_date': T('2014-01-10'), + }, + + # sid 1 + { + 'symbol': 'C', + 'start_date': T('2014-01-01'), + 'end_date': T('2014-01-05'), + }, + { + 'symbol': 'A', # claiming the unused symbol 'A' + 'start_date': T('2014-01-06'), + 'end_date': T('2014-01-10'), + }, + ], + index=[0, 0, 1, 1], + ) + self.write_assets(equities=metadata) + finder = self.asset_finder + + # note: these assertions walk forward in time, starting at assertions + # about ownership before the start_date and ending with assertions + # after the end_date; new assertions should be inserted in the correct + # locations + + # no one held 'A' before 01 + with self.assertRaises(SymbolNotFound): + finder.lookup_symbol('A', T('2013-12-31')) + + # no one held 'C' before 01 + with self.assertRaises(SymbolNotFound): + finder.lookup_symbol('C', T('2013-12-31')) + + for asof in pd.date_range('2014-01-01', '2014-01-05', tz='utc'): + # from 01 through 05 sid 0 held 'A' + assert_equal( + finder.lookup_symbol('A', asof), + finder.retrieve_asset(0), + msg=str(asof), + ) + + # from 01 through 05 sid 1 held 'C' + assert_equal( + finder.lookup_symbol('C', asof), + finder.retrieve_asset(1), + msg=str(asof), + ) + + # no one held 'B' before 06 + with self.assertRaises(SymbolNotFound): + finder.lookup_symbol('B', T('2014-01-05')) + + # no one held 'C' after 06, however, no one has claimed it yet + # so it still maps to sid 1 + assert_equal( + finder.lookup_symbol('C', T('2014-01-07')), + finder.retrieve_asset(1), + ) + + for asof in pd.date_range('2014-01-06', '2014-01-11', tz='utc'): + # from 06 through 10 sid 0 held 'B' + # we test through the 11th because sid 1 is the last to hold 'B' + # so it should ffill + assert_equal( + finder.lookup_symbol('B', asof), + finder.retrieve_asset(0), + msg=str(asof), + ) + + # from 06 through 10 sid 1 held 'A' + # we test through the 11th because sid 1 is the last to hold 'A' + # so it should ffill + assert_equal( + finder.lookup_symbol('A', asof), + finder.retrieve_asset(1), + msg=str(asof), + ) + def test_lookup_symbol(self): # Incrementing by two so that start and end dates for each @@ -551,7 +642,7 @@ class AssetFinderTestCase(WithTradingCalendar, ZiplineTestCase): self.assertEqual( str(e.exception), - "Ambigious ownership of 'MULTIPLE', multiple companies held this" + "Ambiguous ownership of 'MULTIPLE', multiple companies held this" " ticker over the following ranges:\n" "[('2010-01-01 00:00:00', '2012-01-01 00:00:00')," " ('2011-01-01 00:00:00', '2012-01-01 00:00:00')]",