Base JuMP Optimisation

PortfolioOptimisers.CustomJuMPConstraintType
abstract type CustomJuMPConstraint <: JuMPConstraintEstimator

Abstract 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 to model. There is no fallback: a subtype with no method of its own raises. Scale the constraint 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 (ADR 0008).

Arguments

  • model: The JuMP model, mid-assembly; read the weights with get_w.
  • ccnt: The concrete subtype instance.
  • optimiser: The outer optimisation estimator, e.g. the MeanRisk itself.
  • attrs: The processed problem data: attrs.pr is the prior, attrs.wb the bounds.

Returns

  • nothing.

Related

source
PortfolioOptimisers.CustomJuMPObjectiveType
abstract type CustomJuMPObjective <: AbstractEstimator

Abstract 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 through add_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 by get_k.

Arguments

  • model: The JuMP model, mid-assembly; read the weights with get_w.
  • obj: The objective being built, which differs from the declared one inside a Frontier sweep.
  • cobj: The concrete subtype instance.
  • optimiser: The outer optimisation estimator, e.g. the MeanRisk itself.
  • attrs: The processed problem data: attrs.pr is the prior, attrs.wb the bounds.

Returns

  • nothing.

Related

source
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: The ObjectiveFunction being built. During a Frontier sweep this differs from the objective the user declared — the endpoint sub-problems are built as MinimumRisk and MaximumReturn.
  • cobj: The custom objective estimator; the argument to dispatch on.
  • optimiser: The outer optimisation estimator (e.g. the MeanRisk itself); its opt field is the JuMPOptimiser.
  • attrs::ProcessedJuMPOptimiserAttributes: Processed problem data — attrs.pr (prior), attrs.ret (returns estimator), attrs.wb (bounds), and the rest.

Returns

  • nothing.

Related

source
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

source
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. the MeanRisk itself).
  • attrs::ProcessedJuMPOptimiserAttributes: Processed problem data.

Returns

  • nothing.

Related

source
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

source
PortfolioOptimisers.get_kFunction
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:

Related

source
PortfolioOptimisers.NonJuMPOptimisationResultType
abstract type NonJuMPOptimisationResult <: NonFiniteAllocationOptimisationResult

Abstract 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

source