Investable universe
PortfolioOptimisers.optimise — Method
optimise(opt::OptimisationEstimator, args...; kwargs...) -> OptimisationResult
optimise(opt::OptimisationResult, args...; kwargs...) -> OptimisationResultRun a portfolio optimisation with the estimator opt, and return an OptimisationResult.
When the solve of opt returns an OptimisationFailure, the fallback in opt.fb runs next, and the chain continues until one attempt succeeds or no fallback is left. A fallback can also be a precomputed result, which is then the answer.
A result passed as opt is returned unchanged.
Arguments
opt: Optimisation estimator (for example aJuMPOptimisationEstimatorsubtype), or a result to pass through.args: Positional arguments forwarded to the solve of the estimator, usually theReturnsResult. A result ignores them.kwargs: Keyword arguments forwarded to the solve of the estimator. A result ignores them.
Returns
OptimisationResult: The optimisation result.
Related
PortfolioOptimisers.optimise — Method
optimise(
opt::OptimisationEstimator,
args...;
kwargs...
) -> Union{HierarchicalRiskParityResult{HierarchicalResult{__T_pr, __T_clr, __T_wb, __T_fees, __T_retcode, __T_w, __T_imsk}, <:AbstractBaseRiskMeasure, <:Scalariser, Nothing} where {__T_pr, __T_clr, __T_wb, __T_fees, __T_retcode, __T_w, __T_imsk}, HierarchicalRiskParityResult{HierarchicalResult{__T_pr, __T_clr, __T_wb, __T_fees, __T_retcode, __T_w, __T_imsk}, <:AbstractVector{var"#s7444"}, <:Scalariser, Nothing} where {__T_pr, __T_clr, __T_wb, __T_fees, __T_retcode, __T_w, __T_imsk, var"#s7444"<:AbstractBaseRiskMeasure}}
Solve an optimisation estimator, and walk its fallback chain when a solve fails.
The answer is the first attempt that succeeds, or the last failure when every attempt fails. The fb field of that answer records the (estimator, result) pair of each failed attempt, in the order they ran (see FbChain). When no fallback was needed, fb is nothing. A fallback that is a precomputed result ends the chain: it has nothing to solve, and it is the answer whatever its return code.
This is a fold-less entry point, so a time-dependent schedule has no fold to select an entry from. The estimator is reset to its fold-less values before the solve (see reset_time_dependent_estimator). A scheduled fallback resets to its default, or to nothing when it has none, before the chain is walked. Inside a fold loop the reset changes nothing, because the loop resolves every schedule before it optimises.
It is a batch fit, so assert_batch_entry refuses an Online anywhere in the tree of the estimator before any solve. The wrapper resolves only at the warm-up of the online arm of the fold loop, and a plain optimise runs no warm-up. The read-out of a stepped estimator, optimise(opt), never meets this refusal, because the warm-up that seeded its buffer replaced the wrapper.
Algorithm
- Refuse an
Onlinein the tree ofoptwithassert_batch_entry. - Reset every time-dependent schedule of
optto its fold-less value withreset_time_dependent_estimator, givingcurrent_opt. - Solve
current_optwith_optimise, givingres. A precomputed result gives itself. - Stop when
res.retcodeis anOptimisationSuccess, whencurrent_optis a precomputed result, or whencurrent_opt.fbisnothing. - Otherwise record
(current_opt, res)in the chainfb, takecurrent_opt.fbas the newcurrent_opt, warn that the fallback runs, and return to step 3. - Return
reswhenfbis empty. Otherwise returnresrebuilt withfbthroughfactory.
Arguments
opt::OptimisationEstimator: The optimisation estimator to use.args: Additional positional arguments passed to the optimisation function.kwargs: Additional keyword arguments passed to the optimisation function.
Validation
- No field in the tree of
optholds anOnline. AnArgumentErrornaming the field is thrown otherwise.
Returns
res::OptimisationResult: The answer of the chain, carrying the failed attempts infb.
Related
PortfolioOptimisers._optimise — Function
_optimise(opt, args...; kwargs...)Solve one optimisation estimator once, with no fallback.
optimise calls it for each attempt of the fallback chain, and it is the method that a new optimisation estimator writes. Each estimator type writes its own method, and the method returns the result type of that estimator. A precomputed result in the chain answers itself, because it has nothing to solve.
Arguments
opt: Optimisation estimator (for exampleMeanRiskorRiskBudgeting), or a precomputed result.args: The data that the estimator solves over: aReturnsResultfor a continuous optimiser, or aFiniteAllocationInputfor a finite allocator.kwargs: The keyword arguments that the estimator reads. A JuMP head readsstr_namesandsave, which name the model variables and keep the model on the result. Every method ignores the keywords it does not read. No method readsdims, because aReturnsResultholds its observations along the rows.
Returns
res::OptimisationResult: The result of the estimator. Itsretcodedecides whetheroptimiseruns the fallback.
Related
PortfolioOptimisers.optimise — Method
optimise(
td::Union{TimeDependent{<:AbstractVector{<:Union{var"#s7444", var"#s7443"} where {var"#s7444"<:NonFiniteAllocationOptimisationEstimator, var"#s7443"<:NonFiniteAllocationOptimisationResult}}}, TimeDependent{<:TimeDependentOptimiserCallable}, TimeDependent{<:PreviousWeightsFunction}, TimeDependent{<:Union{Function, Type}}},
args...;
kwargs...
) -> Any
Optimise with a TimeDependent schedule standing in for the optimiser, outside any fold loop.
There are no folds to index, so the schedule resolves to its default, and that optimiser runs (see reset_time_dependent_estimator). A fold loop never reaches this method, because the loop resolves the entry of each fold first.
Validation
- The schedule must carry a
default. ATimeDependentDefaultErroris thrown otherwise.
Related
PortfolioOptimisers.port_opt_view — Method
port_opt_view(opt::AbstractOptimisationEstimator, i, args...) -> AbstractOptimisationEstimatorReturn an optimisation estimator unchanged under an asset-subset view.
This is the fallback for an optimisation estimator with no view method of its own. An estimator declared through @propagatable gets a generated method that views each asset-indexed field it carries, and a head such as JuMPOptimiser writes its own. This method serves the rest, so an asset-indexed field of such an estimator keeps the width of the full universe.
Arguments
opt: The optimisation estimator.i: The asset index of the subset: an asset subset of a fold, a cluster of a nested optimisation, or the Investable Mask.args...: Ignored. A caller that views a tracking estimator passes the unreduced returns matrix here.
Returns
opt: The estimator, unchanged.
Related
PortfolioOptimisers.port_opt_view — Method
port_opt_view(
res::NonFiniteAllocationOptimisationResult,
_::Colon,
args...
) -> NonFiniteAllocationOptimisationResult
A precomputed optimisation result cannot be restricted to an asset subset.
Its weights were solved over the full universe, and a sub-portfolio of them has no defined meaning, so an asset-subset view of a result throws. A TimeDependent schedule that holds a result is therefore refused by asset-subsampling cross-validation (MultipleRandomised), whose fold loop views the optimiser to the asset subset of each fold before the swap. The all-assets view (Colon) passes the result through unchanged.
Validation
imust beColon(). Any other index throws anArgumentError.
Returns
res: The result, unchanged.
Related