Near optimal centering (a): private API

PortfolioOptimisers.NearOptimalSetup — Type
struct NearOptimalSetup{__T_w_opt, __T_rk_opt, __T_rt_opt, __T_rt_min, __T_rt_max, __T_rt_ends, __T_w_min, __T_w_max, __T_r, __T_opt, __T_attrs, __T_w_min_retcode, __T_w_opt_retcode, __T_w_max_retcode} <: AbstractResult

Intermediate result type storing the setup data for Near Optimal Centering.

Holds pre-computed portfolio weights, risk and return targets, and sub-problem return codes needed to formulate and solve the NOC optimisation problem.

Fields

  • w_opt: Optimal portfolio weights.
  • rk_opt: Optimal risk target.
  • rt_opt: Optimal return target.
  • rt_min: Minimum return target.
  • rt_max: Maximum return target.
  • rt_ends: Per-term return spans for a return-frontier sweep, as i => (rt_min_i, rt_max_i) pairs, or nothing when no return term declares a frontier bound. The aggregate rt_min/rt_max pair above serves the barrier; these serve the sweep, and the two are different quantities because a term's own span must be read off a portfolio that maximised that term alone.
  • w_min: Minimum risk portfolio weights.
  • w_max: Maximum return portfolio weights.
  • r: Risk measure or vector of risk measures.
  • opt: JuMP optimiser configuration.
  • attrs: Processed JuMP optimiser attributes for the model-assembly pipeline.
  • w_min_retcode: Return code for the minimum-risk sub-problem.
  • w_opt_retcode: Return code for the optimal-objective sub-problem.
  • w_max_retcode: Return code for the maximum-risk sub-problem.

Related

source
PortfolioOptimisers.near_optimal_centering_td_defaults — Function
near_optimal_centering_td_defaults(

) -> @NamedTuple{r::StandardDeviation{RiskMeasureSettings{Float64, Nothing, Bool}, Nothing, Nothing}, obj::MinimumRisk}

Return the static defaults of the NearOptimalCentering fields that may hold a TimeDependent.

Shared by the constructor's test-substitution pass and time_dependent_field_defaults, so the fold-less value of a field is declared once. Fields whose static default is nothing are omitted.

Related

source
PortfolioOptimisers.near_optimal_centering_risks — Function
near_optimal_centering_risks(scalariser, r, pr, fees, slv, w_min, w_opt, w_max)

Compute the scaled risk values for the minimum, optimal, and maximum portfolios.

Used internally by Near Optimal Centering to evaluate the risk at the three anchor portfolios (minimum-risk, optimal, maximum-risk) using the given risk measure(s) and scalarisation strategy.

Arguments

  • scalariser: Risk scalarisation strategy (e.g. SumScalariser, LogSumExpScalariser).
  • r: Risk measure or vector of risk measures.
  • pr: Prior result containing asset data.
  • fees: Optional fees configuration.
  • slv: Solver or vector of solvers.
  • w_min: Minimum-risk portfolio weights.
  • w_opt: Optimal portfolio weights (vector or vector of vectors).
  • w_max: Maximum-risk portfolio weights.

Returns

  • (risk_min, risk_opt, risk_max): Tuple of risk values at the three anchor portfolios.

Related

source
PortfolioOptimisers.near_optimal_centering_setup — Function
near_optimal_centering_setup(noc::NearOptimalCentering, rd::ReturnsResult; kwargs...)

Compute all prerequisite data for Near Optimal Centering.

Solves the minimum-risk, optimal-objective, and maximum-risk sub-problems (unless pre-computed weights are provided), then computes the risk and return targets for the NOC problem.

Arguments

Returns

Related

source
PortfolioOptimisers.return_term_ends — Function
return_term_ends(swept, ret, nb_r, nb_opt, rd, pr, fees, w_min, w_ini)

Solve one maximum-return corner per swept return term and read off that term's span.

The low end of every span is the shared minimum-risk portfolio w_min, which near_optimal_centering_setup already has. The high end of term i's span comes from a portfolio that maximised term i alone, which is why this costs k extra solves. Reading it off the aggregate maximum-return corner instead would make the span an artefact of the other terms' scale, and can leave rt_min > rt_max.

Returns

  • A vector of i => (rt_min_i, rt_max_i) pairs, one per swept term.

Related

source
PortfolioOptimisers.set_near_optimal_centering_constraints! — Function
set_near_optimal_centering_constraints!(model::JuMP.Model, wb::WeightBounds)

Add Near Optimal Centering logarithmic barrier constraints to the JuMP model.

Introduces log variables for portfolio weights, upper bound distances, risk, and return, then adds exponential cone constraints implementing the analytic centre formulation.

Arguments

  • model::JuMP.Model: JuMP optimisation model.
  • wb::WeightBounds: Weight bounds configuration.

