Solve Problem for Minimum Variance Portfolio with Tracking Error Penalty
This example shows how to compute a portfolio that minimizes the tracking error subject to a benchmark portfolio. This example uses estimateCustomObjectivePortfolio
to solve a problem for a minimum variance Portfolio
with a tracking error penalty. The example also shows how to add the tracking error as a "soft constraint" to any portfolio optimization problem. The tracking error measures the standard deviation of the divergence between a portfolio's return and that of a benchmark.
Define the mean and covariance of the assets returns.
% Define assets mean. mu = [ 0.05; 0.1; 0.12; 0.18 ]; % Define assets covariance. Sigma = [ 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 ];
Simulate a timeseries of assets returns with mean mu
and covariance Sigma
. From this point onward, assume that the true mean and covariance are not known and they can only be estimated from the timetable data.
% Find all business days of the last two years. tEnd = datetime('today'); bdates = busdays(tEnd-calyears(2),tEnd); % Create a simulated timetable. rng('default') nScen = size(bdates,1); assetsTT = array2timetable(mvnrnd(mu,Sigma,nScen),RowTimes=bdates);
Define a long-only, fully invested portfolio problem using Portfolio
.
% Define a Portfolio object. p = Portfolio; p = estimateAssetMoments(p,assetsTT); % Specify constraints for a long-only, fully invested portfolio. p = setDefaultConstraints(p);
Assume that there is a market index that follows the maximum Sharpe ratio portfolio. Use estimateMaxSharpeRatio
to create the benchmark portfolio.
% Create the benchmark portfolio. bmkPort = estimateMaxSharpeRatio(p); % Create the benchmark returns timetable. marketTT = timetable(assetsTT.Time,assetsTT.Variables*bmkPort, ... VariableNames={'Benchmark'});
Minimize Tracking Error
You can use two methods to obtain the tracking error. The first method uses the variance of the excess return of the portfolio with respect to the benchmark. This method assumes that the benchmark prices or returns are given, but does not require knowledge of the weights of the assets associated to the benchmark. The second method requires you to decompose the benchmark into the different weights for each asset.
Tracking Error Using Benchmark Returns
To compute the tracking error, you first need to compute the excess return of each asset with respect to the benchmark.
% Compute the excess return.
excessReturn = assetsTT.Variables-marketTT.Variables;
Then, you can compute the excess returns covariance matrix .
excessRetSigma = cov(excessReturn);
Compute the tracking error as the variance of the excess return of the portfolio
For this example, you want to find the portfolio that minimizes the tracking error to the benchmark with, at most, half of the assets in the universe. Furthermore, if an asset is selected in the portfolio, at least 10% must be invested in that asset. This problem is as follows:
To solve this problem, first add the constraints to the Portfolio
object using the setBudget
, setMinMaxNumAssets
, and setBounds
functions.
% Specify that the budget sums to one constraint. p = setBudget(p,1,1); % Specify the maximum number of assets as 15. p = setMinMaxNumAssets(p,[],2); % Specify the conditional bounds. p = setBounds(p,0.1,[],BoundType="conditional");
Define a function handle for the objective function .
% Define the objective function.
TEsquared1 = @(x) x'*excessRetSigma*x;
Use estimateCustomObjectivePortfolio
to compute the solution to the problem.
% Solve the porfolio problem.
wMinTE1 = estimateCustomObjectivePortfolio(p,TEsquared1)
wMinTE1 = 4×1
0.8405
0
0.0000
0.1595
Tracking Error Using Benchmark Weights
You can also define the tracking error as
In this formulation, is the covariance matrix of the assets returns (not the excess returns) and this example assumes that the weight vector of the benchmark portfolio is known. Using the same constraints as the Tracking Error Using the Benchmark Returns method, the problem is as follows:
Since the constraints are the same, you need only to define a new objective function.
% Define the objective function.
TESquared2 = @(x) (x-bmkPort)'*p.AssetCovar*(x-bmkPort);
Use estimateCustomObjectivePortfolio
to compute the solution to the problem.
% Solve the porfolio problem.
wMinTE2 = estimateCustomObjectivePortfolio(p,TESquared2)
wMinTE2 = 4×1
0.8405
0
0.0000
0.1595
The difference in the allocation for the different methods is negligible within a numerical accuracy. This means that the solution to both problems is the same.
norm(wMinTE1-wMinTE2,"inf")
ans = 1.1796e-16
Add Tracking Error Constraints
When you have a portfolio problem with cardinality constraints or conditional bounds and you use an objective function that is different than the return or variance for a mixed-integer problem, this portfolio problem does not support tracking error constraints. One option for including a tracking error constraint with a mixed-integer problem is to add the tracking error as a penalty to the objective function. In this case, the tracking error becomes a soft constraint and the strength of the constraint is controlled with the penalty parameter . The larger is, the stronger the tracking error constraint becomes, and conversely, the smaller is, the weaker the tracking error constraint becomes.
Assume that you are interested in obtaining the portfolio closest to the equally weighted portfolio (EWP) such that the tracking error is smaller than 5.3%. Minimizing the Herfindahl-Hirschman (HH) index, given by , returns the portfolio closest to the EWP that satisfies the necessary constraints. Assuming that the portfolio must satisfy the same constraints as in Minimizing Tracking Error, the problem is as follows:
Define the penalized objective function. In this case, you can use the minimum tracking error portfolio as the benchmark portfolio.
% Define the objective function. lambda =100; penalizedObjFun = @(x) x'*x + ... lambda*(x-bmkPort)'*p.AssetCovar*(x-bmkPort);
Use estimateCustomObjectivePortfolio
to solve problem.
% Solve the penalized problem.
wEWPwithTE = estimateCustomObjectivePortfolio(p,penalizedObjFun)
wEWPwithTE = 4×1
0.7028
0
0.2972
-0.0000
Check if the tracking error satisfies the constraint. If it does not, make larger.
% Check if tracking error is smaller than 5.3%.
sqrt(TESquared2(wEWPwithTE)) <= 0.053
ans = logical
1
Compare the different portfolio allocations.
% Compare the weights of the different portfolios. pwgt = table(wEWPwithTE,wMinTE1,bmkPort, ... VariableNames={'EWPwithTE','MinTE','Benchmark'})
pwgt=4×3 table
EWPwithTE MinTE Benchmark
___________ __________ _________
0.70281 0.84052 0.64257
0 0 0.13245
0.29719 2.6368e-16 0.1138
-5.5511e-17 0.15948 0.11118
When you compare the weights of the portfolio that minimizes the HH index with the tracking error penalty against the weights of the portfolio that minimizes the tracking error, you can see:
As , the weights of the penalized problem become exactly 0.5 in two assets. This happens because a portfolio with 0.5 weights in two assets is the one that is closest to the EW portfolio and satisfies the constraints.
As , the weights of the penalized problem come closer to the weights of the minimum tracking error problem. This result happens because the penalized term in the objective overcomes the HH index.
Selecting different values of modifies the strength of the tracking error constraint.
See Also
estimatePortSharpeRatio
| estimateFrontier
| estimateFrontierByReturn
| estimateFrontierByRisk
| estimateCustomObjectivePortfolio
Related Examples
- Diversify Portfolios Using Custom Objective
- Portfolio Optimization Using Social Performance Measure
- Diversify Portfolios Using Custom Objective
- Portfolio Optimization Against a Benchmark
- Risk Parity or Budgeting with Constraints
- Solve Robust Portfolio Maximum Return Problem with Ellipsoidal Uncertainty
- Solve Problem for Minimum Tracking Error with Net Return Constraint