Hierarchical Equal Risk Contribution
PortfolioOptimisers.HierarchicalEqualRiskContribution Type
struct HierarchicalEqualRiskContribution{__T_opt, __T_ri, __T_ro, __T_scai, __T_scao, __T_ex, __T_fb} <: ClusteringOptimisationEstimatorHierarchical Equal Risk Contribution (HERC) portfolio optimiser.
HierarchicalEqualRiskContribution implements the Hierarchical Equal Risk Contribution algorithm. It clusters assets, then allocates weights so that each cluster contributes equally to total portfolio risk (using ro), and within each cluster, assets are weighted by inverse intra-cluster risk (using ri).
Fields
opt: Base hierarchical optimiser configuration.ri: Inner risk measure.ro: Outer risk measure.scai: Inner scalariser.scao: Outer scalariser.ex: Parallel execution strategy.fb: Fallback result or estimator.
Constructors
HierarchicalEqualRiskContribution(;
opt::HierarchicalOptimiser = HierarchicalOptimiser(),
ri::TD{<:OptRM_VecOptRM} = Variance(),
ro::TD{<:OptRM_VecOptRM} = ri,
scai::TD{<:Scalariser} = SumScalariser(),
scao::TD{<:Scalariser} = scai,
ex::FLoops.Transducers.Executor = FLoops.ThreadedEx(),
fb::TDO_Option{<:OptE_Opt} = nothing
) -> HierarchicalEqualRiskContributionKeywords correspond to the struct's fields. Fields typed TD or TDO_Option may hold a TimeDependent per-fold schedule instead of a static value: the inner/outer risk measures, their scalarisers and the 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 fb). The executor ex is execution control and stays static.
Validation
If
riorrois a vector:!isempty(ri)/!isempty(ro).fbschedules:bind !== :nearest.
Propagated parameters
When factory is called on this type, the following @fprop-tagged fields are automatically propagated:
opt: Recursively updated viafactory.ri: Recursively updated viafactory.ro: Recursively updated viafactory.fb: Recursively updated viafactory.
Examples
julia> HierarchicalEqualRiskContribution()
HierarchicalEqualRiskContribution
opt ┼ HierarchicalOptimiser
│ 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
│ cle ┼ ClustersEstimator
│ │ 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)
│ │ de ┼ Distance
│ │ │ power ┼ nothing
│ │ │ alg ┴ CanonicalDistance()
│ │ alg ┼ HClustAlgorithm
│ │ │ linkage ┴ Symbol: :ward
│ │ onc ┼ OptimalNumberClusters
│ │ │ max_k ┼ nothing
│ │ │ alg ┼ SecondOrderDifference
│ │ │ │ alg ┼ StandardisedValue
│ │ │ │ │ mv ┼ MeanValue
│ │ │ │ │ │ w ┴ nothing
│ │ │ │ │ sv ┼ StdValue
│ │ │ │ │ │ w ┼ nothing
│ │ │ │ │ │ corrected ┴ Bool: true
│ slv ┼ nothing
│ wb ┼ WeightBounds
│ │ lb ┼ Float64: 0.0
│ │ ub ┴ Float64: 1.0
│ fees ┼ nothing
│ sets ┼ nothing
│ wf ┼ IterativeWeightFinaliser
│ │ iter ┴ Int64: 100
│ brt ┼ Bool: false
│ cle_pr ┼ Bool: true
│ strict ┴ Bool: false
ri ┼ Variance
│ settings ┼ RiskMeasureSettings
│ │ scale ┼ Float64: 1.0
│ │ ub ┼ nothing
│ │ rke ┴ Bool: true
│ sigma ┼ nothing
│ chol ┼ nothing
│ rc ┼ nothing
│ alg ┴ SquaredSOCRiskExpr()
ro ┼ Variance
│ settings ┼ RiskMeasureSettings
│ │ scale ┼ Float64: 1.0
│ │ ub ┼ nothing
│ │ rke ┴ Bool: true
│ sigma ┼ nothing
│ chol ┼ nothing
│ rc ┼ nothing
│ alg ┴ SquaredSOCRiskExpr()
scai ┼ SumScalariser()
scao ┼ SumScalariser()
ex ┼ Transducers.ThreadedEx{@NamedTuple{}}: Transducers.ThreadedEx()
fb ┴ nothingMathematical definition
Let
Within each cluster
Where:
: Weight allocated to cluster . : Outer (inter-cluster) risk of cluster . : Inner (intra-cluster) risk of asset . : Number of clusters. : Final weight of asset . : Quasi-diagonal cluster portfolio risk.
Related
PortfolioOptimisers.herc_td_defaults Function
herc_td_defaults(
) -> @NamedTuple{ri::Variance{RiskMeasureSettings{Float64, Nothing, Bool}, Nothing, Nothing, Nothing, SquaredSOCRiskExpr}, ro::Variance{RiskMeasureSettings{Float64, Nothing, Bool}, Nothing, Nothing, Nothing, SquaredSOCRiskExpr}, scai::SumScalariser, scao::SumScalariser}Return the static defaults of the HierarchicalEqualRiskContribution 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
sourcePortfolioOptimisers.needs_previous_weights Method
needs_previous_weights(
opt::HierarchicalEqualRiskContribution
) -> AnyReturn whether the HierarchicalEqualRiskContribution requires previous portfolio weights.
Returns true if any of the base optimiser, inner/outer risk measures, or fallback require previous weights.
Related
sourcePortfolioOptimisers.factory Method
factory(a::Union{Nothing, <:AbstractEstimator, <:AbstractAlgorithm,
<:AbstractResult}, args...; kwargs...) -> aNo-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> factory(nothing, 1, 2; x = 3)
julia> factory(MeanValue())
MeanValue
w ┴ nothingRelated
sourcefactory(
opt::Union{NonFiniteAllocationOptimisationEstimator, NonFiniteAllocationOptimisationResult},
_
) -> SubsetResamplingResultReturn opt unchanged.
Default pass-through factory for optimisation estimators and results. Overridden for estimators that carry parameters requiring update at each optimisation step.
Related
sourcePortfolioOptimisers.port_opt_view Method
port_opt_view(
hec::HierarchicalEqualRiskContribution,
i,
X::AbstractMatrix{<:Union{var"#s29", var"#s28"} where {var"#s29"<:Number, var"#s28"<:AbstractJuMPScalar}},
args...
) -> HierarchicalEqualRiskContribution{HierarchicalOptimiser{__T_pe, __T_cle, __T_slv, __T_wb, __T_fees, __T_sets, __T_wf, __T_brt, __T_cle_pr, __T_strict}, _A, _B, _C, _D, <:Transducers.Executor} where {__T_pe, __T_cle, __T_slv, __T_wb, __T_fees, __T_sets, __T_wf, __T_brt, __T_cle_pr, __T_strict, _A, _B, _C, _D}Return a view of HierarchicalEqualRiskContribution hec sliced to asset indices i.
Related
sourcePortfolioOptimisers.herc_scalarised_risk_o! Function
herc_scalarised_risk_o!(scalariser, wk, roku, rkbo, cl, ros, X, fees)Compute and accumulate the scalarised outer (inter-cluster) HERC risk in-place.
Updates rkbo with inverse-risk weights for cluster cl and accumulates the scaled risk contribution using the given scalariser strategy.
Arguments
scalariser: Scalarisation strategy (SumScalariser,MaxScalariser,MinScalariser, orLogSumExpScalariser).wk: Cluster weight vector.roku: Unitary outer risk vector or matrix.rkbo: Outer risk buffer vector (modified in-place).cl: Cluster asset indices.ros: Vector of outer risk measures.X: Return matrix.fees: Optional fees.
Returns
- Scalarised outer cluster risk scalar.
Related
sourcePortfolioOptimisers.herc_scalarised_risk_i! Function
herc_scalarised_risk_i!(scalariser, wk, riku, cl, ris, X, fees)Compute the scalarised inner (intra-cluster) HERC risk for cluster cl.
Aggregates inner risk measures across the assets in cluster cl using the given scalariser, returning the per-asset risk vector used for intra-cluster weight allocation.
Arguments
scalariser: Scalarisation strategy (SumScalariser,MaxScalariser,MinScalariser, orLogSumExpScalariser).wk: Cluster weight vector.riku: Unitary inner risk vector or matrix.cl: Cluster asset indices.ris: Vector of inner risk measures.X: Return matrix.fees: Optional fees.
Returns
- Per-asset inner risk vector for assets in
cl.
Related
sourcePortfolioOptimisers.herc_unitary_risks_i! Function
herc_unitary_risks_i!(wk, rku, i, r, X, fees)Return the unitary risk vector for inner measure i of a HERC scalarised risk computation.
When rku is a vector it is a shared buffer and the unitary risks for measure r are recomputed into it. When rku is a matrix, the unitary risks are computed into column i, caching them per measure for reuse by herc_scalarised_risk_o! when the inner and outer measures are identical.
Related
sourcePortfolioOptimisers.herc_unitary_risks_o! Function
herc_unitary_risks_o!(wk, rku, i, r, X, fees)Return the unitary risk vector for outer measure i of a HERC scalarised risk computation.
When rku is a vector it is a shared buffer and the unitary risks for measure r are recomputed into it. When rku is a matrix, column i already caches measure i's unitary risks (filled by herc_scalarised_risk_i! when the inner and outer measures are identical) and is returned as-is.
Related
sourcePortfolioOptimisers.herc_risk Function
herc_risk(hec, pr, cls)Compute per-cluster risk contributions for HERC weight allocation.
Evaluates the inner and outer risk measures for all clusters in cls, returning the risk arrays needed to allocate intra- and inter-cluster weights.
Arguments
hec:HierarchicalEqualRiskContributionoptimiser instance.pr: Prior result containing asset moments and return data.cls: Vector of vectors of asset indices per cluster.
Returns
(riku, roku): Inner and outer per-asset risk arrays.
Related
sourcePortfolioOptimisers.optimise Function
optimise(hec::HierarchicalEqualRiskContribution{
<:Any, <:Any, <:Any, <:Any, <:Any, <:Any, Nothing
},
rd::ReturnsResult = ReturnsResult(); dims::Int = 1,
branchorder::Symbol = :optimal, kwargs...) -> HierarchicalResultRun the Hierarchical Equal Risk Contribution portfolio optimisation.
Arguments
hec: The hierarchical equal risk contribution optimiser to use.rd: The returns result to use. Ifisa(hec.opt.pe, AbstractPriorResult),rdis not necessary if doing a standalone optimisation, but may be required/desired by fallbacks and/or clusterisation.dims: The dimension along which observations advance in time.branchorder: The branch order to use for the clusterisation, this optimisation can use non-optimal branch orders, which make the clustering faster but the dendrogram won't be as nice.kwargs: Additional keyword arguments passed to the optimisation function.
Related
source