Skip to content
18

Naive optimisation

PortfolioOptimisers.NaiveOptimisationEstimator Type
julia
abstract type NaiveOptimisationEstimator <: NonFiniteAllocationOptimisationEstimator

Abstract supertype for naive (heuristic) portfolio optimisation estimators.

Naive optimisers compute portfolio weights directly from statistical properties of asset returns (e.g., volatility or equal weights) without solving an optimisation problem.

Related

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

Return whether the naive optimiser's fallback estimator requires previous portfolio weights.

Related

source
PortfolioOptimisers.is_time_dependent Method
julia
is_time_dependent(opt::NaiveOptimisationEstimator) -> Any

Return true if the naive optimiser configuration carries time-dependent constraints.

Related

source
PortfolioOptimisers.reset_time_dependent_estimator Method
julia
reset_time_dependent_estimator(
    opt::NaiveOptimisationEstimator
) -> Any

Replace time-dependent constraints with their static defaults, both on the naive optimiser's own fields and by recursing into the fallback.

source
PortfolioOptimisers.assert_internal_optimiser Method
julia
assert_internal_optimiser(_::NaiveOptimisationEstimator)

Assert internal validity for a naive optimisation estimator. No-op default.

Related

source
PortfolioOptimisers.assert_external_optimiser Method
julia
assert_external_optimiser(_::NaiveOptimisationEstimator)

Assert external validity for a naive optimisation estimator. No-op default.

Related

source
PortfolioOptimisers.naive_optimiser_td_defaults Function
julia
naive_optimiser_td_defaults(

) -> @NamedTuple{wb::WeightBounds{Float64, Float64}, wf::IterativeWeightFinaliser{Int64}}

Return the static defaults of the naive-optimiser fields that may hold a TimeDependent.

Shared by the constructors' test-substitution passes and time_dependent_field_defaults, so the fold-less value of a field is declared once. Fields whose static default is nothing are omitted; RandomWeighted overrides the trait because its wb default is nothing, and InverseVolatility extends it with its prior estimator.

Related

source
PortfolioOptimisers.NaiveOptimisationResult Type
julia
struct NaiveOptimisationResult{__T_pr, __T_wb, __T_retcode, __T_w, __T_fb} <: NonJuMPOptimisationResult

Result type for naive portfolio optimisation estimators.

Fields

  • pr: Prior result.

  • wb: Weight bounds.

  • retcode: Optimisation return code.

  • w: Portfolio weights vector assets × 1.

  • fb: Fallback result or estimator.

Constructors

julia
NaiveOptimisationResult(;
    pr::Option{<:AbstractPriorResult},
    wb::Option{<:WeightBounds}, retcode::OptimisationReturnCode, w::Option{<:VecNum},
    fb::Option{<:OptE_Opt}
) -> NaiveOptimisationResult

Keywords correspond to the struct's fields.

Examples

julia
julia> NaiveOptimisationResult(; pr = nothing, wb = nothing, retcode = OptimisationSuccess(),
                               w = [0.5, 0.5], fb = nothing)
NaiveOptimisationResult
       pr ┼ nothing
       wb ┼ nothing
  retcode ┼ OptimisationSuccess
          │   res ┴ nothing
        w ┼ Vector{Float64}: [0.5, 0.5]
       fb ┴ nothing

Related

source
PortfolioOptimisers.factory Method
julia
factory(a::Union{Nothing, <:AbstractEstimator, <:AbstractAlgorithm,
                 <:AbstractResult}, args...; kwargs...) -> a

No-op factory function for constructing objects with a uniform interface.

Defining methods which dispatch on the first argument allows for a consistent factory interface across different types.

factory and port_opt_view are the two propagation mechanisms in this library. They are duals: factory threads runtime values (prior moments, observation weights, previous portfolio weights) down through a composed struct tree; port_opt_view threads an index selection (a subset of assets or observations) down through the same tree.

Arguments

  • a: Indicates no object should be constructed.

  • args...: Arbitrary positional arguments (ignored).

  • kwargs...: Arbitrary keyword arguments (ignored).

Returns

  • a: The input unchanged.

Examples

julia
julia> factory(nothing, 1, 2; x = 3)

