Weight bounds constraints: private API

PortfolioOptimisers.WbE_WbType
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

source
PortfolioOptimisers.validate_boundsFunction
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...) -> Nothing

Check 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, DomainError otherwise.
  • (VecNum, Number): !isempty(lb), IsEmptyError otherwise. Every entry of lb is at most ub, DomainError otherwise.
  • (Number, VecNum): !isempty(ub), IsEmptyError otherwise. Every entry of ub is at least lb, DomainError otherwise.
  • (VecNum, VecNum): !isempty(lb) and !isempty(ub), IsEmptyError otherwise. length(lb) == length(ub), DimensionMismatch otherwise. Entry by entry, lb is at most ub, DomainError otherwise. The length check runs first, so the entry-by-entry comparison never reads a truncated pair.
  • (VecNum, Any): !isempty(lb), IsEmptyError otherwise. This method takes the (vector, nothing) pair, so it compares the two sides with nothing.
  • (Any, VecNum): !isempty(ub), IsEmptyError otherwise. 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))true

Related

source
PortfolioOptimisers.weight_bounds_constraints_sideFunction
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

  1. 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 -Inf or Inf).

Returns

  • wb::VecNum: Vector of length N filled with val.

Examples

julia> PortfolioOptimisers.weight_bounds_constraints_side(nothing, 3, -Inf)3-element Vector{Float64}: -Inf -Inf -Inf

Related

source
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

  1. When isinf(wb), return fill(wb, N), a Vector that repeats the infinite bound.
  2. Otherwise return range(wb, wb; length = N), a constant StepRangeLen of length N.

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, -Inf for a lower bound and Inf for 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 length N, every entry of which holds wb.

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 Inf

Related

source
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

  1. When N is not zero, check length(wb) == N.
  2. 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, DimensionMismatch otherwise. A reader of a bound compares it with the weights through map, which truncates to the shorter argument, so a bound shorter than the universe leaves every asset past length(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.3

Related

source