X at Risk

PortfolioOptimisers.MIPValueatRiskType
struct MIPValueatRisk{__T_b, __T_s} <: ValueatRiskFormulation

Mixed-integer programming (MIP) formulation for Value-at-Risk.

MIPValueatRisk specifies bounds used in the binary variable formulation of Value-at-Risk within a JuMP optimisation model. It reports the empirical quantile, which is the value the functor of the risk measure computes directly.

Mathematical definition

One binary indicator per observation flags an exceedance, the cardinality constraint caps how many observations may be flagged, and the big-M constant b relaxes the bound on a flagged one. The risk is minimised, so it settles on the smallest value that leaves no more than the permitted number of exceedances.

\[\begin{align} \underset{r,\, \boldsymbol{z}}{\min} \quad & r\\ \text{s.t.} \quad & r \geq -x_t - b z_t\,, \quad t = 1,\ldots,T\\ \quad & \sum_{t=1}^{T} z_t \leq \left(\alpha - s\right) T\\ \quad & z_t \in \left\{0,\, 1\right\}\,. \end{align}\]

Where:

  • $r$: Value-at-Risk variable.
  • $x_t$: Net portfolio return at observation $t$.
  • $z_t$: Binary exceedance indicator at observation $t$.
  • $b$: Big-M constant, the b field.
  • $s$: Cardinality slack, the s field.
  • $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
  • $T$: Number of observations.

Observation weights replace both counts by their weighted sums, so the cardinality constraint reads $\boldsymbol{w}_{o}^\intercal \boldsymbol{z} \leq (\alpha - s) \sum_{t=1}^{T} w_{o,t}$.

Fields

  • b: Big-M constant of the MIP formulation. It relaxes the bound on an observation that the model flags as an exceedance. If nothing, the model uses 1000.
  • s: Cardinality slack of the MIP formulation. It caps the number of flagged observations at (alpha - s) * T. If nothing, the model uses 1e-5.

Constructors

MIPValueatRisk(;    b::Option{<:Number} = nothing,    s::Option{<:Number} = nothing) -> MIPValueatRisk

Keywords correspond to the struct's fields.

Validation

  • If b is not nothing: b > 0.
  • If s is not nothing: s > 0.
  • If both are not nothing: b > s.

Examples

julia> MIPValueatRisk()MIPValueatRisk  b ┼ nothing  s ┴ nothing

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 7.2.2.3.
source
PortfolioOptimisers.DistributionValueatRiskType
struct DistributionValueatRisk{__T_mu, __T_sigma, __T_chol, __T_pe, __T_dist} <: ValueatRiskFormulation

Distribution-based formulation for Value-at-Risk.

DistributionValueatRisk specifies a parametric distribution for computing Value-at-Risk analytically. The distribution parameters can be overridden by prior results during optimisation. This is a different estimand from the empirical quantile that MIPValueatRisk reports, so the risk measure that holds it reports the parametric value in the optimisation model and in the functor alike.

Mathematical definition

\[\begin{align} \mathrm{VaR}_{\alpha}(\boldsymbol{w}) &= -\boldsymbol{\mu}^\intercal \boldsymbol{w} + z_{\alpha} \sqrt{\boldsymbol{w}^\intercal \mathbf{\Sigma} \boldsymbol{w}}\,. \end{align}\]

Where:

  • $\boldsymbol{w}$: Portfolio weights vector $N \times 1$.
  • $\boldsymbol{\mu}$: Expected returns vector $N \times 1$.
  • $\mathbf{\Sigma}$: N × N covariance matrix.
  • $z_{\alpha}$: Lower-tail z-score of the standardised dist at $\alpha$, from compute_value_at_risk_z.
  • $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.

The optimisation model states the standard deviation as a second-order cone over $\mathbf{G} \boldsymbol{w}$, where $\mathbf{G}$ factorises $\mathbf{\Sigma}$. mu and sigma fall back to the prior's own, so factory fills them before either the model or the functor reads them.

Fields

  • mu: Optional expected returns vector assets × 1, the location of dist. Also admits a Deferred Quantity — an expected returns estimator or a prior estimator that computes the vector against the optimisation's own prior, at factory time (see MuSlot and resolve_deferred_quantities). If nothing, the prior supplies it.
  • sigma: Optional covariance matrix assets × assets. Also admits a Deferred Quantity — a covariance estimator or a prior estimator that computes the matrix against the optimisation's own prior, at factory time (see SigmaSlot and resolve_deferred_quantities). If nothing, the prior supplies it.
  • chol: Optional Cholesky factorisation of the covariance matrix. Derived from sigma, so it never defers: it arrives as one pair with whatever sigma resolves to. Give it with a matrix sigma and with neither otherwise — stating it without sigma, or while sigma holds a Deferred Quantity, is refused at construction (see assert_derived_slot_has_source). If nothing, the prior supplies the pair, or the kernel derives the factorisation from a stated sigma.
  • pe: Optional prior estimator that fills every prior-derived slot the measure leaves unstated, from a single fit. A stated slot wins. See resolve_deferred_quantities.
  • dist: Probability distribution.

