Base JuMP Optimisation
PortfolioOptimisers.CustomJuMPConstraint — Type
abstract type CustomJuMPConstraint <: JuMPConstraintEstimatorAbstract supertype for custom JuMP constraint implementations.
Subtype this and implement add_custom_constraint! — the single method the type exists to make you define — to add custom constraints to the JuMP model. Pass the resulting estimator (or a vector of them) as the ccnt field of JuMPOptimiser.
Interfaces
In order to implement a new constraint that works seamlessly with the library, subtype CustomJuMPConstraint with the constraint's parameters as fields, and implement the following method. The verb is public and not exported, so the method is defined on the qualified name, PortfolioOptimisers.add_custom_constraint!.
add_custom_constraint!
add_custom_constraint!(model::JuMP.Model, ccnt::MyConstraint, optimiser, attrs::ProcessedJuMPOptimiserAttributes) -> Nothing: Add the constraint tomodel. There is no fallback: a subtype with no method of its own raises. Scale the constraint byget_constraint_scale, and multiply any constant bound byget_k, the homogenisation variable, so the bound is compared against unrescaled weights under a ratio objective (ADR 0008).
Arguments
model: The JuMP model, mid-assembly; read the weights withget_w.ccnt: The concrete subtype instance.optimiser: The outer optimisation estimator, e.g. theMeanRiskitself.attrs: The processed problem data:attrs.pris the prior,attrs.wbthe bounds.
Returns
nothing.
Related
add_custom_constraint!— the method to implementCustomJuMPObjective/add_custom_objective_term!— the objective-side analogueJuMPOptimiser— itsccntfield is where a custom constraint is supplied
PortfolioOptimisers.VecJuMPConstr — Type
const VecJuMPConstr = AbstractVector{<:CustomJuMPConstraint}Alias for a vector of JuMP constraint estimators.
Related
PortfolioOptimisers.CustomJuMPObjective — Type
abstract type CustomJuMPObjective <: AbstractEstimatorAbstract supertype for custom JuMP objective implementations.
Subtype this and implement add_custom_objective_term! — the single method the type exists to make you define — to add custom penalty or reward terms to the JuMP model objective. Pass the resulting estimator (or a vector of them) as the cobj field of JuMPOptimiser.
Interfaces
In order to implement a new objective term that works seamlessly with the library, subtype CustomJuMPObjective with the term's parameters as fields, and implement the following method. The verb is public and not exported, so the method is defined on the qualified name, PortfolioOptimisers.add_custom_objective_term!.
add_custom_objective_term!
add_custom_objective_term!(model::JuMP.Model, obj::ObjectiveFunction, cobj::MyObjective, optimiser, attrs::ProcessedJuMPOptimiserAttributes) -> Nothing: Contribute the term to the model's objective. There is no fallback: a subtype with no method of its own raises. Contribute throughadd_to_objective_penalty!rather than by touching the objective expression: the accumulated penalty is folded in with the sign the objective's sense needs, so a contribution always worsens the objective and a reward is a negative contribution (ADR 0036). A term that is not homogeneous of degree one in the weights multiplies its constants byget_k.
Arguments
model: The JuMP model, mid-assembly; read the weights withget_w.obj: The objective being built, which differs from the declared one inside aFrontiersweep.cobj: The concrete subtype instance.optimiser: The outer optimisation estimator, e.g. theMeanRiskitself.attrs: The processed problem data:attrs.pris the prior,attrs.wbthe bounds.
Returns
nothing.
Related
add_custom_objective_term!— the method to implementCustomJuMPConstraint/add_custom_constraint!— the constraint-side analogueJuMPOptimiser— itscobjfield is where a custom objective is supplied
PortfolioOptimisers.VecJuMPObj — Type
const VecJuMPObj = AbstractVector{<:CustomJuMPObjective}Alias for a vector of JuMP objective estimators.
Related
PortfolioOptimisers.JuMPOptimisationSolution — Type
struct JuMPOptimisationSolution{__T_w} <: OptimisationModelResultStores the solution (portfolio weights) from a JuMP optimisation model.
Fields
w: Portfolio weights vectorassets × 1.
Constructors
JuMPOptimisationSolution(; w::ArrNum) -> JuMPOptimisationSolutionKeywords correspond to the struct's fields.
Validation
!isempty(w).
Related
Base.propertynames — Method
propertynames(
r::Union{NonRiskJuMPOptimisationResult, RiskJuMPOptimisationResult}
) -> Tuple
Default property enumeration for RJR_NRJR: mirrors the default getproperty by unioning the receiver's own field names with everything forwarded from the embedded JuMPOptimisationResult jr (which itself forwards pa). Concrete subtypes that override getproperty (e.g. via @forward_properties) emit their own, more-specific propertynames.
Base.getproperty — Method
getproperty(
r::Union{NonRiskJuMPOptimisationResult, RiskJuMPOptimisationResult},
sym::Symbol
) -> Any
Default property access for RJR_NRJR: unique fields resolve directly; everything else delegates to the embedded JuMPOptimisationResult jr.
PortfolioOptimisers.add_custom_objective_term! — Function
add_custom_objective_term!(model::JuMP.Model, obj, cobj::Nothing, optimiser, attrs)
add_custom_objective_term!(model::JuMP.Model, obj, cobj::CustomJuMPObjective, optimiser, attrs)Add a custom objective term to the JuMP model.
Implement this for a subtype of CustomJuMPObjective to price a preference the library does not already name. Contribute the term with add_to_objective_penalty! rather than touching the objective expression: the accumulated penalty is folded in by add_penalty_to_objective! with the sign factor matching the objective's optimisation sense, so a contribution always worsens the objective and a reward is a negative contribution. This is what makes a term correct under every objective, MaximumRatio included, without the implementer consulting the sense.
add_to_objective_penalty! promotes an affine accumulator to a quadratic one as needed, so a quadratic term is safe on every configuration.
Terms that are not homogeneous of degree one in w must still multiply any constant by get_k: under a ratio objective the weights are solved in a rescaled space.
There is no no-op fallback for a CustomJuMPObjective — a subtype with no method of its own raises, so a mis-shaped or stale signature fails loudly instead of silently contributing nothing. nothing (no custom term configured) is the only no-op.
Arguments
model::JuMP.Model: JuMP optimisation model, mid-assembly.obj: TheObjectiveFunctionbeing built. During aFrontiersweep this differs from the objective the user declared — the endpoint sub-problems are built asMinimumRiskandMaximumReturn.cobj: The custom objective estimator; the argument to dispatch on.optimiser: The outer optimisation estimator (e.g. theMeanRiskitself); itsoptfield is theJuMPOptimiser.attrs::ProcessedJuMPOptimiserAttributes: Processed problem data —attrs.pr(prior),attrs.ret(returns estimator),attrs.wb(bounds), and the rest.
Returns
nothing.
Related
CustomJuMPObjectiveadd_to_objective_penalty!— how to contribute a termadd_custom_constraint!— the constraint-side analogue
add_custom_objective_term!(model::JuMP.Model, obj, cobjs::VecJuMPObj, optimiser, attrs)Apply each custom objective term in a vector, in order. Dispatches to the per-type add_custom_objective_term! for every element, so a cobj vector composes several custom terms into one objective — they accumulate additively in the shared objective penalty.
Related
PortfolioOptimisers.add_custom_constraint! — Function
add_custom_constraint!(model::JuMP.Model, ccnt::Nothing, optimiser, attrs)
add_custom_constraint!(model::JuMP.Model, ccnt::CustomJuMPConstraint, optimiser, attrs)Add a custom constraint to the JuMP model.
Implement this for a subtype of CustomJuMPConstraint to mandate a preference the library does not already name. Two idioms keep a hand-written constraint correct: scale it by get_constraint_scale, and multiply any constant bound by get_k, the homogenisation variable, so the bound is compared against unrescaled weights under a ratio objective.
There is no no-op fallback for a CustomJuMPConstraint — a subtype with no method of its own raises, so a mis-shaped or stale signature fails loudly instead of silently adding no constraint. nothing (no custom constraint configured) is the only no-op.
Arguments
model::JuMP.Model: JuMP optimisation model, mid-assembly.ccnt: The custom constraint estimator; the argument to dispatch on.optimiser: The outer optimisation estimator (e.g. theMeanRiskitself).attrs::ProcessedJuMPOptimiserAttributes: Processed problem data.
Returns
nothing.
Related
CustomJuMPConstraintadd_custom_objective_term!— the objective-side analogue
add_custom_constraint!(model::JuMP.Model, ccnts::VecJuMPConstr, optimiser, attrs)Apply each custom constraint in a vector, in order. Dispatches to the per-type add_custom_constraint! for every element, so a ccnt vector adds several custom constraints to the same model.
Related
PortfolioOptimisers.get_constraint_scale — Function
get_constraint_scale(model::JuMP.Model)Return the constraint scale expression model[:sc].
Asserts the scale has been registered (via set_model_scales!); errors otherwise.
Related
PortfolioOptimisers.get_w — Function
get_w(model::JuMP.Model)Return the portfolio weight variables model[:w].
Asserts the weights have been registered (via set_w!); errors otherwise.
Related
PortfolioOptimisers.get_k — Function
get_k(model::JuMP.Model)Return the homogenisation variable model[:k].
k is the auxiliary scaling variable used to homogenise fractional/ratio objectives (e.g. maximum ratio); recovered weights are w / k. Asserts :k has been registered; errors otherwise.
Two producers register it, and the error message names both because a head reaches only one of them:
set_maximum_ratio_factor_variables!is the head-level producer. Every head that shapeswfrom an objective calls it:k >= 0underMaximumRatio, and the literal1otherwise._set_risk_budgeting_constraints!declares a freekinstead, because the log barrier it builds is what pins the scale. That head also declaresset_unit_budget!, so downstream builders readeffective_kand get1rather than the free variable.
Related
PortfolioOptimisers.NonJuMPOptimisationResult — Type
abstract type NonJuMPOptimisationResult <: NonFiniteAllocationOptimisationResultAbstract supertype for non-JuMP continuous optimisation results.
Groups the results that do not carry a JuMP model (naive, clustering, and meta-optimiser results). Mirrors the JuMP/non-JuMP split on the result side. The JuMP side is itself two halves, RiskJuMPOptimisationResult for the results that carry a risk measure and NonRiskJuMPOptimisationResult for those that carry none.
The hierarchical members are grouped one level further down, under HierarchicalOptimisationResult.
Interfaces
NonJuMPOptimisationResult adds no method to NonFiniteAllocationOptimisationResult. It is a classification, and it is what lets a method state "carries no JuMP model" in a signature.
Related
PortfolioOptimisers.needs_previous_weights — Method
needs_previous_weights(_::CustomJuMPConstraint) -> Bool
Return false: custom JuMP constraints never require previous portfolio weights.
PortfolioOptimisers.needs_previous_weights — Method
needs_previous_weights(_::CustomJuMPObjective) -> Bool
Return false: custom JuMP objectives never require previous portfolio weights.