Weight bounds constraints: private API
PortfolioOptimisers.WbE_Wb — Type
const WbE_Wb = Union{<:WeightBoundsEstimator, <:WeightBounds}Alias for a weight bounds estimator or result.
Matches either a WeightBoundsEstimator (specifying how to generate weight bounds constraints) or a WeightBounds result. Used internally for dispatch in weight bounds constraint generation.
There is no vector counterpart, and weight_bounds_constraints has no vector method. Weight bounds are one box over the whole universe, so an optimiser holds exactly one. See RkbE_Rkb for why some constraint families are singular and others are not.
Related
PortfolioOptimisers.validate_bounds — Function
validate_bounds(lb::Number, ub::Number) -> Nothing
validate_bounds(lb::VecNum, ub::Number) -> Nothing
validate_bounds(lb::Number, ub::VecNum) -> Nothing
validate_bounds(lb::VecNum, ub::VecNum) -> Nothing
validate_bounds(lb::VecNum, ::Any) -> Nothing
validate_bounds(::Any, ub::VecNum) -> Nothing
validate_bounds(args...) -> NothingCheck that a lower bound does not exceed the corresponding upper bound.
Seven methods split the work by the pair of argument types, and the pair alone decides which preconditions run. Two of the seven exist to catch a nothing on one side: they check that the vector side is non-empty and compare nothing. The catch-all closes the family and checks nothing at all, so (nothing, nothing), (::Number, nothing) and (nothing, ::Number) are accepted without a comparison.
Arguments
lb: Lower bound.ub: Upper bound.
Validation
Each bullet names the method that runs the check, the condition it demands and the error it raises.
(Number, Number):lb <= ub,DomainErrorotherwise.(VecNum, Number):!isempty(lb),IsEmptyErrorotherwise. Every entry oflbis at mostub,DomainErrorotherwise.(Number, VecNum):!isempty(ub),IsEmptyErrorotherwise. Every entry ofubis at leastlb,DomainErrorotherwise.(VecNum, VecNum):!isempty(lb)and!isempty(ub),IsEmptyErrorotherwise.length(lb) == length(ub),DimensionMismatchotherwise. Entry by entry,lbis at mostub,DomainErrorotherwise. The length check runs first, so the entry-by-entry comparison never reads a truncated pair.(VecNum, Any):!isempty(lb),IsEmptyErrorotherwise. This method takes the(vector, nothing)pair, so it compares the two sides with nothing.(Any, VecNum):!isempty(ub),IsEmptyErrorotherwise. This method takes the(nothing, vector)pair, so it compares the two sides with nothing.(args...): no precondition and no raise. This method takes every remaining pair, of which(nothing, nothing),(::Number, nothing)and(nothing, ::Number)are the ones the two bound types reach.
Returns
nothing.
Examples
julia> isnothing(PortfolioOptimisers.validate_bounds(0.0, 1.0))truejulia> isnothing(PortfolioOptimisers.validate_bounds(nothing, nothing))trueRelated
PortfolioOptimisers.weight_bounds_constraints_side — Function
weight_bounds_constraints_side(::Nothing, N::Integer, val::Number)Generate a vector of portfolio weight bounds when no constraint is specified.
weight_bounds_constraints_side returns a vector of length N filled with the value val when the input bound is nothing. This is used to represent unconstrained portfolio weights (e.g., -Inf for lower bounds, Inf for upper bounds) in constraint generation routines.
Algorithm
- Return
fill(val, N), the vector that gives every asset the same free bound.
Arguments
::Nothing: Indicates no constraint for this bound direction.N: Number of assets (length of the output vector).val: Value to fill (typically-InforInf).
Returns
wb::VecNum: Vector of lengthNfilled withval.
Examples
julia> PortfolioOptimisers.weight_bounds_constraints_side(nothing, 3, -Inf)3-element Vector{Float64}: -Inf -Inf -InfRelated
weight_bounds_constraints_side(wb::Number, N::Integer, val::Number)Generate a vector of portfolio weight bounds from a scalar bound.
weight_bounds_constraints_side gives every asset the scalar bound wb. A finite wb becomes a constant range and an infinite one becomes a filled Vector, because range(Inf, Inf; length = N) collects to NaN. The value val is not read by this method: an infinite bound keeps its own sign, so a lower bound of Inf stays Inf and admits no weight rather than becoming the free bound -Inf.
Algorithm
- When
isinf(wb), returnfill(wb, N), aVectorthat repeats the infinite bound. - Otherwise return
range(wb, wb; length = N), a constantStepRangeLenof lengthN.
Arguments
wb::Number: Scalar bound for portfolio weights (can be finite or infinite).N::Integer: Number of assets (length of the output vector).val::Number: Free bound of this side,-Inffor a lower bound andInffor an upper one. This method does not read it, and it is present so that every method of the function takes the same three arguments.
Returns
wb::VecNum: Vector or range of lengthN, every entry of which holdswb.
Examples
julia> PortfolioOptimisers.weight_bounds_constraints_side(0.1, 3, -Inf)StepRangeLen(0.1, 0.0, 3)julia> PortfolioOptimisers.weight_bounds_constraints_side(Inf, 3, -Inf)3-element Vector{Float64}: Inf Inf InfRelated
weight_bounds_constraints_side(wb::VecNum, N::Integer = 0, args...)Propagate asset-specific portfolio weight bounds from a vector.
weight_bounds_constraints_side returns the input vector wb unchanged when asset-specific bounds are provided as a vector. This method is used to propagate explicit per-asset bounds in constraint generation routines.
Algorithm
- When
Nis not zero, checklength(wb) == N. - Return
wb.
Arguments
wb: Vector of bounds for portfolio weights (one per asset).N: Number of assets. A zero states that the caller knows no asset count, and then the length is not checked.args...: Additional positional arguments (ignored).
Validation
iszero(N) || length(wb) == N,DimensionMismatchotherwise. A reader of a bound compares it with the weights throughmap, which truncates to the shorter argument, so a bound shorter than the universe leaves every asset pastlength(wb)unchecked.
Returns
wb::AbstractVector: The input vector, unchanged.
Examples
julia> PortfolioOptimisers.weight_bounds_constraints_side([0.1, 0.2, 0.3])3-element Vector{Float64}: 0.1 0.2 0.3Related