Portfolio metrics

There are a large number of metrics to evaluate the post-hoc goodness of your portfolio. Analyzing investment performance can help quantify the overall quality of investments in a portfolio, identify successful strategies, or highlight areas that need improvement.

Aggregate Returns (aggregate_returns)

function
skportfolio.metrics.metrics.aggregate_returns(returns, convert_to)

Aggregates returns by week, month, or year.

Parameters
  • returns (pd.Series) Daily returns of the strategy, noncumulative.
  • convert_to (str) Can be 'weekly', 'monthly', or 'yearly'.

Annualized Returns (annualize_rets)

function
skportfolio.metrics.metrics.annualize_rets(r, frequency=252) → float

Compunded annual growth rate, also called cagr

Annualized Volatility (annualize_vol)

function
skportfolio.metrics.metrics.annualize_vol(r, frequency=252, levy_alpha=2.0) → float

Annualizes the volatility of a set of returns

Calmar Ratio (calmar_ratio)

function
skportfolio.metrics.metrics.calmar_ratio(r, frequency=252) → float

Determines the Calmar ratio, a measure of risk-adjusted returns for investment funds based on the maximum drawdown. The Calmar ratio is a modified version of the Sterling ratio.

Conditional Drawdown at Risk (cdar)

function
skportfolio.metrics.metrics.cdar(r, level=0.05)

Calculate the conditional drawdown of risk (CDaR) of a portfolio/asset.

Parameters
  • r (pd.Series) Historical returns for an asset / portfolio
  • level (float) Confidence level (alpha)

Conditional Value At Risk (cvar)

function
skportfolio.metrics.metrics.cvar(r, level=0.05) → float

Calculates the conditional value at risk, with cutoff level of 5%

Parameters
  • r (pd.Series) Returns
  • level (float) percentile cutoff tail value

Corrected Sharpe Ratio (corrected_sharpe_ratio)

function
skportfolio.metrics.metrics.corrected_sharpe_ratio(r, riskfree_rate=0.0, period='DAILY', frequency=252) → float

Computes the annualizatin correction of the sharpe ratio of a set of returns. Sharpe Ratio: Estimation, Confidence Intervals, and Hypothesis Testing https://www.twosigma.com/wp-content/uploads/sharpe-tr-1.pdf Equation 10

Cumulative Returns (cumulative_returns)

function
skportfolio.metrics.metrics.cumulative_returns(returns, starting_value=1000) → Series

Computes (1+r).prod() * starting_value

Downside Risk (downside_risk)

function
skportfolio.metrics.metrics.downside_risk(r, target_return=0.0) → float

Calculates downside risk

Drawdown (drawdown)

function
skportfolio.metrics.metrics.drawdown(returns)

Takes a time series of asset returns. returns a DataFrame with columns for the wealth index, the previous peaks and the percentage drawdown

Final cumulative return (final_cum_returns)

function
skportfolio.metrics.metrics.final_cum_returns(returns, starting_value=0)

Compute total returns from simple returns.

Parameters
  • returns (pd.DataFrame, pd.Series, or np.ndarray) Noncumulative simple returns of one or more timeseries.
  • starting_value (float, optional) The starting returns.
Returns (total_returns : pd.Series, np.ndarray, or float)

If input is 1-dimensional (a Series or 1D numpy array), the result is a scalar.

If input is 2-dimensional (a DataFrame or 2D numpy array), the result is a 1D array containing cumulative returns for each column of input.

Kurtosis (kurtosis)

function
skportfolio.metrics.metrics.kurtosis(r) → float

Alternative to scipy.stats.kurtosis

Maximum drawdown (maxdrawdown)

function
skportfolio.metrics.metrics.maxdrawdown(returns)

Returns the maxdrawdown measure of returns

Number of Effective Assets (number_effective_assets)

function
skportfolio.metrics.metrics.number_effective_assets(weigths)

Returns a measure of portfolio diversification, known as number of effective assets. Its maximum value

