Main Content

estimateFrontierByReturn

Estimate optimal portfolios with targeted portfolio returns

Description

[pwgt,pbuy,psell] = estimateFrontierByReturn(obj,TargetReturn) estimates optimal portfolios with targeted portfolio returns 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

Examples

collapse all

To obtain efficient portfolios that have targeted portfolio returns, the estimateFrontierByReturn function accepts one or more target portfolio returns and obtains efficient portfolios with the specified returns. Assume you have a universe of four assets where you want to obtain efficient portfolios with target portfolio returns of 6%, 9%, and 12%.

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 = estimateFrontierByReturn(p, [0.06, 0.09, 0.12]);

display(pwgt);
pwgt = 4×3

    0.8772    0.5032    0.1293
    0.0434    0.2488    0.4541
    0.0416    0.0780    0.1143
    0.0378    0.1700    0.3022

To obtain efficient portfolios for a Portfolio object that has targeted portfolio returns, estimateFrontierByReturn accepts one or more target portfolio returns and obtains efficient portfolios with the specified returns.

Load the stock price data and set portfolio constraints so that the total weight of the portfolio must equal 1 and the maximum allocation to for any one stock is 50%, while the minimum is 5%.

T = readtable('dowPortfolio.xlsx');

Dates

DJI

AA

AIG

AXP

BA

C

CAT

DD

DIS

GE

GM

HD

HON

HPQ

IBM

INTC

JNJ

JPM

KO

MCD

MMM

MO

MRK

MSFT

PFE

PG

T

UTX

VZ

WMT

XOM

1

1/3/2006

1.0847e+04

28.7200

68.4100

51.5300

68.6300

45.2600

55.8600

40.6800

24.1800

33.6000

17.8200

39.7900

36.1400

28.3500

80.1300

24.5700

59.0800

37.7800

38.9800

32.7200

75.9300

52.2700

30.7300

26.1900

22.1600

56.3800

22.7000

54.9400

26.7900

44.9000

56.6400

2

1/4/2006

1.0880e+04

28.8900

68.5100

51.0300

69.3400

44.4200

57.2900

40.4600

23.7700

33.5600

18.3000

39.0500

35.9900

29.1800

80.0300

24.9000

59.9900

37.5600

38.9100

33.0100

75.5400

52.6500

31.0800

26.3200

22.8800

56.4800

22.8700

54.6100

27.5800

44.9900

56.7400

3

1/5/2006

1.0882e+04

29.1200

68.6000

51.5700

68.5300

44.6500

57.2900

40.3800

24.1900

33.4700

19.3400

38.6700

35.9700

28.9700

80.5600

25.2500

59.7400

37.6700

39.1000

33.0500

74.8500

52.5200

31.1300

26.3400

22.9000

56.3000

22.9200

54.4100

27.9000

44.3800

56.4500

4

1/6/2006

1.0959e+04

29.0200

68.8900

51.7500

67.5700

44.6500

58.4300

40.5500

24.5200

33.7000

19.6100

38.9600

36.5300

29.8000

82.9600

25.2800

60.0100

37.9400

39.4700

33.2500

75.4700

52.9500

31.0800

26.2600

23.1600

56.2400

23.2100

54.5800

28.0100

44.5600

57.5700

5

1/9/2006

1.1012e+04

29.3700

68.5700

53.0400

67.0100

44.4300

59.4900

40.3200

24.7800

33.6100

21.1200

39.3800

36.2300

30.1700

81.7600

25.4400

60.3800

38.5500

39.6600

33.8800

75.8400

53.1100

31.5800

26.2100

23.1600

56.6700

23.3000

55.2000

28.1200

44.4000

57.5400

6

1/10/2006

1.1012e+04

28.4400

69.1800

52.8800

67.3300

44.5700

59.2500

40.2000

25.0900

33.4300

20.7900

40.3300

36.1700

30.3300

82.1000

25.1000

60.4900

38.6100

39.7000

33.9100

75.3700

53.0400

31.2700

26.3500

22.7700

56.4500

23.1600

55.2400

28.2400

44.5400

57.9900

7

1/11/2006

1.1043e+04

28.0500

69.6000

52.5900

68.3000

44.9800

59.2800

38.8700

25.3300

33.6600

20.6100

41.4400

36.1900

30.8800

82.1900

25.1200

59.9100

38.5800

39.7200

34.5000

75.2200

53.3100

31.3900

26.6300

23.0600

56.6500

23.3400

54.4100

28.5800

45.2300

58.3800

8

1/12/2006

1.0962e+04

27.6800

69.0400

52.6000

67.9000

45.0200

60.1300

38.0200

25.4100

33.2500

19.7600

41.0500

35.7700

30.5700

81.6100

24.9600

59.6300

37.8700

39.5000

33.9600

74.5700

53.2300

31.4100

26.4800

22.9000

56.0200

23.2400

53.9000

28.6900

44.4300

57.7700

9

1/13/2006

1.0960e+04

27.8100

68.8400

52.5000

67.7000

44.9200

60.2400

37.8600

25.4700

33.3500

19.2000

40.4300

