Repository: quantopian/zipline
File: zipline/finance/risk/cumulative.py (Python)

Code before:
            self.algorithm_returns,
            self.benchmark_returns,
        )
        self.sharpe[dt_loc] = sharpe_ratio(
            self.algorithm_returns,
        )
        self.downside_risk[dt_loc] = downside_risk(
            self.algorithm_returns
        )
        self.sortino[dt_loc] = sortino_ratio(
            self.algorithm_returns,
            _downside_risk=self.downside_risk[dt_loc]
        )
        self.information[dt_loc] = information_ratio(
            self.algorithm_returns,
            self.benchmark_returns,
        )
        self.max_drawdown = max_drawdown(
            self.algorithm_returns
        )
        self.max_drawdowns[dt_loc] = self.max_drawdown
        self.max_leverage = self.calculate_max_leverage()
        self.max_leverages[dt_loc] = self.max_leverage

        self.cvar[dt_loc] = conditional_value_at_risk(
            returns=pd.DataFrame(self.algorithm_returns[-CVAR_LOOKBACK_DAYS:]),
            weights=[1],
            cutoff=CVAR_CUTOFF,
        )

    def to_dict(self):
        """
        Creates a dictionary representing the state of the risk report.
        Returns a dict object of the form:
        """
        dt = self.latest_dt
        dt_loc = self.latest_dt_loc
        period_label = dt.strftime("%Y-%m")
        rval = {
            'trading_days': self.num_trading_days,
            'benchmark_volatility':
            self.benchmark_volatility[dt_loc],
            'algo_volatility':
            self.algorithm_volatility[dt_loc],
            'treasury_period_return': self.treasury_period_return,
            # Though the two following keys say period return,
            # they would be more accurately called the cumulative return.
            # However, the keys need to stay the same, for now, for backwards
            # compatibility with existing consumers.
            'algorithm_period_return':
            self.algorithm_cumulative_returns[dt_loc],

Review comment (performance):
How often is this called? Any concern about the speed of making a `DataFrame` here?

When we originally moved the other metrics to empyrical, they slowed down the zipline test suite dramatically because of all the `Series` constructions, whereas zipline had been using raw numpy arrays previously. Eventually empyrical was updated to support either an `ndarray` or a `Series/DataFrame` as input to each function, without having to wrap the arrays in pandas objects. This dropped the test times back down.

Code after:
        )
        self.downside_risk[dt_loc] = downside_risk(
            self.algorithm_returns
        )
        self.sortino[dt_loc] = sortino_ratio(
            self.algorithm_returns,
            _downside_risk=self.downside_risk[dt_loc]
        )
        self.information[dt_loc] = information_ratio(
            self.algorithm_returns,
            self.benchmark_returns,
        )
        self.max_drawdown = max_drawdown(
            self.algorithm_returns
        )
        self.max_drawdowns[dt_loc] = self.max_drawdown
        self.max_leverage = self.calculate_max_leverage()
        self.max_leverages[dt_loc] = self.max_leverage

    def to_dict(self):
        """
        Creates a dictionary representing the state of the risk report.
        Returns a dict object of the form:
        """
        dt = self.latest_dt
        dt_loc = self.latest_dt_loc
        period_label = dt.strftime("%Y-%m")
        rval = {
            'trading_days': self.num_trading_days,
            'benchmark_volatility':
            self.benchmark_volatility[dt_loc],
            'algo_volatility':
            self.algorithm_volatility[dt_loc],
            'treasury_period_return': self.treasury_period_return,
            # Though the two following keys say period return,
            # they would be more accurately called the cumulative return.
            # However, the keys need to stay the same, for now, for backwards
            # compatibility with existing consumers.
            'algorithm_period_return':
            self.algorithm_cumulative_returns[dt_loc],
            'benchmark_period_return':
            self.benchmark_cumulative_returns[dt_loc],
            'beta': self.beta[dt_loc],
            'alpha': self.alpha[dt_loc],
            'sharpe': self.sharpe[dt_loc],
            'sortino': self.sortino[dt_loc],
            'information': self.information[dt_loc],
            'excess_return': self.excess_returns[dt_loc],
            'max_drawdown': self.max_drawdown,
            'max_leverage': self.max_leverage,
            'period_label': period_label