estimateMaxSharpeRatio

Estimate efficient portfolio to maximize Sharpe ratio for Portfolio object

Description

example

[pwgt,pbuy,psell] = estimateMaxSharpeRatio(obj) estimates efficient portfolio to maximize Sharpe ratio for Portfolio object. For details on the workflow, see Portfolio Object Workflow.

example

[pwgt,pbuy,psell] = estimateMaxSharpeRatio(___,Name,Value) adds optional name-value pair arguments.

Examples

collapse all

Estimate the efficient portfolio that maximizes the Sharpe ratio. The estimateMaxSharpeRatio function maximizes the Sharpe ratio among portfolios on the efficient frontier. This example uses the default 'direct' method to estimate the maximum Sharpe ratio. For more information on the 'direct' method, see Algorithms.

p = Portfolio('AssetMean',[0.3, 0.1, 0.5], 'AssetCovar',...
[0.01, -0.010,  0.004; -0.010,  0.040, -0.002;  0.004, -0.002,  0.023]);
p = setDefaultConstraints(p);
plotFrontier(p, 20);
weights = estimateMaxSharpeRatio(p);
[risk, ret] = estimatePortMoments(p, weights);
hold on
plot(risk,ret,'*r');

Estimate the efficient portfolio that maximizes the Sharpe ratio. The estimateMaxSharpeRatio function maximizes the Sharpe ratio among portfolios on the efficient frontier. This example uses the 'direct' method for a Portfolio object (p) that does not specify a tracking error and only uses linear constraints. The setSolver function is used to control the SolverType and SolverOptions. In this case, the SolverType is quadprog. For more information on the 'direct' method, see Algorithms.

p = Portfolio('AssetMean',[0.3, 0.1, 0.5], 'AssetCovar',...
[0.01, -0.010,  0.004; -0.010,  0.040, -0.002;  0.004, -0.002,  0.023]);
p = setDefaultConstraints(p);
plotFrontier(p, 20);
p = setSolver(p,'quadprog','Display','off','ConstraintTolerance',1.0e-8,'OptimalityTolerance',1.0e-8,'StepTolerance',1.0e-8,'MaxIterations',10000); 
weights = estimateMaxSharpeRatio(p); 
[risk, ret] = estimatePortMoments(p, weights);
hold on
plot(risk,ret,'*r');

Estimate the efficient portfolio that maximizes the Sharpe ratio. The estimateMaxSharpeRatio function maximizes the Sharpe ratio among portfolios on the efficient frontier. This example uses the 'direct' method for a Portfolio object (p) that specifies a tracking error uses nonlinear constraints. The setSolver function is used to control the SolverType and SolverOptions. In this case fmincon is the SolverType.

p = Portfolio('AssetMean',[0.3, 0.1, 0.5], 'AssetCovar',...
[0.01, -0.010,  0.004; -0.010,  0.040, -0.002;  0.004, -0.002,  0.023],'lb', 0,'budget', 1);
plotFrontier(p, 20);

p = setSolver(p, 'fmincon', 'Display', 'off', 'Algorithm', 'sqp', ...
        'SpecifyObjectiveGradient', true, 'SpecifyConstraintGradient', true, ...
        'ConstraintTolerance', 1.0e-8, 'OptimalityTolerance', 1.0e-8, 'StepTolerance', 1.0e-8); 

weights = estimateMaxSharpeRatio(p);        

te = 0.08;
p = setTrackingError(p,te,weights);

[risk, ret] = estimatePortMoments(p,weights);
hold on
plot(risk,ret,'*r');

The estimateMaxSharpeRatio function maximizes the Sharpe ratio among portfolios on the efficient frontier. In the case of Portfolio with a risk-free asset, there are multiple efficient portfolios that maximize the Sharpe ratio on the capital asset line. Because of the nature of 'direct' and 'iterative' methods, the portfolio weights (pwgts) output from each of these methods might be different, but the Sharpe ratio is the same. This example demonstrates the scenario where the pwgts are different and the Sharpe ratio is the same.

load BlueChipStockMoments

mret = MarketMean;
mrsk = sqrt(MarketVar);
cret = CashMean;
crsk = sqrt(CashVar);

p = Portfolio('AssetList', AssetList, 'RiskFreeRate', CashMean);
p = setAssetMoments(p, AssetMean, AssetCovar);

p = setInitPort(p, 1/p.NumAssets);
[ersk, eret] = estimatePortMoments(p, p.InitPort);

p = setDefaultConstraints(p);
pwgt = estimateFrontier(p, 20);
[prsk, pret] = estimatePortMoments(p, pwgt);
pwgtshpr_fully = estimateMaxSharpeRatio(p,'Method','direct');
[riskshpr_fully, retshpr_fully] = estimatePortMoments(p,pwgtshpr_fully);

q = setBudget(p, 0, 1);
qwgt = estimateFrontier(q, 20);
[qrsk, qret] = estimatePortMoments(q, qwgt);

Plot the efficient frontier with a tangent line (0 to 1 cash).

pwgtshpr_direct = estimateMaxSharpeRatio(q,'Method','direct');
pwgtshpr_iter = estimateMaxSharpeRatio(q,'Method','iterative');
[riskshpr_diret, retshpr_diret] = estimatePortMoments(q,pwgtshpr_direct);
[riskshpr_iter, retshpr_iter] = estimatePortMoments(q,pwgtshpr_iter);

