Main Content

setBounds

Set up bounds for portfolio weights for portfolio

Description

obj = setBounds(obj,LowerBound) sets up bounds for portfolio weights for a Portfolio, PortfolioCVaR, or PortfolioMAD object. For details on the respective workflows when using these different objects, see Portfolio Object Workflow, PortfolioCVaR Object Workflow, and PortfolioMAD Object Workflow.

example

obj = setBounds(___,Name,Value) specifies options using one or more name-value pair arguments in addition to the input arguments in the previous syntax, including BoundType as 'Simple' or 'Conditional'.

example

obj = setBounds(obj,LowerBound,UpperBound) sets up bounds for portfolio weights for portfolio objects with an additional option for UpperBound.

Given bound constraints LowerBound and UpperBound and 'Simple' BoundType, every weight in a portfolio Port must satisfy the following:

LowerBound <= Port <= UpperBound

Given bound constraints LowerBound and UpperBound, and 'Conditional' BoundType, every weight in a portfolio Port must satisfy the following:

Port = 0 or LowerBound <= Port <= UpperBound

example

obj = setBounds(___,Name,Value) specifies options using one or more name-value pair arguments in addition to the input arguments in the previous syntax, including BoundType as 'Simple' or 'Conditional'.

example

Examples

collapse all

Suppose you have a balanced fund with stocks that can range from 50% to 75% of your portfolio and bonds that can range from 25% to 50% of your portfolio. Use setBounds to set the bound constraints for a balanced fund. Note that this sets default 'Simple' BoundType, which enforces 0.5<=x1<=0.75, 0.25<=x2<=0.5.

lb = [ 0.5; 0.25 ];
ub = [ 0.75; 0.5 ];

p = Portfolio;
p = setBounds(p, lb, ub);
disp(p.NumAssets);
     2
disp(p.LowerBound);
    0.5000
    0.2500
disp(p.UpperBound);
    0.7500
    0.5000

Suppose you have the mean and covariance of the asset returns for a three asset portfolio:

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

The following uses setBounds with 'Conditional' BoundType (semicontinuous) constraints to set xi = 0 or 0.02 <= xi <= 0.5 for all i = 1,...NumAssets.

p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar);
p = setBounds(p, 0.02, 0.5,'BoundType', 'Conditional', 'NumAssets', 3)   
p = 
  Portfolio with properties:

                       BuyCost: []
                      SellCost: []
                  RiskFreeRate: []
                     AssetMean: [3x1 double]
                    AssetCovar: [3x3 double]
                 TrackingError: []
                  TrackingPort: []
                      Turnover: []
                   BuyTurnover: []
                  SellTurnover: []
                          Name: []
                     NumAssets: 3
                     AssetList: []
                      InitPort: []
                   AInequality: []
                   bInequality: []
                     AEquality: []
                     bEquality: []
                    LowerBound: [3x1 double]
                    UpperBound: [3x1 double]
                   LowerBudget: []
                   UpperBudget: []
                   GroupMatrix: []
                    LowerGroup: []
                    UpperGroup: []
                        GroupA: []
                        GroupB: []
                    LowerRatio: []
                    UpperRatio: []
                  MinNumAssets: []
                  MaxNumAssets: []
    ConditionalBudgetThreshold: []
        ConditionalUpperBudget: []
                     BoundType: [3x1 categorical]

disp(p.LowerBound);
    0.0200
    0.0200
    0.0200
disp(p.UpperBound);
    0.5000
    0.5000
    0.5000
disp(p.BoundType);
     conditional 
     conditional 
     conditional 

Suppose you have the mean and covariance of the asset returns for a three asset portfolio:

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

The following uses setBounds with both 'Simple' and 'Conditional' BoundType constraints for all i = 1,...NumAssets.

p = Portfolio('AssetMean', AssetMean, 'AssetCovar', AssetCovar);
p = setBounds(p, 0.1, 0.5, 'BoundType',["simple"; "conditional"; "conditional"])
p = 
  Portfolio with properties:

                       BuyCost: []
                      SellCost: []
                  RiskFreeRate: []
                     AssetMean: [3x1 double]
                    AssetCovar: [3x3 double]
                 TrackingError: []
                  TrackingPort: []
                      Turnover: []
                   BuyTurnover: []
                  SellTurnover: []
                          Name: []
                     NumAssets: 3
                     AssetList: []
                      InitPort: []
                   AInequality: []
                   bInequality: []
                     AEquality: []
                     bEquality: []
                    LowerBound: [3x1 double]
                    UpperBound: [3x1 double]
                   LowerBudget: []
                   UpperBudget: []
                   GroupMatrix: []
                    LowerGroup: []
                    UpperGroup: []
                        GroupA: []
                        GroupB: []
                    LowerRatio: []
                    UpperRatio: []
                  MinNumAssets: []
                  MaxNumAssets: []
    ConditionalBudgetThreshold: []
        ConditionalUpperBudget: []
                     BoundType: [3x1 categorical]

