Skip to content
13

JuMP Optimiser

PortfolioOptimisers.ProcessedJuMPOptimiserAttributes Type
julia
struct ProcessedJuMPOptimiserAttributes{__T_pr, __T_wb, __T_lt, __T_st, __T_lcsr, __T_ctr, __T_gcardr, __T_sgcardr, __T_smtx, __T_sgmtx, __T_slt, __T_sst, __T_sglt, __T_sgst, __T_tn, __T_fees, __T_plr, __T_ret} <: AbstractResult

Flat bundle of all processed constraint and prior results consumed by assemble_jump_model!.

Produced once per optimise call by processed_jump_optimiser_attributes and passed directly to the model-assembly pipeline, so every builder reads already-resolved results rather than re-processing estimators. See ADR 0008 (0008-jump-model-assembly.md).

Fields

  • pr: Prior result.

  • wb: Weight bounds.

  • lt: Long-side minimum holding threshold.

  • st: Short-side minimum holding threshold.

  • lcsr: Processed linear constraint set result.

  • ctr: Centrality result.

  • gcardr: Processed grouped cardinality constraint result.

  • sgcardr: Processed sub-grouped cardinality constraint result.

  • smtx: Sub-group selection matrix or estimator.

  • sgmtx: Sub-grouped selection matrix or estimator.

  • slt: Sub-group long threshold.

  • sst: Sub-group short threshold.

  • sglt: Sub-grouped long threshold.

  • sgst: Sub-grouped short threshold.

  • tn: Turnover result.

  • fees: Fees result.

  • plr: Phylogeny result.

  • ret: Returns estimator for the JuMP model.

Constructors

julia
ProcessedJuMPOptimiserAttributes(
    pr, wb, lt, st, lcsr, ctr, gcardr, sgcardr,
    smtx, sgmtx, slt, sst, sglt, sgst, tn, fees, plr, ret
) -> ProcessedJuMPOptimiserAttributes

Positional arguments correspond to the struct's fields in order. In practice, construct via processed_jump_optimiser_attributes rather than directly.

Examples

julia
julia> ProcessedJuMPOptimiserAttributes(nothing, nothing, nothing, nothing, nothing, nothing,
                                        nothing, nothing, nothing, nothing, nothing, nothing,
                                        nothing, nothing, nothing, nothing, nothing, nothing) isa
       ProcessedJuMPOptimiserAttributes
true

Related

source
PortfolioOptimisers.assert_finite_nonnegative_real_or_vec Function
julia
assert_finite_nonnegative_real_or_vec(val::Number)

Assert that val is finite and non-negative; throw an ArgCheck error otherwise.

Accepts a scalar Number or a VecNum; the vector overload requires at least one finite and non-negative element and no negative elements.

Arguments

  • val: Scalar or vector to validate.

Returns

  • nothing.

Examples

julia
julia> PortfolioOptimisers.assert_finite_nonnegative_real_or_vec(1.0)

julia> PortfolioOptimisers.assert_finite_nonnegative_real_or_vec([0.5, 1.0])

Related

source
PortfolioOptimisers.JuMPOptimiser Type
julia
struct JuMPOptimiser{__T_pe, __T_slv, __T_wb, __T_bgt, __T_sbgt, __T_lt, __T_st, __T_lcse, __T_cte, __T_gcarde, __T_sgcarde, __T_smtx, __T_sgmtx, __T_slt, __T_sst, __T_sglt, __T_sgst, __T_tn, __T_fees, __T_sets, __T_tr, __T_ple, __T_ret, __T_sca, __T_ccnt, __T_cobj, __T_sc, __T_so, __T_ss, __T_card, __T_scard, __T_nea, __T_l1, __T_l2, __T_linf, __T_lp, __T_brt, __T_cle_pr, __T_strict} <: BaseJuMPOptimisationEstimator

Main JuMP-based portfolio optimiser configuration.

JuMPOptimiser collects all the inputs needed to formulate and solve a JuMP-based portfolio optimisation problem: prior estimator, solver, constraints, bounds, fees, tracking, regularisation, and more. It is intended to be passed to a higher-level optimiser such as MeanRisk or RiskBudgeting.

