Main Content

Portfolio Optimization with Semicontinuous and Cardinality Constraints

This example shows how to use aPortfolioobject to directly handle semicontinuous and cardinality constraints when performing portfolio optimization. Portfolio optimization finds the asset allocation that maximizes the return or minimizes the risk, subject to a set of investment constraints. ThePortfolioclass in Financial Toolbox™ is designed and implemented based on the Markowitz Mean-Variance Optimization framework. The Mean-Variance Optimization framework handles problems where the return is the expected portfolio return, and the risk is the variance of portfolio returns. Using thePortfolioclass, you can minimize the risk on the efficient frontier (EF), maximize the return on the EF, maximize the return for a given risk, and minimize the risk for a given return. You can also usePortfolioCVaRorPortfolioMADclasses in Financial Toolbox™ to specify semicontinuous and cardinality constraints. Such optimization problems integrate with constraints such as group, linear inequality, turnover, and tracking error constraints. These constraints are formulated as nonlinear programming (NLP) problems with continuous variables represented as the asset weights x i .

Semicontinuous and cardinality constraints are two other common categories of portfolio constraints that are formulated mathematically by adding the binary variables v i .

  • Asemicontinuous constraintconfines the allocation of an asset. For example, you can use this constraint to confine the allocated weight of an allocated asset to between 5% and 50%. By using this constraint, you can avoid very small or large positions to minimize the churns and operational costs. To mathematically formulate this type of constraint, a binary variable v i is needed, where v i is0or1. The value0indicates that assetiis not allocated and the value1indicates that assetiis allocated. The mathematical form is lb * v i x i ub * v i , where v i is0or1. Specify this type of constraint as a'Conditional'BoundTypein thePortfolioclass using thesetBoundsfunction.

  • Acardinality constraintlimits the number of assets in the optimal allocation, For example, for a portfolio with a universe of 100 assets, you can specify an optimal portfolio allocation between 20 and 40 assets. This capability helps limit the number of positions, and thus reduce operational costs. To mathematically formulate this type of constraint, binary variables represented as v i are needed, where v i is0or1. The value0indicates that assetiis not allocated and the value1indicates that assetiis allocated. The mathematical form is MinNumAssets 1 NumAssets v i MaxNumAssets , where v i is0or1. Specify this type of constraint by setting the'MinNumAssets'and'MaxNumAssets'constraints in thePortfolioclass using thesetMinMaxNumAssetsfunction.

For more information on semicontinuous and cardinality constraints, seeAlgorithms.

When semicontinuous and cardinality constraints are used for portfolio optimization, this leads to mixed integer nonlinear programming problems (MINLP). ThePortfolioclass allows you to configure these two constraints, specifically, semicontinuous constraints usingsetBoundswith'Conditional'BoundType, and cardinality constraints usingsetMinMaxNumAssets. ThePortfolioclass automatically formulates the mathematical problems and validates the specified constraints. ThePortfolioclass also provides built-in MINLP solvers and flexible solver options for you to tune the solver performance using thesetSolverMINLPfunction.

This example demonstrates aPortfolioobject with semicontinuous and cardinality constraints and uses theBlueChipStockMomentsdataset, which has a universe of 30 assets.

loadBlueChipStockMomentsnumAssets = numel(AssetList)
numAssets = 30

Limit the Minimum Weight for Each Allocated Asset

Create a fully invested portfolio with only long positions: x i 0 and sum ( x i ) = 1 . These are configured withsetDefaultConstraints.

p = Portfolio('AssetList', AssetList,'AssetCovar', AssetCovar,'AssetMean', AssetMean); p = setDefaultConstraints(p);

Suppose that you want to avoid very small positions to minimize the churn and operational costs. Add another constraint to confine the allocated positions to be no less than 5%, by setting the constraints x i = 0 or x i 0 . 05 usingsetBoundswith a'Conditional'BoundType.

pWithMinWeight = setBounds(p, 0.05,'BoundType','Conditional');

Plot the efficient frontiers for bothPortfolioobjects.