Constructors

DistributionValueatRisk(;    mu::Option{<:MuSlot} = nothing,    sigma::Option{<:SigmaSlot} = nothing,    chol::Option{<:MatNum} = nothing,    pe::Option{<:AbstractPriorEstimator} = nothing,    dist::Distributions.Distribution = Distributions.Normal()) -> DistributionValueatRisk

Keywords correspond to the struct's fields.

Validation

  • If mu is not nothing: !isempty(mu).
  • If sigma is not nothing: !isempty(sigma) and size(sigma, 1) == size(sigma, 2).
  • If chol is not nothing: !isempty(chol), and sigma is a matrix rather than nothing or a Deferred Quantity.
Warning

mu, sigma and chol are stated independently, so nothing makes them agree with each other. A caller who wants one consistent set names pe alone and lets it fill all three from a single fit. A caller who states them by hand must make sure that they agree.

View parameters

DistributionValueatRisk defines its own port_opt_view method rather than deriving one from field tags.

  • mu is sliced to the selected assets. A Deferred Quantity passes through unsliced, and then resolves on the subset.
  • sigma is sliced to the selected assets. A stated matrix is sliced on both axes. A Deferred Quantity passes through unsliced, and then resolves on the subset.
  • chol is sliced on its columns alone. Its rows index the factorisation, which the asset selection does not address.
  • pe and dist are carried through unchanged. dist describes the standardised loss, so it carries no asset axis.

Examples

julia> DistributionValueatRisk()DistributionValueatRisk     mu ┼ nothing  sigma ┼ nothing   chol ┼ nothing     pe ┼ nothing   dist ┴ Distributions.Normal{Float64}: Distributions.Normal{Float64}(μ=0.0, σ=1.0)

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 7.2.2.3.
source
PortfolioOptimisers.ValueatRiskType
struct ValueatRisk{__T_settings, __T_alpha, __T_w, __T_alg} <: RiskMeasure

Represents the Value-at-Risk (VaR) risk measure.

ValueatRisk quantifies the maximum expected loss at a given confidence level alpha over a specified time horizon. It can be computed using empirical quantiles (weighted or unweighted) or via a parametric distribution.

Mathematical definition

Let $\boldsymbol{x} = (x_1, \ldots, x_T)^\intercal$ be the portfolio returns vector and $x_{(k)}$ the $k$-th order statistic ($k$-th smallest value). The empirical VaR at significance level $\alpha$ is:

\[\begin{align} \mathrm{VaR}_{\alpha}(\boldsymbol{x}) &= -x_{(\lceil \alpha T \rceil)}\,. \end{align}\]

Where:

  • $\mathrm{VaR}_{\alpha}(\boldsymbol{x})$: Value-at-Risk at significance level $\alpha$.
  • $\boldsymbol{x} = (x_1, \ldots, x_T)^\intercal$: Portfolio returns vector.
  • $x_{(k)}$: $k$-th order statistic ($k$-th smallest value) of $\boldsymbol{x}$.
  • $\alpha$: Significance level (e.g., $\alpha = 0.05$ for 95% VaR).
  • $T$: Number of observations.

For observation-weighted samples with weight vector $\boldsymbol{w}$ summing to $S_w$, VaR is the $\alpha S_w$-quantile of the weighted empirical distribution.

Fields

  • settings: Risk measure settings.
  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.
  • alg: Risk measure optimisation formulation algorithm.

Constructors

ValueatRisk(;    settings::RiskMeasureSettings = RiskMeasureSettings(),    alpha::Num_SigCal = 0.05,    w::Option{<:ObsWeights} = nothing,    alg::ValueatRiskFormulation = MIPValueatRisk()) -> ValueatRisk

Keywords correspond to the struct's fields.

Validation

  • If alpha is a number: 0 < alpha < 1.
  • If w is not nothing: !isempty(w).

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • alg: Recursively updated via factory.

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Functor