Fields

  • pe: Prior estimator.

  • slv: Solver or vector of solvers.

  • wb: Weight bounds estimator or weight bounds.

  • bgt: Portfolio budget constraint.

  • sbgt: Short-sale budget constraint.

  • lt: Long-side minimum holding threshold.

  • st: Short-side minimum holding threshold.

  • lcse: Linear constraint set estimator(s).

  • cte: Centring constraint estimator or constraint(s).

  • gcarde: Grouped cardinality constraint estimator.

  • sgcarde: Sub-grouped cardinality constraint estimator(s).

  • smtx: Sub-group selection matrix or estimator.

  • sgmtx: Sub-grouped selection matrix or estimator.

  • slt: Sub-group long threshold.

  • sst: Sub-group short threshold.

  • sglt: Sub-grouped long threshold.

  • sgst: Sub-grouped short threshold.

  • tn: Turnover constraint estimator(s).

  • fees: Fee estimator or fee structure.

  • sets: Sets used to map estimator values to features.

  • tr: Tracking error constraint(s).

  • ple: Phylogeny constraint estimator(s).

  • ret: Returns estimator for the JuMP model.

  • sca: Scalariser for combining multiple risk measures.

  • ccnt: Custom JuMP constraint.

  • cobj: Custom JuMP objective.

  • sc: Constraint scale factor.

  • so: Objective scale factor.

  • ss: Optional scalar shrinkage parameter.

  • card: Global cardinality constraint.

  • scard: Sub-group cardinality constraint(s).

  • nea: Minimum number of effective assets.

  • l1: L1 regularisation coefficient.

  • l2: L2 regularisation coefficient.

  • linf: L∞ regularisation coefficient.

  • lp: Lp regularisation specification(s).

  • brt: Whether to use bootstrap returns.

  • cle_pr: Whether to pass the prior result to the clustering estimator.

  • strict: Whether to strictly enforce weight bounds.

Constructors

julia
JuMPOptimiser(;
    pe::PrE_Pr = EmpiricalPrior(),
    slv::Slv_VecSlv,
    wb::Option{<:WbE_Wb} = WeightBounds(),
    bgt::Option{<:Num_BgtCE} = 1.0,
    sbgt::Option{<:Num_BgtRg} = nothing,
    lt::Option{<:BtE_Bt} = nothing,
    st::Option{<:BtE_Bt} = nothing,
    lcse::Option{<:LcE_Lc_VecLcE_Lc} = nothing,
    cte::Option{<:Lc_CC_VecCC} = nothing,
    gcarde::Option{<:LcE_Lc} = nothing,
    sgcarde::Option{<:LcE_Lc_VecLcE_Lc} = nothing,
    smtx::Option{<:MatNum_ASetMatE_VecMatNum_ASetMatE} = nothing,
    sgmtx::Option{<:MatNum_ASetMatE_VecMatNum_ASetMatE} = nothing,
    slt::Option{<:BtE_Bt_VecOptBtE_Bt} = nothing,
    sst::Option{<:BtE_Bt_VecOptBtE_Bt} = nothing,
    sglt::Option{<:BtE_Bt_VecOptBtE_Bt} = nothing,
    sgst::Option{<:BtE_Bt_VecOptBtE_Bt} = nothing,
    tn::Option{<:TnE_Tn_VecTnE_Tn} = nothing,
    fees::Option{<:FeesE_Fees} = nothing,
    sets::Option{<:AssetSets} = nothing,
    tr::Option{<:Tr_VecTr} = nothing,
    ple::Option{<:PlCE_PhC_VecPlCE_PlC} = nothing,
    ret::JuMPReturnsEstimator = ArithmeticReturn(),
    sca::NonHierarchicalScalariser = SumScalariser(),
    ccnt::Option{<:CustomJuMPConstraint} = nothing,
    cobj::Option{<:CustomJuMPObjective} = nothing,
    sc::Number = 1,
    so::Number = 1,
    ss::Option{<:Number} = nothing,
    card::Option{<:Integer} = nothing,
    scard::Option{<:Int_VecInt} = nothing,
    nea::Option{<:Number} = nothing,
    l1::Option{<:Number} = nothing,
    l2::Option{<:Number} = nothing,
    linf::Option{<:Number} = nothing,
    lp::Option{LpReg_VecLpReg} = nothing,
    brt::Bool = false,
    cle_pr::Bool = true,
    strict::Bool = false
) -> JuMPOptimiser

Keywords correspond to the struct's fields.

Validation

  • If slv is a vector: !isempty(slv).

  • If bgt is a number: isfinite(bgt).

  • If bgt is a BudgetCostEstimator: isnothing(sbgt).

  • If sbgt is a number: isfinite(sbgt) and sbgt >= 0.

  • If cte is a vector: !isempty(cte).

  • If card is provided: card > 0 and finite.

  • If tn or tr is a vector: each must be non-empty.

  • If nea, l1, l2, or linf is provided: each must be > 0 and finite.

  • If scard is provided: compatible smtx, slt, sst sizes required.

  • If sgcarde is provided: compatible sgmtx, sglt, sgst sizes required.

  • If any estimator-type field (wb, lt, fees, etc.) is provided: !isnothing(sets).

Related

source
PortfolioOptimisers.needs_previous_weights Method
julia
needs_previous_weights(opt::JuMPOptimiser) -> Any