35.8500

31.4300

81.2200

24.7800

59.2600

37.8400

39.3700

33.6500

74.3800

53.2900

31.4000

26.5300

22.9900

56.4900

23.2700

54.1000

28.7500

44.1000

59.0600

10

1/17/2006

1.0896e+04

27.9700

67.8400

52.0300

66.9300

44.4700

60.8500

37.7500

25.1500

33.2000

18.6800

40.1100

35.5600

31.2000

81.0500

24.5200

58.7400

37.6400

39.1100

33.7700

73.9900

52.8500

31.1600

26.3400

22.6300

56.2500

23.1300

54.4100

28.1200

43.6600

59.6100

11

1/18/2006

1.0855e+04

27.8100

67.4200

51.8400

66.5800

44.4100

60.0400

37.5400

24.9700

33.0800

18.9800

40.4200

35.7100

31.2100

81.8300

21.7200

59.6100

37.2400

38.9100

34.1600

74.0700

52.8900

30.9900

26.1800

22.3600

56.5400

23.1100

54.0800

27.8300

43.8800

58.7800

12

1/19/2006

1.0881e+04

28.3300

66.9200

51.6600

66.4200

44.0200

60.6600

37.6900

26.0000

32.9500

19.1000

39.8300

35.8800

31.7700

81.1400

21.5300

59.6000

37.0300

39.0100

34.3600

73.8100

52.6800

31.2600

26.3600

23.2700

56.3900

23.1800

54.4100

28.0700

44.4900

59.5700

13

1/20/2006

1.0667e+04

27.6700

65.5500

50.4900

64.7900

41.9500

58.9800

37.3400

25.4900

31.7000

18.9000

38.7600

34.5700

31.2800

79.4500

20.9100

58.2800

36.0700

38.2100

35.0100

72.2100

52.1800

31.2000

25.7700

23.0300

55.7400

23.0100

53.4600

27.6400

43.7100

58.6300

14

1/23/2006

1.0689e+04

28.0300

65.4600

50.5300

65.3000

42.2400

59.2300

37.3700

25.2900

31.6300

20.6000

38.2900

34.7800

30.8800

79.5000

20.5200

58.6600

36.2800

38.6000

34.8600

72.6500

52.0900

30.8000

25.7100

23.1900

55.5500

22.7700

52.9400

27.6900

43.9500

59.2800

15

1/24/2006

1.0712e+04

28.1600

65.3900

51.8900

65.9200

42.2500

59.5300

37.0900

25.7600

31.3200

21.7300

39.0300

35.2500

30.9100

78.9500

20.4500

56.9000

36.1300

38.9800

35.0000

71.2100

51.7400

30.7600

25.6400

22.9100

55.7700

22.9600

54.8600

27.6000

44.4100

59.0500

16

1/25/2006

1.0710e+04

28.5700

64.6700

51.9700

65.1900

42.4500

60.2300

37.0500

25.2100

31.1300

22.4800

38.5700

34.7900

31.6400

79.0100

20.3800

56.0800

36.4800

39.2100

34.3200

70.0600

51.4900

31.1400

25.7600

23.1400

56.3500

23.4700

55.4000

28.0300

44.6500

58.3200

                                

Setup a portfolio of ten stocks.

symbol = T.Properties.VariableNames(3:12)';
dailyReturn = tick2ret(T{:,3:12});
p = Portfolio('AssetList',symbol,'RiskFreeRate',0.01/252);

Estimate the mean and variance of portfolio based on daily returns using estimateAssetMoments.

p = estimateAssetMoments(p,dailyReturn);

Set the total weight of portfolio to 1 where the LowerBudget = 1 and the UpperBudget = 1.

p = setBudget(p,1,1)
p = 
  Portfolio with properties:

                       BuyCost: []
                      SellCost: []
                  RiskFreeRate: 3.9683e-05
                     AssetMean: [10x1 double]
                    AssetCovar: [10x10 double]
                 TrackingError: []
                  TrackingPort: []
                      Turnover: []
                   BuyTurnover: []
                  SellTurnover: []
                          Name: []
                     NumAssets: 10
                     AssetList: {'AA'  'AIG'  'AXP'  'BA'  'C'  'CAT'  'DD'  'DIS'  'GE'  'GM'}
                      InitPort: []
                   AInequality: []
                   bInequality: []
                     AEquality: []
                     bEquality: []
                    LowerBound: []
                    UpperBound: []
                   LowerBudget: 1
                   UpperBudget: 1
                   GroupMatrix: []
                    LowerGroup: []
                    UpperGroup: []
                        GroupA: []
                        GroupB: []
                    LowerRatio: []
                    UpperRatio: []
                  MinNumAssets: []
                  MaxNumAssets: []
    ConditionalBudgetThreshold: []
        ConditionalUpperBudget: []
                     BoundType: []

Set the maximum allocation for any one security to 50%, and set the minimum for any one security to 5%.

p.LowerBound = repmat(0.05,[10,1]);
p.UpperBound = repmat(0.5,[10,1]);

Calculate the portfolio weights for the maximum Sharpe ratio using estimateMaxSharpeRatio.

