Repository: quantopian/zipline
File: zipline/assets/roll_finder.py (Python)

Code before:
        | ____/                +   <--- 'F'
        |_________|__|___|________
                  a  b   c         <--- Switches

        We should treat 'a' as the roll date rather than 'c' because from the
        perspective of 'a', if a switch happens and we are pretty close to the
        auto-close date, we would probably assume it is time to roll. This
        means that for every date after 'a', `data.current(cf, 'contract')`
        should return the 'G' contract.
        """
        front_contract = oc.sid_to_contract[front].contract
        back_contract = oc.sid_to_contract[back].contract

        # If the front contract has reached its auto close date, the back
        # contract must be the active one, so return it immediately. Similarly,
        # in the rare case that the back contract has not even started yet,
        # short circuit here and return the front contract.
        if dt >= front_contract.auto_close_date:
            return back
        elif dt < back_contract.start_date:
            return front

        tc = self.trading_calendar
        trading_day = tc.day
        prev = dt - trading_day
        get_value = self.session_reader.get_value

        front_vol = get_value(front, prev, 'volume')
        back_vol = get_value(back, prev, 'volume')
        if back_vol > front_vol:
            return back

        gap_start = max(
            back_contract.start_date,
            front_contract.auto_close_date - (trading_day * self.GRACE_DAYS),
        )
        gap_end = prev - trading_day
        if dt < gap_start:
            return front

        # If we are within `self.GRACE_DAYS` of the front contract's auto close
        # date, and a volume flip happened during that period, return the back
        # contract as the active one.
        sessions = tc.sessions_in_range(
            tc.minute_to_session_label(gap_start),
            tc.minute_to_session_label(gap_end),
        )
        for session in sessions:
            front_vol = get_value(front, session, 'volume')
            back_vol = get_value(back, session, 'volume')
            if back_vol > front_vol:

Review comment (suggestion):
@yankees714 Just FYI, I made this change as you pointed out to be `>` instead of `>=` (and Jamie confirmed), and updated the tests accordingly (basically just moving rolls up by a day where necessary).

Code after:
        | ____/                +   <--- 'F'
        |_________|__|___|________
                  a  b   c         <--- Switches

        We should treat 'a' as the roll date rather than 'c' because from the
        perspective of 'a', if a switch happens and we are pretty close to the
        auto-close date, we would probably assume it is time to roll. This
        means that for every date after 'a', `data.current(cf, 'contract')`
        should return the 'G' contract.
        """
        front_contract = oc.sid_to_contract[front].contract
        back_contract = oc.sid_to_contract[back].contract

        tc = self.trading_calendar
        trading_day = tc.day
        prev = dt - trading_day
        get_value = self.session_reader.get_value

        # If the front contract is past its auto close date it cannot be the
        # active contract, so return the back contract. Similarly, if the back
        # contract has not even started yet, just return the front contract.
        # The reason for comparing the back contract's start date to 'prev'
        # instead of to 'dt' is because we need to get each contract's volume
        # on the previous day, so we need to make sure the back contract exists
        # on 'prev' in order to call 'get_value' below.
        if dt > front_contract.auto_close_date:
            return back
        elif prev < back_contract.start_date:
            return front

        front_vol = get_value(front, prev, 'volume')
        back_vol = get_value(back, prev, 'volume')
        if back_vol > front_vol:
            return back

        gap_start = max(
            back_contract.start_date,
            front_contract.auto_close_date - (trading_day * self.GRACE_DAYS),
        )
        gap_end = prev - trading_day
        if dt < gap_start:
            return front

        # If we are within `self.GRACE_DAYS` of the front contract's auto close
        # date, and a volume flip happened during that period, return the back
        # contract as the active one.
        sessions = tc.sessions_in_range(
            tc.minute_to_session_label(gap_start),
            tc.minute_to_session_label(gap_end),
        )
        for session in sessions: