RiskMeasures

Julia library for computing risk measures for random variables. The random variable represents profits or rewards that are to be maximized. The computed risk value is also better when greater.

The following risk measures are currently supported

  • VaR: Value at risk
  • CVaR: Conditional value at risk
  • ERM: Entropic risk measure
  • EVaR: Entropic value at risk
  • expectile: A coherent elicitable risk measure
  • UBSR: Utility-based shortfall risk for a given utility
  • Choquet: Choquet and distortion risk measures for a choquet capacity and distortion functions

When supported, the risk measure returns also the optimal distribution

General assumptions

  • Random variables represent rewards (greater value is preferred)
  • Risk measures become less risk-averse with the increasing value of the risk parameter α or β

Supported distributions

  • General discrete distributions (DiscreteNonParametric)
  • Transformed discrete distributions ('DiscreteAffineDistribution')
  • Mixtures of random variables ('MixtureModel')

Examples

Using arrays

using RiskMeasures

x = [1, 5, 6, 7, 20]
p = [0.1, 0.1, 0.2, 0.5, 0.1]

VaR(x, p, 0.1)   # value at risk
CVaR(x, p, 0.1)  # conditional value at risk
EVaR(x, p, 0.1)  # entropic value at risk
ERM(x, p, 0.1)   # entropic risk measure
expectile(x, p, 0.1)   # expectile risk measure
UBSR(x, p, z -> (z ≥ 0 ? 0 : -1), 0.1)  # utility-based shortfall risk that equals to VaR
β = 0.1; UBSR(x, p, z -> (-exp(-β * z)), 0.1)  # utility-based shortfall risk that equals to ERM
choquet_risk(x, p, cvar_capacity, 0.5) # choquet risk measure
choquet_distortion_risk(x, p, cvar_distortion, 0.5) # law-invariant choquet (distortion) risk measure

Using random variables

using RiskMeasures
using Distributions

X = [1, 5, 6, 7, 20]
P = [0.1, 0.1, 0.2, 0.5, 0.1]
x̃ = DiscreteNonParametric(X, P)

VaR(x̃, 0.1)   # value at risk
CVaR(x̃, 0.1)  # conditional value at risk
EVaR(x̃, 0.1)  # entropic value at risk
ERM(x̃, 0.1)   # entropic risk measure
expectile(x̃, 0.1)   # expectile risk measure
UBSR(x̃, z -> (z ≥ 0 ? 0 : -1), 0.1)  # utility-based shortfall risk that equals to VaR
β = 0.1; UBSR(x̃, z -> (-exp(-β * z)), 0.1)  # utility-based shortfall risk that equals to ERM
choquet_risk(x̃, cvar_capacity, 0.5) # choquet risk measure
choquet_distortion_risk(x̃, cvar_distortion, 0.5) # law-invariant choquet (distortion) risk measure

Using transformed random variables

We can also compute risk measures of transformed random variables

using RiskMeasures
using Distributions

x̃ = DiscreteNonParametric([1, 5, 6, 7, 20], [0.1, 0.1, 0.2, 0.5, 0.1])
VaR(5*x̃ + 10, 0.1)   # value at risk
CVaR(x̃ - 10, 0.1)    # conditional value at risk

Using mixture models

using RiskMeasures
using Distributions

x̃ = DiscreteNonParametric([-5, -3, 2, 7, 33], [0., 0.2, 0.1, 0.5, 0.2])
ỹ = DiscreteNonParametric([1, 5, 6, 7, 20], [0.1, 0.1, 0.2, 0.5, 0.1])
m̃ = MixtureModel([x̃, ỹ], [0.3, 0.7])

VaR(m̃, 0.4)
CVaR(m̃, 0.4)

Please see the documentation and unit tests for more examples of how this package can be used to compute the risk.

Most risk measure functions return tuples that include additional statistics and values. For example, this includes the distribution that attains the risk value and the optimal ERM-β in EVaR.

Functions

Value at Risk

RiskMeasures.VaRFunction
VaR(x̃, α)

Compute the value at risk at risk level α for the random variable .

Risk must satisfy $α ∈ [0,1]$ and α=0.5 computes the median and α=0 computes the essential infimum (smallest value with positive probability) and α=1 returns infinity.

Solves for

\[\max \{t ∈ \mathbb{R} : \mathbb{P}[x̃ < t] \le α \}\]

In general, this function is neither convex nor concave in the random variable x̃.

source

Conditional Value at Risk

RiskMeasures.CVaRFunction
CVaR(x̃, α)

Compute the conditional value at risk at level α for the random variable .

CVaR(values, pmf, α; ...)

Compute CVaR for a discrete random variable with values and the probability mass function pmf.

The risk level α must satisfy $α ∈ [0,1]$. Risk aversion decreases with an increasing α and α = 1 represents the expectation, α = 0 computes the essential infimum (smallest value with positive probability).

Assumes a reward maximization setting and solves the dual form

\[\min_{q ∈ \mathcal{Q}} q^T x̃\]

where

\[\mathcal{Q} = \left\{q ∈ Δ^n : q_i ≤ \frac{p_i}{α}\right\}\]

