Base Uncertainty Sets

PortfolioOptimisers.AbstractUncertaintySetEstimatorType
abstract type AbstractUncertaintySetEstimator <: AbstractEstimator

Fits an uncertainty set around a prior statistic, so that a downstream model can take the worst case over it.

All concrete subtypes should subtype AbstractUncertaintySetEstimator.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractUncertaintySetEstimator and implement the following methods:

mu_ucs

  • mu_ucs(ue::AbstractUncertaintySetEstimator, X::MatNum, F::Option{<:MatNum} = nothing; dims::Int = 1, kwargs...) -> AbstractUncertaintySetResult: Fits the uncertainty set of the mean.

sigma_ucs

  • sigma_ucs(ue::AbstractUncertaintySetEstimator, X::MatNum, F::Option{<:MatNum} = nothing; dims::Int = 1, kwargs...) -> AbstractUncertaintySetResult: Fits the uncertainty set of the covariance. An estimator with no covariance analogue throws instead, as CharacteristicUncertaintySet does.

ucs

  • ucs(ue::AbstractUncertaintySetEstimator, X::MatNum, F::Option{<:MatNum} = nothing; dims::Int = 1, kwargs...) -> Tuple: Fits both sets in one pass, so that a shared prior or a shared simulation is computed once.

Arguments

  • ue: The concrete subtype instance.
  • X: Matrix of asset returns.
  • F: Optional matrix of factor returns, which a factor prior needs.
  • dims: Dimension along which to perform the computation.
  • kwargs...: Additional keyword arguments, forwarded to the prior estimator.

Returns

  • ucs::AbstractUncertaintySetResult: The fitted set, or a tuple of the mean set and the covariance set for ucs.

reads_prior_result

  • reads_prior_result(ue::AbstractUncertaintySetEstimator) -> Bool: States whether the estimator is calibrated on a prior result it is handed rather than on returns data. The root answers false, so a subtype that fits from returns data declares nothing; one that reads a prior result subtypes AbstractPriorUncertaintySetEstimator instead, or, in the four returns-data families, holds pe = nothing.

Related

source
PortfolioOptimisers.AbstractPriorUncertaintySetEstimatorType
abstract type AbstractPriorUncertaintySetEstimator <: AbstractUncertaintySetEstimator

Fits an uncertainty set from the prior result the optimisation is solving on, rather than from returns data.

Every other AbstractUncertaintySetEstimator carries its own prior estimator pe and fits it on the returns it is handed, so the set it builds knows nothing of the prior the optimiser is using. A subtype of this root reads the fitted prior result instead: its factor model, its mu and its sigma are the inputs of the fit, and it carries no pe of its own. Both JuMP builders hold the prior beside the returns, so both pass it, and the three-argument form of the triple routes each estimator to the argument it reads.

The root is unexported. It is a family root that a caller names only when it writes a subtype, and every consumer reaches it through the triple.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractPriorUncertaintySetEstimator and implement the following methods:

mu_ucs

  • mu_ucs(ue::AbstractPriorUncertaintySetEstimator, pr::AbstractPriorResult; kwargs...) -> AbstractUncertaintySetResult: Fits the uncertainty set of the mean.

sigma_ucs

  • sigma_ucs(ue::AbstractPriorUncertaintySetEstimator, pr::AbstractPriorResult; kwargs...) -> AbstractUncertaintySetResult: Fits the uncertainty set of the covariance.

ucs

  • ucs(ue::AbstractPriorUncertaintySetEstimator, pr::AbstractPriorResult; kwargs...) -> Tuple: Fits both sets in one pass, so that a shared geometry is computed once.

Arguments

  • ue: The concrete subtype instance.
  • pr: The prior result the optimisation is solving on.
  • kwargs...: Additional keyword arguments.

Returns

  • ucs::AbstractUncertaintySetResult: The fitted set, or a tuple of the mean set and the covariance set for ucs.

A subtype inherits the three-argument methods of the triple, which drop the returns data and call the two-argument methods above, because the root answers true to reads_prior_result. It needs no method of the returns-data interface AbstractUncertaintySetEstimator declares, because no consumer reaches that interface through this root. The same contract is reached without subtyping by each of the four returns-data families when its pe is nothing: DeltaUncertaintySet, NormalUncertaintySet, ARCHUncertaintySet and CharacteristicUncertaintySet each carry a prior-result arm of the triple over that type, and the optimiser hands such a set the prior it is solving on.

There is no default fit. The root carries a method of each of the three verbs, and each raises and names the type it was called on, so a subtype that declares none says which method its author owes rather than failing on the root.

Related

source
PortfolioOptimisers.AbstractUncertaintySetAlgorithmType
abstract type AbstractUncertaintySetAlgorithm <: AbstractAlgorithm

Selects which shape of uncertainty set an estimator builds, such as a box or an ellipsoid.

All concrete subtypes should subtype AbstractUncertaintySetAlgorithm. A subtype carries the parameters of its own shape and nothing else. The estimator does the fitting.

Interfaces

A subtype is a tag that the estimator dispatches on, so it declares no method of its own. To add a shape, subtype AbstractUncertaintySetAlgorithm and add the ucs, mu_ucs, and sigma_ucs methods of AbstractUncertaintySetEstimator that are specialised on it, one set for each estimator that is to offer the shape.

Related

source
PortfolioOptimisers.AbstractUncertaintySetResultType
abstract type AbstractUncertaintySetResult <: AbstractResult

Carries a fitted uncertainty set, which is the data a worst-case model reads to build its robust expression.

All concrete subtypes should subtype AbstractUncertaintySetResult. A subtype also carries the statistic its bounds were calibrated on, so that the consumer bounds that statistic and not an unrelated one.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractUncertaintySetResult and implement the following method:

port_opt_view

  • port_opt_view(risk_ucs::AbstractUncertaintySetResult, i, args...) -> AbstractUncertaintySetResult: Returns the set restricted to the asset indices i. A hierarchical optimiser calls it once per cluster.

Arguments

  • risk_ucs: The concrete subtype instance.
  • i: Asset index of the cluster.
  • args...: Additional arguments.

Returns

  • risk_ucs::AbstractUncertaintySetResult: The restricted set.

A model that is to take the worst case over the new shape also needs its own set_ucs_return_constraints! method, or its own set_ucs_variance_risk! method, or both.

Related

source
PortfolioOptimisers.AbstractUncertaintyKAlgorithmType
abstract type AbstractUncertaintyKAlgorithm <: AbstractAlgorithm

Computes the radius k of an ellipsoidal uncertainty set, which is how far the true statistic may lie from its estimate.

All concrete subtypes should subtype AbstractUncertaintyKAlgorithm. A plain number in place of one is the radius itself.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractUncertaintyKAlgorithm and implement the following method:

