Portfolio Optimization
Portfolio Optimization
Asset definitions
Asset definitions
We define the assets that are going to be used. In this example, they were chosen among the top 10 performing stocks in S&P.
(*"AAPL","MSFT","AMZN","JNJ","XOM","JPM","GOOG"*)(*"FAS","FIW","FYX","PBP","GEX","PSP"*)(*"OIH","MUB","PSI","GDX","KRE","ITA","TLT"*)portfolio={"OIH","MUB","PSI","GDX","KRE","ITA","TLT"};
We get the pricing data by specifying 2010/01/01 as a starting date and then proceed to plot it.
data=FinancialData[#,"Close",{2010,1,1},"Value"]&/@portfolio;
ListPlot[data,PlotRangeAll,JoinedTrue,PlotLegendsSwatchLegend[portfolio]]
Returns
Returns
What we are interested in are returns, that is, the percentage change of each asset price with respect to the one of the previous trading day.
getReturns[lst_]:=(lst[[#+1]]/lst[[#]])-1&/@Range[Length[lst]-1];
returns=getReturns[data[[#]]]&/@Range[Length[portfolio]];
Having calculated the returns with the defined function, we can proceed to plot the data.
ListPlot[returns,PlotRangeAll,JoinedTrue,PlotLegendsSwatchLegend[portfolio]]
Optimization
Optimization
Now that we have calculated returns, we can proceed to optimize our portfolio; that is, find a set of weights (one for each asset) w, such that the expected risk of the portfolio is minimized for a given expected return. For this, we use modern portfolio theory, in particular, Markowitz optimization.
We can first define the weights vector as a symbolic object with the corresponding assets as subscripts.
weights=Transpose[{Subscript[w,#]&/@portfolio}]
{{},{},{},{},{},{},{}}
w
OIH
w
MUB
w
PSI
w
GDX
w
KRE
w
ITA
w
TLT
The expected return of our portfolio is given by R = · , where m is a row vector whose entries are given by the mean of each asset’s returns.
∑
m
w
meanRet={Mean[#]&/@returns};portfolioMean=Flatten[meanRet.weights][[1]]*252;
Next we calculate the variance of our portfolio, given by var = · C · w, where C is the covariance matrix of the returns.
T
w
covMat=Covariance[Transpose[returns]];portfolioVar=Flatten[Transpose[weights].covMat.weights][[1]]*252;
We multiply our results by 252 to consider annual returns, since there are approximately 252 business days in a year.
Constraints
Constraints
Having arranged our data, we need to specify some constraints on the optimization so that the result makes sense in a real investing environment, as well as to provide a way to personalize the optimization process. There are four basic constraints which one can be interested on:
◼
∑
i
w
i
◼
w
i
w
min
◼
w
i
w
max
◼
R
exp
R
min
The following function combines these constraints into a single constraint list, which we can then pass on to the optimization function.
constraints[wl_,wg_,retMin_]:=Union[GreaterEqualThan[wl][#]&/@Flatten[Transpose[weights]],LessEqualThan[wg][#]&/@Flatten[Transpose[weights]],List[Total[weights][[1]]1],List[GreaterEqualThan[retMin][portfolioMean]]];
The optimization consists of minimizing the portfolio variance for a given expected minimum return.
optPort[x_,y_,z_]:=NMinimize[{portfolioVar,constraints[x,y,z]},Flatten[weights]];
Testing
Testing
In order to test the previous functions and concepts, we can optimize a portfolio for a given set of constraints. Lets say that every asset in our portfolio must take at least 5% of the total investment, and must not surpass 25%. Also, we are interested in finding the minimum variance portfolio, so we can set =0.
R
exp
mv=optPort[0.05,0.25,0.0]
{0.00661625,{0.05,0.25,0.05,0.05,0.1,0.25,0.25}}
w
OIH
w
MUB
w
PSI
w
GDX
w
KRE
w
ITA
w
TLT
This gave us the allocation weights for each asset, as well as the corresponding risk. For better control, we can group expected variance with expected returns as a row vector.
expRetRisk={Sqrt[mv[[1]]],portfolioMean/.mv[[2]]}
{0.0813403,0.100084}
The following graph helps visualize the asset allocation for the minimum variance portfolio.
BarChart[{Last[mv[[2,#]]]&/@Range[Length[portfolio]]},ImageSizeMedium,ChartLabelsportfolio]
Efficient Frontier
Efficient Frontier
As a vital aspect of modern portfolio theory stands the concept of efficient frontier. Introduced my Harry Markowitz in the 50’s, this concept refers to the convex hull of every possible asset allocation for a given number of assets, that is, a given portfolio. This defines the optimal portfolio for every combination of expected risk and expected return.
In order to better visualize this concept, we can generate it by optimizing several portfolios, each uniquely determined by a distinct expected return.
effFrontier=Table[{NMinimize[{Sqrt[portfolioVar],Union[GreaterEqualThan[0.05][#]&/@Flatten[Transpose[weights]],LessEqualThan[0.25][#]&/@Flatten[Transpose[weights]],List[Total[weights][[1]]1],List[Equal[portfolioMean,i]]]},Flatten[weights]][[1]],i},{i,0.0,1,.001}];//Quiet
The following graph shows the efficient frontier for the past example of assets and constraints, along with several randomly generated portfolios. As an important remark, one should note the red dot which represents the minimum variance portfolio found in the previous section.
Show[ListLinePlot[effFrontier,Epilog{Red,PointSizeLarge,Point[expRetRisk]},FrameTrue,FrameLabel{"σ","Expected portfolio return"},PlotRange{Automatic,Automatic},BaseStyle14,ImageSize500],ListPlot[Table[{Sqrt[portfolioVar],portfolioMean}/.Flatten[Select[{Thread[Flatten[Transpose[weights]]#&[Normalize[RandomReal[{0.05,0.25},Length[portfolio]],Total]]]},AllTrue[#,0.05≤Last[#]≤0.25&]&]],{10000}],PlotMarkers{Automatic,5},PlotStyleGray]]//Quiet
Backtesting
Backtesting
An important part of building models is to test them to analyze their performance on real scenarios. Backtesting consists of doing this with past data, that is, test the model with info we already know about.
We begin by extracting the asset’s weights.