RiskPerf.jl

Quantitative risk and performance analysis package for financial time series powered by the Julia language.

Index

Functions

RiskPerf.adjusted_sharpe_ratioMethod
adjusted_sharpe_ratio(returns; multiplier=1.0, risk_free=0.0)

Calculates the adjusted Sharpe Ratio introduced by Pezier and White (2006) by penalizing negative skewness and excess kurtosis.

Formula

$\text{SR} = \dfrac{\mathbb{E}\left[ \text{returns} - \text{risk\_free}\right ]}{\sigma(\text{returns} - \text{risk\_free})}$

$\text{ASR} = \text{SR} \left[1 + \frac{S}{6}\text{SR} - \frac{K-3}{24}\text{SR}^2\right] \times \sqrt{\text{multiplier}}$

Arguments

  • returns: Vector of asset returns.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).

Sources

  • Pezier, Jaques and White, Anthony (2006). The Relative Merits of Investable Hedge Fund Indices and of Funds of Hedge Funds in Optimal Passive Portfolios. ICMA Centre Discussion Papers in Finance.
source
RiskPerf.capmMethod
capm(asset_returns, benchmark_returns; risk_free=0.0)

Calculates the CAPM α and β coefficients based on sample covariance statistics and a simple linear regression model.

The linear regression model looks as follows:

$r_a - r_f = α + β(r_b - r_f) + ϵ$

The α coefficient in this model is also known as Jensen's alpha. β is the slope coefficient, and ϵ is an error term.

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector of benchmark returns (e.g. market portfolio returns for CAPM beta).
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).

Returns

Tuple (α, β) with the estimated α and β coefficients of the CAPM model.

source
RiskPerf.downside_deviationMethod
downside_deviation(returns, threshold; method=:full)

Calculates the downside deviation, also called semi-standard deviation, which captures the downside risk.

Arguments

  • returns: Vector of asset returns.
  • threshold: Scalar value or vector denoting the threshold returns.
  • method: One of :full (default) or :partial. Indicates whether to use the number of all returns (:full), or only the number of returns below the threshold (:partial) in the denominator.

Formula

$\text{Downside Deviation} = \sqrt{\text{Lower Partial Moment}}$

source
RiskPerf.drawdownsMethod
drawdowns(returns; compound)

Calculates the drawdown based on a returns time series.

Arguments

  • returns: Vector of asset returns (usually log-returns).
  • geometric: Use geometric compounding (cumprod) if set to true, otherwise simple arithmetic sum (cumsum), e.g. for log-returns (default).
source
RiskPerf.drawdowns_pnlMethod
drawdowns_pnl(pnl)

Calculates the drawdown based on a Profit-and-Loss (PnL) time series, e.g. daily equity changes in USD.

Arguments

  • pnl: Vector of Profit-and-Loss (PnL) values, e.g. daily equity changes in USD.
source
RiskPerf.expected_shortfallMethod
expected_shortfall(returns, confidence, method; multiplier=1.0)

Computes the Expected Shortfall (ES), also known as Conditional Value-at-Risk (CVaR), Average Value-at-Risk (AVaR) or Expected Tail Loss (ETL). The ES is the expected return on the asset in the worst α% of cases, therefore quantifies the tail-risk of an asset. It is calculated by averaging all of the returns in the distribution that are worse than the VaR of the portfolio at a given significance level α. For instance, for a 5% significance level, the expected shortfall is calculated by taking the average of returns in the worst 5% of cases.

Expected Shortfall puts emphasis on the tail of the loss distribution, whereas Value-at-risk neglects this aspect.

Arguments

  • returns: Vector of asset returns.
  • α: Significance level, e.g. use 0.05 for 95% confidence, or 0.01 for 99% confidence.
  • method: Distribution estimation method: :historical, :gaussian or :cornish_fisher.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.

Methods

  • :historical: Historical based on empirical distribution of returns.
  • :gaussian: Gaussian distribution based on parametric fit (mean, variance).
  • :cornish_fisher: Cornish-Fisher based on Gaussian parametric distribution fit adjusted for third and fourth moments (skewness, kurtosis). Cornish-Fisher expansion aims to approximate the quantile of a true distribution by using higher moments (skewness and kurtosis) of that distribution to adjust for its non-normality. See https://thema.u-cergy.fr/IMG/pdf/2017-21.pdf for details.

Sources

  • Amédée-Manesme, Charles-Olivier and Barthélémy, Fabrice and Maillard, Didier (2017). Computation of the Corrected Cornish–Fisher Expansion using the Response Surface Methodology: Application to VaR and CVaR. THEMA Working Paper n°2017-21, Université de Cergy-Pontoise, France.