Returns

  • Objective expression for the NOC barrier function.

Related

source
PortfolioOptimisers.set_near_optimal_objective_function! — Function
set_near_optimal_objective_function!(alg, model, noc, attrs)

Set the Near Optimal Centering objective function in the JuMP model.

Formulates the NOC objective based on the algorithm variant. For UnconstrainedNearOptimalCentering, uses only the barrier function. For ConstrainedNearOptimalCentering, also adds objective penalties and custom objective terms.

The centring problem is a distance minimisation, so the objective it reports to a custom term is MinimumRisk — the objective actually being built, not noc.obj, which describes the reference-point sub-problems.

The unconstrained variant reaches neither add_custom_objective_term! nor add_penalty_to_objective!, so opt.cobj prices the anchor sub-problems and not the centring solve. No builder on that path contributes to the Objective Penalty either, so the accumulator is empty and the omitted fold changes no number today. The one case a user can observe is a Custom Objective Term that names itself and supplies no builder: it raises on the anchor solve, and raises nowhere when w_min, w_opt and w_max are all supplied and no anchor solve runs.

Arguments

  • alg: NOC algorithm variant (UnconstrainedNearOptimalCentering or ConstrainedNearOptimalCentering).
  • model::JuMP.Model: JuMP optimisation model.
  • noc::NearOptimalCentering: The outer optimisation estimator, passed on to custom objective terms.
  • attrs::ProcessedJuMPOptimiserAttributes: Pre-computed constraint and prior bundle.

Returns

  • nothing.

Related

source
PortfolioOptimisers.solve_noc! — Function
solve_noc!(noc, model, rk_opt, rt_opt, opt, attrs, args...)

Solve the Near Optimal Centering problem given the model, risk, and return targets.

Sets model parameters for the risk and return targets, configures the NOC objective, and solves the JuMP model. Multiple overloads handle different algorithm variants and frontier sweep modes.

Arguments

  • noc::NearOptimalCentering: NOC estimator configuration.
  • model::JuMP.Model: JuMP optimisation model.
  • rk_opt: Risk target(s) for the NOC problem.
  • rt_opt: Return target(s) for the NOC problem.
  • opt::BaseJuMPOptimisationEstimator: JuMP optimiser configuration.
  • args...: Additional arguments (frontier bounds, flags, etc.).

Returns

  • (retcode, sol) or (retcodes, sols) depending on the overload.

Related

source
PortfolioOptimisers.set_noc_anchor_parameters! — Function
set_noc_anchor_parameters!(model, noc, attrs, rk_opts, rt_opts)

Register the two anchor parameters the centring barrier reads, and set the objective.

noc_rk and noc_rt are the risk and return of the near-optimal anchor the barrier centres on. A sweep moves them from point to point, so they are parameters rather than expressions — the model is assembled once and only their values change between solves.

Arguments

  • model::JuMP.Model: The JuMP optimisation model.
  • noc::NearOptimalCentering: Dispatch object for the objective.
  • attrs::ProcessedJuMPOptimiserAttributes: Pre-computed bundle.
  • rk_opts::VecNum: The anchor risks, one per sweep point.
  • rt_opts::VecNum: The anchor returns, one per sweep point.

Returns

  • (noc_rk, noc_rt): The two parameter references.

Related

source
PortfolioOptimisers.set_noc_anchor! — Function
set_noc_anchor!(noc_rk, noc_rt, rk_opts, rt_opts, i)

Move the centring anchor onto sweep point i.

The frontier_sweep! hook of every swept NearOptimalCentering solve. The anchors are the MeanRisk solutions of the same sweep, computed by near_optimal_centering_setup, so anchor i belongs to sweep point i and the index is the flat one frontier_sweep_axes counts. This is the pairing that makes a swept centring solve centre on its own point rather than on some other point's optimum.

Arguments

  • noc_rk: The anchor-risk parameter.
  • noc_rt: The anchor-return parameter.
  • rk_opts::VecNum: The anchor risks, in flat sweep order.
  • rt_opts::VecNum: The anchor returns, in flat sweep order.
  • i::Integer: The flat index of the sweep point.

Returns

  • nothing.

Related

source
PortfolioOptimisers.compute_ret_lbs — Method
compute_ret_lbs(ret_frontier::VecPair, rt_ends::VecPair)

Resolve a NearOptimalCentering return frontier from spans computed during setup.

NearOptimalCentering does not re-solve for its corners here, unlike MeanRisk: near_optimal_centering_setup has already paid for one minimum-risk solve and one maximum-return solve per swept term, so this only turns each span into its N sweep points.

Arguments

  • ret_frontier::VecPair: The :ret_frontier Model State entry.
  • rt_ends::VecPair: The per-term spans, as i => (rt_min_i, rt_max_i).

Returns

  • The return frontier with every span resolved into a range of sweep points.

Related

source