Portfolio Optimization with Semicontinuous and Cardinality Constraints
This example shows how to use aPortfolio
object 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. ThePortfolio
class 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 thePortfolio
class, 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 usePortfolioCVaR
orPortfolioMAD
classes 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
.
Semicontinuous and cardinality constraints are two other common categories of portfolio constraints that are formulated mathematically by adding the binary variables .
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 is needed, where is
0
or1
. The value0
indicates that assetiis not allocated and the value1
indicates that assetiis allocated. The mathematical form is , where is0
or1
. Specify this type of constraint as a'Conditional'
BoundType
in thePortfolio
class using thesetBounds
function.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 are needed, where is
0
or1
. The value0
indicates that assetiis not allocated and the value1
indicates that assetiis allocated. The mathematical form is , where is0
or1
. Specify this type of constraint by setting the'MinNumAssets'
and'MaxNumAssets'
constraints in thePortfolio
class using thesetMinMaxNumAssets
function.
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). ThePortfolio
class allows you to configure these two constraints, specifically, semicontinuous constraints usingsetBounds
with'Conditional'
BoundType
, and cardinality constraints usingsetMinMaxNumAssets
. ThePortfolio
class automatically formulates the mathematical problems and validates the specified constraints. ThePortfolio
class also provides built-in MINLP solvers and flexible solver options for you to tune the solver performance using thesetSolverMINLP
function.
This example demonstrates aPortfolio
object with semicontinuous and cardinality constraints and uses theBlueChipStockMoments
dataset, 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:
. 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
usingsetBounds
with a'Conditional'
BoundType
.
pWithMinWeight = setBounds(p, 0.05,'BoundType','Conditional');
Plot the efficient frontiers for bothPortfolio
objects.
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 twoPortfolio
objects 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
UseestimateFrontierByReturn
to 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 twoPortfolio
objects 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
UsesetMinMaxNumAssets
to set the maximum number of allocated assets for thePortfolio
object. Suppose that you want no more than eight assets invested in the optimal portfolio. To do this with aPortfolio
object, 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');
UseestimateFrontierByReturn
to find the allocation that minimizes the risk on the frontier for the given target return.
pwgtWithMaxNum = estimateFrontierByReturn(pWithMaxNumAssets, targetRetn);
Plot the composition of the twoPortfolio
objects 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. UsesetBounds
to 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 usingsetBounds
with a'Conditional'
BoundType
. Otherwise, the optimizer cannot evaluate which assets are allocated and cannot formulate theMinNumAssets
constraint. 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 bothsetBounds
andsetMinMaxNumAssets
functions.
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
, orMaxNumAssets
are active, the optimization problem is formulated as a mixed integer nonlinear programming (MINLP) problem. ThePortfolio
class automatically constructs the MINLP problem based on the specified constraints.
When working with aPortfolio
object, you can select one of three solvers using thesetSolverMINLP
function. 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 of30
for 'MaxIterationsInactiveCut'
. The value50
works 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');
UseestimateFrontierByRisk
to 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
, andMaxNumAssets
Constraints with Other Constraints
You can define other constraints for aPortfolio
object using theset
functions. These other constraints for aPortfolio
object, 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 usesetMinMaxNumAssets
to add a constraint to limit maximum number of assets to invest.
q = setMinMaxNumAssets(q, [], 8);
On top of these previously specified constraints, usesetBounds
to add a constraint to limit the weight for the allocated assets. You can use constraints with mixedBoundType
values, where'Simple'
means
and'Conditional'
means
.
Allow the assets intrackingPort
有BoundType
value'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);
UseestimateFrontierByReturn
to 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
Portfolio
|setBounds
|setMinMaxNumAssets
|setSolverMINLP
Related Examples
- Creating the Portfolio Object
- Working with Portfolio Constraints Using Defaults
- Asset Allocation Case Study
- Portfolio Optimization Examples Using Financial Toolbox™
- Black-Litterman Portfolio Optimization Using Financial Toolbox™
- Portfolio Optimization Using Factor Models
- Portfolio Optimization Using Social Performance Measure
- Diversify Portfolios Using Custom Objective
More About
- Portfolio Object
- Portfolio Optimization Theory
- Working with 'Conditional' BoundType, MinNumAssets, and MaxNumAssets Constraints Using Portfolio Objects
- Portfolio Object Workflow