Modern Portfolio Theory
Modern portfolio theory (MPT) uses a statistical model to show how, by diversifying investments, an investor can optimize their portfolio by finding the optimal asset allocation for a given risk. Rather than traditional value investing where investors attempt to pick investments based on some form of "fundamental analysis" such as high dividend yields or low price-to-earning or price-to-book ratios, MPT deals in the statistical volatility (risk) and return of an investment. Additionally, the covariance between investments is used to determine how different mixes of investments change the overall volatility of the portfolio. The investor is assumed to desire the maximum expected return with lowest risk and the theory shows how to find that asset allocation.
moneychimp has a very well done tutorial on the concepts of MPT. The Wikipedia article is also a good starting point and includes more details and formulas. Finally, Dr. Sharpe, inventor of the Sharpe ratio and winner of the Nobel Prize in Economics, at Stanford has an excellent web page with many examples and sample code for doing macro investment analysis including MPT.
The Project
After reading Dr. Sharpe's articles and examples, I wanted to try his analysis with real investment data. The MPT approach appealed to me as someone who had never believed in the value investing theory that an individual investment can be accurately priced. The statistical model of risk vs. return makes more sense to me and seems less arbitrary. Additionally, MPT dove-tails nicely with the idea of using index funds for diversification and finally, it's simpler to work with as any investment can be analyzed.
To complete this project, I wrote a Python program for downloading historical data from Yahoo and some Octave scripts to plot the data using Dr. Sharpe's function.
Required Software
I used Cygwin/X with the python, octaveand octave-forgepackages installed. Octave is an excellent open source Matlab clone. None of my code is platform dependent and should work on any system with Python and Octave installed.
Conveniently for us, Dr. Sharpe has written a Matlab function to calculate a portfolio for a given set of investments. It can be downloaded here: gqp.m
My scripts are here:
Downloading the historical data
The python script mpt_getdata.pytakes a list of ticker symbols and bounds from a file and downloads the historical investment data from Yahoo.
| Running mpt_getdata.py to download historical data |
| > ./mpt_getdata.py
stocks IVE VTI IVW IJH IJK IJS IJR IJT |
As input, the script takes a file with a stock ticker on each line followed by a lower and upper bound of holdings for the investment. The bounds are expressed as values between one and zero.
| stocks |
| IVE 0 1 VTI 0 1 IVW 0 1 IJH 0 1 IJK 0 1 IJS 0 1 IJR 0 1 IJT 0 1 |
The data downloaded from Yahoo is the monthly closing price adjusted for dividends. It comes in the format of comma separated values (csv) files.
| IVE.csv |
| Date,Open,High,Low,Close,Volume,Adj.
Close* 1-Sep-06,70.66,71.69,69.66,71.19,393400,71.19 1-Aug-06,69.18,70.50,68.28,70.30,391586,70.30 3-Jul-06,68.61,69.50,66.26,69.33,264410,69.33 1-Jun-06,69.00,70.04,65.64,68.71,340731,68.71 1-May-06,70.65,71.81,67.16,68.75,229909,68.42 3-Apr-06,69.30,70.74,68.24,70.62,342215,70.28 1-Mar-06,68.07,69.72,67.06,68.76,204760,68.43 1-Feb-06,66.90,68.60,65.91,67.65,334221,67.32 3-Jan-06,65.25,67.53,64.96,66.90,290845,66.58 |
Analyzing the Data
Now that the data has been downloaded, we'll use Octave to analyze it. First we'll load the mpt_setup.mscript created by mpt_getdata.pyto setup the initial vector of investment names and bounds. Then, we'll plot the optimal portfolios over the risk tolerances (0,100).
IMPORTANT:All the historical data will be truncated to the investment with the shortest history. For example, if you have one investment with only one year of historical data, the history of all the other investments will be truncated to one year.
| Analyzing the data in Octave |
| > octave octave:1> mpt_setup octave:2> mpt_invest(investments,lb,ub,0,100) IVE.csv 0.000000 VTI.csv 0.000000 IVW.csv 0.000000 IJH.csv 0.000000 IJK.csv 0.000000 IJS.csv 1.000000 IJR.csv 0.000000 IJT.csv 0.000000 sd_expected = 5.1895 e_expected = 1.0125 |

| Our MPT portfolio |
| IVE.csv 0.000000 VTI.csv 0.000000 IVW.csv 0.000000 IJH.csv 0.000000 IJK.csv 0.000000 IJS.csv 1.000000 IJR.csv 0.000000 IJT.csv 0.000000 sd_expected = 5.1895 e_expected = 1.0125 |
| Analyzing the data in Octave |
| octave:3>
mpt_invest(investments,lb,ub,0,20) IVE.csv 0.000000 VTI.csv 0.188330 IVW.csv 0.221459 IJH.csv 0.590210 IJK.csv 0.000000 IJS.csv 0.000000 IJR.csv 0.000000 IJT.csv 0.000000 sd_expected = 3.9976 e_expected = 0.56279 |
| Standard deviation range |
| octave:4>
mpt_stdrange(3.9976,.56279) ans = 0.58782 ans = 1.0675 ans = 1.5472 |
In the example above, with a standard deviation of 3.9976 and average monthly return of 0.56279 the range is 0.58782 to 1.5472 with a mean of 1.0675. This means that $1 invested in this portfolio will have a 68% chance (size of one standard deviation) of being worth between $0.56 and $1.55 with an expected average value of $1.07.
Contact
Future Improvements
Bugs
Using a non-zero lower bound for any investment may cause an invalid staring vector (x0) creating undefined results.