# estimateFrontier

Estimate specified number of optimal portfolios on the efficient frontier

## Syntax

``````[pwgt,pbuy,psell] = estimateFrontier(obj)``````
``````[pwgt,pbuy,psell] = estimateFrontier(obj,NumPorts)``````

## Description

example

``````[pwgt,pbuy,psell] = estimateFrontier(obj)``` estimates the specified number of optimal portfolios on the efficient frontier for `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` objects. For details on the respective workflows when using these different objects, see Portfolio Object Workflow, PortfolioCVaR Object Workflow, and PortfolioMAD Object Workflow.```

example

``````[pwgt,pbuy,psell] = estimateFrontier(obj,NumPorts)``` estimates the specified number of optimal portfolios on the efficient frontier with an additional option specified for `NumPorts`. ```

## Examples

collapse all

Create efficient portfolios:

```load CAPMuniverse p = Portfolio('AssetList',Assets(1:12)); p = estimateAssetMoments(p, Data(:,1:12),'missingdata',true); p = setDefaultConstraints(p); plotFrontier(p);```

```pwgt = estimateFrontier(p, 5); pnames = cell(1,5); for i = 1:5 pnames{i} = sprintf('Port%d',i); end Blotter = dataset([{pwgt},pnames],'obsnames',p.AssetList); disp(Blotter);```
``` Port1 Port2 Port3 Port4 Port5 AAPL 0.017926 0.058247 0.097816 0.12955 0 AMZN 0 0 0 0 0 CSCO 0 0 0 0 0 DELL 0.0041906 0 0 0 0 EBAY 0 0 0 0 0 GOOG 0.16144 0.35678 0.55228 0.75116 1 HPQ 0.052566 0.032302 0.011186 0 0 IBM 0.46422 0.36045 0.25577 0.11928 0 INTC 0 0 0 0 0 MSFT 0.29966 0.19222 0.082949 0 0 ORCL 0 0 0 0 0 YHOO 0 0 0 0 0 ```

Create a `Portfolio` object for 12 stocks based on `CAPMuniverse.mat`.` `

```load CAPMuniverse p0 = Portfolio('AssetList',Assets(1:12)); p0 = estimateAssetMoments(p0, Data(:,1:12),'missingdata',true); p0 = setDefaultConstraints(p0);```

Use `setMinMaxNumAssets` to define a maximum number of 3 assets.

`p1 = setMinMaxNumAssets(p0, [], 3);`

Use `setBounds` to define a lower and upper bound and a `BoundType` of `'Conditional'`.

```p1 = setBounds(p1, 0.1, 0.5,'BoundType', 'Conditional'); pwgt = estimateFrontier(p1, 5); ```

The following table shows that the optimized allocations only have maximum 3 assets invested, and small positions less than 0.1 are avoided.

`result = table(p0.AssetList', pwgt)`
```result=12×2 table Var1 pwgt ________ _______________________________________________________________________ {'AAPL'} 0 0 0 0.14308 0 {'AMZN'} 0 0 0 0 0 {'CSCO'} 0 0 0 0 0 {'DELL'} 0 0 0 0 0 {'EBAY'} 0 0 0 0 0.5 {'GOOG'} 0.16979 0.29587 0.42213 0.49998 0.5 {'HPQ' } -4.4409e-16 0 0 0 0 {'IBM' } 0.49602 0.4363 0.37309 0.35694 0 {'INTC'} 0 0 0 0 0 {'MSFT'} 0.33419 0.26783 0.20479 0 0 {'ORCL'} 0 0 0 0 0 {'YHOO'} 0 0 0 0 0 ```

The `estimateFrontier` function uses the MINLP solver to solve this problem. Use the `setSolverMINLP` function to configure the `SolverType` and options.

`p1.solverTypeMINLP`
```ans = 'OuterApproximation' ```
`p1.solverOptionsMINLP`
```ans = struct with fields: MaxIterations: 1000 AbsoluteGapTolerance: 1.0000e-07 RelativeGapTolerance: 1.0000e-05 NonlinearScalingFactor: 1000 ObjectiveScalingFactor: 1000 Display: 'off' CutGeneration: 'basic' MaxIterationsInactiveCut: 30 ActiveCutTolerance: 1.0000e-07 IntMainSolverOptions: [1x1 optim.options.Intlinprog] NumIterationsEarlyIntegerConvergence: 30 ```

Create efficient portfolios:

```load CAPMuniverse p = PortfolioCVaR('AssetList',Assets(1:12)); p = simulateNormalScenariosByData(p, Data(:,1:12), 20000 ,'missingdata',true); p = setDefaultConstraints(p); p = setProbabilityLevel(p, 0.95); plotFrontier(p);```

```pwgt = estimateFrontier(p, 5); pnames = cell(1,5); for i = 1:5 pnames{i} = sprintf('Port%d',i); end Blotter = dataset([{pwgt},pnames],'obsnames',p.AssetList); disp(Blotter);```
``` Port1 Port2 Port3 Port4 Port5 AAPL 0.011002 0.07341 0.11855 0.12957 0 AMZN 0 0 0 0 0 CSCO 0 0 0 0 0 DELL 0.023234 0 0 0 0 EBAY 0 0 0 0 0 GOOG 0.20304 0.3804 0.56259 0.75956 1 HPQ 0.041781 0.0094108 0 0 0 IBM 0.4452 0.36408 0.2625 0.11086 0 INTC 0 0 0 0 0 MSFT 0.27575 0.1727 0.056365 0 0 ORCL 0 0 0 0 0 YHOO 0 0 0 0 0 ```

Create efficient portfolios:

```load CAPMuniverse p = PortfolioMAD('AssetList',Assets(1:12)); p = simulateNormalScenariosByData(p, Data(:,1:12), 20000 ,'missingdata',true); p = setDefaultConstraints(p); plotFrontier(p);```

```pwgt = estimateFrontier(p, 5); pnames = cell(1,5); for i = 1:5 pnames{i} = sprintf('Port%d',i); end Blotter = dataset([{pwgt},pnames],'obsnames',p.AssetList); disp(Blotter);```
``` Port1 Port2 Port3 Port4 Port5 AAPL 0.030785 0.074603 0.11383 0.13349 0 AMZN 0 0 0 0 0 CSCO 0 0 0 0 0 DELL 0.010139 0 0 0 0 EBAY 0 0 0 0 0 GOOG 0.1607 0.35186 0.54435 0.74908 1 HPQ 0.056834 0.024903 0 0 0 IBM 0.45716 0.38008 0.29373 0.11743 0 INTC 0 0 0 0 0 MSFT 0.28438 0.16855 0.048097 0 0 ORCL 0 0 0 0 0 YHOO 0 0 0 0 0 ```

Obtain the default number of efficient portfolios over the entire range of the efficient frontier.

```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 ]; p = Portfolio; p = setAssetMoments(p, m, C); p = setDefaultConstraints(p); pwgt = estimateFrontier(p); disp(pwgt);```
``` 0.8891 0.7215 0.5540 0.3865 0.2190 0.0515 0 0 0 0 0.0369 0.1289 0.2209 0.3129 0.4049 0.4969 0.4049 0.2314 0.0579 0 0.0404 0.0567 0.0730 0.0893 0.1056 0.1219 0.1320 0.1394 0.1468 0 0.0336 0.0929 0.1521 0.2113 0.2705 0.3297 0.4630 0.6292 0.7953 1.0000 ```

Starting from the initial portfolio, the `estimateFrontier` function returns purchases and sales to get from your initial portfolio to each efficient portfolio on the efficient frontier. Given an initial portfolio in `pwgt0`, you can obtain purchases and sales.

```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 ]; p = Portfolio; p = setAssetMoments(p, m, C); p = setDefaultConstraints(p); pwgt0 = [ 0.3; 0.3; 0.2; 0.1 ]; p = setInitPort(p, pwgt0); [pwgt, pbuy, psell] = estimateFrontier(p); display(pwgt);```
```pwgt = 4×10 0.8891 0.7215 0.5540 0.3865 0.2190 0.0515 0 0 0 0 0.0369 0.1289 0.2209 0.3129 0.4049 0.4969 0.4049 0.2314 0.0579 0 0.0404 0.0567 0.0730 0.0893 0.1056 0.1219 0.1320 0.1394 0.1468 0 0.0336 0.0929 0.1521 0.2113 0.2705 0.3297 0.4630 0.6292 0.7953 1.0000 ```
`display(pbuy);`
```pbuy = 4×10 0.5891 0.4215 0.2540 0.0865 0 0 0 0 0 0 0 0 0 0.0129 0.1049 0.1969 0.1049 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0521 0.1113 0.1705 0.2297 0.3630 0.5292 0.6953 0.9000 ```
`display(psell);`
```psell = 4×10 0 0 0 0 0.0810 0.2485 0.3000 0.3000 0.3000 0.3000 0.2631 0.1711 0.0791 0 0 0 0 0.0686 0.2421 0.3000 0.1596 0.1433 0.1270 0.1107 0.0944 0.0781 0.0680 0.0606 0.0532 0.2000 0.0664 0.0071 0 0 0 0 0 0 0 0 ```