source
RiskPerf.higher_partial_momentMethod
higher_partial_moment(returns, threshold, n, method)

This function calculates the Higher Partial Moment (HPM) for a given threshold.

Arguments

  • returns: Vector of asset returns.
  • threshold: Scalar value or vector denoting the threshold returns.
  • n: n-th moment to calculate.
  • method: One of :full or :partial. Indicates whether to use the number of all returns (:full), or only the number of returns above the threshold (:partial) in the denominator.

Formula

$\text{HPM}_n = \frac{1}{D} \sum_{i=1}^N \max(0, \text{returns}_i - \text{threshold})^n$

where N is the number of returns, and D is the denominator.

source
RiskPerf.information_ratioMethod
information_ratio(asset_returns, benchmark_returns; multiplier=1.0)

This function calculates the Information Ratio as the active return divided by the tracking error. The calculation equals William F. Sharpe's revision of the original version of the Sharpe Ratio (see function sharpe_ratio).

Formula

$\text{IR} = \dfrac{\mathbb{E}\left[\text{asset\_returns} - \text{benchmark\_returns} \right]}{\sigma(\text{asset\_returns} - \text{benchmark\_returns})} \times \sqrt{\text{multiplier}}$

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector or scalar value of benchmark returns having same same frequency (e.g. daily) as the provided returns.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.

Sources

  • Sharpe, William F. (1994). "The Sharpe Ratio". The Journal of Portfolio Management.
source
RiskPerf.jensen_alphaMethod
jensen_alpha(asset_returns, benchmark_returns; risk_free=0.0)

Jensen's alpha, or simply alpha, is a risk-adjusted excess-performance measure. It indicates the average return of an investment above or below that predicted by the capital asset pricing model (CAPM). The measure adjusts the excess returns such that the risk is identical for the investment and benchmark.

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector of benchmark returns (e.g. market portfolio returns for CAPM beta).
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).

Returns

Jensen's alpha measure.

Sources

  • Bacon, Carl (2008). Practical Portfolio Performance Measurement and Attribution, 2nd Edition, John Wiley & Sons Ltd. Page 72.
source
RiskPerf.kurtosisMethod
kurtosis(x; method=:excess)

Calculates the kurtosis using on the specified method.

Methods

  • Excess (default)
  • Moment
  • Cornish-Fisher

Arguments

  • x: Vector of values.
  • method: Estimation method: :excess, :moment or :cornish_fisher.
source
RiskPerf.log_returnsMethod
log_returns(prices::Matrix; drop_first=false, first_value=NaN)

Calculates log-return series for each column of the provided prices matrix, where each column denotes a prices series of an asset, e.g. a stock.

Please note that the provided prices series should be regularly spaced, for example hourly or daily data.

Arguments

  • prices: Matrix of size [N x k] of prices, where each column denotes a price series of an asset, e.g. a stock.
  • drop_first: Boolean value indicating whether to drop the first return or not (default=false).
  • first_value: Value to be used for the first return if drop_first=false.

Formula

$r_{t, i} = \log\left(\dfrac{P_{t, i}}{P_{t-1, i}}\right)$

where $r_{t, i}$ is the return at time $t$ for asset $i$, $P_{t, i}$ is the price at time $t$ for asset $i$, and $P_{t-1, i}$ is the price at time $t-1$ for asset $i$.

Examples

julia> using RiskPerf

julia> prices = [100.0 99.0; 101.0 99.5; 100.5 99.8; 99.8 99.2; 101.3 100.0]
5×2 Matrix{Float64}:
 100.0   99.0
 101.0   99.5
 100.5   99.8
  99.8   99.2
 101.3  100.0

julia> log_returns(prices)
5×2 Matrix{Float64}:
 NaN           NaN
   0.00995033    0.00503779
  -0.00496279    0.00301054
  -0.00698954   -0.00603017
   0.0149182     0.00803217

julia> log_returns(prices; drop_first=true)
4×2 Matrix{Float64}:
  0.00995033   0.00503779
 -0.00496279   0.00301054
 -0.00698954  -0.00603017
  0.0149182    0.00803217
source
RiskPerf.log_returnsMethod
log_returns(prices::Vector; drop_first=false, first_value=NaN)

Calculates the log-return series based on the provided time series of N prices. Please note that the provided prices series should be regularly spaced, for example hourly or daily data.