k_ucs

  • k_ucs(km::AbstractUncertaintyKAlgorithm, q::Number, X, sigma_X::MatNum) -> Number: Returns the radius.

Arguments

  • km: The concrete subtype instance.
  • q: Significance level.
  • X: Matrix of sampled estimation errors, one row per sample. An algorithm that runs no simulation absorbs it.
  • sigma_X: Shape matrix of the ellipsoid, whose first dimension is the dimension of the ellipsoid.

Returns

  • k::Number: Radius of the ellipsoid.

Related

source
PortfolioOptimisers.AbstractCompactRadiusAlgorithmType
abstract type AbstractCompactRadiusAlgorithm <: AbstractAlgorithm

Computes the radius $\kappa$ of a CompactCovarianceUncertaintySet from the prior result and the geometry the set was built on, so that the radius refits whenever the sample or the factor span moves.

A member stands in the kappa slot of an OrthogonalUncertaintySet, whose bound is Num_CptRad. A plain number in that slot is the radius itself, exactly as it is today, and k_compact returns it unchanged.

This family is not the calibration-rule channel, and the two do not meet. A Calibration Rule reads (pr, w, slv, ctx) and nothing else. The compact radius cannot be sized from those alone, because its units move with a sibling field of its own owner: the penalty is $\kappa \lVert (\mathbf{I} - \mathbf{Q}\mathbf{Q}^{\intercal})\mathbf{C}\boldsymbol{w} \rVert_{2}^{2}$ with $\mathbf{C} = \mathbf{W}^{-1/2}$, so under IdentityMetric $\kappa$ carries variance units and under InverseIdiosyncraticVarianceMetric it is dimensionless. A rule that saw only the prior result would have to state one of the two readings and be wrong under the other. So the radius is sized in family, where the metric, the loadings block and the span are all in hand, exactly as the mean radius of the same estimator is sized by k_norm_ball through the method slot. A radius slot admits the rule that computes it.

A rule is named for the method it runs, and neither bare word is claimed elsewhere in the library. ResidualInflation inflates the residual variance to a confidence bound, and VarianceFraction matches the penalty to a fraction of the nominal variance at a reference portfolio.

Interfaces

k_compact

  • k_compact(alg::AbstractCompactRadiusAlgorithm, q::Number, metric::AbstractOrthogonalityMetric, pr::AbstractPriorResult, rr::AbstractLoadingsRegressionResult, C::VecNum, Q::MatNum) -> Number: Returns the radius, finite and >= 0. The owner's own constructor states the range, so a rule writes no range check of its own.

Related

source
PortfolioOptimisers.AbstractUncertaintyEpsAlgorithmType
abstract type AbstractUncertaintyEpsAlgorithm <: AbstractAlgorithm

Computes the radius eps of an $\ell_1$ uncertainty set, which controls how far the true characteristic vector may lie from its estimate, and therefore how many assets the portfolio holds.

All concrete subtypes should subtype AbstractUncertaintyEpsAlgorithm. A plain number in place of one is the radius itself. It is the counterpart of AbstractUncertaintyKAlgorithm for the $\ell_1$ family.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractUncertaintyEpsAlgorithm and implement the following method:

l1_resolve_eps

  • l1_resolve_eps(method::AbstractUncertaintyEpsAlgorithm, mus::VecNum, sds::Option{<:VecNum}, paired::Bool) -> Number: Returns the radius.

Arguments

  • method: The concrete subtype instance.
  • mus: Characteristic vector, sorted in non-increasing order.
  • sds: Per-asset scaling under the same permutation, or nothing when the set is unscaled.
  • paired: Whether to read the paired ladder of the dollar-neutral problem rather than the long-only one.

Returns

  • eps::Number: Radius of the set.

Related

source
PortfolioOptimisers.AbstractUncertaintySetClassType
abstract type AbstractUncertaintySetClass <: AbstractUncertaintySetResult

Names the axis an uncertainty set lives on, which fixes the row count of its shape matrix or of its geometry map.

The family has exactly two inhabitants, and both ship. A consumer dispatches on the tag, because a mean set and a covariance set are the same struct with a shape matrix, or a geometry map, of a different size: EllipsoidalUncertaintySet and NormBallUncertaintySet both carry one. The tag names the axis alone and not the geometry, so a norm ball of order one, which is no ellipsoid, carries the same tag as an ellipsoid on the same axis.

Interfaces

A subtype is a tag that carries no field and declares no method of its own.

Related

source
PortfolioOptimisers.BoxUncertaintySetType
struct BoxUncertaintySet{__T_lb, __T_ub, __T_val} <: AbstractUncertaintySetResult

Holds the element-wise lower and upper bounds of a box uncertainty set on a mean vector or on a covariance matrix.

A box is a convex polytope, so it reads as a polyhedral confidence interval on the entries it bounds. Its worst case is Equation 11.19 on the mean axis and Equation 11.20 on the covariance axis of the source.

The two axes read the bounds differently, so a set fitted for one axis is not a set for the other. On the mean axis set_ucs_return_constraints! reads the bounds only through their half-width $(\boldsymbol{u} - \boldsymbol{\ell}) / 2$, the $\delta_{\boldsymbol{\mu}}$ of Equation 11.14, and centres that width on val. Neither lb nor ub is a bound on the mean on its own, which is why two estimators write one set two ways and agree: ARCHUncertaintySet stores the two quantiles of the bootstrap mean, while DeltaUncertaintySet and the normal box write $\boldsymbol{\ell} = \boldsymbol{0}$ and put the whole width in $\boldsymbol{u}$. On the covariance axis set_ucs_variance_risk! reads $\operatorname{tr}(\mathbf{A}_{u} \mathbf{\Sigma}_{u}) - \operatorname{tr}(\mathbf{A}_{l} \mathbf{\Sigma}_{l})$ under $\mathbf{A}_{u} - \mathbf{A}_{l} = \mathbf{W}$, so both bounds bind on their own and the covariance box is absolute. That route names no centre, so it never reads val.

Mathematical definition

\[\begin{align} U^{\text{box}}_{\boldsymbol{\mu}} &= \left\{ \boldsymbol{\mu}\, \vert\, \lvert \boldsymbol{\mu} - \boldsymbol{\hat{\mu}} \rvert \leq \delta \right\} \\ U^{\text{box}}_{\mathbf{\Sigma}} &= \left\{ \mathbf{\Sigma}\, \vert\, \mathbf{\Sigma}_{l} \leq \mathbf{\Sigma} \leq \mathbf{\Sigma}_{u},\, \mathbf{\Sigma} \succeq 0 \right\}\,. \end{align}\]