Return true if any sub-estimator of opt requires previous portfolio weights.

Checks turnover, fees, tracking error, custom constraint, and custom objective fields.

Arguments

  • opt::JuMPOptimiser: JuMP optimiser configuration.

Returns

  • Bool: true if any sub-estimator needs previous weights; false otherwise.

Examples

julia
julia> PortfolioOptimisers.needs_previous_weights(JuMPOptimiser(; slv = Solver()))
false

Related

source
PortfolioOptimisers.factory Method
julia
factory(
    opt::JuMPOptimiser,
    w::AbstractVector
) -> JuMPOptimiser{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, var"#s179", var"#s1791", _W, _X, var"#s1792", var"#s1793", _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, Bool, Bool, Bool} where {_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, var"#s179"<:JuMPReturnsEstimator, var"#s1791"<:NonHierarchicalScalariser, _W, _X, var"#s1792"<:Number, var"#s1793"<:Number, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6}

Return a copy of opt with all weight-tracking estimator fields updated via factory for the new weights w.

Updates turnover, fees, tracking error, custom constraint, and custom objective fields; all other fields are carried through unchanged.

Arguments

  • opt::JuMPOptimiser: JuMP optimiser configuration.

  • w::AbstractVector: New portfolio weights.

Returns

  • JuMPOptimiser: Updated optimiser with weight-tracking fields refreshed.

Examples

julia
julia> opt = JuMPOptimiser(; slv = Solver());

julia> PortfolioOptimisers.factory(opt, fill(0.1, 10)) isa JuMPOptimiser
true

Related