Arguments

  • prices: Vector of prices.
  • drop_first: Boolean value indicating whether to drop the first return or not (default=false).
  • first_value: Value to be used for the first return if drop_first=false.

Formula

$r_t = \log\left(\dfrac{P_t}{P_{t-1}}\right)$

where $r_t$ is the return at time $t$, $P_t$ is the price at time $t$, and $P_{t-1}$ is the price at time $t-1$.

Examples

julia> using RiskPerf

julia> prices = [100.0, 101.0, 100.5, 99.8, 101.3]
5-element Vector{Float64}:
 100.0
 101.0
 100.5
  99.8
 101.3

julia> log_returns(prices)
5-element Vector{Float64}:
 NaN
   0.009950330853168092
  -0.004962789342129014
  -0.006989544181712186
   0.014918227937219366

julia> log_returns(prices; drop_first=true)
4-element Vector{Float64}:
  0.009950330853168092
 -0.004962789342129014
 -0.006989544181712186
  0.014918227937219366
source
RiskPerf.lower_partial_momentMethod
lower_partial_moment(returns, threshold, n, method)

This function calculates the Lower Partial Moment (LPM) for a given threshold.

Arguments

  • returns: Vector of asset returns.
  • threshold: Scalar value or vector denoting the threshold returns.
  • n: n-th moment to calculate.
  • method: One of :full or :partial. Indicates whether to use the number of all returns (:full), or only the number of returns below the threshold (:partial) in the denominator.

Formula

$\text{LPM}_n = \frac{1}{D} \sum_{i=1}^N \max(0, \text{threshold} - \text{returns}_i)^n$

where N is the number of returns, and D is the denominator.

source
RiskPerf.modified_jensenMethod
modified_jensen(asset_returns, benchmark_returns; risk_free=0.0)

Divides Jensen’s alpha by the systematic risk, which measures the systematic risk-adjusted return per unit of systematic risk. See also jensen_alpha

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector of benchmark returns (e.g. market portfolio returns for CAPM beta).
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).

Returns

Modified Jensen's alpha measure.

Sources

  • Bacon, Carl (2008). Practical Portfolio Performance Measurement and Attribution, 2nd Edition, John Wiley & Sons Ltd. Page 77.
source
RiskPerf.omega_ratioMethod
omega_ratio(returns, target_return)

This function calculates the Omega ratio. Note that the ratio returns Inf if all returns are greater or equal to the target return.

Formula

$\Omega = -\dfrac{ \mathbb{E}\left[ \text{max}(\text{returns} - \text{target\_return}, 0) \right] }{ \mathbb{E}\left[ \text{min}(\text{target\_return} - \text{returns}, 0) \right] }$

Arguments

  • returns: Vector of asset returns.
  • target_return: Vector or scalar value of benchmark returns having same same frequency (e.g. daily) as the provided returns.
source
RiskPerf.relative_risk_contributionMethod
relative_risk_contribution(weights, covariance_matrix)

Formula

The relative risk contribution (RRC) of an asset is defined as the ratio of the asset's risk contribution RC to the total portfolio risk $\sigma(w)$:

$\text{RRC}_i = \frac{\text{RC}_i}{\sigma(w)} = \frac{w_i(\Sigma w)_i}{w^T\Sigma w}$

such that $\sum_{i=1}^N \text{RRC}_i = 1$.

Arguments

  • weights: Vector of asset weights in portfolio.
  • covariance_matrix: Covariance matrix of asset returns.
source
RiskPerf.sharpe_ratioMethod
sharpe_ratio(returns; multiplier=1.0, risk_free=0.0)

Calculates the Sharpe Ratio (SR) according to the original definition by William F. Sharpe in 1966. For calculating the Sharpe Ratio according to Sharpe's revision in 1994, please see function information_ratio (IR).

Formula

$\text{SR} = \dfrac{\mathbb{E}\left[\text{returns} - \text{risk\_free} \right]}{\sigma(\text{returns})} \times \sqrt{\text{multiplier}}$

$\text{IR} = \dfrac{\mathbb{E}\left[\text{asset\_returns} - \text{benchmark\_returns} \right]}{\sigma(\text{asset\_returns} - \text{benchmark\_returns})} \times \sqrt{\text{multiplier}}$

Arguments

  • returns: Vector of asset returns.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).

Sources

  • Sharpe, W. F. (1966). Mutual Fund Performance. Journal of Business.
  • Sharpe, William F. (1994). The Sharpe Ratio. The Journal of Portfolio Management.