and $Δ^n$ is the probability simplex, and $p$ is the distribution of $x̃$.

Returns

A named tuple with CVaR value and the pmf that achieves it.

Keyword Arguments:

  • check_inputs=true: check that the inputs are valid.
  • fast=false: use linear-time experimental implementation

More details: https://en.wikipedia.org/wiki/Expected_shortfall

Examples

julia> CVaR([1, 2, 3, 4, 5], [0.2, 0.2, 0.2, 0.2, 0.2], 0.4).value
1.5
source

Entropic Value at Risk

RiskMeasures.EVaRFunction
EVaR(x̃, α; βmin = 1e-5, βmax = 100, reciprocal = false, check_inputs = true)

Compute the EVaR risk measure of the random variable with risk level α in [0,1].

EVaR(values, pmf, α; ...)

Compute EVaR for a discrete random variable with values and the probability mass function pmf.

When α = 1, the function computes the expected value, and when α = 0, then the function computes the essential infimum (the minimum value with positive probability).

The function solves

\[\max_{β ∈ [βmin, βmax]} \operatorname{ERM}_β (x̃) - β^{-1} \log (1/(α)).\]

Large values of βmax may cause the computation to overflow.

If reciprocal = false, then the quasi-concave problem above is solved directly. If reciprocal = true, then the optimization is reformulated in terms of λ = 1/β to get a concave function that can be solved (probably) more efficiently

The function implicitly assumes that all elements of the probability space have non-zero probability.

Returns

A named tuple with the EVaR value, the optimal β that attains the maximum, and the worst-case pmf. Note that β is numerically unstable when EVaR equals the essential infimum, because the supremum is attained in the limit as β → ∞.

See: Ahmadi-Javid, A. “Entropic Value-at-Risk: A New Coherent Risk Measure.” Journal of Optimization Theory and Applications 155(3), 2012.

Examples

julia> round(EVaR([1, 2, 3, 4, 5], [0.2, 0.2, 0.2, 0.2, 0.2], 0.4).value; digits=4)
1.2942
source

Entropic Risk Measure

RiskMeasures.ERMFunction
ERM(x̃, β; x̃min = -Inf, check_inputs = true)

Compute the entropic risk measure of the random variable with risk level β.

The optional x̃min parameter is used as an offset in order to avoid overflows when computing the exponential function. If not provided, the minimum value of is used instead.

Assumes a maximization problem. Using β = 0 computes the expectation and β = Inf computes the essential infimum (smallest value with positive probability).

More details: https://en.wikipedia.org/wiki/Entropic_risk_measure

Examples

julia> ERM([1.0, 2.0, 3.0], [0.2, 0.3, 0.5], 0.0)   # β = 0 gives the expectation
2.3

julia> round(ERM([1.0, 2.0, 3.0], [0.2, 0.3, 0.5], 1.0); digits=4)
1.9728
source
RiskMeasures.softminFunction
softmin(x̃, β; x̃min = -Inf, check_inputs = true)

Compute a weighted softmin function for random variable with risk level β. This can be seen as an approximation of the arg min function and not the min function.

The operator computes a distribution p such that

\[p_i = \frac{e^{-β x_i}}{\mathbb{E}[e^{-β x̃}]}\]

The optional x̃min parameter is used as an offset in order to avoid overflows when computing the exponential function. If not provided, the minimum value of is used instead.

The value β must be positive.

Examples

julia> round.(softmin([0.0, 1.0], [0.5, 0.5], 1.0); digits=3)
2-element Vector{Float64}:
 0.731
 0.269
source

Expectile

RiskMeasures.expectileFunction
expectile(x̃, α)

Compute the expectile risk measure of the random variable with risk level α ∈ (0,1). When α = 1/2, the function computes the expected value.

expectile(values, pmf, α; ...)

Compute expectile for a discrete random variable with values and the probability mass function pmf.

Expectile is only coherent when α ∈ (0,1/2].

Note that the range for α does not include 0 or 1.

The function solves

\[\argmin_{x \in \mathbb{R}} α \mathbb{E}[(\tilde{x} - x)^2_+] + (1-α) \mathbb{E}[( ilde{x} - x)^2_-]\]

Examples

julia> round(expectile([1.0, 2.0, 3.0, 4.0, 5.0], [0.2, 0.2, 0.2, 0.2, 0.2], 0.25).value; digits=4)
2.3333
source

Essential Infimum

RiskMeasures.essinfFunction
essinf(x̃)

Compute the essential infimum of the random variable , which is the minimum value with positive probability.

source

Choquet Risk

RiskMeasures.choquet_riskFunction
choquet_risk(x̃, c, α)

Compute the risk measure for a given choquet capacity function c and random variable .

choquet_risk(x, pmf, c, α)

Compute the risk measure for a given choquet capacity function c and random variable x with probabilities pmf.

The choquet risk measure solves

\[\operatorname{choquet}(x, p, c, α) = \min \{ x^T q \mid q \in \Delta_n, q(\mathcal{U}) \le c(\mathcal{U}, p, \alpha), \forall \mathcal{U} \}\]