source
PortfolioOptimisers.port_opt_view Method
julia
port_opt_view(
    opt::JuMPOptimiser,
    i,
    X::AbstractMatrix{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    args...
) -> JuMPOptimiser{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, var"#s179", var"#s1791", _W, _X, var"#s1792", var"#s1793", _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, Bool, Bool, Bool} where {_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, var"#s179"<:JuMPReturnsEstimator, var"#s1791"<:NonHierarchicalScalariser, _W, _X, var"#s1792"<:Number, var"#s1793"<:Number, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6}

Return a cluster-sliced copy of opt restricted to asset indices i.

Slices all per-asset estimator fields (prior, weight bounds, thresholds, turnover, fees, tracking, custom constraint/objective) to the cluster; solver and scalar parameters are carried through unchanged.

Arguments

  • opt::JuMPOptimiser: JuMP optimiser configuration.

  • i: Asset index or index set for the cluster.

  • X::MatNum: Full returns matrix used to slice tracking estimators.

Returns

  • JuMPOptimiser: Cluster-restricted optimiser.

Examples

julia
julia> opt = JuMPOptimiser(; slv = Solver());

julia> X = rand(50, 5);

julia> PortfolioOptimisers.port_opt_view(opt, 1:3, X) isa JuMPOptimiser
true

Related

source
PortfolioOptimisers.processed_jump_optimiser_attributes Function
julia
processed_jump_optimiser_attributes(
    opt::JuMPOptimiser,
    rd::ReturnsResult;
    dims::Int = 1
) -> ProcessedJuMPOptimiserAttributes

Compute all constraint and prior results needed for model assembly.

Resolves every estimator field of opt against rd — running priors, weight bounds, thresholds, linear constraints, centrality, cardinality, turnover, fees, and phylogeny — and returns the fully processed bundle as a ProcessedJuMPOptimiserAttributes. The result is consumed directly by assemble_jump_model! and also stored in the per-optimiser Result struct, so processing happens exactly once per optimise call.

Arguments

  • opt::JuMPOptimiser: JuMP optimiser configuration.

  • rd: The returns result to use.

  • dims::Int = 1: Observation dimension passed to the prior estimator.

Returns

Related

source
PortfolioOptimisers.processed_jump_optimiser Function
julia
processed_jump_optimiser(
    opt::JuMPOptimiser,
    rd::ReturnsResult;
    dims::Int = 1
) -> JuMPOptimiser

Build a fully-processed JuMPOptimiser from raw configuration and returns data.

Calls processed_jump_optimiser_attributes then repackages the result via jump_optimiser_from_attributes. Used where a processed optimiser is needed for inner sub-problems (e.g. NearOptimalCentering) while the attrs bundle is reused directly by assemble_jump_model!.

Arguments

  • opt::JuMPOptimiser: Raw optimiser configuration.

  • rd: The returns result to use.

  • dims::Int = 1: Observation dimension passed to the prior estimator.

Returns

  • JuMPOptimiser: Optimiser with all estimator slots populated from processed results.

Related

source
PortfolioOptimisers.assemble_jump_model! Function
julia
assemble_jump_model!(
    model::JuMP.Model,
    optimiser::JuMPOptimisationEstimator,
    opt::JuMPOptimiser,
    attrs::ProcessedJuMPOptimiserAttributes,
    rd::ReturnsResult,
    r::Option{<:RM_VecRM} = nothing,
    obj::ObjectiveFunction = MinimumRisk(),
    miprb_flag::Bool = false,
    b1::Option{<:MatNum} = nothing,
    sdp_asset_phylogeny::Bool = true
) -> Nothing

Run the invariant model-assembly sequence shared by all single-JuMP-model optimisers.

Executes the constraint-builder pipeline — from set_linear_weight_constraints! through add_custom_constraint! — that sits between the per-optimiser head (weight variables) and tail (objective + solve). The head must have populated Model State (w/k variables) before calling this function. See Model Assembly in CONTEXT.md and 0008-jump-model-assembly.md.

Arguments

  • model::JuMP.Model: The JuMP optimisation model.

  • optimiser::JuMPOptimisationEstimator: Dispatch object for risk, tracking, and custom constraint builders.

  • opt::JuMPOptimiser: Supplies scalar settings (nea, l1, l2, linf, lp, card, scard, tr, ccnt, sca, ss).

  • attrs::ProcessedJuMPOptimiserAttributes: Pre-computed constraint and prior bundle produced by processed_jump_optimiser_attributes.

  • rd: The returns result to use.

  • r::Option{<:RiskMeasure} = nothing: Risk measure(s), or nothing to skip risk constraints and scalarisation (the RelaxedRiskBudgeting path).

  • obj::ObjectiveFunction = MinimumRisk(): Objective used by the return constraints.

  • miprb_flag::Bool = false: Mixed-integer risk-budgeting flag for set_mip_constraints!; only RiskBudgeting passes true.

  • b1::Option{<:MatNum} = nothing: Factor loading matrix for FactorRiskContribution; nothing for all other optimisers.

  • sdp_asset_phylogeny::Bool = true: Whether to apply the standard asset-space SDP phylogeny constraints. FactorRiskContribution passes false and applies its own factor-space variant in its tail instead.

Returns

  • nothing. Mutates model in place.

Examples

julia
julia> using PortfolioOptimisers

julia> ProcessedJuMPOptimiserAttributes(nothing, nothing, nothing, nothing, nothing, nothing,
                                        nothing, nothing, nothing, nothing, nothing, nothing,
                                        nothing, nothing, nothing, nothing, nothing, nothing) isa
       ProcessedJuMPOptimiserAttributes
true

Related

source
PortfolioOptimisers.set_risk_and_scalarise! Function
julia
set_risk_and_scalarise!(
    ::Model,
    ::Nothing,
    args...;
    kwargs...
)

Add risk-measure constraints and scalarise the combined risk expression in model.

One step of assemble_jump_model!, dispatched on r: when r is nothing (e.g. RelaxedRiskBudgeting, whose risk lives in its head) this is a no-op. extra is the optional trailing-argument tuple — empty for most optimisers, or (b1,) for FactorRiskContribution — splatted into set_risk_constraints! so the non-factor call signature is reproduced exactly.

Arguments

  • model::JuMP.Model: JuMP optimisation model (mutated in place).

  • r: Risk measure(s), or nothing to skip this step entirely.

  • optimiser: Dispatch object for set_risk_constraints!.

  • opt::JuMPOptimiser: Supplies the scalariser opt.sca.

  • pr: Prior result passed to risk builders.

  • pl: Phylogeny result passed to risk builders.

  • fees: Fees result passed to risk builders.

  • extra: Trailing-argument tuple splatted into risk builders (() or (b1,)).

  • rd: Returns result forwarded as a keyword argument to risk builders.

Returns

  • nothing.

Related

source
PortfolioOptimisers.jump_optimiser_from_attributes Function
julia
jump_optimiser_from_attributes(
    opt::JuMPOptimiser,
    attrs::ProcessedJuMPOptimiserAttributes
) -> JuMPOptimiser

Repackage a ProcessedJuMPOptimiserAttributes into a JuMPOptimiser.

Maps result-named fields onto the optimiser's estimator-named slots (lcsrlcse, plrple, prpe, …) and carries all remaining settings through from opt. Used where a processed optimiser object is needed for inner sub-problems (e.g. near_optimal_centering_setup) while the same attrs is also passed directly to assemble_jump_model! — so processing happens once and is never round-tripped.

Arguments

  • opt::JuMPOptimiser: Source optimiser supplying solver, scalar settings, and any fields not present in attrs.

  • attrs::ProcessedJuMPOptimiserAttributes: Pre-computed constraint and prior bundle.

Returns

  • JuMPOptimiser: Optimiser with all estimator slots populated from attrs.

Related

source