disp(p.LowerBound);
    0.1000
    0.1000
    0.1000
disp(p.UpperBound);
    0.5000
    0.5000
    0.5000
disp(p.BoundType);
     simple 
     conditional 
     conditional 

You can use supply lower and upper bounds as vectors, which defines different values for each asset. The following have -0.8 <= x1 <= 0.2; x2 = 0 or 0.1 <= x2 <= 0.5; x3 = 0 or 0.1 <= x3 <=0.5. Note that as 'Simple' BoundType, the assets can be held as short or long positions. However, when using 'Conditional' BoundType, the assets can only be long positions.

p = setBounds(p, [-0.8, 0.1, 0.1], [-0.2,0.5,0.5], 'BoundType',["simple"; "conditional"; "conditional"]);
disp(p.LowerBound);
   -0.8000
    0.1000
    0.1000
disp(p.UpperBound);
   -0.2000
    0.5000
    0.5000
disp(p.BoundType);
     simple 
     conditional 
     conditional 

Set the minimum cardinality constraint for a three-asset portfolio for which you have the mean and covariance values of the asset returns.

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

When working with a Portfolio object, the setMinMaxNumAssets function enables you to set up limits on the number of assets invested. These limits are also known as cardinality constraints. When managing a portfolio, it is common that you want to invest in at least a certain number of assets. In addition, you should also clearly define the weight requirement for each invested asset. You can do this using setBounds with a 'Conditional' BoundType. If you do not specify a 'Conditional' BoundType, the optimizer cannot understand which assets are invested assets and cannot formulate the MinNumAssets constraint.

The following example specifies that at least two assets should be invested and the investments should be greater than 16%.

p = setMinMaxNumAssets(p, 2, []);  
p = setBounds(p, 0.16, 'BoundType', 'conditional');

Use estimateFrontierByReturn to estimate optimal portfolios with targeted portfolio returns.

pwgt = estimateFrontierByReturn(p,[ 0.008, 0.01 ])
pwgt = 3×2

    0.2861    0.3967
    0.5001    0.2437
    0.2138    0.3595

Suppose you have a balanced fund with stocks that can range from 50% to 75% of your portfolio and bonds that can range from 25% to 50% of your portfolio. To set the bound constraints for a balanced fund.

lb = [ 0.5; 0.25 ];
ub = [ 0.75; 0.5 ];

p = PortfolioCVaR;
p = setBounds(p, lb, ub);
disp(p.NumAssets);
     2
disp(p.LowerBound);
    0.5000
    0.2500
disp(p.UpperBound);
    0.7500
    0.5000

Suppose you have a balanced fund with stocks that can range from 50% to 75% of your portfolio and bonds that can range from 25% to 50% of your portfolio. To set the bound constraints for a balanced fund with semicontinuous constraints, use setBounds with 'Conditional' BoundType constraints to set xi = 0.25 or 0.5 <= xi <= 0.5 or 0.75 for all i = 1,...NumAssets.

lb = [ 0.5; 0.25 ];
ub = [ 0.75; 0.5 ];

p = PortfolioCVaR;
p = setBounds(p,lb,ub,'BoundType',["conditional"; "conditional"]);
disp(p.NumAssets);
     2
disp(p.LowerBound);
    0.5000
    0.2500
disp(p.UpperBound);
    0.7500
    0.5000

Suppose you have a balanced fund with stocks that can range from 50% to 75% of your portfolio and bonds that can range from 25% to 50% of your portfolio. To set the bound constraints for a balanced fund.

lb = [ 0.5; 0.25 ];
ub = [ 0.75; 0.5 ];

p = PortfolioMAD;
p = setBounds(p, lb, ub);
disp(p.NumAssets);
     2
disp(p.LowerBound);
    0.5000
    0.2500
disp(p.UpperBound);
    0.7500
    0.5000

Suppose you have a balanced fund with stocks that can range from 50% to 75% of your portfolio and bonds that can range from 25% to 50% of your portfolio. To set the bound constraints for a balanced fund with semicontinuous constraints, use setBounds with 'Conditional' BoundType constraints to set xi = 0.25 or 0.5 <= xi <= 0.5 or 0.75 for all i = 1,...NumAssets.