source
RiskPerf.simple_returnsMethod
simple_returns(prices::Matrix; drop_first=false, first_value=NaN)

Calculates the simple returns series for each column of the provided prices matrix, where each column denotes a prices series of an asset, e.g. a stock.

Please note that the provided prices series should be regularly spaced, for example hourly or daily data.

Arguments

  • prices: Matrix of size [N x k] where each column denotes a price series of an asset, e.g. a stock.
  • drop_first: Boolean value indicating whether to drop the first return or not (default=false).
  • first_value: Value to be used for the first return if drop_first=false.

Formula

$r_{t, i} = \dfrac{P_{t, i}}{P_{t-1, i}} - 1$

where $r_{t, i}$ is the return at time $t$ for asset $i$, $P_{t, i}$ is the price at time $t$ for asset $i$, and $P_{t-1, i}$ is the price at time $t-1$ for asset $i$.

Examples

julia> using RiskPerf

julia> prices = [100.0 99.0; 101.0 99.5; 100.5 99.8; 99.8 99.2; 101.3 100.0]
5×2 Matrix{Float64}:
 100.0   99.0
 101.0   99.5
 100.5   99.8
  99.8   99.2
 101.3  100.0

julia> simple_returns(prices)
5×2 Matrix{Float64}:
 NaN           NaN
   0.01          0.00505051
  -0.0049505     0.00301508
  -0.00696517   -0.00601202
   0.0150301     0.00806452

julia> simple_returns(prices; drop_first=true)
4×2 Matrix{Float64}:
  0.01         0.00505051
 -0.0049505    0.00301508
 -0.00696517  -0.00601202
  0.0150301    0.00806452
source
RiskPerf.simple_returnsMethod
simple_returns(prices::Vector; drop_first=false, first_value=NaN)

Calculates the simple returns series based on the provided time series of N prices. Please note that the provided prices series should be regularly spaced, for example hourly or daily data.

Formula

$r_t = \dfrac{P_t}{P_{t-1}} - 1$

where $r_t$ is the return at time $t$, $P_t$ is the price at time $t$, and $P_{t-1}$ is the price at time $t-1$.

Arguments

  • prices: Vector of prices.
  • drop_first: Boolean value indicating whether to drop the first return or not (default=false).
  • first_value: Value to be used for the first return if drop_first=false.

Examples

julia> using RiskPerf

julia> prices = [100.0, 101.0, 100.5, 99.8, 101.3]
5-element Vector{Float64}:
 100.0
 101.0
 100.5
  99.8
 101.3

julia> simple_returns(prices)
5-element Vector{Float64}:
 NaN
   0.010000000000000009
  -0.004950495049504955
  -0.006965174129353269
   0.01503006012024044

julia> simple_returns(prices; drop_first=true)
4-element Vector{Float64}:
  0.010000000000000009
 -0.004950495049504955
 -0.006965174129353269
  0.01503006012024044
source
RiskPerf.skewnessMethod
skewness(x; method=:moment)

Calculates the skewness using the specified method.

Methods

  • Moment (default)
  • Fisher-Pearson
  • Sample

Arguments

  • x: Vector of values.
  • method: Estimation method: :moment, :fisher_pearson or :sample.
source
RiskPerf.sortino_ratioMethod
sortino_ratio(returns; multiplier=1.0, risk_free=0.0)

Calculates the Sortino Ratio, a downside risk-adjusted performance measure. Contrary to the Sharpe Ratio, only deviations below the minimum acceptable returns are included in the calculation of the risk (downside deviation instead of standard deviation).

Arguments

  • returns: Vector of asset returns.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
  • MAR: Optional vector or scalar value denoting the minimum acceptable return(s). Must have same frequency as the provided returns, e.g. daily.

Formula

$\text{Sortino Ratio} = \dfrac{\text{returns} - \text{MAR}}{\text{downside deviation}} \times \sqrt{\text{multiplier}}$

The downside deviation is simply the standard deviation of the returns below the minimum acceptable return.

Sources

  • Sortino, F. and Price, L. (1996). Performance Measurement in a Downside Risk Framework. Journal of Investing.
source
RiskPerf.tracking_errorMethod
tracking_error(asset_returns, benchmark_returns; multiplier=1.0)

Calculates the ex-post Tracking Error based on the standard deviation of the active returns.

Formula

$\text{TE} = \sigma\left( \text{asset\_returns} - \text{benchmark\_returns} \right) \times \sqrt{\text{multiplier}}$

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector of benchmark returns.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
source
RiskPerf.treynor_ratioMethod
treynor_ratio(asset_returns, benchmark_returns; multiplier=1.0, risk_free=0.0)

