Main Content

Solve Tracking Error Portfolio Problems

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 the assets mean.
mu = [ 0.05; 0.1; 0.12; 0.18 ];
% Define the 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);
plotFrontier(p);

Figure contains an axes object. The axes object with title Efficient Frontier, xlabel Standard Deviation of Portfolio Returns, ylabel Mean of Portfolio Returns contains an object of type line. This object represents Efficient Frontier.

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.8317
         0
    0.0000
    0.1683

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.8317
         0
         0
    0.1683

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.2204e-16

Add Tracking Error as Soft Constraint

When you want to find a portfolio that focuses on two different objectives, you can define one of those objectives as a soft constraint and adding that objective as a penalty to the objective function. In this example, 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) while controlling its tracking error. 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 tracking error penalized objective function using the max Sharpe ratio portfolio as the benchmark.

% 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.7856
         0
         0
    0.2144

Check the size of the tracking error. If the tracking error is too big, make λ larger.

% Check size of tracking error.
sqrt(TESquared2(wEWPwithTE))
ans = 
0.0388

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.78558        0.83165     0.64102 
           0              0     0.15599 
           0     1.6653e-16    0.067687 
     0.21442        0.16835     0.13531 

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

| | | |

Topics