Compact Uncertainty Sets
PortfolioOptimisers.CompactCovarianceUncertaintySet — Type
struct CompactCovarianceUncertaintySet{__T_kappa, __T_C, __T_Q, __T_val} <: AbstractUncertaintySetResultHolds a worst-case variance penalty as a radius, a diagonal metric square root and a basis of the directions the penalty spares.
The set inflates the variance on every direction outside the span of its basis and on none inside it, so a portfolio built out of that span pays nothing. The consumer adds one quadratic term and rank free variables instead of the dense $N \times N$ matrix the same worst case would otherwise need, which is why the type is called compact: no lifted semidefinite block appears, and the programme stays a second-order cone programme. The basis is orthonormal over all $N$ rows, so a row slice of it is not orthonormal, and port_opt_view re-orthonormalises the slice rather than slicing the projector.
Mathematical definition
\[\begin{align} \underset{\mathbf{\Sigma} \in U^{\text{cpt}}_{\mathbf{\Sigma}}}{\max} \boldsymbol{w}^{\intercal} \mathbf{\Sigma} \boldsymbol{w} &= \boldsymbol{w}^{\intercal} \hat{\mathbf{\Sigma}} \boldsymbol{w} + \kappa \underset{\boldsymbol{z}}{\min} \lVert \mathbf{C} \boldsymbol{w} - \mathbf{Q} \boldsymbol{z} \rVert_{2}^{2} \\ U^{\text{cpt}}_{\mathbf{\Sigma}} &= \left\{ \mathbf{\Sigma} \succeq 0 \, \vert \, \mathbf{\Sigma} \preceq \hat{\mathbf{\Sigma}} + \kappa \mathbf{C}^{\intercal} (\mathbf{I} - \mathbf{Q}\mathbf{Q}^{\intercal}) \mathbf{C} \right\}\,. \end{align}\]
Where:
- $U^{\text{cpt}}_{\mathbf{\Sigma}}$: Compact uncertainty set for the covariance matrix.
- $\mathbf{\Sigma}$: Uncertain covariance.
- $\hat{\mathbf{\Sigma}}$: Estimated covariance matrix.
- $\boldsymbol{w}$: Portfolio weights vector $N \times 1$.
- $\kappa \geq 0$: Radius, the multiplier of the penalty.
- $\mathbf{C} = \operatorname{diag}(\boldsymbol{c})$: Diagonal metric square root, $N \times N$.
- $\mathbf{Q}$: Basis of the spared subspace, $N \times r$, with orthonormal columns.
- $\boldsymbol{z}$: Coefficient vector of the inner problem, $r \times 1$.
The two lines are one object because the inner problem is a least-squares problem whose value is $\lVert (\mathbf{I} - \mathbf{Q}\mathbf{Q}^{\intercal})\mathbf{C}\boldsymbol{w} \rVert_{2}^{2}$, and $\mathbf{I} - \mathbf{Q}\mathbf{Q}^{\intercal}$ is symmetric and idempotent. The variational form on the right of the first line is the weaker of the two: it projects onto $\operatorname{col}(\mathbf{Q})$ for any $\mathbf{Q}$, whereas the closed form of the second line needs orthonormal columns. A weight vector with $\mathbf{C}\boldsymbol{w} \in \operatorname{col}(\mathbf{Q})$ pays a zero penalty, and $r = 0$ leaves $\kappa \lVert \mathbf{C}\boldsymbol{w} \rVert_{2}^{2}$.
Fields
kappa: Radius $\kappa \geq 0$, the multiplier of the quadratic penalty, and0disables the penalty and leaves the nominal variance. A set is a Result, so this is always a number: anOrthogonalUncertaintySetwhose ownkappaheld anAbstractCompactRadiusAlgorithmresolved it before building the set.
C: Diagonal of the metric square root $\mathbf{C}$, of length $N$, held as a vector rather than as a matrix.
Q: Basis $\mathbf{Q}$ of the subspace the penalty spares, $N \times r$, with orthonormal columns. A rank of0is admitted and leaves the penalty $\kappa \lVert \mathbf{C}\boldsymbol{w} \rVert_{2}^{2}$.
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
CompactCovarianceUncertaintySet(; kappa::Number, C::VecNum, Q::MatNum, val::Option{<:MatNum} = nothing) -> CompactCovarianceUncertaintySetKeywords correspond to the struct's fields.
Validation
isfinite(kappa)andkappa >= 0.!isempty(C),all(isfinite, C)andall(x -> x >= 0, C).all(isfinite, Q).size(Q, 1) == length(C).- If
valis provided:size(val, 1) == size(val, 2) == length(C).
Examples
julia> CompactCovarianceUncertaintySet(; kappa = 2.0, C = [1.0, 1.0], Q = reshape([1.0, 0.0], 2, 1))CompactCovarianceUncertaintySet kappa ┼ Float64: 2.0 C ┼ Vector{Float64}: [1.0, 1.0] Q ┼ 2×1 Matrix{Float64} val ┴ nothingRelated
PortfolioOptimisers.port_opt_view — Method
port_opt_view(
risk_ucs::CompactCovarianceUncertaintySet,
i,
args...
) -> Union{CompactCovarianceUncertaintySet{var"#s185", var"#s1851", <:AbstractMatrix{var"#s137"}, Nothing} where {var"#s185"<:Number, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), var"#s1851"<:AbstractVector{var"#s137"}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar})}, CompactCovarianceUncertaintySet{var"#s185", var"#s1851", var"#s1852", <:AbstractMatrix{var"#s137"}} where {var"#s185"<:Number, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), var"#s1851"<:AbstractVector{var"#s137"}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}), var"#s1852"<:AbstractMatrix{var"#s137"}, var"#s137"<:(Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar})}}
Return a view of a CompactCovarianceUncertaintySet restricted to the asset indices i, re-orthonormalising the basis it slices.
The restricted penalty is the projection onto the sliced span, and not the slice of the projection. The two differ: $\mathbf{Q}^{\intercal}\mathbf{Q} = \mathbf{I}$ sums over all $N$ rows, so the rows of one cluster satisfy $\mathbf{Q}_{i}^{\intercal}\mathbf{Q}_{i} = \mathbf{I} - \mathbf{Q}_{-i}^{\intercal}\mathbf{Q}_{-i}$, which is not the identity and makes $\mathbf{Q}_{i}\mathbf{Q}_{i}^{\intercal}$ no projector at all. The subspace itself survives the slice, so re-orthonormalising the sliced rows recovers a basis of the right span.
Algorithm
- Take
view(risk_ucs.C, i), the diagonal of the metric square root restricted to the selected assets. - Take
view(risk_ucs.Q, i, :), the rows of the basis the selected assets occupy, and pass it throughorthonormalise_basis. The rank can fall, because the columns of a slice can become dependent. - Take
nothing_scalar_array_view(risk_ucs.val, i), the nominal covariance restricted to the same assets on both axes, which passes anothingthrough unchanged. - Build a
CompactCovarianceUncertaintySetfrom the three, carryingkappathrough unchanged. A set is a Result, so it carries the radius as a number and holds no rule that could be run again: whether the number was stated by the caller or computed by anAbstractCompactRadiusAlgorithm, the estimator, the prior result and the metric that would size it are all out of reach here.
Step 2 can lower the rank, so a radius sized against the full span is no longer the tightest one for the sliced problem. It stays a valid multiplier of the sliced penalty, and the mean axis already carries the same staleness: its radius is a quantile at the dimension of the Orthogonal Subspace, and a slice moves that dimension too. A caller who needs the radius sized against the smaller universe fits the set on a prior that was reduced first, which is the route the two JuMP builders already take.
Arguments
risk_ucs: Compact covariance uncertainty set.i: Cluster or asset index.args...: Additional positional arguments (ignored).
Returns
risk_ucs::CompactCovarianceUncertaintySet: The set restricted toi.
Related
PortfolioOptimisers.mu_ucs — Method
mu_ucs(uc::CompactCovarianceUncertaintySet, args...; kwargs...)Always throw. CompactCovarianceUncertaintySet is covariance-only.
The method is a refusal rather than a procedure, so it carries no # Algorithm section. It shadows the passthrough method every other Result reaches, which would otherwise hand a covariance set to a consumer of the mean.
Arguments
uc: Compact covariance uncertainty set.args...: Additional positional arguments (ignored).kwargs...: Additional keyword arguments (ignored).
Validation
- The method always throws an
ArgumentError. The set bounds a covariance matrix through a quadratic penalty on the weights, and no mean analogue is defined for it. The message names the fix:BoxUncertaintySet,EllipsoidalUncertaintySetorL1UncertaintySetfor a mean set.
Returns
- Never returns.
Related