julia> factory(MeanValue())
MeanValue
  w ┴ nothing

Related

source
julia
factory(res::NonFiniteAllocationOptimisationResult, fb::Option{<:OptE_Opt})

Rebuild a continuous optimisation result with an updated fallback optimiser fb.

Every optimisation result carries fb as its last field, so the generic rebuild copies all fields unchanged except the trailing fb. Concrete result types may override this method when rebuilding requires more than swapping fb.

Related

source
julia
factory(
    opt::Union{NonFiniteAllocationOptimisationEstimator, NonFiniteAllocationOptimisationResult},
    _
) -> SubsetResamplingResult

Return opt unchanged.

Default pass-through factory for optimisation estimators and results. Overridden for estimators that carry parameters requiring update at each optimisation step.

Related

source
PortfolioOptimisers.InverseVolatility Type
julia
struct InverseVolatility{__T_pe, __T_wb, __T_sets, __T_wf, __T_fb, __T_sq, __T_brt, __T_strict} <: NaiveOptimisationEstimator

Inverse Volatility portfolio optimiser.

InverseVolatility allocates portfolio weights inversely proportional to each asset's volatility (standard deviation). Optionally, sq = true uses variance instead.

Mathematical definition

wi=1/σij=1N1/σj,.

Where:

  • wi: Portfolio weight of asset i.

  • σi: Standard deviation of asset i (variance when sq = true).

  • N: Number of assets.

Fields

  • pe: Prior estimator.

  • wb: Weight bounds.

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

  • wf: Weight finaliser.

  • fb: Fallback result or estimator.

  • sq: Whether to use variance instead of volatility in the inverse weighting.

  • brt: Whether to use bootstrap returns.

  • strict: Whether to strictly enforce weight bounds.

Constructors

julia
InverseVolatility(;
    pe::TD{<:PrE_Pr} = EmpiricalPrior(),
    wb::TD_Option{<:WbE_Wb} = WeightBounds(),
    sets::TD_Option{<:AssetSets} = nothing,
    wf::TD{<:WeightFinaliser} = IterativeWeightFinaliser(),
    fb::TDO_Option{<:OptE_Opt} = nothing,
    sq::Bool = false,
    brt::Bool = false,
    strict::Bool = false
) -> InverseVolatility

Keywords correspond to the struct's fields. Fields typed TD, TD_Option or TDO_Option may hold a TimeDependent per-fold schedule instead of a static value: the prior estimator, weight bounds, asset sets, weight finaliser and fallback are problem definition, so a cross-validation fold loop resolves them per fold, and a fold-less optimise runs with each at its static default. sq, brt and strict are execution control and stay static.

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • fb: Recursively updated via factory.

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Examples

julia
julia> InverseVolatility()
InverseVolatility
      pe ┼ EmpiricalPrior
         │        ce ┼ PortfolioOptimisersCovariance
         │           │   ce ┼ Covariance
         │           │      │    me ┼ SimpleExpectedReturns
         │           │      │       │   w ┴ nothing
         │           │      │    ce ┼ GeneralCovariance
         │           │      │       │   ce ┼ StatsBase.SimpleCovariance: StatsBase.SimpleCovariance(true)
         │           │      │       │    w ┴ nothing
         │           │      │   alg ┴ FullMoment()
         │           │   mp ┼ MatrixProcessing
         │           │      │     pdm ┼ Posdef
         │           │      │         │      alg ┼ UnionAll: NearestCorrelationMatrix.Newton
         │           │      │         │   kwargs ┴ @NamedTuple{}: NamedTuple()
         │           │      │      dn ┼ nothing
         │           │      │      dt ┼ nothing
         │           │      │     alg ┼ nothing
         │           │      │   order ┴ NTuple{4, Symbol}: (:pdm, :dn, :dt, :alg)
         │        me ┼ SimpleExpectedReturns
         │           │   w ┴ nothing
         │   horizon ┴ nothing
      wb ┼ WeightBounds
         │   lb ┼ Float64: 0.0
         │   ub ┴ Float64: 1.0
    sets ┼ nothing
      wf ┼ IterativeWeightFinaliser
         │   iter ┴ Int64: 100
      fb ┼ nothing
      sq ┼ Bool: false
     brt ┼ Bool: false
  strict ┴ Bool: false