(r::ValueatRisk)(x::VecNum)(r::ValueatRisk{<:Any, <:Any, <:Any, <:DistributionValueatRisk})(w::VecNum, X, fees)

alg selects the quantity, and each method reports the one that its own JuMP formulation builds. The first computes the empirical quantile of a portfolio returns vector, weighted by w when the measure states observation weights. The second computes the parametric quantile from the moments that DistributionValueatRisk holds, so it takes the asset weights instead. X and fees are unused, because the model's terms are the prior's moments and no return series enters them.

Arguments

  • x::VecNum: Portfolio returns vector.
  • w::VecNum: Asset weights vector.

Examples

julia> ValueatRisk()ValueatRisk  settings ┼ RiskMeasureSettings           │   scale ┼ Float64: 1.0           │      ub ┼ nothing           │     rke ┴ Bool: true     alpha ┼ Float64: 0.05         w ┼ nothing       alg ┼ MIPValueatRisk           │   b ┼ nothing           │   s ┴ nothing

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 7.2.2.3.
source
PortfolioOptimisers.ValueatRiskRangeType
struct ValueatRiskRange{__T_settings, __T_alpha, __T_beta, __T_w, __T_alg} <: RiskMeasure

Represents the Value-at-Risk Range risk measure.

ValueatRiskRange evaluates the Value-at-Risk at level alpha on the portfolio returns and the Value-at-Risk at level beta on the negated portfolio returns, then sums the two to give the total spread between the downside and the upside tail.

Mathematical definition

\[\begin{align} \mathrm{VaRRange}_{\alpha,\beta}(\boldsymbol{x}) &= \mathrm{VaR}_{\alpha}(\boldsymbol{x}) + \mathrm{VaR}_{\beta}(-\boldsymbol{x})\,. \end{align}\]

Where:

  • $\mathrm{VaRRange}_{\alpha,\beta}(\boldsymbol{x})$: Value-at-Risk Range.
  • $\mathrm{VaR}_{\alpha}(\boldsymbol{x})$: Lower-tail loss quantile.
  • $\mathrm{VaR}_{\beta}(-\boldsymbol{x})$: Upper-tail gain quantile.
  • $\boldsymbol{x}$: Portfolio returns vector $T \times 1$.
  • $\alpha$: Lower-tail significance level.
  • $\beta$: Upper-tail significance level.

The upper tail is the base measure applied to the negated returns $-\boldsymbol{x}$, so both tails are reported on the same sign convention and the range is their sum, not their difference.

Fields

  • settings: Risk measure settings.
  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.
  • alg: Risk measure optimisation formulation algorithm.

Constructors

ValueatRiskRange(;    settings::RiskMeasureSettings = RiskMeasureSettings(),    alpha::Num_SigCal = 0.05,    beta::Num_SigCal = alpha,    w::Option{<:ObsWeights} = nothing,    alg::ValueatRiskFormulation = MIPValueatRisk()) -> ValueatRiskRange

Keywords correspond to the struct's fields.

Validation

  • If alpha is a number: 0 < alpha < 1.
  • If beta is a number: 0 < beta < 1.
  • If w is not nothing: !isempty(w).

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • alg: Recursively updated via factory.

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Functor

(r::ValueatRiskRange)(x::VecNum)(r::ValueatRiskRange{<:Any, <:Any, <:Any, <:Any, <:DistributionValueatRisk})(w::VecNum, X, fees)

alg selects the quantity, as it does for ValueatRisk. The first method computes the sum of the two empirical tail quantiles of a portfolio returns vector. It holds the upper tail in the negated convention of ValueatRisk, so it writes the sum as loss - gain. The second computes the parametric range, in which the two legs share one $\boldsymbol{\mu}^\intercal \boldsymbol{w}$ term that cancels, leaving the spread of the two z-scores over one standard deviation.

Arguments

  • x::VecNum: Portfolio returns vector.
  • w::VecNum: Asset weights vector.

Examples

julia> ValueatRiskRange()ValueatRiskRange  settings ┼ RiskMeasureSettings           │   scale ┼ Float64: 1.0           │      ub ┼ nothing           │     rke ┴ Bool: true     alpha ┼ Float64: 0.05      beta ┼ Float64: 0.05         w ┼ nothing       alg ┼ MIPValueatRisk           │   b ┼ nothing           │   s ┴ nothing

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 7.2.2.3.
source
PortfolioOptimisers.DrawdownatRiskType
struct DrawdownatRisk{__T_settings, __T_alpha, __T_w, __T_b, __T_s} <: RiskMeasure

Represents the Drawdown-at-Risk (DaR) risk measure.