w1 = estimateMaxSharpeRatio(p)
w1 = 10×1

    0.0500
    0.0500
    0.0500
    0.0500
    0.0500
    0.0500
    0.0500
    0.4357
    0.0500
    0.1643

Estimate moments of portfolio returns using estimatePortMoments.

[risk1, ret1] = estimatePortMoments(p,w1)
risk1 = 
0.0090
ret1 = 
0.0013

Calculate portfolio weights given a target return.

TargetReturn = 0.001
TargetReturn = 
1.0000e-03
TargetReturn = 1.0000e-03
TargetReturn = 
1.0000e-03

Use estimateFrontierByReturn to estimate optimal portfolios with targeted portfolio returns.

w2 = estimateFrontierByReturn(p,TargetReturn)
w2 = 10×1

    0.0500
    0.0500
    0.0500
    0.0500
    0.1668
    0.0500
    0.0870
    0.2949
    0.1105
    0.0908

Estimate moments of portfolio returns using estimatePortMoments, where risk2 is estimates for standard deviations of portfolio returns for each portfolio and ret2 is estimates for means of portfolio returns for each portfolio.

[risk2,ret2] = estimatePortMoments(p,w2)
risk2 = 
0.0076
ret2 = 
1.0000e-03

When any one, or any combination of the constraints from 'Conditional' BoundType, MinNumAssets, and MaxNumAssets are active, the portfolio problem is formulated as mixed integer programming problem and the MINLP solver is used.

Create a Portfolio object for 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);
p = setDefaultConstraints(p);           

Use setBounds with semicontinuous constraints to set xi = 0 or 0.02 <= xi <= 0.5 for all i = 1,...NumAssets.

p = setBounds(p, 0.02, 0.7,'BoundType', 'Conditional', 'NumAssets', 3);                    

When working with a Portfolio object, the setMinMaxNumAssets function enables you to set up the limits on the number of assets invested (as known as cardinality) constraints. This sets the total number of allocated assets satisfying the Bound constraints that are between MinNumAssets and MaxNumAssets. By setting MinNumAssets = MaxNumAssets = 2, only two of the three assets are invested in the portfolio.

p = setMinMaxNumAssets(p, 2, 2);  

Use estimateFrontierByReturn to estimate optimal portfolios with targeted portfolio returns.

[pwgt, pbuy, psell] = estimateFrontierByReturn(p,[ 0.0072321, 0.0119084 ])
pwgt = 3×2

         0    0.5000
    0.6922         0
    0.3078    0.5000

pbuy = 3×2

         0    0.5000
    0.6922         0
    0.3078    0.5000

psell = 3×2

     0     0
     0     0
     0     0

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

p.solverTypeMINLP
ans = 
'OuterApproximation'
p.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
                     ExtendedFormulation: 0
                            NumInnerCuts: 10
                     NumInitialOuterCuts: 10

To obtain efficient portfolios that have targeted portfolio returns, the estimateFrontierByReturn function accepts one or more target portfolio returns and obtains efficient portfolios with the specified returns. Assume you have a universe of four assets where you want to obtain efficient portfolios with target portfolio returns of 7%, 10%, and 13%.

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

rng(11);

p = PortfolioCVaR;
p = simulateNormalScenariosByMoments(p, m, C, 2000);
p = setDefaultConstraints(p);
p = setProbabilityLevel(p, 0.95);

pwgt = estimateFrontierByReturn(p, [0.07 0.10, 0.13]);

display(pwgt);
pwgt = 4×3

    0.7371    0.3072         0
    0.1504    0.3919    0.4396
    0.0286    0.1011    0.1360
    0.0839    0.1999    0.4244

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

To obtain efficient portfolios that have targeted portfolio returns, the estimateFrontierByReturn function accepts one or more target portfolio returns and obtains efficient portfolios with the specified returns. Assume you have a universe of four assets where you want to obtain efficient portfolios with target portfolio returns of 7%, 10%, and 13%.

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

rng(11);

p = PortfolioMAD;
p = simulateNormalScenariosByMoments(p, m, C, 2000);
p = setDefaultConstraints(p);

pwgt = estimateFrontierByReturn(p, [0.07 0.10, 0.13]);

display(pwgt);
pwgt = 4×3

    0.7436    0.3151         0
    0.1357    0.3829    0.4425
    0.0326    0.0936    0.1319
    0.0880    0.2083    0.4255

The function rng(seed) is used to reset 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

Target values for portfolio return, specified as a NumPorts vector.

Note

TargetReturn specifies target returns for portfolios on the efficient frontier. If any TargetReturn values are outside the range of returns for efficient portfolios, the TargetReturn is replaced with the minimum or maximum efficient portfolio return, depending upon whether the target return is below or above the range of efficient portfolio returns.

Data Types: double

Output Arguments

collapse all

Optimal portfolios on the efficient frontier with specified target returns from TargetReturn, 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 optimal portfolios with targeted portfolio returns.

[pwgt, pbuy, psell] = obj.estimateFrontierByReturn(TargetReturn);

Version History

Introduced in R2011a