Calculates the Treynor ratio as the ratio of excess return divided by the CAPM beta. This ratio is similar to the Sharpe Ratio, but instead of dividing by the volatility, we devide by the CAPM beta as risk proxy.

Formula

$\text{TR} = \dfrac{ \mathbb{E}\left[ \text{asset\_returns} - \text{risk\_free} \right]}{\beta} \times \text{multiplier}$

Arguments

  • asset_returns: Vector of asset returns.
  • benchmark_returns: Vector of benchmark returns (e.g. market portfolio returns).
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
  • risk_free: Optional vector or scalar value denoting the risk-free return (must have same frequency as the provided returns, e.g. daily).
source
RiskPerf.upside_deviationMethod
upside_deviation(returns, threshold; method=:full)

Calculates the upside deviation, also called semi-standard deviation, which captures the upside "risk".

Arguments

  • returns: Vector of asset returns.
  • threshold: Scalar value or vector denoting the threshold returns.
  • method: One of :full (default) or :partial. Indicates whether to use the number of all returns (:full), or only the number of returns above the threshold (:partial) in the denominator.

Formula

$\text{Upside Deviation} = \sqrt{\text{Higher Partial Moment}}$

source
RiskPerf.upside_potential_ratioMethod
upside_potential_ratio(returns, threshold; method=:partial)

The Upside Potential Ratio is a risk-adjusted performance measure similarly to the Sharpe Ratio and the Sortino Ratio. This ratio considers only upside returns (above threshold) in the numerator, and only downside returns (below threshold) in the denominator (see downside_deviation).

Arguments

  • returns: Vector of asset returns.
  • threshold: Scalar value or vector denoting the threshold returns.
  • method: One of :full (default) or :partial. Indicates whether to use the number of all returns (:full), or only the number of returns above the threshold (:partial) in the denominator.

Sources

  • Plantinga, A., van der Meer, R. and Sortino, F. (2001). The Impact of Downside Risk on Risk-Adjusted Performance of Mutual Funds in the Euronext Markets.
source
RiskPerf.value_at_riskMethod
value_at_risk(returns, confidence, method; multiplier=1.0)

Computes the Value-at-Risk (VaR) for a given significance level α based on the chosen estimation method. The VaR value represents the maximum expected loss at a certain significance level α. For a more tail-risk focused measure, see expected_shortfall.

Arguments

  • returns: Vector of asset returns.
  • α: Significance level, e.g. use 0.05 for 95% confidence, or 0.01 for 99% confidence.
  • method: Distribution estimation method: :historical, :gaussian or :cornish_fisher.
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.

Methods

  • :historical: Historical based on empirical distribution of returns.
  • :gaussian: Gaussian distribution based on parametric fit (mean, variance).
  • :cornish_fisher: Cornish-Fisher based on Gaussian parametric distribution fit adjusted for third and fourth moments (skewness, kurtosis). Cornish-Fisher expansion aims to approximate the quantile of a true distribution by using higher moments (skewness and kurtosis) of that distribution to adjust for its non-normality. See https://thema.u-cergy.fr/IMG/pdf/2017-21.pdf for details.

Sources

  • Favre, Laurent and Galeano, Jose-Antonio (2002). Mean-Modified Value-at-Risk Optimization with Hedge Funds. Journal of Alternative Investment.
  • Amédée-Manesme, Charles-Olivier and Barthélémy, Fabrice and Maillard, Didier (2017). Computation of the Corrected Cornish–Fisher Expansion using the Response Surface Methodology: Application to VaR and CVaR. THEMA Working Paper n°2017-21, Université de Cergy-Pontoise, France.
source
RiskPerf.volatilityMethod
volatility(returns; multiplier=1.0)

Calculates the volatility based on the standard deviation of the returns. The optional multiplier parameter allows for scaling the resulting volatility metric, i.e. for annualization.

Formula

$\sigma_{vol} = \sigma(\text{returns}) \times \sqrt{\text{multiplier}}$

where $\sigma$ denotes the sample standard deviation.

Arguments

  • returns: Vector of asset returns (usually log-returns).
  • multiplier: Optional scalar multiplier, i.e. use 12 to annualize monthly returns, and use 252 to annualize daily returns.
source

Bug reports and feature requests

Please report any issues via the GitHub issue tracker.

Acknowledgements

This package was inspired by the R package PerformanceAnalytics of Peter Carl and Brian G. Peterson.