Where:

  • $U^{\text{box}}_{\boldsymbol{\mu}}$: Box uncertainty set for expected returns.
  • $U^{\text{box}}_{\mathbf{\Sigma}}$: Box uncertainty set for the covariance matrix.
  • $\boldsymbol{\mu}$, $\mathbf{\Sigma}$: Uncertain expected returns and covariance.
  • $\boldsymbol{\hat{\mu}}$: Estimated (reference) mean vector.
  • $\delta$: Half-width of the box (element-wise).
  • $\mathbf{\Sigma}_{l}$, $\mathbf{\Sigma}_{u}$: Lower and upper bounds for the covariance matrix.
  • $\mathbf{\Sigma} \succeq 0$: Positive semi-definiteness constraint.

Fields

  • lb: Lower bound.
  • ub: Upper bound.
  • val: Quantity the set is a neighbourhood of — a characteristic vector on the mean axis, a covariance matrix on the covariance axis. nothing defers to the consumer's own quantity. When it is set, it takes precedence over the returns estimator's field and over the prior.

Constructors

BoxUncertaintySet(;    lb::ArrNum,    ub::ArrNum,    val::Option{<:ArrNum} = nothing) -> BoxUncertaintySet

Keywords correspond to the struct's fields.

Validation

  • !isempty(lb).
  • !isempty(ub).
  • size(lb) == size(ub).
  • If val is provided: size(val) == size(lb).

Examples

julia> BoxUncertaintySet(; lb = [0.1, 0.2], ub = [0.3, 0.4])BoxUncertaintySet   lb ┼ Vector{Float64}: [0.1, 0.2]   ub ┼ Vector{Float64}: [0.3, 0.4]  val ┴ nothing

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Equation 11.14.
  • [86] M. Sousa Lobo and S. Boyd. The worst-case risk of a portfolio. Technical report, Stanford University (2000).
source
PortfolioOptimisers.BoxUncertaintySetAlgorithmType
struct BoxUncertaintySetAlgorithm <: AbstractUncertaintySetAlgorithm

Selects a box uncertainty set, a convex polytope of element-wise bounds, from an estimator that can build either shape.

Its sibling EllipsoidalUncertaintySetAlgorithm selects the ellipsoid instead. The box carries no correlation between the entries it bounds, and its worst case is a linear or semidefinite programme rather than a second-order cone one.

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 11.3.1.
source
PortfolioOptimisers.MuUncertaintySetClassType
struct MuUncertaintySetClass <: AbstractUncertaintySetClass

Tags an EllipsoidalUncertaintySet or a NormBallUncertaintySet as living on the mean axis, where the shape matrix is $N \times N$ and the geometry map has $N$ rows.

The tag is what the consumers dispatch on. port_opt_view slices such a set with the plain asset index, and the robust-return builder refuses a set that carries the covariance tag instead.

Related

source
PortfolioOptimisers.SigmaUncertaintySetClassType
struct SigmaUncertaintySetClass <: AbstractUncertaintySetClass

Tags an EllipsoidalUncertaintySet or a NormBallUncertaintySet as living on the covariance axis, where the shape matrix is $N^{2} \times N^{2}$ and the geometry map has $N^{2}$ rows.

The tag is what the consumers dispatch on. port_opt_view maps the asset index through the fourth-moment index generator before it slices the shape matrix or the geometry map, because the set bounds a vectorised covariance.

Related

source
PortfolioOptimisers.NormalKUncertaintyAlgorithmType
struct NormalKUncertaintyAlgorithm{__T_kwargs} <: AbstractUncertaintyKAlgorithm

Fits the ellipsoid radius k empirically, as the 1 - q quantile of the Mahalanobis distances of the sampled estimation errors.

The route makes no distributional assumption: it reads the errors the estimator family sampled, whether they come from a parametric draw or from a bootstrap resample. Its two closed-form siblings are ChiSqKUncertaintyAlgorithm and GeneralKUncertaintyAlgorithm.

The sample must be the estimation error, not the estimate. Under normality the centred Mahalanobis distance is a chi-squared variate, so this algorithm and ChiSqKUncertaintyAlgorithm compute one radius two ways and agree up to sampling noise, and that radius depends on the dimension and the significance level alone. Feeding the raw estimates instead makes the distance non-central, and the radius then grows with the non-centrality $T \hat{\boldsymbol{\mu}}^{\intercal} \hat{\mathbf{\Sigma}}^{-1} \hat{\boldsymbol{\mu}}$, inflating a radius that is meant to measure estimation error alone.

The quantile is taken against the shape matrix this algorithm is handed, not against the shape the estimator started from. ellipsoidal_set replaces the asymptotic covariance with its diagonal before it calls k_ucs, so under the diagonal = true default the radius is a quantile of Mahalanobis distances measured against the diagonal shape. The two radii differ, and neither shape is reliably the larger.

Mathematical definition

\[k = \sqrt{Q_{1-q}\!\left(\left\{ \boldsymbol{\delta}^{(m)\intercal} \mathbf{\Sigma}_{\boldsymbol{\delta}}^{-1} \boldsymbol{\delta}^{(m)} \right\}_{m=1}^{M}\right)}\,.\]

Where:

  • $\boldsymbol{\delta}^{(m)}$: The $m$-th sampled estimation error, a row of the X argument of k_ucs.
  • $\mathbf{\Sigma}_{\boldsymbol{\delta}}$: Shape matrix of the ellipsoid.
  • $Q_{1-q}$: The 1 - q quantile function.
  • $M$: Number of samples.

Fields

  • kwargs: Additional keyword arguments.

Constructors

NormalKUncertaintyAlgorithm(;    kwargs::NamedTuple = (;))

Keyword arguments correspond to the field above.

Validation

  • kwargs must be a valid NamedTuple.

Examples

julia> NormalKUncertaintyAlgorithm()NormalKUncertaintyAlgorithm  kwargs ┴ @NamedTuple{}: NamedTuple()

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 11.3.2.
source
PortfolioOptimisers.GeneralKUncertaintyAlgorithmType
struct GeneralKUncertaintyAlgorithm <: AbstractUncertaintyKAlgorithm

Computes the ellipsoid radius k as sqrt((1 - q) / q), the closed form that holds for any distribution of the estimation errors.

It is the second branch of Equation 11.23 of the source, and it reads neither the data nor the shape matrix. The radius comes from Cantelli's one-sided Chebyshev inequality, so it holds for any law of the estimation errors that has the stated second moment. Use ChiSqKUncertaintyAlgorithm instead when the errors are normal, because the chi-squared radius is the tighter one there.

The guarantee is a bound in one direction and not a simultaneous region for the whole vector. It covers the scalar a robust row bounds — the worst-case value of $\boldsymbol{w}^{\intercal} \boldsymbol{\mu}$ along the weights the model picks — with probability at least $1 - q$, whereas the chi-squared radius is a joint confidence region for every entry at once.

Mathematical definition

\[k = \sqrt{\dfrac{1 - q}{q}}\,.\]

Where:

  • $q$: Significance level.