DrawdownatRisk quantifies the maximum drawdown not exceeded at a given confidence level alpha. It operates on absolute drawdowns computed from the portfolio returns series. Its optimisation model is the mixed-integer programme of MIPValueatRisk applied to the drawdown series rather than to the return series, so b and s carry the same meaning here as they do there.

Mathematical definition

Define the cumulative wealth process and absolute drawdown at time $t$:

\[\begin{align} c_t &= \sum_{s=1}^{t} x_s\,, \\ d_t &= c_t - \max_{0 \leq s \leq t} c_s \leq 0\,. \end{align}\]

Where:

  • $\boldsymbol{x}$: Portfolio returns vector $T \times 1$.
  • $c_t$: Cumulative simple portfolio return at period $t$.
  • $d_t \leq 0$: Absolute drawdown at period $t$.

The Drawdown-at-Risk at level $\alpha$ is the $\lceil \alpha T \rceil$-th smallest (most extreme) drawdown:

\[\begin{align} \mathrm{DaR}_{\alpha}(\boldsymbol{x}) &= -d_{(\lceil \alpha T \rceil)}\,. \end{align}\]

Where:

  • $\mathrm{DaR}_{\alpha}(\boldsymbol{x})$: Drawdown-at-Risk at level $\alpha$.
  • $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
  • $T$: Number of observations.
  • $d_t \leq 0$: Absolute drawdown at period $t$.
  • $d_{(k)}$: $k$-th order statistic (sorted ascending) of the drawdown series.

Fields

  • settings: Risk measure settings.
  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.
  • b: Big-M constant of the MIP formulation. It relaxes the bound on an observation that the model flags as an exceedance. If nothing, the model uses 1000.
  • s: Cardinality slack of the MIP formulation. It caps the number of flagged observations at (alpha - s) * T. If nothing, the model uses 1e-5.

Constructors

DrawdownatRisk(;    settings::RiskMeasureSettings = RiskMeasureSettings(),    alpha::Num_SigCal = 0.05,    w::Option{<:ObsWeights} = nothing,    b::Option{<:Number} = nothing,    s::Option{<:Number} = nothing) -> DrawdownatRisk

Keywords correspond to the struct's fields.

Validation

  • If alpha is a number: 0 < alpha < 1.
  • If w is not nothing: !isempty(w).
  • If b is not nothing: b > 0.
  • If s is not nothing: s > 0.
  • If both b and s are not nothing: b > s.

Functor

(r::DrawdownatRisk)(x::VecNum)

Computes the Drawdown-at-Risk of a portfolio returns vector x.

Arguments

  • x::VecNum: Portfolio returns vector.

Examples

julia> DrawdownatRisk()DrawdownatRisk  settings ┼ RiskMeasureSettings           │   scale ┼ Float64: 1.0           │      ub ┼ nothing           │     rke ┴ Bool: true     alpha ┼ Float64: 0.05         w ┼ nothing         b ┼ nothing         s ┴ nothing

Related

References

  • [102] A. Chekhlov, S. Uryasev and M. Zabarankin. Drawdown measure in portfolio optimization. International Journal of Theoretical and Applied Finance 8, 13–58 (2005).
  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 7.2.4.3.
source
PortfolioOptimisers.RelativeDrawdownatRiskType
struct RelativeDrawdownatRisk{__T_settings, __T_alpha, __T_w} <: HierarchicalRiskMeasure

Represents the Relative Drawdown-at-Risk risk measure for hierarchical optimisation.

RelativeDrawdownatRisk quantifies the maximum relative (compounded) drawdown not exceeded at a given confidence level alpha. It operates on relative drawdowns computed from the portfolio returns series.

Mathematical definition

Define the compounded wealth process and relative drawdown at time $t$:

\[\begin{align} C_t &= \prod_{s=1}^{t} (1 + x_s)\,, \\ rd_t &= \frac{C_t}{\max_{0 \leq s \leq t} C_s} - 1 \leq 0\,. \end{align}\]

Where:

  • $\boldsymbol{x}$: Portfolio returns vector $T \times 1$.
  • $C_t$: Compound wealth process at period $t$.
  • $rd_t \leq 0$: Relative drawdown at period $t$.

The Relative Drawdown-at-Risk at level $\alpha$ is:

\[\begin{align} \mathrm{RDaR}_{\alpha}(\boldsymbol{x}) &= -rd_{(\lceil \alpha T \rceil)}\,. \end{align}\]