Related

source
PortfolioOptimisers.assert_external_optimiser Method
julia
assert_external_optimiser(opt::InverseVolatility)

Assert that InverseVolatility is valid for external use.

Requires that opt.pe is not an AbstractPriorResult.

Related

source
PortfolioOptimisers._optimise Method
julia
_optimise(
    iv::InverseVolatility;
    ...
) -> Union{NaiveOptimisationResult{__T_pr, __T_wb, OptimisationFailure{String}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}, NaiveOptimisationResult{__T_pr, __T_wb, OptimisationSuccess{Nothing}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}}
_optimise(
    iv::InverseVolatility,
    rd::ReturnsResult;
    dims,
    kwargs...
) -> Union{NaiveOptimisationResult{_A, _B, OptimisationFailure{String}, _C, Nothing} where {_A, _B, _C}, NaiveOptimisationResult{_A, _B, OptimisationSuccess{Nothing}, _C, Nothing} where {_A, _B, _C}}

Run the inverse volatility portfolio optimisation.

Internal dispatch called by optimise. Computes covariance via the prior estimator, assigns weights inversely proportional to volatility (or variance when iv.sq = true), then applies weight bounds.

Related

source
PortfolioOptimisers.optimise Function
julia
optimise(iv::InverseVolatility{<:Any, <:Any, <:Any, <:Any, Nothing},
         rd::ReturnsResult = ReturnsResult(); dims::Int = 1, kwargs...) -> NaiveOptimisationResult

Run the inverse volatility portfolio optimisation.

Arguments

  • iv: The inverse volatility optimiser to use.

  • rd: The returns result to use. If isa(iv.pe, AbstractPriorResult), rd is not necessary.

  • dims: The dimension along which observations advance in time.

  • kwargs: Additional keyword arguments passed to the optimisation function.

source
PortfolioOptimisers.EqualWeighted Type
julia
struct EqualWeighted{__T_wb, __T_sets, __T_wf, __T_fb, __T_strict} <: NaiveOptimisationEstimator

Equal-weighted portfolio optimiser.

EqualWeighted allocates equal weight to all N assets in the portfolio.

Mathematical definition

wi=1Ni.

Where:

  • wi: Portfolio weight of asset i.

  • N: Number of assets.

Fields

  • wb: Weight bounds.

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

  • wf: Weight finaliser.

  • fb: Fallback result or estimator.

  • strict: Whether to strictly enforce weight bounds.

Constructors

julia
EqualWeighted(;
    wb::TD_Option{<:WbE_Wb} = WeightBounds(),
    sets::TD_Option{<:AssetSets} = nothing,
    wf::TD{<:WeightFinaliser} = IterativeWeightFinaliser(),
    fb::TDO_Option{<:OptE_Opt} = nothing,
    strict::Bool = false
) -> EqualWeighted

Keywords correspond to the struct's fields. Fields typed TD, TD_Option or TDO_Option may hold a TimeDependent per-fold schedule instead of a static value: the weight bounds, asset sets, weight finaliser and fallback are problem definition, so a cross-validation fold loop resolves them per fold, and a fold-less optimise runs with each at its static default. strict is execution control and stays static.

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • fb: Recursively updated via factory.

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Examples

julia
julia> EqualWeighted()
EqualWeighted
      wb ┼ WeightBounds
         │   lb ┼ Float64: 0.0
         │   ub ┴ Float64: 1.0
    sets ┼ nothing
      wf ┼ IterativeWeightFinaliser
         │   iter ┴ Int64: 100
      fb ┼ nothing
  strict ┴ Bool: false

Related

source
PortfolioOptimisers._optimise Method
julia
_optimise(
    ew::EqualWeighted,
    rd::ReturnsResult;
    dims,
    kwargs...
) -> Union{NaiveOptimisationResult{__T_pr, __T_wb, OptimisationFailure{String}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}, NaiveOptimisationResult{__T_pr, __T_wb, OptimisationSuccess{Nothing}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}}

Run the equal-weighted portfolio optimisation.

Internal dispatch called by optimise. Assigns equal weights to all assets, then applies weight bounds.

Related