wgt = estimateFrontier(p); wgtWithMinWeight = estimateFrontier(pWithMinWeight); figure(1); plotFrontier(p, wgt); holdon; plotFrontier(pWithMinWeight, wgtWithMinWeight); holdoff; legend('Baseline portfolio',与minWeight约束t','location','best');

The figure shows that the twoPortfolioobjects have almost identical efficient frontiers. However, the one with the minimum weight requirement is more practical, since it prevents the close-to-zero positions.

Check the optimal weights for the portfolio with default constraints to see how many assets are below the 5% limit for each optimal allocation.

toler = eps; sum(wgt>toler & wgt<0.05)
ans =1×105 7 5 4 2 3 4 2 0 0

UseestimateFrontierByReturnto investigate the portfolio compositions for a target return on the frontier for both cases.

targetRetn = 0.011; pwgt = estimateFrontierByReturn(p, targetRetn); pwgtWithMinWeight = estimateFrontierByReturn(pWithMinWeight, targetRetn);

Plot the composition of the twoPortfolioobjects for the universe of 30 assets.

figure(2); barh([pwgt, pwgtWithMinWeight]); gridonxlabel(的比例of Investment') yticks(1:p.NumAssets); yticklabels(p.AssetList); title('Asset Allocation'); legend('Without min weight limit','With min weight limit','location','best');

Show only the allocated assets.

idx = (pwgt>toler) | (pwgtWithMinWeight>toler); barh([pwgt(idx), pwgtWithMinWeight(idx)]); gridonxlabel(的比例of Investment') yticks(1:sum(idx)); yticklabels(p.AssetList(idx)); title('Asset Allocation'); legend('Without min weight limit','With min weight limit','location','best');

Limit the Maximum Number of Assets to Allocate

UsesetMinMaxNumAssetsto set the maximum number of allocated assets for thePortfolioobject. Suppose that you want no more than eight assets invested in the optimal portfolio. To do this with aPortfolioobject, usesetMinMaxNumAssets.

pWithMaxNumAssets = setMinMaxNumAssets(p, [], 8); wgt = estimateFrontier(p); wgtWithMaxNumAssets = estimateFrontier(pWithMaxNumAssets); plotFrontier(p, wgt); holdon; plotFrontier(pWithMaxNumAssets, wgtWithMaxNumAssets); holdoff; legend('Baseline portfolio','With MaxNumAssets constraint','location','best');

UseestimateFrontierByReturnto find the allocation that minimizes the risk on the frontier for the given target return.

pwgtWithMaxNum = estimateFrontierByReturn(pWithMaxNumAssets, targetRetn);

Plot the composition of the twoPortfolioobjects for the universe of 30 assets.

idx = (pwgt>toler) | (pwgtWithMaxNum>toler); barh([pwgt(idx), pwgtWithMaxNum(idx)]); gridonxlabel(的比例of Investment') yticks(1:sum(idx)); yticklabels(p.AssetList(idx)); title('Asset Allocation'); legend('Baseline portfolio','With MaxNumAssets constraint','location','best');

sum(abs(pwgt)>toler)
ans = 11

Count the total number of allocated assets to verify that only eight assets at most are allocated.

总和(abs (pwgtWithMaxNum) >托勒)
ans = 8

Limit the Minimum and Maximum Number of Assets to Allocate

Suppose that you want to set both the lower and upper bounds for the number of assets to allocate in a portfolio, given the universe of assets. UsesetBoundsto specify the allowed number of assets to allocate as from 5 through 10, and the allocated weight as no less than 5%.

p1 = setMinMaxNumAssets(p, 5, 10); p1 = setBounds(p1, 0.05,'BoundType','conditional');

If an asset is allocated, it is necessary to clearly define the minimum weight requirement for that asset. This is done usingsetBoundswith a'Conditional'BoundType. Otherwise, the optimizer cannot evaluate which assets are allocated and cannot formulate theMinNumAssetsconstraint. For more details, seeConditional Bounds with LowerBound Defined as Empty or Zero.

Plot the efficient frontier to compare this portfolio to the baseline portfolio, which has only default constraints.

wgt = estimateFrontier(p); wgt1 = estimateFrontier(p1); plotFrontier(p, wgt); holdon; plotFrontier(p1, wgt1); holdoff; legend('Baseline portfolio','With MaxNumAssets constraint','location','best');

Asset Allocation for an Equal-Weighted Portfolio

Create an equal-weighted portfolio using bothsetBoundsandsetMinMaxNumAssetsfunctions.

numAssetsAllocated = 8; weight= 1/numAssetsAllocated; p2 = setBounds(p, weight, weight,'BoundType','conditional'); p2 = setMinMaxNumAssets(p2, numAssetsAllocated, numAssetsAllocated);

When any one, or any combination of'Conditional'BoundType,MinNumAssets, orMaxNumAssetsare active, the optimization problem is formulated as a mixed integer nonlinear programming (MINLP) problem. ThePortfolioclass automatically constructs the MINLP problem based on the specified constraints.

When working with aPortfolioobject, you can select one of three solvers using thesetSolverMINLPfunction. In this example, instead of using default MINLP solver options, customize the solver options to help with a convergence issue. Use a large number (50) for'MaxIterationsInactiveCut'withsetSolverMINLP, instead of the default value of30for 'MaxIterationsInactiveCut'. The value50works well in finding the efficient frontier of optimal asset allocation.

p2 = setSolverMINLP(p2,'OuterApproximation','MaxIterationsInactiveCut', 50);

Plot the efficient frontiers for the baseline and equal-weighted portfolios.

wgt = estimateFrontier(p); wgt2 = estimateFrontier(p2); plotFrontier(p, wgt); holdon; plotFrontier(p2, wgt2); holdoff; legend('Baseline portfolio','Equal Weighted portfolio','location','best');

UseestimateFrontierByRiskto optimize for a specific risk level, in this case.05, to determine what allocation maximizes the portfolio return.

targetRisk = 0.05; pwgt = estimateFrontierByRisk(p, targetRisk); pwgt2 = estimateFrontierByRisk(p2, targetRisk); idx = (pwgt>toler) | (pwgt2>toler); barh([pwgt(idx), pwgt2(idx)]); gridonxlabel(的比例of investment') yticks(1:sum(idx)); yticklabels(p.AssetList(idx)); title('Asset Allocation'); legend('Baseline portfolio','Equal weighted portfolio','location','best');

Use'Conditional'BoundType,MinNumAssets, andMaxNumAssetsConstraints with Other Constraints

You can define other constraints for aPortfolioobject using thesetfunctions. These other constraints for aPortfolioobject, such as group, linear inequality, turnover, and tracking error can be used together with the'Conditional'BoundType,'MinNumAssets', and'MaxNumAssets'constraints. For example, specify a tracking error constraint usingsetTrackingError.

ii = [15, 16, 20, 21, 23, 25, 27, 29, 30];% indexes of assets to include in tracking portfoliotrackingPort(ii) = 1/numel(ii); q = setTrackingError(p, 0.5, trackingPort);

Then usesetMinMaxNumAssetsto add a constraint to limit maximum number of assets to invest.

q = setMinMaxNumAssets(q, [], 8);

On top of these previously specified constraints, usesetBoundsto add a constraint to limit the weight for the allocated assets. You can use constraints with mixedBoundTypevalues, where'Simple'means lb x i ub and'Conditional'means x i = 0 or lb x i ub .

Allow the assets intrackingPortBoundTypevalue'Conditional'in the optimum allocation.

lb = zeros(q.NumAssets, 1); ub = zeros(q.NumAssets, 1)*0.5; lb(ii) = 0.1; ub(ii) = 0.3; boundType = repmat("simple",q.NumAssets,1); boundType(ii) ="conditional"; q = setBounds(q, lb, ub,'BoundType',boundType);

Plot the efficient frontier:

plotFrontier(q);

UseestimateFrontierByReturnto find the allocation that minimizes the risk for a given return at0.125.

targetRetn = 0.0125; pwgt = estimateFrontierByReturn(q, targetRetn);

Show the allocation of assets by weight.

idx = abs(pwgt)>eps; assetnames = q.AssetList'; Asset = assetnames(idx); Weight = pwgt(idx); resultAlloc = table(Asset, Weight)
resultAlloc=7×2 tableAsset Weight ________ _______ {'JNJ' } 0.1 {'MMM' } 0.19503 {'MO' } 0.1485 {'MSFT'} 0.1 {'PG' } 0.1 {'WMT' } 0.2212 {'XOM' } 0.13527

See Also

|||

Related Examples

More About

External Websites

Baidu
map