Obtain the default number of efficient portfolios over the entire range of the efficient frontier.

```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 ]; m = m/12; C = C/12; rng(11); AssetScenarios = mvnrnd(m, C, 20000); p = PortfolioCVaR; p = setScenarios(p, AssetScenarios); p = setDefaultConstraints(p); p = setProbabilityLevel(p, 0.95); pwgt = estimateFrontier(p); disp(pwgt);```
``` 0.8454 0.6847 0.5166 0.3541 0.1897 0.0315 0 0 0 0 0.0606 0.1429 0.2281 0.3167 0.3989 0.4732 0.3531 0.1804 0 0 0.0456 0.0638 0.0944 0.1079 0.1344 0.1583 0.1733 0.1919 0.2212 0 0.0484 0.1085 0.1609 0.2213 0.2770 0.3370 0.4736 0.6277 0.7788 1.0000 ```

The function `rng`($seed$) resets the random number generator to produce the documented results. It is not necessary to reset the random number generator to simulate scenarios.

Starting from the initial portfolio, the `estimateFrontier` function returns purchases and sales to get from your initial portfolio to each efficient portfolio on the efficient frontier. Given an initial portfolio in `pwgt0`, you can obtain purchases and sales.

```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 ]; m = m/12; C = C/12; rng(11); AssetScenarios = mvnrnd(m, C, 20000); p = PortfolioCVaR; p = setScenarios(p, AssetScenarios); p = setDefaultConstraints(p); p = setProbabilityLevel(p, 0.95); pwgt0 = [ 0.3; 0.3; 0.2; 0.1 ]; p = setInitPort(p, pwgt0); [pwgt, pbuy, psell] = estimateFrontier(p); display(pwgt);```
```pwgt = 4×10 0.8454 0.6847 0.5166 0.3541 0.1897 0.0315 0 0 0 0 0.0606 0.1429 0.2281 0.3167 0.3989 0.4732 0.3531 0.1804 0 0 0.0456 0.0638 0.0944 0.1079 0.1344 0.1583 0.1733 0.1919 0.2212 0 0.0484 0.1085 0.1609 0.2213 0.2770 0.3370 0.4736 0.6277 0.7788 1.0000 ```
`display(pbuy);`
```pbuy = 4×10 0.5454 0.3847 0.2166 0.0541 0 0 0 0 0 0 0 0 0 0.0167 0.0989 0.1732 0.0531 0 0 0 0 0 0 0 0 0 0 0 0.0212 0 0 0.0085 0.0609 0.1213 0.1770 0.2370 0.3736 0.5277 0.6788 0.9000 ```
`display(psell);`
```psell = 4×10 0 0 0 0 0.1103 0.2685 0.3000 0.3000 0.3000 0.3000 0.2394 0.1571 0.0719 0 0 0 0 0.1196 0.3000 0.3000 0.1544 0.1362 0.1056 0.0921 0.0656 0.0417 0.0267 0.0081 0 0.2000 0.0516 0 0 0 0 0 0 0 0 0 ```

The function `rng`($seed$) resets the random number generator to produce the documented results. It is not necessary to reset the random number generator to simulate scenarios.

Obtain the default number of efficient portfolios over the entire range of the efficient frontier.

```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 ]; m = m/12; C = C/12; rng(11); AssetScenarios = mvnrnd(m, C, 20000); p = PortfolioMAD; p = setScenarios(p, AssetScenarios); p = setDefaultConstraints(p); pwgt = estimateFrontier(p); disp(pwgt);```
``` 0.8823 0.7151 0.5490 0.3819 0.2175 0.0499 0 0 0 0 0.0420 0.1290 0.2130 0.2971 0.3822 0.4667 0.3615 0.1752 0 0 0.0394 0.0600 0.0822 0.1068 0.1238 0.1487 0.1780 0.2101 0.2267 0 0.0363 0.0959 0.1557 0.2142 0.2765 0.3347 0.4605 0.6147 0.7733 1.0000 ```