Inverting the form gives $\left(1 + k^{2}\right)^{-1} = q$, which is Cantelli's bound at $k$ standard deviations. So the radius is the smallest one whose distribution-free tail bound is exactly $q$, and no assumption on the law tightens it.

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Equation 11.23.
  • [87] F. J. Fabozzi, P. N. Kolm, D. A. Pachamanova and S. M. Focardi. Robust Portfolio Optimization and Management (John Wiley & Sons, Hoboken, NJ, 2007).
source
PortfolioOptimisers.ChiSqKUncertaintyAlgorithmType
struct ChiSqKUncertaintyAlgorithm <: AbstractUncertaintyKAlgorithm

Computes the ellipsoid radius k as the square root of the 1 - q chi-squared quantile, the closed form that holds when the estimation errors are normal.

The degrees of freedom is read from size(sigma_X, 1), the first dimension of the shape matrix. That is $N$ on the mean axis, where the shape matrix is the asymptotic covariance of the mean, and $N^{2}$ on the covariance axis, where it is the asymptotic covariance of the vectorised covariance. The same algorithm therefore gives a different radius on each axis.

The source states this closed form for the mean axis only. Equation 11.23 defines $\kappa^{2}_{\boldsymbol{\mu}}$ with $n$ degrees of freedom, $n$ being the number of assets, and obtains $\kappa^{2}_{\mathbf{\Sigma}}$ by simulation rather than in closed form. Applying the same form on the covariance axis is this library's extension of it, and the extension is conservative: a symmetric $N \times N$ matrix has $N(N+1)/2$ free entries, and the normal method's shape matrix $T \left(\mathbf{I} + \mathbf{K}\right) \left(\mathbf{\Sigma}_{\boldsymbol{\mu}} \otimes \mathbf{\Sigma}_{\boldsymbol{\mu}}\right)$ has exactly that rank, so $N^{2}$ overstates the dimension of the ellipsoid it calibrates. At $N = 20$ and $q = 0.05$ the radius is $21.157$ where the free-entry count gives $15.646$. Use NormalKUncertaintyAlgorithm on the covariance axis to calibrate the radius on the sampled errors instead.

Mathematical definition

\[k = \sqrt{\chi^{2,\,-1}_{p}(1 - q)}\,, \qquad p = \operatorname{size}(\mathbf{\Sigma}_{\boldsymbol{\delta}}, 1)\,.\]

Where:

  • $\chi^{2,\,-1}_{p}$: Inverse cumulative distribution function of the chi-squared distribution with $p$ degrees of freedom.
  • $\mathbf{\Sigma}_{\boldsymbol{\delta}}$: Shape matrix of the ellipsoid.
  • $q$: Significance level.

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Equation 11.23.
  • [87] F. J. Fabozzi, P. N. Kolm, D. A. Pachamanova and S. M. Focardi. Robust Portfolio Optimization and Management (John Wiley & Sons, Hoboken, NJ, 2007).
source
PortfolioOptimisers.EllipsoidalUncertaintySetType
struct EllipsoidalUncertaintySet{__T_sigma, __T_k, __T_class, __T_val} <: AbstractUncertaintySetResult

Holds the shape matrix, the radius, and the axis tag of an ellipsoidal uncertainty set on a mean vector or on a covariance matrix.

An ellipsoid is a Mahalanobis ball, so it reads as a confidence region that carries the correlation between the entries it bounds. Its worst case is Equation 11.25 on the mean axis and Equation 11.26 on the covariance axis of the source, and both are second-order cones.

class names the axis, and the axis fixes both the size of sigma and the index a view applies. A MuUncertaintySetClass carries an $N \times N$ shape matrix and takes the plain asset index. A SigmaUncertaintySetClass carries an $N^{2} \times N^{2}$ one, because it bounds a vectorised covariance, so port_opt_view recovers $N$ from the shape matrix and maps the asset index through fourth_moment_index_generator before it slices. The two consumers dispatch on the tag too, and the robust-return builder refuses a set that carries the covariance tag.

A view carries k through unchanged, so it is not the set the same estimator would fit on the subset alone. The restricted shape matrix does equal the one fitted on the subset, entry for entry, whenever the shape is diagonal. The radius does not, because two of the three algorithms calibrate it on the dimension or on the sample. Only GeneralKUncertaintyAlgorithm agrees, because its radius reads neither the data nor the shape. A view is therefore the conservative choice, and a caller who wants the subset's own radius fits the subset.

Mathematical definition

\[\begin{align} U^{\text{ellip}}_{\boldsymbol{\mu}} &= \left\{ \boldsymbol{\mu}\, \vert\, \left( \boldsymbol{\mu} - \boldsymbol{\hat{\mu}} \right)^{\intercal} \mathbf{\Sigma}^{-1}_{\boldsymbol{\mu}} \left( \boldsymbol{\mu} - \boldsymbol{\hat{\mu}} \right) \leq k^{2}_{\boldsymbol{\mu}} \right\} \\ U^{\text{ellip}}_{\mathbf{\Sigma}} &= \left\{ \mathbf{\Sigma}\, \vert\, \left( \text{vec}\left(\mathbf{\Sigma}\right) - \text{vec}\left(\mathbf{\hat{\Sigma}} \right) \right)^{\intercal} \mathbf{\Sigma}^{-1}_{\mathbf{\Sigma}} \left( \text{vec}\left(\mathbf{\Sigma}\right) - \text{vec}\left(\mathbf{\hat{\Sigma}} \right) \right) \leq k^{2}_{\mathbf{\Sigma}},\, \mathbf{\Sigma} \succeq 0 \right\}\,. \end{align}\]

Where:

  • $U^{\text{ellip}}_{\boldsymbol{\mu}}$: Ellipsoidal uncertainty set for expected returns.
  • $U^{\text{ellip}}_{\mathbf{\Sigma}}$: Ellipsoidal uncertainty set for covariance matrix.
  • $\boldsymbol{\mu}$, $\mathbf{\Sigma}$: Uncertain expected returns and covariance.
  • $\boldsymbol{\hat{\mu}}$, $\mathbf{\hat{\Sigma}}$: Estimated reference mean and covariance.
  • $\mathbf{\Sigma}_{\boldsymbol{\mu}}$: Covariance matrix of estimation error in mean.
  • $\mathbf{\Sigma}_{\mathbf{\Sigma}}$: Covariance matrix of estimation error in covariance (vectorised).
  • $k^{2}_{\boldsymbol{\mu}}$, $k^{2}_{\mathbf{\Sigma}}$: Scaling parameters (squared ellipsoid radii).
  • $\text{vec}(\cdot)$: Vectorisation operator (column-stacking).
  • $\mathbf{\Sigma} \succeq 0$: Positive semi-definiteness constraint.