clf;
portfolioexamples_plot('Efficient Frontier with Capital Allocation Line', ...
                {'line', prsk, pret, {'EF'}, '-r', 2}, ...
                {'line', qrsk, qret, {'EF with riskfree'}, '-b', 1}, ...
                {'scatter', [mrsk, crsk, ersk, riskshpr_fully, riskshpr_diret, riskshpr_iter], ...
    [mret, cret, eret, retshpr_fully , retshpr_diret, retshpr_iter], {'Market', 'Cash', 'Equal','Sharpe fully invest', 'Sharpe diret','Sharpe iter'}}, ...
                {'scatter', sqrt(diag(p.AssetCovar)), p.AssetMean, p.AssetList, '.r'});  

When a risk-free asset is not available to the portfolio, or in other words, the portfolio is fully invested, the efficient frontier is curved, corresponding to the red line in the above figure. Therefore, there is a unique (risk, return) point that maximizes the Sharpe ratio, which the 'iterative' and 'direct' methods will both find. If the portfolio is allowed to invest in a risk-free asset, part of the red efficient frontier line is replaced by the capital allocation line, resulting in the efficient frontier of a portfolio with a risk-free investment (blue line). All the (risk, return) points on the straight blue line share the same Sharpe ratio. Also, it is likely that the 'iterative' and 'direct' methods end up with different points, therefore there are different portfolio allocations.

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.5,'BoundType', 'Conditional', 'NumAssets', 3);                    

When working with a Portfolio object, the setMinMaxNumAssets function enables you to set up cardinality constraints for a long-only portfolio. This sets the cardinality constraints for the Portfolio object, where the total number of allocated assets satisfying the nonzero semi-continuous constraints 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 estimateMaxSharpeRatio to estimate efficient portfolio to maximize Sharpe ratio.

weights = estimateMaxSharpeRatio(p,'Method','iterative')
weights = 3×1

    0.0000
    0.5000
    0.5000

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

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
                  IntMasterSolverOptions: [1x1 optim.options.Intlinprog]
    NumIterationsEarlyIntegerConvergence: 30

Input Arguments

collapse all

Object for portfolio, specified using a Portfolio object.

Note

The risk-free rate is obtained from the property RiskFreeRate in the Portfolio object. If you leave the RiskFreeRate unset, it is assumed to be 0. If the max return of portfolio is less than the RiskFreeRate, the solution is set as pwgt at max return and the resulting Sharpe ratio will be negative.

For more information on creating a portfolio object, see

Data Types: object

Name-Value Pair Arguments

Specify optional comma-separated pairs of Name,Value arguments. Name is the argument name and Value is the corresponding value. Name must appear inside quotes. You can specify several name and value pair arguments in any order as Name1,Value1,...,NameN,ValueN.

Example: [pwgt,pbuy,psell] = estimateMaxSharpeRatio(p,'Method’,'iterative')

Method to estimate Sharpe ratio, specified as the comma-separated pair consisting of 'Method' and a character vector with one of the following values:

Note

If you are using estimateMaxSharpeRatio with a Portfolio object with semicontinuous and cardinality constraints specified by setBounds and setMinMaxNumAssets, you can only use the 'iterative' method.

Data Types: char

Output Arguments

collapse all

Portfolio on the efficient frontier with a maximum Sharpe ratio, returned as a NumAssets vector.

Purchases relative to an initial portfolio for a portfolio on the efficient frontier with a maximum Sharpe ratio, returned as a NumAssets vector.

pbuy is returned for a Portfolio input object (obj).

Sales relative to an initial portfolio for a portfolio on the efficient frontier with maximum Sharpe ratio, returned as a NumAssets vector.

psell is returned for a Portfolio input object (obj).

More About

collapse all

Sharpe Ratio

The Sharpe ratio is the ratio of the difference between the mean of portfolio returns and the risk-free rate divided by the standard deviation of portfolio returns.

The estimateMaxSharpeRation function maximizes the Sharpe ratio among portfolios on the efficient frontier.

Tips

You can also use dot notation to estimate an efficient portfolio that maximizes the Sharpe ratio.

[pwgt,pbuy,psell] = obj.estimateMaxSharpeRatio;

Algorithms

The maximization of the Sharpe ratio is accomplished by either using the 'direct' or 'iterative' method. For the 'direct' method, consider the following scenario. To maximize the Sharpe ratio is to:

MaximizeμTxrfxTCx,s.t.xi=1,  0xi1,

where μ and C are the mean and covariance matrix, and rf is the risk-free rate.

If μT x - rf ≤ 0 for all x the portfolio that maximizes the Sharpe ratio is the one with maximum return.

If μT x - rf > 0, let t=1μTxrf

and y = tx (Cornuejols [1] section 8.2). Then after some substitutions, we can transform the original problem into the following form,

Minimize yTCy, s.t. yi=t, t>0, 0yit , μTyrft=1. 

Only one optimization needs to be solved, hence the name “direct”. The portfolio weights can be recovered by x* = y* / t*.

For the 'iterative' method, the idea is to iteratively explore the portfolios at different return levels on the efficient frontier and locate the one with maximum Sharpe ratio. Therefore, multiple optimization problems are solved during the process, instead of only one in the 'direct' method. Consequently, the 'iterative' method is slow compared to 'direct' method.

References

[1] Cornuejols, G. and Reha Tütüncü. Optimization Methods in Finance. Cambridge University Press, 2007.

Introduced in R2011b