lb = [ 0.5; 0.25 ];
ub = [ 0.75; 0.5 ];

p = PortfolioMAD;
p = setBounds(p,lb,ub,'BoundType',["conditional"; "conditional"]);
disp(p.NumAssets);
     2
disp(p.LowerBound);
    0.5000
    0.2500
disp(p.UpperBound);
    0.7500
    0.5000

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

Lower-bound weight for each asset, specified as a scalar or vector for a Portfolio, PortfolioCVaR, or PortfolioMAD input object (obj).

Note

  • If either LowerBound or UpperBound are input as empties with [], the corresponding attributes in the Portfolio, PortfolioCVaR, or PortfolioMAD object are cleared and set to [].

  • If LowerBound or UpperBound are specified as scalars and NumAssets exists or can be computed, then they undergo scalar expansion. The default value for NumAssets is 1.

  • If both LowerBound and UpperBound exist and they are not ordered correctly, the setBounds function switches bounds if necessary.

  • If 'Conditional'BoundType is specified, the LowerBound cannot be a negative value.

Data Types: double

(Optional) Upper-bound weight for each asset, specified as a scalar or vector for a Portfolio, PortfolioCVaR, or PortfolioMAD input object (obj).

Note

  • If either LowerBound or UpperBound are input as empties with [], the corresponding attributes in the Portfolio, PortfolioCVaR, or PortfolioMAD object are cleared and set to [].

  • If LowerBound or UpperBound are specified as scalars and NumAssets exists or can be computed, then they undergo scalar expansion. The default value for NumAssets is 1.

  • If both LowerBound and UpperBound exist and they are not ordered correctly, the setBounds function switches bounds if necessary.

  • If 'Conditional'BoundType is specified, the UpperBound cannot be a negative value.

Data Types: double

Name-Value Arguments

Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

Before R2021a, use commas to separate each name and value, and enclose Name in quotes.

Example: obj = setBounds(p,0.02,'BoundType','Conditional');

Type of bounds for each asset weight, specified as the comma-separated pair consisting of 'BoundType' and a scalar character vector or string with a value of 'Simple' or 'Conditional' or a cell array of character vectors with values of 'Simple' or 'Conditional'.

  • 'Simple' is LowerBound <= AssetWeight <= UpperBound

  • 'Conditional' is LowerBound <= AssetWeight <= UpperBound or AssetWeight = 0.

    Warning

    If you specify the Bound range to be inclusive of zero (using either a ‘Simple’ or ‘Conditional’ BoundType), when you use setMinMaxNumAssets to specify the MinNumAssets constraint, and then use one of the estimate functions, it is ambiguous for the optimizer to define the minimum requirement for an allocated asset. In this case, the optimizer considers that an asset with zero weight is a valid allocated asset and the optimization proceeds, but with the warning that the allocation has less than the MinNumAssets required. For more information, see Troubleshooting for Setting 'Conditional' BoundType, MinNumAssets, and MaxNumAssets Constraints.

Data Types: char | cell | string

Number of assets in portfolio, specified as the comma-separated pair consisting of 'NumAssets' and a scalar numeric value.

Note

NumAssets cannot be used to change the dimension of a Portfolio, PortfolioCVaR, or PortfolioMAD object.

  • If either LowerBound or UpperBound are input as empties with [], the corresponding attributes in the Portfolio, PortfolioCVaR, or PortfolioMAD object are cleared and set to [].

  • If LowerBound or UpperBound are specified as scalars and NumAssets exists or can be imputed, then they undergo scalar expansion. The default value for NumAssets is 1.

  • If both LowerBound and UpperBound exist and they are not ordered correctly, the setBounds function switches bounds if necessary.

Data Types: double

Output Arguments

collapse all

Updated portfolio object, returned as a Portfolio, PortfolioCVaR, or PortfolioMAD object.

Tips

You can also use dot notation to set up the bounds for portfolio weights.

 obj = obj.setBounds(LowerBound, UpperBound, Name,Value);

If any of LowerBound, UpperBound, or BoundType are input as empties with [ ], the corresponding attributes in the portfolio object are cleared and set to [ ]. If BoundType is cleared as [ ], the bound type defaults to 'Simple'.

 p = setBounds(p, LowerBound, [ ], 'BoundType',[ ]);

To reset a portfolio object to be a continuous problem, run the following:

p = setMinMaxNumAssets(p, [],[]);
p = setBounds(p, p.LowerBound, p.UpperBound, 'BoundType', 'Simple');

Version History

Introduced in R2011a