source
PortfolioOptimisers.optimise Method
julia
optimise(ew::EqualWeighted{<:Any, <:Any, <:Any, Nothing},
         rd::ReturnsResult; dims::Int = 1, kwargs...) -> NaiveOptimisationResult

Run the equal-weighted portfolio optimisation.

Arguments

  • ew: The equal-weighted optimiser to use.

  • rd: The returns result to use. Used to know how many assets there are.

  • dims: The dimension along which observations advance in time.

  • kwargs: Additional keyword arguments passed to the optimisation function.

source
PortfolioOptimisers.RandomWeighted Type
julia
struct RandomWeighted{__T_alpha, __T_rng, __T_seed, __T_wb, __T_sets, __T_wf, __T_fb, __T_strict} <: NaiveOptimisationEstimator

Random-weighted portfolio optimiser.

RandomWeighted draws portfolio weights at random from a Dirichlet distribution with concentration parameter alpha. This can be used for simulation, benchmarking, or stress-testing.

Mathematical definition

wDirichlet(α),.

Where:

  • w: Portfolio weight vector.

  • α: Scalar or vector concentration parameter. Larger values concentrate the distribution near equal weights.

Fields

  • alpha: Dirichlet concentration parameter.

  • rng: Random number generator.

  • seed: Seed for the random number generator.

  • wb: Weight bounds.

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

  • wf: Weight finaliser.

  • fb: Fallback result or estimator.

  • strict: Whether to strictly enforce weight bounds.

Constructors

julia
RandomWeighted(;
    alpha::Num_VecNum = 1,
    rng::Random.AbstractRNG = Random.default_rng(),
    seed::Option{<:Integer} = nothing,
    wb::TD_Option{<:WbE_Wb} = nothing,
    sets::TD_Option{<:AssetSets} = nothing,
    wf::TD{<:WeightFinaliser} = IterativeWeightFinaliser(),
    fb::TDO_Option{<:OptE_Opt} = nothing,
    strict::Bool = false
) -> RandomWeighted

Keywords correspond to the struct's fields. Fields typed TD, TD_Option or TDO_Option may hold a TimeDependent per-fold schedule instead of a static value: the weight bounds, asset sets, weight finaliser and fallback are problem definition, so a cross-validation fold loop resolves them per fold, and a fold-less optimise runs with each at its static default (nothing for wb, sets and fb). rng, seed and strict are execution control and stay static.

Validation

  • If alpha is provided: all elements positive and finite.

  • fb schedules: bind !== :nearest.

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • fb: Recursively updated via factory.

View parameters

When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:

Examples

julia
julia> RandomWeighted()
RandomWeighted
   alpha ┼ Int64: 1
     rng ┼ Random.TaskLocalRNG: Random.TaskLocalRNG()
    seed ┼ nothing
      wb ┼ nothing
    sets ┼ nothing
      wf ┼ IterativeWeightFinaliser
         │   iter ┴ Int64: 100
      fb ┼ nothing
  strict ┴ Bool: false

Related

source
PortfolioOptimisers._optimise Method
julia
_optimise(
    rw::RandomWeighted,
    rd::ReturnsResult;
    dims,
    kwargs...
) -> Union{NaiveOptimisationResult{__T_pr, __T_wb, OptimisationFailure{String}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}, NaiveOptimisationResult{__T_pr, __T_wb, OptimisationSuccess{Nothing}, __T_w, Nothing} where {__T_pr, __T_wb, __T_w}}

Run the random-weighted portfolio optimisation.

Internal dispatch called by optimise. Draws weights from a Dirichlet distribution parameterised by rw.alpha, then applies weight bounds.

Related

source
PortfolioOptimisers.optimise Method
julia
optimise(rw::RandomWeighted{<:Any, <:Any, <:Any, <:Any, <:Any, <:Any, Nothing},
         rd::ReturnsResult; dims::Int = 1, kwargs...) -> NaiveOptimisationResult

Run the random-weighted portfolio optimisation.

Arguments

  • rw: The random-weighted optimiser to use.

  • rd: The returns result to use. Used to know how many assets there are.

  • dims: The dimension along which observations advance in time.

  • kwargs: Additional keyword arguments passed to the optimisation function.

source