Base Uncertainty Sets
PortfolioOptimisers.AbstractUncertaintySetEstimator — Type
abstract type AbstractUncertaintySetEstimator <: AbstractEstimatorFits 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, asCharacteristicUncertaintySetdoes.
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 forucs.
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 answersfalse, so a subtype that fits from returns data declares nothing; one that reads a prior result subtypesAbstractPriorUncertaintySetEstimatorinstead, or, in the four returns-data families, holdspe = nothing.
Related
PortfolioOptimisers.AbstractPriorUncertaintySetEstimator — Type
abstract type AbstractPriorUncertaintySetEstimator <: AbstractUncertaintySetEstimatorFits 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 forucs.
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
PortfolioOptimisers.AbstractUncertaintySetAlgorithm — Type
abstract type AbstractUncertaintySetAlgorithm <: AbstractAlgorithmSelects 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
PortfolioOptimisers.AbstractUncertaintySetResult — Type
abstract type AbstractUncertaintySetResult <: AbstractResultCarries 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 indicesi. 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
PortfolioOptimisers.AbstractUncertaintyKAlgorithm — Type
abstract type AbstractUncertaintyKAlgorithm <: AbstractAlgorithmComputes 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
PortfolioOptimisers.AbstractCompactRadiusAlgorithm — Type
abstract type AbstractCompactRadiusAlgorithm <: AbstractAlgorithmComputes 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
ResidualInflationVarianceFractionNum_CptRadk_compactOrthogonalUncertaintySetCompactCovarianceUncertaintySetAbstractCalibrationAlgorithm: the parallel channel, which sizes a quantity whose units do not move with a sibling field.
PortfolioOptimisers.AbstractUncertaintyEpsAlgorithm — Type
abstract type AbstractUncertaintyEpsAlgorithm <: AbstractAlgorithmComputes 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, ornothingwhen 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
PortfolioOptimisers.AbstractUncertaintySetClass — Type
abstract type AbstractUncertaintySetClass <: AbstractUncertaintySetResultNames 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
PortfolioOptimisers.BoxUncertaintySet — Type
struct BoxUncertaintySet{__T_lb, __T_ub, __T_val} <: AbstractUncertaintySetResultHolds 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.nothingdefers 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) -> BoxUncertaintySetKeywords correspond to the struct's fields.
Validation
!isempty(lb).!isempty(ub).size(lb) == size(ub).- If
valis 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 ┴ nothingRelated
References
PortfolioOptimisers.BoxUncertaintySetAlgorithm — Type
struct BoxUncertaintySetAlgorithm <: AbstractUncertaintySetAlgorithmSelects 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.
PortfolioOptimisers.MuUncertaintySetClass — Type
struct MuUncertaintySetClass <: AbstractUncertaintySetClassTags 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
PortfolioOptimisers.SigmaUncertaintySetClass — Type
struct SigmaUncertaintySetClass <: AbstractUncertaintySetClassTags 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
PortfolioOptimisers.NormalKUncertaintyAlgorithm — Type
struct NormalKUncertaintyAlgorithm{__T_kwargs} <: AbstractUncertaintyKAlgorithmFits 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
Xargument ofk_ucs. - $\mathbf{\Sigma}_{\boldsymbol{\delta}}$: Shape matrix of the ellipsoid.
- $Q_{1-q}$: The
1 - qquantile function. - $M$: Number of samples.
Fields
kwargs: Additional keyword arguments.
Constructors
NormalKUncertaintyAlgorithm(; kwargs::NamedTuple = (;))Keyword arguments correspond to the field above.
Validation
kwargsmust be a validNamedTuple.
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.
PortfolioOptimisers.GeneralKUncertaintyAlgorithm — Type
struct GeneralKUncertaintyAlgorithm <: AbstractUncertaintyKAlgorithmComputes 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
PortfolioOptimisers.ChiSqKUncertaintyAlgorithm — Type
struct ChiSqKUncertaintyAlgorithm <: AbstractUncertaintyKAlgorithmComputes 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
PortfolioOptimisers.EllipsoidalUncertaintySet — Type
struct EllipsoidalUncertaintySet{__T_sigma, __T_k, __T_class, __T_val} <: AbstractUncertaintySetResultHolds 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 matrixassets × 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.nothingdefers 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) -> EllipsoidalUncertaintySetKeywords correspond to the struct's fields.
Validation
!isempty(sigma).size(sigma, 1) == size(sigma, 2).k > 0.- If
valis provided:length(val) == size(sigma, 1). The rule reads a length rather than a size, so it holds on both axes:valis 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 ┴ nothingRelated
References
PortfolioOptimisers.EllipsoidalUncertaintySetAlgorithm — Type
struct EllipsoidalUncertaintySetAlgorithm{__T_method, __T_diagonal} <: AbstractUncertaintySetAlgorithmSelects 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) -> EllipsoidalUncertaintySetAlgorithmmethod: 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: trueRelated
AbstractUncertaintySetAlgorithmAbstractUncertaintyKAlgorithmEllipsoidalUncertaintySetBoxUncertaintySetAlgorithm
References
- [5] D. Cajas. Advanced Portfolio Optimization: A Cutting-edge Quantitative Approach (Springer Nature Switzerland, 2025). Section 11.3.2.
PortfolioOptimisers.NormBallUncertaintySetAlgorithm — Type
struct NormBallUncertaintySetAlgorithm{__T_method, __T_diagonal, __T_p} <: AbstractUncertaintySetAlgorithmSelects 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 aNumber. It is read against the geometry map rather than against a shape matrix, sok_norm_ballserves it and notk_ucs.
diagonal: Whether to use only the diagonal of the covariance matrix.
p: Norm order $p \geq 1$ of the ball,Infadmitted. 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) -> NormBallUncertaintySetAlgorithmKeywords correspond to the struct's fields.
Validation
!isnan(p)andp >= 1.Infis admitted.
Examples
julia> NormBallUncertaintySetAlgorithm()NormBallUncertaintySetAlgorithm method ┼ ChiSqKUncertaintyAlgorithm() diagonal ┼ Bool: true p ┴ Int64: 2Related
AbstractUncertaintySetAlgorithmAbstractUncertaintyKAlgorithmNormBallUncertaintySetEllipsoidalUncertaintySetAlgorithmBoxUncertaintySetAlgorithmnorm_ball_setnorm_ball_deviation_set
References
PortfolioOptimisers.ucs — Method
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, ornothing.args...: Additional positional arguments (ignored).kwargs...: Additional keyword arguments (ignored).
Returns
uc::Option{<:Tuple{<:Option{<:AbstractUncertaintySetResult}, <:Option{<:AbstractUncertaintySetResult}}}: The input, unchanged.
Related
PortfolioOptimisers.ucs — Method
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
- Check that
rd.Xis notnothing, and raise otherwise. - When
uc.pe's estimator tree requires factor returns — whenneeds_factor_returnsanswerstrue— check thatrd.Fis notnothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does. - 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 anIsNothingError.- If
needs_factor_returns(uc.pe) === true:!isnothing(rd.F), raising anIsNothingError.
Returns
uc::Tuple{<:AbstractUncertaintySetResult, <:AbstractUncertaintySetResult}: Expected returns and covariance uncertainty sets.
Related
PortfolioOptimisers.ucs — Method
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
ArgumentErrornaming the type ofue.
Related
PortfolioOptimisers.ucs — Method
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.
uc | Reads | Forwards to |
|---|---|---|
an estimator with a pe of its own | rd | ucs(uc, rd) |
an AbstractPriorUncertaintySetEstimator, or a returns-data estimator with pe = nothing | pr | ucs(uc, pr; rd = rd) |
a built pair, or nothing | neither | itself, 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, ornothing.rd:ReturnsResult. Read by an estimator with apeof its own, and dropped by a prior-reading one.pr:AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with apeof its own.kwargs...: Additional keyword arguments passed to the estimator.
Returns
uc::Tuple{<:AbstractUncertaintySetResult, <:AbstractUncertaintySetResult}: Expected returns and covariance uncertainty sets.
Related
PortfolioOptimisers.mu_ucs — Method
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 ornothing.args...: Additional positional arguments (ignored).kwargs...: Additional keyword arguments (ignored).
Returns
uc::Option{<:AbstractUncertaintySetResult}: The input, unchanged.
Related
PortfolioOptimisers.mu_ucs — Method
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
- Check that
rd.Xis notnothing, and raise otherwise. - When
uc.pe's estimator tree requires factor returns — whenneeds_factor_returnsanswerstrue— check thatrd.Fis notnothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does. - 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 anIsNothingError.- If
needs_factor_returns(uc.pe) === true:!isnothing(rd.F), raising anIsNothingError.
Returns
uc::AbstractUncertaintySetResult: Expected returns uncertainty set.
Related
PortfolioOptimisers.mu_ucs — Method
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, ornothing.rd:ReturnsResult. Read by an estimator with apeof its own, and dropped by a prior-reading one.pr:AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with apeof its own.kwargs...: Additional keyword arguments passed to the estimator.
Returns
uc::AbstractUncertaintySetResult: Expected returns uncertainty set.
Related
PortfolioOptimisers.sigma_ucs — Method
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 ornothing.args...: Additional positional arguments (ignored).kwargs...: Additional keyword arguments (ignored).
Returns
uc::Option{<:AbstractUncertaintySetResult}: The input, unchanged.
Related
PortfolioOptimisers.sigma_ucs — Method
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
- Check that
rd.Xis notnothing, and raise otherwise. - When
uc.pe's estimator tree requires factor returns — whenneeds_factor_returnsanswerstrue— check thatrd.Fis notnothing, and raise otherwise. A factor leaf reads the factor returns, wherever it sits in the tree, and no other prior does. - 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 anIsNothingError.- If
needs_factor_returns(uc.pe) === true:!isnothing(rd.F), raising anIsNothingError.
Returns
uc::AbstractUncertaintySetResult: Covariance uncertainty set.
Related
PortfolioOptimisers.sigma_ucs — Method
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, ornothing.rd:ReturnsResult. Read by an estimator with apeof its own, and dropped by a prior-reading one.pr:AbstractPriorResult. Read by a prior-reading estimator, and dropped by one with apeof its own.kwargs...: Additional keyword arguments passed to the estimator.
Returns
uc::AbstractUncertaintySetResult: Covariance uncertainty set.
Related
PortfolioOptimisers.reads_prior_result — Function
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}) -> BoolStates 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, ornothing.
Returns
reads::Bool:truewhen the estimator reads a prior result,falsewhen it fits its own prior or is a built set.
Related
PortfolioOptimisers.k_ucs — Function
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.
- Form
k_mus = LinearAlgebra.diag(X * (sigma_X \ transpose(X))), the squared Mahalanobis distance of every row ofXagainst the shape matrix. The solve is done once for the whole sample rather than row by row. - Take the
1 - qquantile ofk_musunderkm.kwargs, and return its square root, the radius.
- Return
sqrt((one(q) - q) / q), the radius. The method reads neitherXnorsigma_X, so both are absorbed byargs....
- Read the degrees of freedom from
size(sigma_X, 1), the dimension of the ellipsoid. - Return the square root of the
1 - qchi-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_setpasses the diagonal of the asymptotic covariance under itsdiagonal = truedefault, 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
NormalKUncertaintyAlgorithmGeneralKUncertaintyAlgorithmChiSqKUncertaintyAlgorithmEllipsoidalUncertaintySetAlgorithm
References
PortfolioOptimisers.port_opt_view — Method
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, ornothing.i: Cluster or asset index (ignored).args...: Additional positional arguments (ignored).
Returns
risk_ucs::Option{<:AbstractUncertaintySetEstimator}: The input, unchanged.
Related
PortfolioOptimisers.port_opt_view — Method
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
- Take
view(risk_ucs.lb, i)andview(risk_ucs.ub, i), the two bounds restricted to the selected assets. - Take
nothing_scalar_array_view(risk_ucs.val, i), the centre restricted to the same assets, which passes anothingthrough unchanged. - Build a
BoxUncertaintySetfrom 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 toi.
Related
PortfolioOptimisers.port_opt_view — Method
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
- Take
view(risk_ucs.lb, i, i)andview(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. - Take
nothing_scalar_array_view(risk_ucs.val, i), the fitted covariance restricted to the same assets, which passes anothingthrough unchanged. - Build a
BoxUncertaintySetfrom 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 toi.
Related
PortfolioOptimisers.port_opt_view — Method
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
- 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 anothingpasses through unchanged. The step runs first, because step 2 overwritesi. - Recover
Nasfloor(Int, sqrt(size(risk_ucs.sigma, 1)))from the shape matrix, and expandiwithfourth_moment_index_generator(N, i), giving the positions the selected assets occupy in the vectorised covariance. - Take
view(risk_ucs.sigma, i, i)under the expanded index, giving the restricted shape matrix. - Build an
EllipsoidalUncertaintySetfrom the two views, carryingkandclassthrough 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 exceptGeneralKUncertaintyAlgorithm.
Arguments
risk_ucs: Covariance ellipsoidal uncertainty set.i: Cluster or asset index.args...: Additional positional arguments (ignored).
Returns
risk_ucs::EllipsoidalUncertaintySet: The set restricted toi.
Related
PortfolioOptimisers.port_opt_view — Method
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
- Take
view(risk_ucs.sigma, i, i), the $N \times N$ shape matrix restricted to the selected assets on both dimensions. - Take
nothing_scalar_array_view(risk_ucs.val, i), the fitted characteristic vector restricted to the same assets, which passes anothingthrough unchanged. - Build an
EllipsoidalUncertaintySetfrom the two views, carryingkandclassthrough 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 exceptGeneralKUncertaintyAlgorithm.
Arguments
risk_ucs: Mean ellipsoidal uncertainty set.i: Cluster or asset index.args...: Additional positional arguments (ignored).
Returns
risk_ucs::EllipsoidalUncertaintySet: The set restricted toi.
Related
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).