The function `rng`($seed$) resets the random number generator to produce the documented results. It is not necessary to reset the random number generator to simulate scenarios.

Starting from the initial portfolio, the `estimateFrontier` function returns purchases and sales to get from your initial portfolio to each efficient portfolio on the efficient frontier. Given an initial portfolio in `pwgt0`, you can obtain purchases and sales.

```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 ]; m = m/12; C = C/12; rng(11); AssetScenarios = mvnrnd(m, C, 20000); p = PortfolioMAD; p = setScenarios(p, AssetScenarios); p = setDefaultConstraints(p); pwgt0 = [ 0.3; 0.3; 0.2; 0.1 ]; p = setInitPort(p, pwgt0); [pwgt, pbuy, psell] = estimateFrontier(p); display(pwgt);```
```pwgt = 4×10 0.8823 0.7151 0.5490 0.3819 0.2175 0.0499 0 0 0 0 0.0420 0.1290 0.2130 0.2971 0.3822 0.4667 0.3615 0.1752 0 0 0.0394 0.0600 0.0822 0.1068 0.1238 0.1487 0.1780 0.2101 0.2267 0 0.0363 0.0959 0.1557 0.2142 0.2765 0.3347 0.4605 0.6147 0.7733 1.0000 ```
`display(pbuy);`
```pbuy = 4×10 0.5823 0.4151 0.2490 0.0819 0 0 0 0 0 0 0 0 0 0 0.0822 0.1667 0.0615 0 0 0 0 0 0 0 0 0 0 0.0101 0.0267 0 0 0 0.0557 0.1142 0.1765 0.2347 0.3605 0.5147 0.6733 0.9000 ```
`display(psell);`
```psell = 4×10 0 0 0 0 0.0825 0.2501 0.3000 0.3000 0.3000 0.3000 0.2580 0.1710 0.0870 0.0029 0 0 0 0.1248 0.3000 0.3000 0.1606 0.1400 0.1178 0.0932 0.0762 0.0513 0.0220 0 0 0.2000 0.0637 0.0041 0 0 0 0 0 0 0 0 ```

The function `rng`($seed$) resets the random number generator to produce the documented results. It is not necessary to reset the random number generator to simulate scenarios.

## Input Arguments

collapse all

Object for portfolio, specified using `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` object. For more information on creating a portfolio object, see

Data Types: `object`

Number of points to obtain on the efficient frontier, specified as a scalar integer.

Note

If no value is specified for `NumPorts`, the default value is obtained from the hidden property `defaultNumPorts` (default value is `10`). If `NumPorts` = `1`, this function returns the portfolio specified by the hidden property `defaultFrontierLimit` (current default value is `'min'`).

Data Types: `double`

## Output Arguments

collapse all

Optimal portfolios on the efficient frontier with specified number of portfolios spaced equally from minimum to maximum portfolio return, returned as a `NumAssets`-by-`NumPorts` matrix. `pwgt` is returned for a `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` input object (`obj`).

Purchases relative to an initial portfolio for optimal portfolios on the efficient frontier, returned as `NumAssets`-by-`NumPorts` matrix.

Note

If no initial portfolio is specified in `obj.InitPort`, that value is assumed to be `0` such that `pbuy = max(0, pwgt)` and `psell = max(0, -pwgt)`.

`pbuy` is returned for a `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` input object (`obj`).

Sales relative to an initial portfolio for optimal portfolios on the efficient frontier, returned as a `NumAssets`-by-`NumPorts` matrix.

Note

If no initial portfolio is specified in `obj.InitPort`, that value is assumed to be `0` such that `pbuy = max(0, pwgt)` and `psell = max(0, -pwgt)`.

`psell` is returned for `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` input object (`obj`).

## Tips

• You can also use dot notation to estimate the specified number of optimal portfolios over the entire efficient frontier.

` [pwgt, pbuy, psell] = obj.estimateFrontier(NumPorts);`

• When introducing transaction costs and turnover constraints to the `Portfolio`, `PortfolioCVaR`, or `PortfolioMAD` object, the portfolio optimization objective contains a term with an absolute value. For more information on how Financial Toolbox™ handles such cases algorithmically, see References.

## References

[1] Cornuejols, G., and R. Tutuncu. Optimization Methods in Finance. Cambridge University Press, 2007.

## Version History

Introduced in R2011a