Fields

  • sigma: Covariance matrix assets × assets.
  • k: Uncertainty set scaling parameter.
  • class: Uncertainty set class.
  • val: Quantity the set is a neighbourhood of — a characteristic vector on the mean axis, a covariance matrix on the covariance axis. nothing defers to the consumer's own quantity. When it is set, it takes precedence over the returns estimator's field and over the prior.

Constructors

EllipsoidalUncertaintySet(;    sigma::MatNum,    k::Number,    class::AbstractUncertaintySetClass,    val::Option{<:ArrNum} = nothing) -> EllipsoidalUncertaintySet

Keywords correspond to the struct's fields.

Validation

  • !isempty(sigma).
  • size(sigma, 1) == size(sigma, 2).
  • k > 0.
  • If val is provided: length(val) == size(sigma, 1). The rule reads a length rather than a size, so it holds on both axes: val is a characteristic vector of length $N$ beside an $N \times N$ shape matrix, and an $N \times N$ covariance matrix beside an $N^{2} \times N^{2}$ one.

Examples

julia> EllipsoidalUncertaintySet([1.0 0.2; 0.2 1.0], 2.5, SigmaUncertaintySetClass())EllipsoidalUncertaintySet  sigma ┼ 2×2 Matrix{Float64}      k ┼ Float64: 2.5  class ┼ SigmaUncertaintySetClass()    val ┴ nothing

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Equation 11.22.
  • [26] Y. Feng and D. P. Palomar. A signal processing perspective of financial engineering. Foundations and Trends in Signal Processing 9, 1–231 (2016).
source
PortfolioOptimisers.EllipsoidalUncertaintySetAlgorithmType
struct EllipsoidalUncertaintySetAlgorithm{__T_method, __T_diagonal} <: AbstractUncertaintySetAlgorithm

Selects an ellipsoidal uncertainty set, and carries the radius algorithm and the diagonal switch it needs.

Its sibling BoxUncertaintySetAlgorithm selects the box instead. The ellipsoid reads the correlation between the entries it bounds through its shape matrix, which diagonal = true discards to remove the noise in the off-diagonal estimation errors.

Fields

  • method: Ellipsoidal uncertainty set estimation method.
  • diagonal: Whether to use only the diagonal of the covariance matrix.

Constructors

EllipsoidalUncertaintySetAlgorithm(;    method::Num_UcSK = ChiSqKUncertaintyAlgorithm(),    diagonal::Bool = true) -> EllipsoidalUncertaintySetAlgorithm
  • method: Sets the scaling algorithm or value for the ellipsoidal.
  • diagonal: Sets whether to use only diagonal elements.

Examples

julia> EllipsoidalUncertaintySetAlgorithm()EllipsoidalUncertaintySetAlgorithm    method ┼ ChiSqKUncertaintyAlgorithm()  diagonal ┴ Bool: true

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 11.3.2.
source
PortfolioOptimisers.NormBallUncertaintySetAlgorithmType
struct NormBallUncertaintySetAlgorithm{__T_method, __T_diagonal, __T_p} <: AbstractUncertaintySetAlgorithm

Selects a norm-ball uncertainty set, and carries the radius algorithm, the diagonal switch and the norm order it needs.

Its siblings BoxUncertaintySetAlgorithm and EllipsoidalUncertaintySetAlgorithm select the two older shapes. The set it selects is a NormBallUncertaintySet, which holds a geometry map rather than a shape matrix, so an estimator that emits it factorises the shape once at fit time, or skips the shape entirely and stores its own deviations. diagonal = true discards the correlation between the estimation errors of different entries, exactly as it does on the ellipsoid.

Fields

  • method: Radius algorithm of the ball, or the radius itself as a Number. It is read against the geometry map rather than against a shape matrix, so k_norm_ball serves it and not k_ucs.
  • diagonal: Whether to use only the diagonal of the covariance matrix.
  • p: Norm order $p \geq 1$ of the ball, Inf admitted. It reaches the set unchanged, and the consumer raises the cone of the dual order.

Constructors

NormBallUncertaintySetAlgorithm(;    method::Num_UcSK = ChiSqKUncertaintyAlgorithm(),    diagonal::Bool = true,    p::Number = 2) -> NormBallUncertaintySetAlgorithm

Keywords correspond to the struct's fields.

Validation

  • !isnan(p) and p >= 1. Inf is admitted.

Examples

julia> NormBallUncertaintySetAlgorithm()NormBallUncertaintySetAlgorithm    method ┼ ChiSqKUncertaintyAlgorithm()  diagonal ┼ Bool: true         p ┴ Int64: 2

Related

References

  • [88] A. Ben-Tal and A. Nemirovski. Robust Convex Optimization. Mathematics of Operations Research 23, 769–805 (1998). Section 3, Equation 14.
  • [89] D. Goldfarb and G. Iyengar. Robust Portfolio Selection Problems. Mathematics of Operations Research 28, 1–38 (2003). Section 5.
source
PortfolioOptimisers.ucsMethod
ucs(uc::Option{<:Tuple{<:Option{<:AbstractUncertaintySetResult},
                       <:Option{<:AbstractUncertaintySetResult}}}, args...; kwargs...)

Returns a pair of already-built uncertainty sets unchanged, so that a consumer can call ucs without first asking whether its slot holds an estimator or a result.

The method is a passthrough. It runs no procedure and it carries no # Algorithm section. Its sibling that takes an AbstractUncertaintySetEstimator is the method that fits.

Arguments

  • uc: Tuple of uncertainty sets, or nothing.
  • args...: Additional positional arguments (ignored).
  • kwargs...: Additional keyword arguments (ignored).

Returns

  • uc::Option{<:Tuple{<:Option{<:AbstractUncertaintySetResult}, <:Option{<:AbstractUncertaintySetResult}}}: The input, unchanged.

Related

source
PortfolioOptimisers.ucsMethod
ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult; kwargs...)

Fits both uncertainty sets in one pass from an estimator and a ReturnsResult.

The method unpacks the container and forwards to the matrix method, so an estimator that shares a prior or a simulation between the two axes computes it once.

Algorithm

  1. Check that rd.X is not nothing, and raise otherwise.
  2. When uc.pe's estimator tree requires factor returns — when needs_factor_returns answers true — check that rd.F is not nothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does.
  3. Forward to ucs(uc, rd.X, rd.F; iv = rd.iv, ivpa = rd.ivpa, kwargs...), giving the pair of fitted sets. The implied volatility fields travel with the returns, because a prior that reads them takes them by keyword.

Arguments

  • uc: Uncertainty set estimator. Used to construct the uncertainty set.
  • rd: ReturnsResult. Contains the returns data and associated metadata.
  • kwargs...: Additional keyword arguments passed to the estimator.

Validation

  • !isnothing(rd.X), raising an IsNothingError.
  • If needs_factor_returns(uc.pe) === true: !isnothing(rd.F), raising an IsNothingError.

