Hierarchical Equal Risk Contribution: private API

PortfolioOptimisers.herc_td_defaultsFunction
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

source
PortfolioOptimisers.herc_scalarised_risk_o!Function
herc_scalarised_risk_o!(sca::Scalariser, wk::VecNum, roku::VecNum_MatNum,
                        rkbo::VecNum, cl::VecInt, ros::VecOptRM, X::MatNum,
                        fees::Option{<:Fees}) -> Number

Combine several outer measures into the one risk that cluster cl contributes to its branch.

Each measure builds its own naive risk parity sub-portfolio over cl, because the weights follow that measure's own unitary risks. The scalariser then combines the per-measure risks into one number.

Arguments

  • sca: Scalarisation strategy (SumScalariser, MaxScalariser, MinScalariser, or LogSumExpScalariser).
  • wk: Scratch weight vector for unitary_expected_risks!, of length size(X, 2).
  • roku: Unitary outer risk buffer. A vector is overwritten per measure; a matrix already caches column i per measure, see herc_unitary_risks_o!.
  • rkbo: Weight buffer, written in place over the entries of cl. The caller zeroes those entries again after the split.
  • cl: Asset indices of the cluster.
  • ros: Vector of outer risk measures, already resolved by factory.
  • X: Asset return matrix, observations by assets.
  • fees: Fees, or nothing.

Returns

  • risk::Number: The combined outer risk of the cluster.

Details

  • Each measure's contribution is multiplied by its own settings.scale before the scalariser sees it.

Related

source
PortfolioOptimisers.herc_scalarised_risk_i!Function
herc_scalarised_risk_i!(sca::Scalariser, wk::VecNum, riku::VecNum_MatNum,
                        cl::VecInt, ris::VecOptRM, X::MatNum,
                        fees::Option{<:Fees}) -> VecNum

Combine several inner measures into the one weight vector that shares a cluster's weight between its assets.

Arguments

Returns

  • w::VecNum: The intra-cluster weights, of length length(cl). They sum to one under MaxScalariser and MinScalariser, and to the total of the measures' settings.scale under SumScalariser. LogSumExpScalariser gives a total that varies with the cluster, but only in the far decimals: two measures at unit scale gave 3.772618, 3.772634 and 3.772624 on the three clusters of a twelve-asset sample. _optimise normalises the whole weight vector at the end, so a total that is the same for every cluster cancels, and the three scalarisers put the same weight on each cluster to 1e-6.

Details

  • The two methods normalise at different points, and the difference is deliberate. SumScalariser and LogSumExpScalariser normalise each measure's inverse-risk vector first and combine the resulting weight vectors. MaxScalariser and MinScalariser select one measure — the one whose total scaled risk over cl is largest or smallest — and normalise that measure's vector alone, because selecting between already-normalised vectors would compare quantities that all sum to one.
  • Each measure's contribution is multiplied by its own settings.scale.

Related

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

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

source
PortfolioOptimisers.herc_riskFunction
herc_risk(hec::HierarchicalEqualRiskContribution, pr::AbstractPriorResult,
          cls::VecVecInt, fees::Option{<:Fees}) -> Tuple

Compute the intra-cluster weights and the per-cluster outer risks that HERC allocates with.

Arguments

  • hec: The optimiser. Its ri/ro arity and its executor ex select the method.
  • pr: Prior result. Its X is the return matrix and its moments resolve the measures.
  • cls: Asset indices of each cluster, one entry per cluster.
  • fees: Resolved fees, or nothing. The caller resolves them on its own universe and strips both liquidation carriers first, because a cluster-level risk figure prices no forced exit: the exiting asset is in no cluster, its column being NaN.

Returns

  • (w, rkcl, ri, ro)::Tuple: The intra-cluster weights over the whole universe, each cluster's outer risk, and the two resolved risk measures.

Details

  • Eight methods cover the four arity pairs of ri and ro against a sequential or a parallel executor. A parallel executor gets one buffer column per cluster, so no two iterations write the same entry.
  • When hec.ri === hec.ro the measure is resolved once and the unitary risks are computed once, because the two allocations then read the same vector.
  • w covers the whole universe. Each cluster's entries sum to one, so a cluster's share still has to be applied on top.

Related

source