From 4235dbd758ea25c77465b52290d06e3d364681d0 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Thu, 27 Oct 2016 16:23:03 -0400 Subject: [PATCH] BUG: Fix continuous future history with offsets. Apply offset value when writing out the rolls in a continuous future which is offset from the primary. --- tests/test_continuous_futures.py | 54 ++++++++++++++++++++++++++++++++ zipline/assets/roll_finder.py | 5 +-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/tests/test_continuous_futures.py b/tests/test_continuous_futures.py index cc3bd451..0db936fe 100644 --- a/tests/test_continuous_futures.py +++ b/tests/test_continuous_futures.py @@ -456,6 +456,60 @@ def record_current_contract(algo, data): 3, "Should be FOJ16 on session after roll.") + def test_history_sid_session_secondary(self): + cf = self.data_portal.asset_finder.create_continuous_future( + 'FO', 1, 'calendar') + window = self.data_portal.get_history_window( + [cf], + Timestamp('2016-03-04 18:01', tz='US/Eastern').tz_convert('UTC'), + 30, '1d', 'sid') + + self.assertEqual(window.loc['2016-01-26', cf], + 1, + "Should be FOG16 at beginning of window.") + + self.assertEqual(window.loc['2016-01-27', cf], + 2, + "Should be FOH16 after first roll.") + + self.assertEqual(window.loc['2016-02-25', cf], + 2, + "Should be FOH16 on session before roll.") + + self.assertEqual(window.loc['2016-02-26', cf], + 3, + "Should be FOJ16 on session with roll.") + + self.assertEqual(window.loc['2016-02-29', cf], + 3, + "Should be FOJ16 on session after roll.") + + # Advance the window a month. + window = self.data_portal.get_history_window( + [cf], + Timestamp('2016-04-06 18:01', tz='US/Eastern').tz_convert('UTC'), + 30, '1d', 'sid') + + self.assertEqual(window.loc['2016-02-25', cf], + 2, + "Should be FOH16 at beginning of window.") + + self.assertEqual(window.loc['2016-02-26', cf], + 3, + "Should be FOJ16 on session with roll.") + + self.assertEqual(window.loc['2016-02-29', cf], + 3, + "Should be FOJ16 on session after roll.") + + self.assertEqual(window.loc['2016-03-24', cf], + 4, + "Should be FOK16 on session with roll.") + + self.assertEqual(window.loc['2016-03-28', cf], + 4, + "Should be FOK16 on session after roll.") + def test_history_sid_session_volume_roll(self): cf = self.data_portal.asset_finder.create_continuous_future( 'FO', 0, 'volume') diff --git a/zipline/assets/roll_finder.py b/zipline/assets/roll_finder.py index 3df6c94c..fe6ec5e5 100644 --- a/zipline/assets/roll_finder.py +++ b/zipline/assets/roll_finder.py @@ -79,7 +79,7 @@ class RollFinder(with_metaclass(ABCMeta, object)): is after the range. """ oc = self.asset_finder.get_ordered_contracts(root_symbol) - front = self.get_contract_center(root_symbol, end, offset) + front = self.get_contract_center(root_symbol, end, 0) back = oc.contract_at_offset(front, 1, end.value) if back is not None: first = self._active_contract(oc, front, back, end) @@ -106,7 +106,8 @@ class RollFinder(with_metaclass(ABCMeta, object)): session_loc -= 1 roll_session = sessions[session_loc + 1] if roll_session > start: - rolls.insert(0, (front, roll_session)) + rolls.insert(0, (oc.contract_sids[i + offset], + roll_session)) i -= 1 auto_close_date = Timestamp(oc.auto_close_dates[i], tz='UTC')