Returns

  • uc::Tuple{<:AbstractUncertaintySetResult, <:AbstractUncertaintySetResult}: Expected returns and covariance uncertainty sets.

Related

source
PortfolioOptimisers.ucsMethod
ucs(ue::AbstractPriorUncertaintySetEstimator, ::AbstractPriorResult; kwargs...)
mu_ucs(ue::AbstractPriorUncertaintySetEstimator, ::AbstractPriorResult; kwargs...)
sigma_ucs(ue::AbstractPriorUncertaintySetEstimator, ::AbstractPriorResult; kwargs...)

Refuses a prior-reading uncertainty set estimator that declares no fit of its own, and names it.

AbstractPriorUncertaintySetEstimator states three verbs over a Prior Result, and a member owes a method of each. These three are the root's own methods, and they raise. They exist because the three-argument form of the triple forwards here, so a member that declares none of the three would otherwise fail with a MethodError naming the root rather than the type the author wrote.

There is no default fit. An estimator of this family reads a fitted prior result, and no two members read the same part of it, so a fallback would have to invent a set rather than build one. That is the polarity factor_residual_config uses for a per-type declaration whose absence is a defect rather than an answer.

Arguments

  • ue: Uncertainty set estimator, which the raise names.
  • pr: Prior result (ignored).
  • kwargs...: Additional keyword arguments (ignored).

Validation

  • Throws an ArgumentError naming the type of ue.

Related

source
PortfolioOptimisers.ucsMethod
ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult, pr::AbstractPriorResult; kwargs...)

Fits both uncertainty sets from an estimator that is handed the returns data and the prior result the optimisation is solving on.

This is the form both JuMP builders call, and it exists so that one call site serves every estimator. Each estimator reads the one argument its own fit is defined on, decided by reads_prior_result, and the third method of the form is the passthrough that already takes args..., so a slot holding a built pair answers here too.

ucReadsForwards to
an estimator with a pe of its ownrducs(uc, rd)
an AbstractPriorUncertaintySetEstimator, or a returns-data estimator with pe = nothingprucs(uc, pr; rd = rd)
a built pair, or nothingneitheritself, unchanged

The prior is dropped rather than checked on the first row. An estimator that carries its own pe fits it on the returns it is handed, so the optimisation's own prior is not an input of that fit, and passing it changes no number. An estimator on the second row is calibrated on pr: inside an optimiser that is the prior being solved on, so the set's centre and the objective's mu are the same number by construction.

Arguments

  • uc: Uncertainty set estimator, built pair, or nothing.
  • rd: ReturnsResult. Read by an estimator with a pe of its own, and dropped by a prior-reading one.
  • pr: AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with a pe of its own.
  • kwargs...: Additional keyword arguments passed to the estimator.

Returns

  • uc::Tuple{<:AbstractUncertaintySetResult, <:AbstractUncertaintySetResult}: Expected returns and covariance uncertainty sets.

Related

source
PortfolioOptimisers.mu_ucsMethod
mu_ucs(uc::Option{<:AbstractUncertaintySetResult}, args...; kwargs...)

Returns an already-built mean uncertainty set unchanged, so that a consumer can call mu_ucs without first asking whether its slot holds an estimator or a result.

The method is a passthrough. It runs no procedure and it carries no # Algorithm section. Its sibling that takes an AbstractUncertaintySetEstimator is the method that fits.

Arguments

  • uc: Expected returns uncertainty set or nothing.
  • args...: Additional positional arguments (ignored).
  • kwargs...: Additional keyword arguments (ignored).

Returns

  • uc::Option{<:AbstractUncertaintySetResult}: The input, unchanged.

Related

source
PortfolioOptimisers.mu_ucsMethod
mu_ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult; kwargs...)

Fits the mean uncertainty set from an estimator and a ReturnsResult.

The method unpacks the container and forwards to the matrix method. A caller that needs both axes calls ucs instead, which fits them in one pass.

Algorithm

  1. Check that rd.X is not nothing, and raise otherwise.
  2. When uc.pe's estimator tree requires factor returns — when needs_factor_returns answers true — check that rd.F is not nothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does.
  3. Forward to mu_ucs(uc, rd.X, rd.F; iv = rd.iv, ivpa = rd.ivpa, kwargs...), giving the fitted mean set. The implied volatility fields travel with the returns, because a prior that reads them takes them by keyword.

Arguments

  • uc: Uncertainty set estimator. Used to construct the expected returns uncertainty set.
  • rd: ReturnsResult. Contains the returns data and associated metadata.
  • kwargs...: Additional keyword arguments passed to the estimator.

Validation

  • !isnothing(rd.X), raising an IsNothingError.
  • If needs_factor_returns(uc.pe) === true: !isnothing(rd.F), raising an IsNothingError.

Returns

  • uc::AbstractUncertaintySetResult: Expected returns uncertainty set.

Related

source
PortfolioOptimisers.mu_ucsMethod
mu_ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult, pr::AbstractPriorResult; kwargs...)

Fits the mean uncertainty set from an estimator that is handed the returns data and the prior result the optimisation is solving on.

This is the form the robust-return builder calls. The routing table of ucs states which argument each estimator reads, decided by reads_prior_result, and the third method of the form is the passthrough that already takes args..., so a slot holding a built set answers here too.

Arguments

  • uc: Uncertainty set estimator, built set, or nothing.
  • rd: ReturnsResult. Read by an estimator with a pe of its own, and dropped by a prior-reading one.
  • pr: AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with a pe of its own.
  • kwargs...: Additional keyword arguments passed to the estimator.

Returns

  • uc::AbstractUncertaintySetResult: Expected returns uncertainty set.

Related

source
PortfolioOptimisers.sigma_ucsMethod
sigma_ucs(uc::Option{<:AbstractUncertaintySetResult}, args...; kwargs...)

Returns an already-built covariance uncertainty set unchanged, so that a consumer can call sigma_ucs without first asking whether its slot holds an estimator or a result.

The method is a passthrough. It runs no procedure and it carries no # Algorithm section. Its sibling that takes an AbstractUncertaintySetEstimator is the method that fits.

Arguments

  • uc: Covariance uncertainty set or nothing.
  • args...: Additional positional arguments (ignored).
  • kwargs...: Additional keyword arguments (ignored).

Returns

  • uc::Option{<:AbstractUncertaintySetResult}: The input, unchanged.

Related

source
PortfolioOptimisers.sigma_ucsMethod
sigma_ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult; kwargs...)

Fits the covariance uncertainty set from an estimator and a ReturnsResult.

The method unpacks the container and forwards to the matrix method. An estimator with no covariance analogue raises there, as CharacteristicUncertaintySet does.

