Postprocessing Results

After obtaining efficient portfolios or estimates for expected portfolio risks and returns, use your results to set up trades to move toward an efficient portfolio. For information on the workflow when using Portfolio objects, see Portfolio Object Workflow.

Setting Up Tradable Portfolios

Suppose you set up a portfolio optimization problem and obtained portfolios on the efficient frontier. Use the dataset object from Statistics Toolbox™ to form a blotter that lists your portfolios with the names for each asset. For example, suppose you want to obtain five portfolios along the efficient frontier. You can set up a blotter with weights multiplied by 100 to view the allocations for each portfolio:

m = [ 0.05; 0.1; 0.12; 0.18 ];
C = [ 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 ];
pwgt0 = [ 0.3; 0.3; 0.2; 0.1 ];
 
 p = Portfolio('InitPort', pwgt0);
 p = setAssetList(p, 'Bonds','Large-Cap Equities','Small-Cap Equities','Emerging Equities');
 p = setAssetMoments(p, m, C);
 p = setDefaultConstraints(p);
 pwgt = estimateFrontier(p, 5);
 
 pnames = cell(1,5);
   for i = 1:5
       pnames{i} = sprintf('Port%d',i);
   end
 
 Blotter = dataset([{100*pwgt},pnames],'obsnames',p.AssetList);
 display(Blotter);
Blotter = 

                          Port1     Port2     Port3     Port4     Port5
    Bonds                 88.906    51.216    13.525         0      0  
    Large-Cap Equities    3.6875    24.387    45.086    27.479      0  
    Small-Cap Equities    4.0425    7.7088    11.375    13.759      0  
    Emerging Equities      3.364    16.689    30.014    58.762    100  

This result indicates that you would invest primarily in bonds at the minimum-risk/minimum-return end of the efficient frontier (Port1), and that you would invest completely in emerging equity at the maximum-risk/maximum-return end of the efficient frontier (Port5). You can also select a particular efficient portfolio, for example, suppose you want a portfolio with 15% risk and you add purchase and sale weights outputs obtained from the "estimateFrontier" methods to set up a trade blotter:

m = [ 0.05; 0.1; 0.12; 0.18 ];
C = [ 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 ];
pwgt0 = [ 0.3; 0.3; 0.2; 0.1 ];
 
p = Portfolio('InitPort', pwgt0);
p = setAssetList(p, 'Bonds','Large-Cap Equities','Small-Cap Equities','Emerging Equities');
p = setAssetMoments(p, m, C);
p = setDefaultConstraints(p);
[pwgt, pbuy, psell] = estimateFrontierByRisk(p, 0.15);
 
Blotter = dataset([{100*[pwgt0, pwgt, pbuy, psell]}, ...
     {'Initial','Weight', 'Purchases','Sales'}],'obsnames',p.AssetList);
 
display(Blotter);
Blotter = 

                          Initial    Weight    Purchases    Sales 
    Bonds                 30         20.299         0       9.7007
    Large-Cap Equities    30         41.366    11.366            0
    Small-Cap Equities    20         10.716         0       9.2838
    Emerging Equities     10         27.619    17.619            0

If you have prices for each asset (in this example, they can be ETFs), add them to your blotter and then use the tools of the dataset object to obtain shares and shares to be traded. For an example, see Asset Allocation.

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 constructor if you want to modify it, otherwise it creates a new object. See Constructing 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, the help header for lcprog, and the quadprog documentation.

Speed of Optimization

Although it is difficult to characterize when one algorithm is faster than the other, the default solver, lcprog is generally faster for smaller problems and the quadprog solver is generally 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 method estimateAssetMoments 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 or NaN values in your data, the supported missing data feature requires that your covariance matrix must be positive-definite, i.e., 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 methods.

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);

or

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);

Since the portfolio optimization tools require a bounded portfolio set, these errors (and similar errors) can occur if your portfolio set is either empty and, if nonempty, unbounded. Specifically, the portfolio optimization algorithm requires that your portfolio set have at least a finite lower bound. The best way to deal with these problems is to use the validation methods in Validate the Portfolio Problem. Specifically, use 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 and gradually reduce to the value that you want.

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.

See Also

| |

Related Examples

More About

Was this topic helpful?