Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Modern Portfolio Theory

In 1952, Harry Markowitz introduced the concept of Modern Portfolio Theory through his doctoral
thesis, commonly referred to as the Markowitz model. This theory is based on the idea that investors
aim to maximize a portfolio' s expected return while considering a certain level of risk. Efficient
portfolios, which meet this criterion, are those where achieving a higher expected return necessitates
taking on more risk. As a result, investors must strike a balance between risk and expected return. The
relationship between risk and expected return for efficient portfolios is illustrated by the efficient
frontier, a graph that displays this trade - off. All efficient portfolios, represented as points on the
efficient frontier, are diversified to minimize risk. In this chapter we review some of the core concepts of
MTP and illustrate how to approach the portfolio optimization problem in the Wolfram Language.

Portfolio Construction
We begin our exploration of the topic of modern portfolio theory by defining a universe of stocks
comprising a random sample of 25 of the constituents of the S&P 500 index as a selected point in time:
I n [ ] : = startDate = DateObject[{2018, 1, 3}]
O u t [ ] =

Wed 3 Jan 2018

I n [ ] : = portfolioStocks = RandomSampleSelectEntity["Equities", #] & /@

EntityMemberList SP500 EQUITIES , startDate, EntityQ, 25 // Sort;


nstocks = Length @ portfolioStocks
portfolioStocks // Short
O u t [ ] =

25
O u t [ ] / / S h o r t =

 AAP , ALGN , AMT , BBY , BMY , CME , CRM ,

DISCA , DVN , EMR , GE , HOG , ICE , IDXX , LKQ , LYB ,

MAS , PEP , REG , RHI , RJF , SIG , TAP , TPR , UA 

The RandomWeighting function is used to generate 10,000 different sets of weights that are applied to
the stocks in the investment universe to create 10,000 different portfolios. All of the portfolio weights
must lie in the range {0, 1}, i.e. we do not allow short sales and the sum of the weights must equal 1.0
(no leverage). We examine the annual return and volatility of these portfolios over the preceding 5
years.
2 Modern Portfolio Theory.nb

I n [ ] : = wgts = RandomWeighting[10 000, nstocks, 1.0];

I n [ ] : = weights = Table[ωi , {i, nstocks}];

I n [ ] : = tsPortfolioReturns = PortfolioReturns[portfolioStocks, {2013, 1, 3}, {2017, 12, 29}];

I n [ ] : = AbsoluteTiming[
portfolioRiskReturn = ParallelTable[PortfolioRiskReturn[tsPortfolioReturns,
weights /. weights  wgt], {wgt, wgts}, Method  "CoarsestGrained"];]
O u t [ ] =

{101.076, Null}

The result is an array of annual return and volatilities for each of the 10,000 portfolios:
I n [ ] : = portfolioRiskReturn〚1 ;; 5, 1 ;; 2〛
O u t [ ] =

{{0.127391, 0.139031}, {0.155703, 0.138864},


{0.130991, 0.140689}, {0.122654, 0.133249}, {0.121784, 0.134468}}

Minimum Variance Portfolio


We will shortly plot these results on a chart, but first we will use the FindMinimum function to identify
the return and volatility of the portfolio having the minimum variance, amongst all the possible varia-
tions of allocation weightings.
I n [ ] : = {portfolioAverageReturns, portfolioVolatility} =
Take[PortfolioRiskReturn[tsPortfolioReturns, weights], 2];

I n [ ] : = portfolioConstraints = Total[weights]  1 && And @@ (0 ≤ # ≤ 1 & /@ weights);


(*Set constraints on weights to that the um of the weights =
1 and all weights lie in the rang e{0,1}*)

I n [ ] : = minVarPortfolio = {portfolioVolatility, portfolioAverageReturns} /.


FindMinimum[{portfolioVolatility, portfolioConstraints}, weights]〚2〛
O u t [ ] =

{0.104783, 0.0998676}

For completeness, we also find the volatility and return of the S&P 500 index over the same period

I n [ ] : = tsSP500Returns = EntityDailyReturns SP500 EQUITIES , {2013, 1, 3}, {2017, 12, 29};

I n [ ] : = SP500RiskReturn = PortfolioRiskReturn[tsSP500Returns]〚{2, 1}〛


O u t [ ] =

{0.118687, 0.120999}

The Efficient Frontier


The efficient frontier comprises portfolios which, for a given level of risk, have the highest expected
return and, conversely, for a given rate of return have the lowest volatility. We can identify portfolios
Modern Portfolio Theory.nb 3

lying on the frontier using the FindMinimum function to identify the allocation weights for portfolios
that have the lowest volatility for a specified rate of return (in the range of 1% to 32%).
I n [ ] : = effFrontier = ParallelTable[{FindMinimum[{portfolioVolatility,
portfolioConstraints && portfolioAverageReturns  i}, weights]〚1〛, i},
{i, 0.01, 0.32, .02}, Method  "CoarsestGrained"] // Quiet;

We will also compute the allocation weights for several portfolios on the frontier:
I n [ ] : = effFrontierWgts = ParallelTable[FindMinimum[{portfolioVolatility, Total[weights]  1 &&
portfolioAverageReturns  i && And @@ (0 ≤ # ≤ 1 & /@ weights)}, weights]〚2〛,
{i, 0.15, 0.30, .05}, Method  "CoarsestGrained"] // Quiet;

Finally, we are ready to combine all of the above information in a single plot that shows the efficient
frontier, global minimum variance portfolio and other portfolios on the frontier and the collection of
portfolios we created using random sets of allocation weights:
O u t [ ] =
Return

0.30

The Efficient Froniter


0.25

0.20

0.15

0.10

0.05

Volatility
0.11 0.12 0.13 0.14 0.15 0.16 0.17

Composition of Portfolios on the Efficient Frontier


It is striking that none of the randomly generated portfolios lie close to the efficient frontier. That’s
because the frontier portfolios typically have allocation weights that are “extreme”, with very large
weights for some stocks and very small allocations to others. For example:
4 Modern Portfolio Theory.nb

I n [ ] : = portfolio1 = AssociationThread[portfolioStocks  Values @ effFrontierWgts〚1〛]


O u t [ ] =

 AAP  0.00215412, ALGN  0.0279105, AMT  0.0707088,

BBY  0.0205041, BMY  0.0375922, CME  0.175761, CRM  7.38827 × 10-6 ,

DISCA  8.84198 × 10-6 , DVN  6.58751 × 10-6 , EMR  0.0102983,

GE  0.0000425169, HOG  0.0000209618, ICE  0.026013, IDXX  0.0633854,

LKQ  0.0000269247, LYB  0.00567528, MAS  7.66668 × 10-6 ,

PEP  0.405446, REG  0.0580264, RHI  3.98111 × 10-6 , RJF  7.00697 × 10-6 ,

SIG  0.00325516, TAP  0.0131276, TPR  0.00288251, UA  0.077128

I n [ ] : = PieChart3D[portfolio1,
ChartLegends  Placed[Automatic, Right], SectorOrigin  {Automatic, 1}]
O u t [ ] =

AAP CME GE LYB


ALGN CRM HOG MAS
AMT DISCA ICE PEP
BBY DVN IDXX REG
BMY EMR LKQ RHI

Performance of Portfolios on the Efficient Frontier


Because the allocation weights have been optimized so that efficient portfolios provide the maximum
expected returns for a given level of risk, the equity curve of compounded returns is relatively smooth
and monotonic and the portfolios easily outperform the S&P500 index over the formation period from
2013-2017:
I n [ ] : = tsPortReturns = PortfolioReturns[tsPortfolioReturns, Values @ effFrontierWgts]
O u t [ ] =

TimeSeries Time: 03 Jan 2013 GMT-5 to 29 Dec 2017 GMT-5 


Data points: 1258
Modern Portfolio Theory.nb 5

I n [ ] : = DateListPlot[
{CompoundReturn[tsPortReturns], CompoundReturn[tsSP500Returns]}, Filling  Axis,
PlotLabels  Join[Table[StringJoin["Portfolio ", ToString[i]], {i, 4}], {" SP500"}],
ImageSize  Large, PlotRange  All]
O u t [ ] =

4 Portfolio 4

3
Portfolio 3

2
Portfolio 2

Portfolio 1
1
SP500

2014 2016 2018

When we evaluate portfolio performance after the formation period, however, the story is very differ-
ent. Although efficient portfolios outperform the S&P500 over the period from 2018-2022, there are
times when they under-perform the index and the equity curve suffers from several large periodic
declines lasting for several days, or weeks. This is the result of the extreme allocation profile of the
portfolios, which entails making several large bets on stocks such as PEP and CME, which performed
well during the formation period, but did much less well in the subsequent period from 2018. This
variability in performance is a typical characteristic of portfolios constructed by mean-variance opti-
mization.

For this reason equity portfolio managers will typically impose additional constraints on the allocation
weights, to avoid over- or under-weighting specific stocks or industry sectors, with the aim of construct-
ing portfolios that perform more robustly out of sample.

I n [ ] : = tsSP500Returns = EntityDailyReturns SP500 EQUITIES , {2018, 1, 3}, {2022, 12, 30}


O u t [ ] =

TimeSeries Time: 03 Jan 2018 GMT-5 to 30 Dec 2022 GMT-5 


Data points: 1258

I n [ ] : = tsPortfolioReturns = PortfolioReturns[portfolioStocks, {2018, 1, 3}, {2022, 12, 30}];


6 Modern Portfolio Theory.nb

I n [ ] : = tsPortReturns = PortfolioReturns[tsPortfolioReturns, Values @ effFrontierWgts]


O u t [ ] =

TimeSeries Time: 03 Jan 2018 GMT-5 to 30 Dec 2022 GMT-5 


Data points: 1258

I n [ ] : = DateListPlot[
{CompoundReturn[tsPortReturns], CompoundReturn[tsSP500Returns]}, Filling  Axis,
PlotLabels  Join[Table[StringJoin["Portfolio ", ToString[i]], {i, 4}], {" SP500"}],
ImageSize  Large]
O u t [ ] =

1.5

1.0

Portfolio 3
Portfolio 2
Portfolio 1
Portfolio 4
0.5
SP500

0.0

2018 2020 2022

Dynamics of the Efficient Frontier


One of the major challenges in portfolio construction is that the temporal variability in asset returns
and covariances induces substantial change in the shape of the efficient frontier. This means that the
composition of a portfolio with a specific risk-return profile is liable to alter significantly over time.
Furthermore, the volatility of an optimal portfolio with a specific rate of expected returns will likewise
be subject to substantial variation. To illustrate this effect, we estimate the efficient frontier for our
universe of 25 stocks for six years, using daily returns data for the prior five years in each case.

Depending on the year in question, we observe that an optimal portfolio with an expected return of,
say, 12% per year, might have an estimated annual volatility of as low as 7% (in 2015) to as high as 12%
(in 2019).
Modern Portfolio Theory.nb 7

I n [ ] : = initDate = DateObject[{2010, 1, 4}]


effFrontiers = {};
O u t [ ] =

Mon 4 Jan 2010

I n [ ] : = Do[startdate = DatePlus[initDate, Quantity[i, "Year"]];


tsPortfolioReturns = PortfolioReturns[
portfolioStocks, startdate, DatePlus[startdate, Quantity[5, "Years"]]];
{portfolioAverageReturns, portfolioVolatility} =
Take[PortfolioRiskReturn[tsPortfolioReturns, weights], 2];
AppendTo[effFrontiers, ParallelTable[{FindMinimum[{portfolioVolatility,
portfolioConstraints && portfolioAverageReturns  i}, weights]〚1〛, i},
{i, 0.005, 0.15, .02}, Method  "CoarsestGrained"]] // Quiet;, {i, 0, 5}];

I n [ ] : = Table[ListLinePlot[effFrontiers〚i〛, InterpolationOrder  2, PlotLabel  ToString[2014 + i],


PlotRange  All, Filling  Axis, ImageSize  Small], {i, 6}]
O u t [ ] =
2015 2016 2017
0.14 0.14 0.14
0.12 0.12 0.12
0.10 0.10 0.10
0.08 , 0.08 , 0.08 ,
0.06 0.06 0.06
0.04 0.04 0.04
0.02 0.02 0.02

0.02 0.04 0.06 0.08 0.02 0.04 0.06 0.08 0.10 0.12 0.0980.1000.1020.1040.1060.1080.110

2018 2019 2020


0.14 0.14 0.14
0.12 0.12 0.12
0.10 0.10 0.10
0.08 , 0.08 , 0.08 
0.06 0.06 0.06
0.04 0.04 0.04
0.02 0.02 0.02

0.106 0.108 0.110 0.112 0.114 0.116 0.116 0.117 0.118 0.119 0.120 0.121 0.118 0.120 0.122 0.124 0.126

Notes
◼ More on Modern Portfolio Theory

You might also like