Repository: quantopian/zipline
File: tests/test_continuous_futures.py (Python)

Code before:
    def test_get_contract_center(self):
        asset_finder = self.asset_finder
        get_contract_center = partial(
            self.volume_roll_finder.get_contract_center,
            root_symbol='CL',
            offset=0,
        )

        # Test that the current contract adheres to the rolls.
        self.assertEqual(
            get_contract_center(dt=pd.Timestamp('2017-01-18', tz='UTC')),
            self.asset_finder.retrieve_asset(1000),
        )
        self.assertEqual(
            get_contract_center(dt=pd.Timestamp('2017-01-19', tz='UTC')),
            self.asset_finder.retrieve_asset(1001),
        )

        # Test that we still get the correct current contract close to the max
        # day boundary.
        self.assertEqual(
            get_contract_center(dt=pd.Timestamp('2017-04-17', tz='UTC')),
            self.asset_finder.retrieve_asset(1003),
        )
        self.assertEqual(
            get_contract_center(dt=pd.Timestamp('2017-04-18', tz='UTC')),
            self.asset_finder.retrieve_asset(1004),
        )


class OrderedContractsTestCase(WithAssetFinder,
                               ZiplineTestCase):

    @classmethod
    def make_root_symbols_info(self):
        return pd.DataFrame({
            'root_symbol': ['FO', 'BA', 'BZ'],
            'root_symbol_id': [1, 2, 3],
            'exchange': ['CME', 'CME', 'CME']})

    @classmethod
    def make_futures_info(self):
        fo_frame = DataFrame({
            'root_symbol': ['FO'] * 4,
            'asset_name': ['Foo'] * 4,
            'symbol': ['FOF16', 'FOG16', 'FOH16', 'FOJ16'],
            'sid': range(1, 5),
            'start_date': pd.date_range('2015-01-01', periods=4, tz="UTC"),
            'end_date': pd.date_range('2016-01-01', periods=4, tz="UTC"),
            'notice_date': pd.date_range('2016-01-01', periods=4, tz="UTC"),
            'expiration_date': pd.date_range(

Review comment (bug):
I'm thinking it might be more maintainable to define these dates relative to `self.END_DATE`, i.e. in https://github.com/quantopian/zipline/pull/1917 I pushed the end date back, which would have broken the intention of these tests and I don't think I would have realized it.

Code after:
            start=self.START_DATE + self.trading_calendar.day,
            end=self.second_end_date,
            offset=0,
        )
        self.assertEqual(
            rolls,
            [
                (1000, pd.Timestamp('2017-01-19', tz='UTC')),
                (1001, pd.Timestamp('2017-02-13', tz='UTC')),
                (1002, None),
            ],
        )

    def test_no_roll(self):
        # If we call 'get_rolls' with start and end dates that do not have any
        # rolls between them, we should still expect the last roll date to be
        # computed successfully.
        date_not_near_roll = pd.Timestamp('2017-02-01', tz='UTC')
        rolls = self.volume_roll_finder.get_rolls(
            root_symbol='CL',
            start=date_not_near_roll,
            end=date_not_near_roll + self.trading_calendar.day,
            offset=0,
        )
        self.assertEqual(rolls, [(1001, None)])

    def test_roll_in_grace_period(self):
        """
        The volume roll finder can look for data up to a week before the given
        date. This test asserts that we not only return the correct active
        contract during that previous week (grace period), but also that we do
        not go into exception if one of the contracts does not exist.
        """
        rolls = self.volume_roll_finder.get_rolls(
            root_symbol='CL',
            start=self.second_end_date,
            end=self.third_end_date,
            offset=0,
        )
        self.assertEqual(
            rolls,
            [
                (1002, pd.Timestamp('2017-03-16', tz='UTC')),
                (1003, None),
            ],
        )

    def test_end_before_auto_close(self):
        # Test that we correctly roll from CLJ17 (1003) to CLK17 (1004) even
        # though CLJ17 has an auto close date after its end date.
        rolls = self.volume_roll_finder.get_rolls(