Metrics#
Portfolio and asset performance/risk metric functions: return compounding and annualization, higher-moment statistics, risk-adjusted performance (Sharpe ratio), drawdown analysis, and Value-at-Risk / Conditional Value-at-Risk estimation.
Portfolio and asset performance/risk metric functions.
This module provides a collection of statistical and financial functions for analyzing return series, including higher-moment statistics (skewness, kurtosis), return compounding and annualization, risk-adjusted performance (Sharpe ratio), drawdown analysis, and Value-at-Risk / Conditional Value-at-Risk estimation (historic and Gaussian/Cornish-Fisher).
All functions that accept a returns argument r are designed to work
transparently with either a pandas.Series (a single return series)
or a pandas.DataFrame (multiple return series, one per column),
returning a scalar or a pandas.Series of per-column results
accordingly.
- annualize_rets(r: Series | DataFrame, periods_per_year: int) float | Series[source]#
Annualize a set of returns.
Notes
We should infer the periods per year, but that is currently left as an exercise to the reader :-)
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of periodic returns.
periods_per_year (int) – Number of periods per year (e.g. 252 for daily returns, 12 for monthly returns).
- Returns:
The annualized return. Returns a float if r is a Series, or a Series of per-column annualized returns if r is a DataFrame.
- Return type:
float or pandas.Series
- annualize_vol(r: Series | DataFrame, periods_per_year: int) float | Series[source]#
Annualize the volatility of a set of returns.
Notes
We should infer the periods per year, but that is currently left as an exercise to the reader :-)
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of periodic returns.
periods_per_year (int) – Number of periods per year (e.g. 252 for daily returns, 12 for monthly returns).
- Returns:
The annualized volatility. Returns a float if r is a Series, or a Series of per-column annualized volatilities if r is a DataFrame.
- Return type:
float or pandas.Series
- compound(r: Series | DataFrame) float | Series[source]#
Compound the set of returns in r.
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of periodic returns.
- Returns:
The compounded (total) return over the whole period. Returns a float if r is a Series, or a Series of per-column compounded returns if r is a DataFrame.
- Return type:
float or pandas.Series
- cvar_historic(r: Series | DataFrame, level: float = 5) float | Series[source]#
Compute the historic Conditional Value at Risk (CVaR) of r.
The CVaR (also known as expected shortfall) is the average of the returns that fall beyond the historic VaR threshold.
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
level (float, default 5) – The percentile level, in percent, used to compute the underlying VaR threshold (see
var_historic()).
- Returns:
The historic CVaR, expressed as a positive number. Returns a float if r is a Series, or a Series of per-column CVaR values if r is a DataFrame.
- Return type:
float or pandas.Series
- Raises:
TypeError – If r is neither a
pandas.Seriesnor apandas.DataFrame.
- drawdown(return_series: Series) DataFrame[source]#
Compute the wealth index, running maximum, and drawdown of a return series.
- Parameters:
return_series (pandas.Series) – Time series of asset returns.
- Returns:
DataFrame indexed like return_series, with columns:
Wealth: the cumulative wealth index, starting at 1000.Previous Peak: the running maximum of the wealth index.Drawdown: the percentage drawdown from the previous peak.
- Return type:
pandas.DataFrame
- kurtosis(r: Series | DataFrame) float | Series[source]#
Compute the kurtosis of the supplied returns.
Alternative to
scipy.stats.kurtosis()that uses the population standard deviation (ddof=0).- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
- Returns:
The kurtosis of r. Returns a float if r is a Series, or a Series of per-column kurtosis values if r is a DataFrame.
- Return type:
float or pandas.Series
- portfolio_return_daily_ts(portfolio_weights: DataFrame, asset_returns: DataFrame) Series[source]#
Calculate daily portfolio returns from weights and asset returns.
The two DataFrames are aligned on their common dates (index) and common assets (columns) before computing the weighted sum of returns.
- Parameters:
portfolio_weights (pandas.DataFrame) – DataFrame with dates as index and assets as columns, containing the portfolio weight of each asset on each date.
asset_returns (pandas.DataFrame) – DataFrame with dates as index and assets as columns, containing the periodic return of each asset on each date.
- Returns:
Series of daily portfolio returns, indexed by the dates common to both portfolio_weights and asset_returns.
- Return type:
pandas.Series
- semideviation(r: Series | DataFrame) float | Series[source]#
Compute the semideviation (negative semideviation) of r.
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
- Returns:
The semideviation, computed as the population standard deviation (
ddof=0) of the negative values in r. Returns a float if r is a Series, or a Series of per-column semideviations if r is a DataFrame.- Return type:
float or pandas.Series
- Raises:
TypeError – If r is neither a
pandas.Seriesnor apandas.DataFrame.
- sharpe_ratio(r: Series | DataFrame, riskfree_rate: float, periods_per_year: int) float | Series[source]#
Compute the annualized Sharpe ratio of a set of returns.
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of periodic returns.
riskfree_rate (float) – Annual risk-free rate, expressed as a decimal (e.g.
0.03for 3%). It’s converted internally to a per-period rate using periods_per_year.periods_per_year (int) – Number of periods per year (e.g. 252 for daily returns, 12 for monthly returns).
- Returns:
The annualized Sharpe ratio. Returns a float if r is a Series, or a Series of per-column Sharpe ratios if r is a DataFrame.
- Return type:
float or pandas.Series
- skewness(r: Series | DataFrame) float | Series[source]#
Compute the skewness of the supplied returns.
Alternative to
scipy.stats.skew()that uses the population standard deviation (ddof=0).- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
- Returns:
The skewness of r. Returns a float if r is a Series, or a Series of per-column skewness values if r is a DataFrame.
- Return type:
float or pandas.Series
- summary_stats(r: DataFrame, riskfree_rate: float = 0.0, periods_per_year: int = 252) DataFrame[source]#
Compute aggregated summary statistics for the returns in r.
- Parameters:
r (pandas.DataFrame) – DataFrame of periodic returns, one column per asset/strategy.
riskfree_rate (float, default 0.0) – Annual risk-free rate, expressed as a decimal, used to compute the Sharpe ratio (see
sharpe_ratio()).periods_per_year (int, default 252) – Number of periods per year used for annualizing returns, volatility, and the Sharpe ratio.
- Returns:
A single-row DataFrame (indexed by
'Strategy') with one column per summary statistic:Annualized Return,Annualized Vol,Sharpe Ratio,Max Drawdown,Skewness,Kurtosis,Cornish-Fisher VaR (5%), andHistoric CVaR (5%).- Return type:
pandas.DataFrame
- var_gaussian(r: Series | DataFrame, level: float = 5, *, modified: bool = False) float | Series[source]#
Compute the parametric Gaussian VaR of r.
- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
level (float, default 5) – The percentile level, in percent (e.g.
5for the 5th percentile / 95% VaR).modified (bool, default False) – If True, apply the Cornish-Fisher modification to the Z-score using the observed skewness and kurtosis of r, returning the modified VaR instead of the plain Gaussian VaR.
- Returns:
The parametric (optionally Cornish-Fisher modified) Gaussian VaR, expressed as a positive number. Returns a float if r is a Series, or a Series of per-column VaR values if r is a DataFrame.
- Return type:
float or pandas.Series
- var_historic(r: Series | DataFrame, level: float = 5) float | Series[source]#
Compute the historic Value at Risk (VaR) at a specified level.
Returns the number such that level percent of the returns fall below that number (as a positive loss figure), and
100 - levelpercent are above it.- Parameters:
r (pandas.Series or pandas.DataFrame) – Series or DataFrame of returns.
level (float, default 5) – The percentile level, in percent (e.g.
5for the 5th percentile / 95% VaR).
- Returns:
The historic VaR, expressed as a positive number. Returns a float if r is a Series, or a Series of per-column VaR values if r is a DataFrame.
- Return type:
float or pandas.Series
- Raises:
TypeError – If r is neither a
pandas.Seriesnor apandas.DataFrame.