Troubleshooting Portfolio Optimization Results
Portfolio Object Destroyed When Modifying
If a Portfolio
object is destroyed when modifying, remember to
pass an existing object into the Portfolio
object if you want to
modify it, otherwise it creates a new object. See Creating the Portfolio Object for details.
Optimization Fails with “Bad Pivot” Message
If the optimization fails with a "bad pivot" message from
lcprog
, try a larger value for tolpiv
which is a tolerance for pivot selection in the lcprog
algorithm
(try 1.0e-7
, for example) or try the
interior-point-convex
version of quadprog
. For details, see Choosing and Controlling the Solver for Mean-Variance Portfolio Optimization, the help header for
lcprog
, and quadprog
.
Speed of Optimization
Although it is difficult to characterize when one algorithm is faster than the
other, the default solver, lcprog
is faster for smaller problems
and the quadprog
solver is faster for larger problems. If one
solver seems to take too much time, try the other solver. To change solvers, use
setSolver
.
Matrix Incompatibility and "Non-Conformable" Errors
If you get matrix incompatibility or "non-conformable" errors, the representation of data in the tools follows a specific set of basic rules described in Conventions for Representation of Data.
Missing Data Estimation Fails
If asset return data has missing or NaN
values, the estimateAssetMoments
function with
the 'missingdata'
flag set to true
may fail
with either too many iterations or a singular covariance. To correct this problem,
consider this:
If you have asset return data with no missing or
NaN
values, you can compute a covariance matrix that may be singular without difficulties. If you have missing orNaN
values in your data, the supported missing data feature requires that your covariance matrix must be positive-definite, that is, nonsingular.estimateAssetMoments
uses default settings for the missing data estimation procedure that might not be appropriate for all problems.
In either case, you might want to estimate the moments of asset
returns separately with either the ECM estimation functions such as ecmnmle
or with your own
functions.
mv_optim_transform
Errors
If you obtain optimization errors such as:
Error using mv_optim_transform (line 233) Portfolio set appears to be either empty or unbounded. Check constraints. Error in Portfolio/estimateFrontier (line 63) [A, b, f0, f, H, g, lb] = mv_optim_transform(obj);
Error using mv_optim_transform (line 238) Cannot obtain finite lower bounds for specified portfolio set. Error in Portfolio/estimateFrontier (line 63) [A, b, f0, f, H, g, lb] = mv_optim_transform(obj);
estimateBounds
to examine your
portfolio set, and use checkFeasibility
to ensure that
your initial portfolio is either feasible and, if infeasible, that you have
sufficient turnover to get from your initial portfolio to the portfolio set.
Tip
To correct this problem, try solving your problem with larger values for turnover or tracking-error and gradually reduce to the value that you want.
solveContinuousCustomObjProb
or solveMICustomObjProb
Errors
These errors can occur if the portfolio set is empty or unbounded. If the
portfolio set is empty, the error states that the problem is infeasible. The best
way to deal with these problems is to use the validation functions in Validate the Portfolio Problem for Portfolio Object.
Specifically, use estimateBounds
to examine your
portfolio set, and use checkFeasibility
to ensure that
your initial portfolio is either feasible or, if infeasible, that you have
sufficient turnover to get from your initial portfolio to the portfolio set.
Efficient Portfolios Do Not Make Sense
If you obtain efficient portfolios that do not seem to make sense, this can happen
if you forget to set specific constraints or you set incorrect constraints. For
example, if you allow portfolio weights to fall between 0
and
1
and do not set a budget constraint, you can get portfolios
that are 100% invested in every asset. Although it may be hard to detect, the best
thing to do is to review the constraints you have set with display of the object. If
you get portfolios with 100% invested in each asset, you can review the display of
your object and quickly see that no budget constraint is set. Also, you can use
estimateBounds
and checkFeasibility
to determine if
the bounds for your portfolio set make sense and to determine if the portfolios you
obtained are feasible relative to an independent formulation of your portfolio
set.
Efficient Frontiers Do Not Make Sense
If you obtain efficient frontiers that do not seem to make sense, this can happen
for some cases of mean and covariance of asset returns. It is possible for some
mean-variance portfolio optimization problems to have difficulties at the endpoints
of the efficient frontier. It is rare for standard portfolio problems, but this can
occur. For example, this can occur when using unusual combinations of turnover
constraints and transaction costs. Usually, the workaround of setting the hidden
property enforcePareto
produces a single portfolio for the entire
efficient frontier, where any other solutions are not Pareto optimal (which is what
efficient portfolios must be).
An example of a portfolio optimization problem that has difficulties at the endpoints of the efficient frontier is this standard mean-variance portfolio problem (long-only with a budget constraint) with the following mean and covariance of asset returns:
m = [ 1; 2; 3 ]; C = [ 1 1 0; 1 1 0; 0 0 1 ]; p = Portfolio; p = Portfolio(p, 'assetmean', m, 'assetcovar', C); p = Portfolio(p, 'lowerbudget', 1, 'upperbudget', 1); p = Portfolio(p, 'lowerbound', 0); plotFrontier(p)
To work around this problem, set the hidden Portfolio object property for
enforcePareto
. This property instructs the optimizer to
perform extra steps to ensure a Pareto-optimal solution. This slows down the solver,
but guarantees a Pareto-optimal solution.
p.enforcePareto = true; plotFrontier(p)
Troubleshooting estimateCustomObjectivePortfolio
When using estimateCustomObjectivePortfolio
, nonconvex functions are not
supported for problems with cardinality constraints or conditional bounds.
Specifically, the following error displays when using estimateCustomObjectivePortfolio
with a Portfolio
object that includes
'Conditional'
BoundType
(semicontinuous) constraints using setBounds
or
MinNumAssets
and MaxNumAssets
(cardinality) constraints using setMinMaxNumAssets
.
Error using solveMICustomObjProb Objective function must be convex in problems with cardinality constraints and/or conditional bounds. Error in Portfolio/estimateCustomObjectivePortfolio (line 88) [pwgt,exitflag] = solveMICustomObjProb(obj,prob,fun,flags);
Note
This error applies only to quadratic functions. This error is not detected in nonlinear functions. Therefore, if you are using a nonlinear function, you must validate your input.
For more information, see Role of Convexity in Portfolio Problems.
Troubleshooting for Setting 'Conditional'
BoundType
, MinNumAssets
, and
MaxNumAssets
Constraints
When configuring a Portfolio
, PortfolioCVaR
, or PortfolioMAD
object to include
'Conditional'
BoundType
(semicontinuous) constraints using setBounds
or
MinNumAssets
and MaxNumAssets
(cardinality) constraints using setMinMaxNumAssets
, the values of the inputs that you supply can result
in warning messages.
Conditional Bounds with LowerBound
Defined as Empty or Zero
When using setBounds
with
the BoundType
set to 'Conditional'
and the
LowerBound
input argument is empty ([
]
) or 0
, the Conditional
bound is not effective and is equivalent to a Simple
bound.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0, 0.5, 'BoundType', 'Conditional'); p = setMinMaxNumAssets(p, 3, 3); estimateFrontier(p, 10)
Warning: Conditional bounds with 'LowerBound' as zero are equivalent to simple bounds. Consider either using strictly positive 'LowerBound' or 'simple' as the 'BoundType' instead. > In internal.finance.PortfolioMixedInteger/checkBoundType (line 46) In Portfolio/checkarguments (line 204) In Portfolio/setBounds (line 80) Warning: The solution may have less than 'MinNumAssets' assets with nonzero weight. To enforce 'MinNumAssets' requirement, set strictly positive lower conditional bounds. > In internal.finance.PortfolioMixedInteger/hasIntegerConstraints (line 44) In Portfolio/estimateFrontier (line 51) ans = Columns 1 through 8 0.5000 0.3555 0.3011 0.3299 0.3585 0.3873 0.4160 0.4448 0.5000 0.5000 0.4653 0.3987 0.3322 0.2655 0.1989 0.1323 0.0000 0.1445 0.2335 0.2714 0.3093 0.3472 0.3850 0.4229 Columns 9 through 10 0.4735 0.5000 0.0657 0 0.4608 0.5000
In all the 10 optimal allocations, there are allocations (the first and last
ones) that only have two assets, which is in conflict with the
MinNumAssets
constraint that three assets should be
allocated. Also there are two warnings, which actually explain what happens. In
this case, the 'Conditional'
bound constraints are defined as
xi
= 0
or 0
<=
xi
<= 0.5
, which are internally
modeled as
0
*vi<=xi<=0.5
*vi,
where vi is 0
or 1
,
where 0
indicates not allocated, and 1
indicates allocated. Here, vi=1
, which
still allows the asset to have a weight of 0
. In other words,
setting LowerBound
as 0
or empty, doesn’t
clearly define the minimum allocation for an allocated asset. Therefore, a
0
weighted asset is also considered as an allocated
asset. To fix this warning, follow the instructions in the warning message, and
set a LowerBound
value that is strictly
positive.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0.3, 0.5, 'BoundType', 'Conditional'); p = setMinMaxNumAssets(p, 3, 3); estimateFrontier(p, 10)
ans = Columns 1 through 8 0.3000 0.3180 0.3353 0.3489 0.3580 0.3638 0.3694 0.3576 0.4000 0.3820 0.3642 0.3479 0.3333 0.3199 0.3067 0.3001 0.3000 0.3000 0.3005 0.3032 0.3088 0.3163 0.3240 0.3423 Columns 9 through 10 0.3289 0.3000 0.3000 0.3000 0.3711 0.4000
Length of 'BoundType'
Must Be Conformable with NumAssets
The setBounds
optional name-value argument for 'BoundType'
must be defined
for all assets in a Portfolio
, PortfolioCVaR
, or PortfolioMAD
object. By default,
the 'BoundType'
is 'Simple'
and applies to
all assets. Using setBounds
, you
can choose to define a 'BoundType'
for each asset. In this
case, the number of 'BoundType'
specifications must match the
number of assets (NumAssets
) in the Portfolio
, PortfolioCVaR
, or PortfolioMAD
object. The
following example demonstrates the error when the number of
'BoundType'
specifications do not match the number of
assets in the Portfolio
object.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0.1, 0.5, 'BoundType',["simple"; "conditional"])
Cannot create bound constraints. Caused by: Error using internal.finance.PortfolioMixedInteger/checkBoundType (line 28) Length of 'BoundType' must be conformable with 'NumAssets'=3.
To correct this, modify the BoundType
to include three
specifications because the Portfolio
object has three
assets.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0.1, 0.5, 'BoundType',["simple"; "conditional";"conditional"]) p.BoundType
p = Portfolio with properties: BuyCost: [] SellCost: [] RiskFreeRate: [] AssetMean: [3×1 double] AssetCovar: [3×3 double] TrackingError: [] TrackingPort: [] Turnover: [] BuyTurnover: [] SellTurnover: [] Name: [] NumAssets: 3 AssetList: [] InitPort: [] AInequality: [] bInequality: [] AEquality: [] bEquality: [] LowerBound: [3×1 double] UpperBound: [3×1 double] LowerBudget: 1 UpperBudget: 1 GroupMatrix: [] LowerGroup: [] UpperGroup: [] GroupA: [] GroupB: [] LowerRatio: [] UpperRatio: [] BoundType: [3×1 categorical] MinNumAssets: [] MaxNumAssets: [] ans = 3×1 categorical array simple conditional conditional
Redundant Constraints from 'BoundType'
, 'MinNumAssets'
, 'MaxNumAssets'
Constraints
When none of the constraints from 'BoundType'
,
'MinNumAssets'
, or 'MaxNumAssets'
are
active, the redundant constraints from 'BoundType'
,
'MinNumAssets'
, 'MaxNumAssets'
warning
occurs. This happens when you explicitly use setBounds
and
setMinMaxNumAssets
but with values that are inactive. That is,
the 'Conditional'
BoundType
has a LowerBound
= [
]
or 0
, 'MinNumAssets'
is
0
, or 'MaxNumAssets'
is the same value
as NumAssets
. In other words, if any of these three are
active, the warning will not show up when using the estimate
functions or plotFrontier
. The following two
examples show the rationale.
The first example is when the BoundType
is explicitly set
as 'Conditional'
but the LowerBound
is
0
, and no 'MinNumAssets'
and
'MaxNumAssets'
constraints are defined using setMinMaxNumAssets
.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0, 0.5, 'BoundType', 'Conditional'); estimateFrontier(p, 10)
Warning: Redundant constraints from 'BoundType', 'MinNumAssets', 'MaxNumAssets'. > In internal.finance.PortfolioMixedInteger/hasIntegerConstraints (line 24) In Portfolio/estimateFrontier (line 51) ans = Columns 1 through 8 0.5000 0.3555 0.3011 0.3299 0.3586 0.3873 0.4160 0.4448 0.5000 0.5000 0.4653 0.3987 0.3321 0.2655 0.1989 0.1323 0 0.1445 0.2335 0.2714 0.3093 0.3471 0.3850 0.4229 Columns 9 through 10 0.4735 0.5000 0.0657 0 0.4608 0.5000
The second example is when you explicitly set the three constraints, but all
with inactive values. In this example, the BoundType
is
'Conditional'
and the LowerBound
is
0
, thus specifying ineffective
'Conditional'
BoundType
constraints, and the
'MinNumAssets'
and 'MaxNumAssets'
values are 0
and 3
, respectively. The
setMinMaxNumAssets
function specifies ineffective
'MinNumAssets'
and 'MaxNumAssets'
constraints.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0, 0.5, 'BoundType', 'Conditional'); p = setMinMaxNumAssets(p, 0, 3); estimateFrontier(p, 10)
Warning: Redundant constraints from 'BoundType', 'MinNumAssets', 'MaxNumAssets'. > In internal.finance.PortfolioMixedInteger/hasIntegerConstraints (line 24) In Portfolio/estimateFrontier (line 51) ans = Columns 1 through 8 0.5000 0.3555 0.3011 0.3299 0.3586 0.3873 0.4160 0.4448 0.5000 0.5000 0.4653 0.3987 0.3321 0.2655 0.1989 0.1323 0 0.1445 0.2335 0.2714 0.3093 0.3471 0.3850 0.4229 Columns 9 through 10 0.4735 0.5000 0.0657 0 0.4608 0.5000
Infeasible Problem with Conditional (Semi-Continuous) Bounds, Cardinality Constraints, or Conditional Budget Constraints
The Portfolio
, PortfolioCVaR
, or PortfolioMAD
object performs
validations of all the constraints before solving any specific optimization
problems. The Portfolio
, PortfolioCVaR
, or
PortfolioMAD
object first considers all constraints other
than conditional bounds, cardinality constraints, and conditional budget
constraints and issues an error message if they are not compatible. Then the
Portfolio
, PortfolioCVaR
, or
PortfolioMAD
object adds the remaining constraints to
check if they are compatible with the already checked constraints. This
separation is natural because conditional bounds, cardinality constraints, and
conditional budget constraints require additional binary variables in the
mathematical formulation that leads to an MINLP, while other constraints only
need continuous variables. You can follow the error messages to check when the
infeasible problem occurs and take actions to fix the constraints.
One possible scenario is when the BoundType
is
'Conditional'
and Groups are defined for the
Portfolio
object. In this case, the Group definitions are
themselves in conflict. Consequently, the 'Conditional'
bound
constraint cannot be applied when running estimateFrontierLimits
.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0.1, 0.5, 'BoundType','Conditional'); p = setGroups(p, [1,1,0], 0.3, 0.5); p = addGroups(p, [0,1,0], 0.6, 0.7); pwgt = estimateFrontierLimits(p)
Error using Portfolio/buildMixedIntegerProblem (line 31) Infeasible problem prior to considering constraints involving integer variables. Verify compatibility of continuous constraints. Error in Portfolio/estimateFrontierLimits>int_frontierLimits (line 93) ProbStruct = buildMixedIntegerProblem(obj); Error in Portfolio/estimateFrontierLimits (line 73) pwgt = int_frontierLimits(obj, minsolution, maxsolution);
To correct this error, change the LowerGroup
in the
addGroups
function to also be
0.3
to match the GroupMatrix
input
from setGroups
.
AssetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; AssetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); p = setBounds(p, 0.1, 0.5, 'BoundType','Conditional'); p = setGroups(p, [1,1,0], 0.3, 0.5); p = addGroups(p, [0,1,0], 0.3, 0.7); pwgt = estimateFrontierLimits(p)
pwgt = 0 0.2000 0.5000 0.3000 0.5000 0.5000
A second possible scenario is when the BoundType
is
'Conditional'
and the setEquality
function is used
with the bEquality
parameter set to 0.04
.
This sets an equality constraint to have x1 +
x3 = 0.04
. At the same time, setBounds
also
set the semicontinuous constraints to have xi =
0
or 0.1
<= xi
<= 2.5
, which lead to x1 +
x
3 = 0
or 0.1
<=
x1 + x3 <= 5
.
The semicontinuous constraints are not compatible with the equality constraint
because there is no way to get x
1 + x
3 to
equal 0.04
. Therefore, the error message is
displayed.
AssetMean = [ 0.05; 0.1; 0.12; 0.18 ]; AssetCovar = [ 0.0064 0.00408 0.00192 0; 0.00408 0.0289 0.0204 0.0119; 0.00192 0.0204 0.0576 0.0336; 0 0.0119 0.0336 0.1225 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); A = [ 1 0 1 0 ]; b = 0.04; p = setEquality(p, A, b); p = setBounds(p, 0.1, 2.5, 'BoundType','Conditional'); p = setMinMaxNumAssets(p, 2, 2); pwgt = estimateFrontierLimits(p)
Error using Portfolio/buildMixedIntegerProblem (line 109) Infeasible problem when considering constraints involving integer variables. Verify constraints compatibility or decrease 'AbsoluteGapTolerance' or 'RelativeGapTolerance'. Error in Portfolio/estimateFrontierLimits>int_frontierLimits (line 93) ProbStruct = buildMixedIntegerProblem(obj); Error in Portfolio/estimateFrontierLimits (line 73) pwgt = int_frontierLimits(obj, minsolution, maxsolution);
To correct this error, change the bEquality
parameter from
0.04
to .4
.
AssetMean = [ 0.05; 0.1; 0.12; 0.18 ]; AssetCovar = [ 0.0064 0.00408 0.00192 0; 0.00408 0.0289 0.0204 0.0119; 0.00192 0.0204 0.0576 0.0336; 0 0.0119 0.0336 0.1225 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar, 'Budget', 1); A = [ 1 0 1 0 ]; b = 0.4; p = setEquality(p, A, b); p = setBounds(p, 0.1, 2.5, 'BoundType','Conditional'); p = setMinMaxNumAssets(p, 2, 2); pwgt = estimateFrontierLimits(p)
pwgt = 0.4000 0 0.6000 0 0 0.4000 0 0.6000
Redundant Conditional Budget Constraint
This redundant conditional budget constraint warning occurs when you are using
setConditionalBudget
with a Portfolio
, PortfolioCVaR
, or PortfolioMAD
object and the
conditional threshold of all assets is greater than or equal to their respective
upper bounds. This happens when the UpperBound
≤
ConditionalBudgetThreshold
. In this case, assets are not
allowed to invest more than the conditional threshold, which makes the
conditional budget constraint unnecessary. The following example shows the case
where this
happens:
assetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; assetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio(AssetMean=assetMean,AssetCovar=assetCovar); p = setBounds(p,0,0.5); p = setConditionalBudget(p,0.5,0.75); estimateFrontier(p)
Warning: Redundant conditional budget constraint. > In internal.finance.PortfolioMixedInteger/hasIntegerConstraints (line 59) In Portfolio/estimateFrontier (line 54) ans = 0 0.0454 0.0909 0.1825 0.3186 0.4547 0.5000 0.5000 0.5000 0.5000 0 0.2008 0.4015 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 0.5000 0 0.0169 0.0338 0.0491 0.0629 0.0766 0.1574 0.2716 0.3858 0.5000
To correct this warning, use setBounds
to
specify an UpperBound
value that is > than the
ConditionalBudgetThreshold
that you specify using
setConditionalBudget
.
assetMean = [ 0.0101110; 0.0043532; 0.0137058 ]; assetCovar = [ 0.00324625 0.00022983 0.00420395; 0.00022983 0.00049937 0.00019247; 0.00420395 0.00019247 0.00764097 ]; p = Portfolio(AssetMean=assetMean,AssetCovar=assetCovar); p = setBounds(p,0,0.55); p = setConditionalBudget(p,0.5,0.75); estimateFrontier(p)
ans = 0.0000 0.0477 0.0953 0.1799 0.3226 0.4653 0.5000 0.5000 0.5000 0.5000 0.0001 0.2107 0.4212 0.5500 0.5500 0.5500 0.5500 0.5500 0.5500 0.5000 0.0000 0.0177 0.0355 0.0519 0.0663 0.0808 0.1749 0.2947 0.4144 0.5500
Unbounded Portfolio Problem
This error occurs when you are using a Portfolio
, PortfolioCVaR
, or PortfolioMAD
object and there is
no UpperBound
defined in setBounds
and
you are using setMinMaxNumAssets
. In this case, this is formulated as a mixed
integer programming problem and an UpperBound
is required to
enforce MinNumAssets
and MaxNumAssets
constraints.
The optimizer first attempts to estimate the upper bound of each asset, based
on all the specified constraints. If the UpperBound
cannot be
found, an error message occurs which instructs you to set an explicit
UpperBound
. In most cases, as long as you set some upper
bounds to the problem using any set
function, the optimizer
can successfully find a good
estimation.
AssetMean = [ 0.05; 0.1; 0.12; 0.18 ]; AssetCovar = [ 0.0064 0.00408 0.00192 0; 0.00408 0.0289 0.0204 0.0119; 0.00192 0.0204 0.0576 0.0336; 0 0.0119 0.0336 0.1225 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar); p = setBounds(p, 0.1, 'BoundType','Conditional'); p = setGroups(p, [1,1,1,0], 0.3, 0.5); p = setMinMaxNumAssets(p, 3, 3); pwgt = estimateFrontierLimits(p)
Error using Portfolio/buildMixedIntegerProblem (line 42) Unbounded portfolio problem. Upper bounds cannot be inferred from the existing constraints. Set finite upper bounds using 'setBounds'. Error in Portfolio/estimateFrontierLimits>int_frontierLimits (line 93) ProbStruct = buildMixedIntegerProblem(obj); Error in Portfolio/estimateFrontierLimits (line 73) pwgt = int_frontierLimits(obj, minsolution, maxsolution);
To correct this error, specify an UpperBound
value for
setBounds
.
AssetMean = [ 0.05; 0.1; 0.12; 0.18 ]; AssetCovar = [ 0.0064 0.00408 0.00192 0; 0.00408 0.0289 0.0204 0.0119; 0.00192 0.0204 0.0576 0.0336; 0 0.0119 0.0336 0.1225 ]; p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar); p = setBounds(p, 0.1, .9, 'BoundType','Conditional'); p = setGroups(p, [1,1,1,0], 0.3, 0.5); p = setMinMaxNumAssets(p, 3, 3); pwgt = estimateFrontierLimits(p)
pwgt = 0.1000 0 0.1000 0.1000 0.1000 0.4000 0 0.9000
Total Number of Portfolio Weights with a Value > 0 Are Greater Than MaxNumAssets
Specified
When using a Portfolio
, PortfolioCVaR
, or PortfolioMAD
object, the optimal
allocation w
may contain some very small values that leads to
sum
(w
>0
) larger
than MaxNumAssets
, even though the
MaxNumAssets
constraint is specified using setMinMaxNumAssets
. For example, in the following code when
setMinMaxNumAssets
is used to set
MaxNumAssets
to 15
, the
sum
(w
>0
) indicates
that there are 19
assets. A close examination of the weights
shows that the weights are extremely small and are actually
0.
T = readtable('dowPortfolio.xlsx'); symbol = T.Properties.VariableNames(3:end); assetReturn = tick2ret(T{:,3:end}); p = Portfolio('AssetList', symbol, 'budget', 1); p = setMinMaxNumAssets(p, 10, 15); p = estimateAssetMoments(p,assetReturn); p = setBounds(p,0.01,0.5,'BoundType','Conditional','NumAssets',30); p = setTrackingError(p,0.05,ones(1, p.NumAssets)/p.NumAssets); w = estimateFrontierLimits(p,'min'); % minimum risk portfolio sum(w>0) % Number of assets that are allocated in the optimal portfolio w(w<eps) % Check the weights of the very small weighted assets
ans = 19 ans = 1.0e-20 * -0.0000 0 0 0.0293 0 0.3626 0.2494 0 0.0926 -0.0000 0 0.0020 0 0 0 0
This situation only happens when the OuterApproximation
algorithm is used with setSolverMINLP
to
solve a MINLP portfolio optimization problem. The
OuterApproximation
internally fixes the latest solved
integer variables and runs an NLP with quadprog
or fmincon
, which introduces numerical
issues and leads to weights that are very close to 0.
If you do not want to deal with very small values, you can use setSolverMINLP
to
select a different algorithm. In this example, the
'TrustRegionCP'
algorithm is
specified.
T = readtable('dowPortfolio.xlsx'); symbol = T.Properties.VariableNames(3:end); assetReturn = tick2ret(T{:,3:end}); p = Portfolio('AssetList', symbol, 'budget', 1); p = setMinMaxNumAssets(p, 10, 15); p = estimateAssetMoments(p,assetReturn); p = setBounds(p,0.01,0.5,'BoundType','Conditional','NumAssets',30); p = setTrackingError(p,0.05,ones(1, p.NumAssets)/p.NumAssets); p = setSolverMINLP(p,'TrustRegionCP'); w = estimateFrontierLimits(p,'min'); % minimum risk portfolio sum(w>0) % Number of assets that are allocated in the optimal portfolio w(w<eps) % The weights of the very small weighted assets are strictly zeros
ans = 14 ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
See Also
Portfolio
| estimateAssetMoments
| checkFeasibility
| setBounds
| setMinMaxNumAssets
Related Examples
- Postprocessing Results to Set Up Tradable Portfolios
- Creating the Portfolio Object
- Working with Portfolio Constraints Using Defaults
- Estimate Efficient Portfolios for Entire Efficient Frontier for Portfolio Object
- Estimate Efficient Frontiers for Portfolio Object
- Asset Allocation Case Study
- Portfolio Optimization Examples Using Financial Toolbox
- Portfolio Optimization with Semicontinuous and Cardinality Constraints
- Black-Litterman Portfolio Optimization Using Financial Toolbox
- Portfolio Optimization Using Factor Models
- Portfolio Optimization Using Social Performance Measure
- Diversify Portfolios Using Custom Objective
- Troubleshooting CVaR Portfolio Optimization Results
- Troubleshooting MAD Portfolio Optimization Results