Algorithm

  1. Check that rd.X is not nothing, and raise otherwise.
  2. When uc.pe's estimator tree requires factor returns — when needs_factor_returns answers true — check that rd.F is not nothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does.
  3. Forward to sigma_ucs(uc, rd.X, rd.F; iv = rd.iv, ivpa = rd.ivpa, kwargs...), giving the fitted covariance set. The implied volatility fields travel with the returns, because a prior that reads them takes them by keyword.

Arguments

  • uc: Uncertainty set estimator. Used to construct the covariance uncertainty set.
  • rd: ReturnsResult. Contains the returns data and associated metadata.
  • kwargs...: Additional keyword arguments passed to the estimator.

Validation

  • !isnothing(rd.X), raising an IsNothingError.
  • If needs_factor_returns(uc.pe) === true: !isnothing(rd.F), raising an IsNothingError.

Returns

  • uc::AbstractUncertaintySetResult: Covariance uncertainty set.

Related

source
PortfolioOptimisers.sigma_ucsMethod
sigma_ucs(uc::AbstractUncertaintySetEstimator, rd::ReturnsResult, pr::AbstractPriorResult; kwargs...)

Fits the covariance uncertainty set from an estimator that is handed the returns data and the prior result the optimisation is solving on.

This is the form the uncertainty set variance builder calls. The routing table of ucs states which argument each estimator reads, decided by reads_prior_result, and the third method of the form is the passthrough that already takes args..., so a slot holding a built set answers here too.

Arguments

  • uc: Uncertainty set estimator, built set, or nothing.
  • rd: ReturnsResult. Read by an estimator with a pe of its own, and dropped by a prior-reading one.
  • pr: AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with a pe of its own.
  • kwargs...: Additional keyword arguments passed to the estimator.

Returns

  • uc::AbstractUncertaintySetResult: Covariance uncertainty set.

Related

source
PortfolioOptimisers.reads_prior_resultFunction
reads_prior_result(ue::AbstractUncertaintySetEstimator) -> Bool
reads_prior_result(::AbstractPriorUncertaintySetEstimator) -> Bool
reads_prior_result(::DeltaUncertaintySet{Nothing}) -> Bool
reads_prior_result(::NormalUncertaintySet{Nothing}) -> Bool
reads_prior_result(::ARCHUncertaintySet{Nothing}) -> Bool
reads_prior_result(::CharacteristicUncertaintySet{Nothing}) -> Bool
reads_prior_result(::Option{<:AbstractUncertaintySetResult}) -> Bool

States whether an uncertainty set estimator is calibrated on the prior result it is handed, rather than on a prior it fits for itself from returns data.

It is a per-type predicate, read off the type and the pe field and never off a method table, so that the three consumers which must route an estimator to the argument it reads — the three-argument form of the ucs triple, ucs_risk_measure and the Pipeline's uncertainty step — ask one question and agree on the answer. Two kinds of estimator answer true: every AbstractPriorUncertaintySetEstimator, which carries no pe at all, and each of the four returns-data families when its pe is nothing, each of which declares its own method beside its prior-result arm. Every other estimator answers false, which is the default a caller's own subtype inherits. A built set, or nothing, answers false too: it is fitted already and passes through every verb unchanged, so a slot that may hold either an estimator or a result can be asked without a test of its own.

Arguments

  • ue: Uncertainty set estimator, built set, or nothing.

Returns

  • reads::Bool: true when the estimator reads a prior result, false when it fits its own prior or is a built set.

Related

source
PortfolioOptimisers.k_ucsFunction
k_ucs(km::NormalKUncertaintyAlgorithm, q::Number, X::MatNum, sigma_X::MatNum)
k_ucs(::GeneralKUncertaintyAlgorithm, q::Number, args...)
k_ucs(::ChiSqKUncertaintyAlgorithm, q::Number, ::Any, sigma_X::MatNum)
k_ucs(type::Number, args...)

Compute the radius k of an ellipsoidal uncertainty set at significance level q.

The two closed forms are the two branches of Equation 11.23 of the source, and the simulated route is its empirical counterpart. A plain Number in place of an algorithm is the radius itself.

Algorithm

The first three methods each run one procedure. The fourth, k_ucs(type::Number, args...), returns its own argument and takes no step, so it carries none of the numbered text below.

NormalKUncertaintyAlgorithm:

  1. Form k_mus = LinearAlgebra.diag(X * (sigma_X \ transpose(X))), the squared Mahalanobis distance of every row of X against the shape matrix. The solve is done once for the whole sample rather than row by row.
  2. Take the 1 - q quantile of k_mus under km.kwargs, and return its square root, the radius.

GeneralKUncertaintyAlgorithm:

  1. Return sqrt((one(q) - q) / q), the radius. The method reads neither X nor sigma_X, so both are absorbed by args....

ChiSqKUncertaintyAlgorithm:

  1. Read the degrees of freedom from size(sigma_X, 1), the dimension of the ellipsoid.
  2. Return the square root of the 1 - q chi-squared quantile at that many degrees of freedom, the radius. The method runs no simulation, so it ignores the sample container.

Arguments

  • km: Scaling algorithm instance.
  • q: Significance level.
  • X: Matrix of estimation errors, one row per sample. Every caller passes centred deviations, not levels: each row is a deviation from the point estimate, and the method cannot check it. An uncentred sample makes the distance non-central and inflates the radius.
  • sigma_X: Shape matrix of the ellipsoid, and the shape the distances are measured against. It is $N \times N$ on the mean axis and $N^{2} \times N^{2}$ on the covariance axis. ellipsoidal_set passes the diagonal of the asymptotic covariance under its diagonal = true default, so the quantile is taken against that diagonal and not against the full matrix.
  • args...: Additional arguments, which the algorithms that need no sample absorb.
  • type: Number value for direct scaling.

Returns

  • k::Number: Radius of the ellipsoid.

Related

