The source files can be found in user_guide/.

Choosing a strategy

The previous pages showed how to call each tool. This page helps you choose one. Four questions about your situation lead to a choice. The investor profiles work through four complete cases, and this page gives the questions behind them.

The four questions

1. How much compute can you spend on each rebalance?

Naive optimisers (InverseVolatility, EqualWeighted) need no solver and return at once. JuMP optimisers (MeanRisk, RiskBudgeting) solve a convex program, which takes longer than a naive rule. Meta-optimisers (NestedClustered, Stacking) and cross-validated tuning solve many programs and cost the most.

2. How often do you rebalance?

If you rebalance often, use cheap and stable rules, and bound the Turnover or charge the Fees, so that the trading costs do not cancel the excess return. If you rebalance rarely, you can spend more compute on each optimisation.

3. How much do you trust your estimates?

If you have forecasts, add them to the prior with a view prior (BlackLittermanPrior, EntropyPoolingPrior). If you do not trust the moments, make the optimisation robust with an uncertainty set on the covariance (UncertaintySetVariance) or on the expected returns. Or use the hierarchy of the correlations (HierarchicalRiskParity) in place of point estimates.

4. How large is your capital, and how many constraints does your mandate set?

A small account needs a finite allocation, such as GreedyAllocation, to buy whole shares and leave little cash. An institutional mandate has many constraints, such as weight bounds, group limits and tracking, and the JuMP optimisers take all of them.

A table of starting points

SituationUse
Little compute, and you want diversificationInverseVolatility or EqualWeighted
The trade-off between risk and returnMeanRisk with an objective, or its efficient frontier
Each asset carries the same share of the riskRiskBudgeting
Tail losses or drawdowns matter more than the varianceset the r of MeanRisk to a tail measure (ConditionalValueatRisk) or a drawdown measure (MaximumDrawdown)
Many assets, and a covariance that changesHierarchicalRiskParity or another clustering optimiser
You do not trust one fitNestedClustered or Stacking, or an uncertainty set
You have viewsBlackLittermanPrior or EntropyPoolingPrior
Trading costs matteradd Turnover or Fees to a JuMPOptimiser
You trade the portfolioend with GreedyAllocation

Most strategies combine several rows, such as a view prior, constraints and a finite allocation.

Three strategies on the same data

We run three strategies from the table on the same data: equal weights, the minimum-risk MeanRisk and HRP. We plot their weights. In the plot, the minimum-risk bar has few colours, and the HRP bar has one colour for every asset.

using PortfolioOptimisers, CSV, TimeSeries, Clarabel, StatsPlots, GraphRecipesX = TimeArray(CSV.File(joinpath(@__DIR__, "../examples/SP500.csv.gz")); timestamp = :Date)[(end - 252):end]rd = prices_to_returns(X)pr = prior(EmpiricalPrior(), rd)slv = Solver(; name = :clarabel, solver = Clarabel.Optimizer,             settings = Dict("verbose" => false),             check_sol = (; allow_local = true, allow_almost = true))res_ew = optimise(EqualWeighted(), rd)res_mr = optimise(MeanRisk(; obj = MinimumRisk(),                           opt = JuMPOptimiser(; pe = pr, slv = slv)))res_hrp = optimise(HierarchicalRiskParity(; r = Variance(),                                          opt = HierarchicalOptimiser(; pe = pr,                                                                      cle = clusterise(ClustersEstimator(),                                                                                       pr.X))))plot_stacked_bar_composition([res_ew, res_mr, res_hrp], rd;                             xticks = (1:3, ["EqualWeighted", "MinRisk", "HRP"]))
Example block output

This page was generated using Literate.jl.