The choquet capacity function c that returns a non-negative value and is parametrized by the list of indices S, a probability mass function pmf, and level α ∈ [0,1].

The runtime of this function can be quadratic depending on the evaluation of the capacity function.

Examples

julia> choquet_risk([1, 2, 3, 4, 5], [0.2, 0.2, 0.2, 0.2, 0.2], cvar_capacity, 0.4).value
1.5
source
RiskMeasures.choquet_distortion_riskFunction
choquet_distortion_risk(x̃, g, α)

Compute the choquet risk measure for a law-invariant capacity c(A) = g(P[A]), where g : [0,1] × R → [0,1] is a distortion function with g(0, α) = 0 and g(1, α) = 1.

choquet_distortion_risk(x, pmf, g, α)

Compute the choquet risk measure for a law-invariant capacity c(A) = g(P[A]), where g : [0,1] × R → [0,1] is a distortion function with g(0, α) = 0 and g(1, α) = 1.

The choquet distortion risk measure solves

\[\operatorname{choquet}(x, p, c, α) = \min \{ x^T q \mid q \in \Delta_n, q(\mathcal{U}) \le g(p(\mathcal{U}), \alpha), \forall \mathcal{U} \}\]

More efficient than choquet_risk for law-invariant measures: g is evaluated on scalars rather than index sets, and cumulative probabilities are computed once.

Examples

julia> choquet_distortion_risk([1, 2, 3, 4, 5], [0.2, 0.2, 0.2, 0.2, 0.2], cvar_distortion, 0.4).value
1.5
source
RiskMeasures.cvar_capacityFunction
cvar_capacity(S, pmf, α)

Compute the choquet capacity function equivalent to CVaR at level α, to be used with choquet_risk. Here S is the list of indices into the pmf.

Examples

julia> cvar_capacity([1], [0.2, 0.3, 0.5], 0.4)
0.5
source
RiskMeasures.cvar_distortionFunction
cvar_distortion(t, α)

Compute the choquet capacity function equivalent to CVaR at level α, to be used with choquet_distortion_risk.

Examples

julia> cvar_distortion(0.2, 0.4)
0.5
source
RiskMeasures.closure_cFunction
closure_c(ρ)

Given a risk function ρ(values, pmf, α) -> Real, return a closure that computes the submodular function c(S, pmf, α) = -ρ(-1_S, pmf, α) where 1_S is the indicator vector of an index set S. When ρ is coherent and comonotonic, then choquet_risk recovers the same risk.

Examples

julia> ρ(values, pmf, α) = CVaR(values, pmf, α).value;

julia> c = closure_c(ρ);

julia> choquet_risk([1, 2, 3, 4, 5], [0.2, 0.2, 0.2, 0.2, 0.2], c, 0.4).value
1.5
source

UBSR

RiskMeasures.UBSRFunction
UBSR(x̃, u, λ; ...)

Compute the Utility Based Shortfall RiskMeasure (UBSR) for a discrete random variable , for a monotone function u, and risk-threshold λ.

UBSR(x, p, u, λ; ...)

Compute the Utility Based Shortfall RiskMeasure (UBSR) for a discrete random variable with values x, and pmf p, for a monotone function u, and risk-threshold λ.

\[\operatorname{UBSR}(x, p, u, λ) = \sup \{z ∈ ℝ \mid \mathbb{E}[u(\tilde{x} - z)] ≥ -λ \} = \sup \{z ∈ ℝ \mid -g(z) \le λ \}\]

where

\[g(z) := \mathbb{E}[u(\tilde{x} - z)]\]

The UBSR can be seen as the right-continuous inverse of g

If u is NOT monotone (non-decreasing), the UBSR return is undefined and may terminate with an error.

Keyword Arguments:

  • zmin=-1e6, zmax=1e6: Lower and upper bounds for the bisection search.
  • tol=1e-6: Tolerance for convergence of the bisection method.

Returns

  • A named tuple with the computed UBSR value.

Examples

julia> round(UBSR([1.0, 2.0, 3.0], [0.2, 0.3, 0.5], z -> z, 0.0).value; digits=4)   # u(z) = z, λ = 0 gives the expectation
2.3
source

Notable Internal Functions

RiskMeasures.partition!Function
partition!(vals::AbstractVector{<:Real}, p::AbstractVector{<:Real}, pivot_ind::Int, f::Int, b::Int)

Partition the values in vals and p between f and b (inclusive) using the Dutch Flag algorithm into less than pivot, equal to pivot, and greater than pivot.

Returns

A tuple (lt, gt) where i < lt => x[i] < pivot_val and i > gt => x[i] > pivot_val and lt ≤ i ≤ gt => x[i] = pivot_val, where pivot_val = vals[pivot_ind].

source
RiskMeasures.qql!Function
qql!(vals, p, α)

Compute VaR in expected linear time without performing correctness checks. The runtime of the algorithm is randomized but the output value is deterministic.

The input must satisfy 0 < α < 1 and p and vals must have the same length.

Returns

A named tuple with VaR value as a float and the index that achieves it.

source