References

  • [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 11.3.2.
  • [87] F. J. Fabozzi, P. N. Kolm, D. A. Pachamanova and S. M. Focardi. Robust Portfolio Optimization and Management (John Wiley & Sons, Hoboken, NJ, 2007).
source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(risk_ucs::Option{<:AbstractUncertaintySetEstimator}, i, args...)

Returns an uncertainty set estimator unchanged, because an estimator carries no asset axis to restrict.

The method is a passthrough. It runs no procedure and it carries no # Algorithm section. A hierarchical optimiser calls port_opt_view once per cluster, and an estimator that reaches this method is fitted later against the cluster's own returns, so the restriction happens in the fit rather than here. The methods that take a built result do index; each states its own steps.

Arguments

  • risk_ucs: Uncertainty set estimator, or nothing.
  • i: Cluster or asset index (ignored).
  • args...: Additional positional arguments (ignored).

Returns

  • risk_ucs::Option{<:AbstractUncertaintySetEstimator}: The input, unchanged.

Related

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    risk_ucs::BoxUncertaintySet{<:AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, <:AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}},
    i,
    args...
) -> Union{BoxUncertaintySet{var"#s185", <:AbstractArray{var"#s137", N}, Nothing} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s185"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}, BoxUncertaintySet{var"#s185", var"#s1851", <:AbstractArray{var"#s137", N}} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s185"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s1851"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}}

Return a view of a vector BoxUncertaintySet restricted to the asset indices i.

The method takes the mean axis, where each bound carries one entry per asset, so the asset index applies to both bounds directly.

Algorithm

  1. Take view(risk_ucs.lb, i) and view(risk_ucs.ub, i), the two bounds restricted to the selected assets.
  2. Take nothing_scalar_array_view(risk_ucs.val, i), the centre restricted to the same assets, which passes a nothing through unchanged.
  3. Build a BoxUncertaintySet from the three views. The bounds stay a pair, so the half-width the mean route reads is the half-width of the restricted box.

Arguments

  • risk_ucs: Vector-valued box uncertainty set.
  • i: Cluster or asset index.
  • args...: Additional positional arguments (ignored).

Returns

  • risk_ucs::BoxUncertaintySet: The set restricted to i.

Related

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    risk_ucs::BoxUncertaintySet{<:AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, <:AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}},
    i,
    args...
) -> Union{BoxUncertaintySet{var"#s185", <:AbstractArray{var"#s137", N}, Nothing} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s185"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}, BoxUncertaintySet{var"#s185", var"#s1851", <:AbstractArray{var"#s137", N}} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s185"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N, var"#s1851"<:AbstractArray{var"#s137", N}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}}

Return a view of a matrix BoxUncertaintySet restricted to the asset indices i.

The method takes the covariance axis, where each bound is an N × N matrix, so the asset index applies to both dimensions of each bound.

Algorithm

  1. Take view(risk_ucs.lb, i, i) and view(risk_ucs.ub, i, i), the two bounds restricted to the selected assets on both axes. Both stay symmetric, because the source bounds are symmetric and the same index is applied twice.
  2. Take nothing_scalar_array_view(risk_ucs.val, i), the fitted covariance restricted to the same assets, which passes a nothing through unchanged.
  3. Build a BoxUncertaintySet from the three views. Both bounds bind on their own on this axis, so each is restricted rather than combined.

Arguments

  • risk_ucs: Matrix-valued box uncertainty set.
  • i: Cluster or asset index.
  • args...: Additional positional arguments (ignored).

Returns

  • risk_ucs::BoxUncertaintySet: The set restricted to i.

Related

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    risk_ucs::EllipsoidalUncertaintySet{<:AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, <:Any, <:SigmaUncertaintySetClass},
    i,
    args...
) -> Union{EllipsoidalUncertaintySet{<:AbstractMatrix{var"#s137"}, <:Number, SigmaUncertaintySetClass, Nothing} where var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), EllipsoidalUncertaintySet{var"#s185", var"#s1851", SigmaUncertaintySetClass, <:AbstractArray{var"#s137", N}} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), var"#s185"<:AbstractMatrix{var"#s137"}, var"#s1851"<:Number, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}}

Return a view of a covariance EllipsoidalUncertaintySet restricted to assets at index i, mapping the sigma index through the fourth-moment index generator.

The set bounds a vectorised covariance, so its shape matrix lives on the $N^{2}$ axis while its centre lives on the $N$ axis. The method therefore applies two different indices, one to each field.

Algorithm

  1. Take nothing_scalar_array_view(risk_ucs.val, i), the fitted $N \times N$ covariance restricted to the selected assets. It takes the plain asset index, and a nothing passes through unchanged. The step runs first, because step 2 overwrites i.
  2. Recover N as floor(Int, sqrt(size(risk_ucs.sigma, 1))) from the shape matrix, and expand i with fourth_moment_index_generator(N, i), giving the positions the selected assets occupy in the vectorised covariance.
  3. Take view(risk_ucs.sigma, i, i) under the expanded index, giving the restricted shape matrix.
  4. Build an EllipsoidalUncertaintySet from the two views, carrying k and class through unchanged. The radius is not recalibrated on the smaller dimension, so the view is more conservative than a fit on the subset under every radius algorithm except GeneralKUncertaintyAlgorithm.

Arguments

  • risk_ucs: Covariance ellipsoidal uncertainty set.
  • i: Cluster or asset index.
  • args...: Additional positional arguments (ignored).

Returns

  • risk_ucs::EllipsoidalUncertaintySet: The set restricted to i.

Related

source
PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    risk_ucs::EllipsoidalUncertaintySet{<:AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, <:Any, <:MuUncertaintySetClass},
    i,
    args...
) -> Union{EllipsoidalUncertaintySet{<:AbstractMatrix{var"#s137"}, <:Number, MuUncertaintySetClass, Nothing} where var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), EllipsoidalUncertaintySet{var"#s185", var"#s1851", MuUncertaintySetClass, <:AbstractArray{var"#s137", N}} where {var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), var"#s185"<:AbstractMatrix{var"#s137"}, var"#s1851"<:Number, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), N}}

Return a view of a mean EllipsoidalUncertaintySet restricted to assets at index i.

The set bounds a characteristic vector, so its shape matrix and its centre both live on the $N$ axis and one index serves both.

Algorithm

  1. Take view(risk_ucs.sigma, i, i), the $N \times N$ shape matrix restricted to the selected assets on both dimensions.
  2. Take nothing_scalar_array_view(risk_ucs.val, i), the fitted characteristic vector restricted to the same assets, which passes a nothing through unchanged.
  3. Build an EllipsoidalUncertaintySet from the two views, carrying k and class through unchanged. The radius is not recalibrated on the smaller dimension, so the view is more conservative than a fit on the subset under every radius algorithm except GeneralKUncertaintyAlgorithm.

Arguments

  • risk_ucs: Mean ellipsoidal uncertainty set.
  • i: Cluster or asset index.
  • args...: Additional positional arguments (ignored).

Returns

  • risk_ucs::EllipsoidalUncertaintySet: The set restricted to i.

Related

source

References

[5]
D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025).
[26]
Y. Feng and D. P. Palomar. A signal processing perspective of financial engineering. Foundations and Trends in Signal Processing 9, 1–231 (2016).
[86]
M. Sousa Lobo and S. Boyd. The Worst-Case Risk of a Portfolio (Stanford University, 2000).
[87]
F. J. Fabozzi, P. N. Kolm, D. A. Pachamanova and S. M. Focardi. Robust Portfolio Optimization and Management (John Wiley & Sons, Hoboken, NJ, 2007).
[88]
A. Ben-Tal and A. Nemirovski. Robust Convex Optimization. Mathematics of Operations Research 23, 769–805 (1998).
[89]
D. Goldfarb and G. Iyengar. Robust Portfolio Selection Problems. Mathematics of Operations Research 28, 1–38 (2003).