Omega Ratio (omega_ratio)

function
skportfolio.metrics.metrics.omega_ratio(ret, target_ret=0.0, risk_free_rate=0.0, frequency=252)

Returns the omega ratio of a strategy. Omega is a ratio of winning size weighted by probabilities to losing size weighted by probabilities. It considers size and odds of winning and losing trades, as well as all moments because the definition incorporates the whole distribution of returns.

Important advantages are:

  • There is no parameter (estimation).
  • There is no need to estimate (higher) moments.
  • Works with all kinds of distributions.
  • Use a function (of Loss Threshold) to measure performance rather than a single number (as in Sharpe Ratio).
  • It is as smooth as the return distribution.
  • It is monotonic decreasing

Look here for further details:

Parameters
  • ret (pd.Series) Return of the strategy, typically obtained by the dot product of the asset returns dataframe and weights vector.
  • target_ret (float, optional) The desidered return per sample, aka the minimum acceptable return.
  • risk_free_rate (float, optional) The default risk free rate (default 0)
  • frequency (int, optional) The annualization frequency (default APPROX_BDAYS_PER_YEAR)
See Also

sharpe_ratio, sortino_ratio, calmar_ratio

Portfolio Return (portfolio_return)

function
skportfolio.metrics.metrics.portfolio_return(prices, weights, rets_estimator=MeanHistoricalLinearReturns())

Calculates the portfolio return as \(\mathbb{E}\lbrack \mathbf{r}^T \mathbf{w} \rbrack\).

Portfolio Volatility (portfolio_vol)

function
skportfolio.metrics.metrics.portfolio_vol(returns, weights, frequency=252, risk_estimator=SampleCovariance(returns_data=True))

Computes the portfolio volatility using the risk_estimator, default set to sample covariance

Semi-volatility (semistd)

function
skportfolio.metrics.metrics.semistd(r) → float

Returns the semideviation aka negative semideviation of r r must be a Series or a DataFrame

Sharpe Ratio (sharpe_ratio)

function
skportfolio.metrics.metrics.sharpe_ratio(r, riskfree_rate=0.0, period='DAILY', frequency=252)

Computes the annualized sharpe ratio of a set of returns. See the notes above about the annualization

Skewness (skewness)

function
skportfolio.metrics.metrics.skewness(r) → float

Alternative to scipy.stats.skewness

Sortino Ratio (sortino_ratio)

function
skportfolio.metrics.metrics.sortino_ratio(r, riskfree_rate=0.0, frequency=252) → float

The Sortino ratio is an improvement of the Sharpe ratio. What sets the Sortino ratio apart is that it acknowledges the difference between upside and downward risks. More specifically, it provides an accurate rate of return, given the likelihood of downside risk, while the Sharpe ratio treats both upside and downside risks equally. As a rule of thumb, a Sortino ratio of 2 and above is considered ideal.

Parameters
  • r (pd.Series) portfolio returns obtained from (prices @ weights).pct_change()

Tail Ratio (tail_ratio)

function
skportfolio.metrics.metrics.tail_ratio(returns, upper_tail=95.0, lower_tail=5.0)

Determines the ratio between the right (95%) and left tail (5%). For example, a ratio of 0.25 means that losses are four times as bad as profits.

Parameters
  • returns (pd.Series or np.ndarray) Daily returns of the strategy, noncumulative. - See full explanation in :func:~empyrical.stats.cum_returns.
  • upper_tail (float) Upper percentile
  • lower_tail (float) Lower percentile

Value At Risk (value_at_risk)

function
skportfolio.metrics.metrics.value_at_risk(r, level=0.05)

Computes the value at risk with cutoff level of default 5%

Var Gaussian (var_gaussian)

function
skportfolio.metrics.metrics.var_gaussian(r, level=5, modified=False)

Returns the parametric gaussian VaR of a Series or DataFrame args: r: pd.Series level: percentile level modified: True if Corni