Main Content

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 ΣRˆ.

excessRetSigma = cov(excessReturn);

Compute the tracking error as the variance of the excess return of the portfolio

xTΣRˆx.

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:

minx  xTΣRˆxs.t.ixi=1,         i#(xi0)2,         x=0orx0.1

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 xTΣRˆx.

% 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.0000
         0
    0.1595

Tracking Error Using Benchmark Weights

You can also define the tracking error as

(x-x0)TΣ(x-x0).

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:

minx  (x-x0)TΣ(x-x0)s.t.ixi=1,         i#(xi0)2,         x=0orx0.01

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 = 2.2898e-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 λ0. 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 xTx, 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:

minx  xTx+λ(x-x0)TΣ(x-x0)s.t.ixi=1,         i#(xi0)2,         x=0orx0.01

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

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     8.3267e-17     0.13245 
     0.29719              0      0.1138 
           0        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 λ0, 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 λ0 modifies the strength of the tracking error constraint.

See Also

| | | |

Related Examples

More About