Where:

  • $\mathrm{RDaR}_{\alpha}(\boldsymbol{x})$: Relative Drawdown-at-Risk at level $\alpha$.
  • $\alpha$: Significance level (left tail probability), $\alpha \in (0, 1)$.
  • $T$: Number of observations.
  • $rd_t \leq 0$: Relative drawdown at period $t$.
  • $rd_{(k)}$: $k$-th order statistic (sorted ascending) of the relative drawdown series.

Fields

  • settings: Risk measure settings.
  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.

Constructors

RelativeDrawdownatRisk(;    settings::HierarchicalRiskMeasureSettings = HierarchicalRiskMeasureSettings(),    alpha::Num_SigCal = 0.05,    w::Option{<:ObsWeights} = nothing) -> RelativeDrawdownatRisk

Keywords correspond to the struct's fields.

Validation

  • If alpha is a number: 0 < alpha < 1.
  • If w is not nothing: !isempty(w).

Functor

(r::RelativeDrawdownatRisk)(x::VecNum)

Computes the Relative Drawdown-at-Risk of a portfolio returns vector x.

Arguments

  • x::VecNum: Portfolio returns vector.

Examples

julia> RelativeDrawdownatRisk()RelativeDrawdownatRisk  settings ┼ HierarchicalRiskMeasureSettings           │   scale ┴ Float64: 1.0     alpha ┼ Float64: 0.05         w ┴ nothing

Related

References

  • [102] A. Chekhlov, S. Uryasev and M. Zabarankin. Drawdown measure in portfolio optimization. International Journal of Theoretical and Applied Finance 8, 13–58 (2005).
source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(r, args...)

Get a view or subset of a Value-at-Risk formulation for slicing.

Returns the formulation unchanged (for non-distribution types) or sliced (for distribution-based types). Used internally in hierarchical optimisation.

Arguments

  • r: Value-at-Risk formulation.
  • args...: Additional arguments (index, etc.).

Returns

  • Sliced or unchanged formulation.

Related

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(x, i, args...; kwargs...) -> nothing_scalar_array_view(x, i)

Sub-select an estimator, result, or algorithm to the asset/observation index i.

port_opt_view is the index-selection counterpart of factory: where factory threads runtime values down a composed struct tree, port_opt_view threads an index selection — restricting every data-bearing field and composed child to the subset i. It is the mechanism that makes meta-optimisers (NestedClustered, SubsetResampling) and cross-validation variants operate on subproblems with identical struct shapes.

Callers do not normally call port_opt_view directly; it is driven by meta-optimisers and cross-validation internals. It is public (not exported) because extension authors who implement a new composed estimator may need to define a method. Use @vprop on data-bearing fields to have the method generated automatically.

This universal fallback handles leaf values: arrays are sliced via nothing_scalar_array_view; scalars, nothing, estimators without data fields, and algorithms pass through unchanged. Composed structs that recurse into children define their own (more specific) method — emitted by @vprop or hand-written.

The threaded tail args... (typically the returns matrix X for the JuMP families) and any kwargs are accepted and dropped here, so a macro-threaded port_opt_view(child, i, X) never MethodErrors on a leaf field.

Algorithm

  1. Drop args... and kwargs.... This method is the leaf of the recursion, so it threads nothing further.
  2. Return nothing_scalar_array_view of x at i, whose own algorithm names the rule for each leaf type.

Related

source
port_opt_view(r, args...)

Get a view or subset of a Value-at-Risk formulation for slicing.

Returns the formulation unchanged (for non-distribution types) or sliced (for distribution-based types). Used internally in hierarchical optimisation.

Arguments

  • r: Value-at-Risk formulation.
  • args...: Additional arguments (index, etc.).

Returns

  • Sliced or unchanged formulation.

Related

source
PortfolioOptimisers.factoryMethod
factory(
    alg::DistributionValueatRisk,
    pr::AbstractPriorResult,
    args...;
    kwargs...
) -> DistributionValueatRisk{_A, _B, _C, Nothing, <:Distributions.Distribution{F, S}} where {_A, _B, _C, F<:Distributions.VariateForm, S<:Distributions.ValueSupport}

Create an instance of DistributionValueatRisk by resolving its Deferred Quantities, then falling back to the prior result for whatever is still unstated.

sigma and chol are selected as a pair (sigma_chol_selector), not field by field: a stated sigma with no factor must not be paired with the prior's, which factorises a different matrix.

Related

source

References

[5]
D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025).
[102]
A. Chekhlov, S. Uryasev and M. Zabarankin. Drawdown measure in portfolio optimization. International Journal of Theoretical and Applied Finance 8, 13–58 (2005).