Repository: quantopian/zipline
File: zipline/finance/performance/tracker.py (Python)

Code before:

        minute_packet = self.to_dict(emission_type='minute')
        return minute_packet

    def handle_market_close(self, dt, data_portal):
        """
        Handles the close of the given day, in both minute and daily emission.
        In daily emission, also updates performance, benchmark and risk metrics
        as it would in handle_minute_close if it were minute emission.

        Parameters
        __________
        dt : Timestamp
            The minute that is ending

        Returns
        _______
        A daily perf packet.
        """
        completed_date = self.day

        if self.emission_rate == 'daily':
            self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
            self.update_performance()
            account = self.get_account(False)

            benchmark_value = self.all_benchmark_returns[completed_date]

            self.cumulative_risk_metrics.update(
                completed_date,
                self.todays_performance.returns,
                benchmark_value,
                account.leverage)

        # increment the day counter before we move markers forward.
        self.day_count += 1.0

        # Get the next trading day and, if it is past the bounds of this
        # simulation, return the daily perf packet
        next_trading_day = self.env.next_trading_day(completed_date)

        # Take a snapshot of our current performance to return to the
        # browser.
        daily_update = self.to_dict(emission_type='daily')

        # On the last day of the test, don't create tomorrow's performance
        # period.  We may not be able to find the next trading day if we're at
        # the end of our historical data
        if self.market_close >= self.last_close:
            return daily_update


Review comment (bug):
the method that was previously `handle_market_close_daily` and contains this block was only called in daily mode. I suspect running this block would not effectively update anything, as that would have been done in the latest `handle_minute_close`. Additionally, I believe lines like `benchmark_value = self.all_benchmark_returns[completed_date]` would crash if called in minute emission, since the `completed_date` is normalized and the benchmark would not have midnight


Code after:

        minute_packet = self.to_dict(emission_type='minute')
        return minute_packet

    def handle_market_close(self, dt, data_portal):
        """
        Handles the close of the given day, in both minute and daily emission.
        In daily emission, also updates performance, benchmark and risk metrics
        as it would in handle_minute_close if it were minute emission.

        Parameters
        __________
        dt : Timestamp
            The minute that is ending

        Returns
        _______
        A daily perf packet.
        """
        completed_date = self.day

        if self.emission_rate == 'daily':
            # this method is called for both minutely and daily emissions, but
            # this chunk of code here only applies for daily emissions. (since
            # it's done every minute, elsewhere, for minutely emission).
            self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
            self.update_performance()
            account = self.get_account(False)

            benchmark_value = self.all_benchmark_returns[completed_date]

            self.cumulative_risk_metrics.update(
                completed_date,
                self.todays_performance.returns,
                benchmark_value,
                account.leverage)

        # increment the day counter before we move markers forward.
        self.day_count += 1.0

        # Get the next trading day and, if it is past the bounds of this
        # simulation, return the daily perf packet
        next_trading_day = self.env.next_trading_day(completed_date)

        # Take a snapshot of our current performance to return to the
        # browser.
        daily_update = self.to_dict(emission_type='daily')

        # On the last day of the test, don't create tomorrow's performance
        # period.  We may not be able to find the next trading day if we're at
        # the end of our historical data