<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://quantsoftware.gatech.edu/index.php?action=history&amp;feed=atom&amp;title=MC1-Project-2-archive</id>
	<title>MC1-Project-2-archive - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://quantsoftware.gatech.edu/index.php?action=history&amp;feed=atom&amp;title=MC1-Project-2-archive"/>
	<link rel="alternate" type="text/html" href="http://quantsoftware.gatech.edu/index.php?title=MC1-Project-2-archive&amp;action=history"/>
	<updated>2026-04-14T23:19:17Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.4</generator>
	<entry>
		<id>http://quantsoftware.gatech.edu/index.php?title=MC1-Project-2-archive&amp;diff=665&amp;oldid=prev</id>
		<title>Tucker: Created page with &quot;==Overview==  In this project you will use what you learned about optimizers to optimize a portfolio.  That means that you will find how much of a portfolio&#039;s funds should be...&quot;</title>
		<link rel="alternate" type="text/html" href="http://quantsoftware.gatech.edu/index.php?title=MC1-Project-2-archive&amp;diff=665&amp;oldid=prev"/>
		<updated>2015-11-25T20:51:19Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==Overview==  In this project you will use what you learned about optimizers to optimize a portfolio.  That means that you will find how much of a portfolio&amp;#039;s funds should be...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Overview==&lt;br /&gt;
&lt;br /&gt;
In this project you will use what you learned about optimizers to optimize a portfolio.  That means that you will find how much of a portfolio&amp;#039;s funds should be allocated to each stock so as to optimize it&amp;#039;s performance.  In this case we define &amp;quot;optimal&amp;quot; as maximum Sharpe ratio.&lt;br /&gt;
&lt;br /&gt;
You will leverage the functions you created in the last project that assessed the value of a portfolio with a given set of allocations.&lt;br /&gt;
&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
Implement a Python function named &amp;lt;tt&amp;gt;find_optimal_allocations()&amp;lt;/tt&amp;gt; that can find the optimal allocations for a given stock portfolio. You should optimize for Sharpe ratio.&lt;br /&gt;
&lt;br /&gt;
The function should accept as input historical stock prices (supplied as a pandas dataframe, with each column representing one equity), and return a list of floats (as a one-dimensional numpy array) that represents the allocations to each of the equities. Use functions developed in the portfolio analysis project to compute daily portfolio value and statistics.&lt;br /&gt;
&lt;br /&gt;
==Template==&lt;br /&gt;
&lt;br /&gt;
Instructions:&lt;br /&gt;
* Download &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;&amp;#039;[[Media:mc1_p2.zip|mc1_p2.zip]]&amp;#039;&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;, unzip inside &amp;lt;tt&amp;gt;ml4t/&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Copy &amp;lt;tt&amp;gt;analysis.py&amp;lt;/tt&amp;gt; (your solution for MC1-Project-1) to &amp;lt;tt&amp;gt;mc1_p2/portfolio/&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;find_optimal_allocations()&amp;lt;/tt&amp;gt; function in &amp;lt;tt&amp;gt;mc1_p2/portfolio/optimization.py&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* To execute, run &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;&amp;#039;python -m portfolio.optimization&amp;#039;&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;mc1_p2/&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
A helper function (&amp;lt;tt&amp;gt;optimize_portfolio&amp;lt;/tt&amp;gt;) has been included in the template code (see &amp;lt;tt&amp;gt;mc1_p2/portfolio/optimization.py&amp;lt;/tt&amp;gt;), which is called with the desired date range and symbols (see &amp;lt;tt&amp;gt;test_run()&amp;lt;/tt&amp;gt;):&lt;br /&gt;
 start_date = &amp;#039;2010-01-01&amp;#039;&lt;br /&gt;
 end_date = &amp;#039;2010-12-31&amp;#039;&lt;br /&gt;
 symbols = [&amp;#039;GOOG&amp;#039;, &amp;#039;AAPL&amp;#039;, &amp;#039;GLD&amp;#039;, &amp;#039;XOM&amp;#039;]&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;optimize_portfolio&amp;#039;&amp;#039;&amp;#039;(start_date, end_date, symbols)&lt;br /&gt;
&lt;br /&gt;
This in turn reads stock price data, and calls the function to find optimal allocations (you need to implement this):&lt;br /&gt;
 allocs = &amp;#039;&amp;#039;&amp;#039;find_optimal_allocations&amp;#039;&amp;#039;&amp;#039;(prices)&lt;br /&gt;
&lt;br /&gt;
Your solution to the optimization problem should leverage the functions you wrote in the last assignment, namely&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;&amp;#039;get_portfolio_value&amp;#039;&amp;#039;&amp;#039;(prices, allocs, start_val)&amp;lt;/tt&amp;gt;: Compute daily portfolio value given stock prices, allocations and starting value.&amp;lt;br /&amp;gt;Ensure that it returns a pandas &amp;lt;tt&amp;gt;Series&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;DataFrame&amp;lt;/tt&amp;gt; (with a single column).&lt;br /&gt;
* &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;&amp;#039;get_portfolio_stats&amp;#039;&amp;#039;&amp;#039;(port_val, daily_rf, samples_per_year)&amp;lt;/tt&amp;gt;: Calculate statistics on daily portfolio value, given daily risk-free rate and data sampling frequency.&amp;lt;br /&amp;gt;This function should return a &amp;#039;&amp;#039;tuple&amp;#039;&amp;#039; consisting of the following statistics (in order): cumulative return, average daily return, standard deviation of daily return, Sharpe ratio&amp;lt;br /&amp;gt;Note: The return statement provided ensures this order.&lt;br /&gt;
* &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;&amp;#039;plot_normalized_data&amp;#039;&amp;#039;&amp;#039;(df, title, xlabel, ylabel)&amp;lt;/tt&amp;gt;: Normalize given stock prices and plot for comparison.&amp;lt;br /&amp;gt;This is used to create a chart that illustrates the value of your portfolio over the year and compares it to SPY.&amp;lt;br /&amp;gt;Note: Before plotting, portfolio and SPY values should be normalized to 1.0 at the beginning of the period. Also, use the &amp;lt;tt&amp;gt;plot_data()&amp;lt;/tt&amp;gt; utility function to generate and show your plot.&lt;br /&gt;
&lt;br /&gt;
We will provide implementations of these functions that you can call from your optimizer code. Note that when your code is submitted for this project, you will not be submitting your analysis.py code, but instead your code will be calling our implementation of that.  Accordingly, be sure you&amp;#039;ve implemented the API for these functions correctly!&lt;br /&gt;
&lt;br /&gt;
The helper function (&amp;lt;tt&amp;gt;optimize_portfolio()&amp;lt;/tt&amp;gt;) prints out the optimal allocations, and some statistics. It also plots a chart comparing the daily value of your portfolio over the year and compares it to SPY. The portfolio and SPY are normalized to 1.0 at the beginning of the period.  We will not be calling &amp;lt;tt&amp;gt;optimize_portfolio&amp;lt;/tt&amp;gt; to test your code, we will be calling &amp;lt;tt&amp;gt;find_optimal_allocations()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Make sure the output and plot look like the examples shown below.&lt;br /&gt;
&lt;br /&gt;
==Suggestions==&lt;br /&gt;
&lt;br /&gt;
Refer to comments in &amp;lt;tt&amp;gt;find_optimal_allocations()&amp;lt;/tt&amp;gt; for pointers regarding how to implement it. In order to specify bounds and constraints when using the &amp;lt;tt&amp;gt;scipy.optmize&amp;lt;/tt&amp;gt; module, you&amp;#039;ll need to use a special syntax explained here:&lt;br /&gt;
http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html&lt;br /&gt;
&lt;br /&gt;
For bounds, you simply need to pass in a sequence of 2-tuples &amp;lt;tt&amp;gt;(&amp;amp;lt;low&amp;amp;gt;, &amp;amp;lt;high&amp;amp;gt;)&amp;lt;/tt&amp;gt;. Just remember that you need to supply as many tuples as the number of stocks in your portfolio.&lt;br /&gt;
&lt;br /&gt;
For constraints, it&amp;#039;s a little tricky. You need to pass in a sequence of dicts (dictionaries), one dictionary per constraint. Each dictionary must specify the type of constraint (&amp;lt;tt&amp;gt;&amp;#039;eq&amp;#039;&amp;lt;/tt&amp;gt; for equality, or &amp;lt;tt&amp;gt;&amp;#039;ineq&amp;#039;&amp;lt;/tt&amp;gt; for inequality), and a function that &amp;#039;&amp;#039;returns 0 only when the input satisfies the constraint&amp;#039;&amp;#039; (this is the same input that is supplied to your evaluation function). E.g. to constrain the sum of all values in the input array to be less than 50, you could pass in the following (lambdas are just anonymous functions defined on-the-spot):&lt;br /&gt;
 constraints = ({ &amp;#039;type&amp;#039;: &amp;#039;eq&amp;#039;, &amp;#039;fun&amp;#039;: lambda inputs: 50.0 - np.sum(inputs) })&lt;br /&gt;
&lt;br /&gt;
==Example output 1==&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s an example output for your function. These are actual correct values that you can use to check your work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Start Date: 2010-01-01&lt;br /&gt;
End Date: 2010-12-31&lt;br /&gt;
Symbols: [&amp;#039;GOOG&amp;#039;, &amp;#039;AAPL&amp;#039;, &amp;#039;GLD&amp;#039;, &amp;#039;XOM&amp;#039;]&lt;br /&gt;
Optimal allocations: [  5.38105153e-16   3.96661695e-01   6.03338305e-01  -5.42000166e-17]&lt;br /&gt;
Sharpe Ratio: 2.00401501102&lt;br /&gt;
Volatility (stdev of daily returns): 0.0101163831312&lt;br /&gt;
Average Daily Return: 0.00127710312803&lt;br /&gt;
Cumulative Return: 0.360090826885&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Corresponding comparison plot:&lt;br /&gt;
&lt;br /&gt;
[[File:comparison_optimal.png]]&lt;br /&gt;
&lt;br /&gt;
==Example output 2==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Start Date: 2004-01-01&lt;br /&gt;
End Date: 2006-01-01&lt;br /&gt;
Symbols: [&amp;#039;AXP&amp;#039;, &amp;#039;HPQ&amp;#039;, &amp;#039;IBM&amp;#039;, &amp;#039;HNZ&amp;#039;]&lt;br /&gt;
Optimal allocations: [  7.75113042e-01   2.24886958e-01  -1.18394877e-16  -7.75204553e-17]&lt;br /&gt;
Sharpe Ratio: 0.842697383626&lt;br /&gt;
Volatility (stdev of daily returns): 0.0093236393828&lt;br /&gt;
Average Daily Return: 0.000494944887734&lt;br /&gt;
Cumulative Return: 0.255021425162&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Example2.png]]&lt;br /&gt;
&lt;br /&gt;
==Example output 3==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Start Date: 2004-12-01&lt;br /&gt;
End Date: 2006-05-31&lt;br /&gt;
Symbols: [&amp;#039;YHOO&amp;#039;, &amp;#039;XOM&amp;#039;, &amp;#039;GLD&amp;#039;, &amp;#039;HNZ&amp;#039;]&lt;br /&gt;
Optimal allocations: [ -3.84053467e-17   7.52817663e-02   5.85249656e-01   3.39468578e-01]&lt;br /&gt;
Sharpe Ratio: 1.5178365773&lt;br /&gt;
Volatility (stdev of daily returns): 0.00797126844855&lt;br /&gt;
Average Daily Return: 0.000762170576913&lt;br /&gt;
Cumulative Return: 0.315973959221&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example output 4==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Start Date: 2005-12-01&lt;br /&gt;
End Date: 2006-05-31&lt;br /&gt;
Symbols: [&amp;#039;YHOO&amp;#039;, &amp;#039;HPQ&amp;#039;, &amp;#039;GLD&amp;#039;, &amp;#039;HNZ&amp;#039;]&lt;br /&gt;
Optimal allocations: [ -1.67414005e-15   1.01227499e-01   2.46926722e-01   6.51845779e-01]&lt;br /&gt;
Sharpe Ratio: 3.2334265871&lt;br /&gt;
Volatility (stdev of daily returns): 0.00842416845541&lt;br /&gt;
Average Daily Return: 0.00171589132005&lt;br /&gt;
Cumulative Return: 0.229471589743&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Minor differences in float values may arise due to different implementations.&lt;br /&gt;
&lt;br /&gt;
==What to turn in==&lt;br /&gt;
Be sure to follow these instructions diligently!&lt;br /&gt;
&lt;br /&gt;
Via T-Square, submit as attachments (no zip files; refer to schedule for deadline):&lt;br /&gt;
&lt;br /&gt;
* Your code as &amp;lt;tt&amp;gt;optimization.py&amp;lt;/tt&amp;gt; (only the function &amp;lt;tt&amp;gt;find_optimal_allocations()&amp;lt;/tt&amp;gt; will be tested)&lt;br /&gt;
* Plot comparing the optimal portfolio with SPY as &amp;lt;tt&amp;gt;comparison_optimal.png&amp;lt;/tt&amp;gt; using the following parameters:&amp;lt;br /&amp;gt;Start Date: 2010-01-01, End Date: 2010-12-31, Symbols: [&amp;#039;GOOG&amp;#039;, &amp;#039;AAPL&amp;#039;, &amp;#039;GLD&amp;#039;, &amp;#039;HNZ&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
Unlimited resubmissions are allowed up to the deadline for the project.&lt;br /&gt;
&lt;br /&gt;
==Rubric==&lt;br /&gt;
&lt;br /&gt;
* Part 1: Chart is correct [20 points]&lt;br /&gt;
** Normalized values start at 1.0 on left (10 points)&lt;br /&gt;
** Shape of curves are correct (10 points)&lt;br /&gt;
* Part 2: 10 test cases [80 points]&amp;lt;br /&amp;gt;We will test your code against 10 cases (8 points per case).  Each case will be deemed &amp;quot;correct&amp;quot; if:&lt;br /&gt;
** sum(allocations) = 1.0 +- 0.02&lt;br /&gt;
** Each allocation is between 0 and 1.0 +- 0.02 (negative allocations are allowed if they are very small)&lt;br /&gt;
** Each allocation matches reference solution +- 0.10&lt;br /&gt;
&lt;br /&gt;
==Required, Allowed &amp;amp; Prohibited==&lt;br /&gt;
&lt;br /&gt;
Required:&lt;br /&gt;
* Your project must be coded in Python 2.7.x.&lt;br /&gt;
* Your code must run on one of the university-provided computers (e.g. buffet02.cc.gatech.edu), or on one of the provided virtual images.&lt;br /&gt;
* Your code must run in less than 5 seconds on one of the university-provided computers.&lt;br /&gt;
&lt;br /&gt;
Allowed:&lt;br /&gt;
* You can develop your code on your personal machine, but it must also run successfully on one of the university provided machines or virtual images.&lt;br /&gt;
* Your code may use standard Python libraries.&lt;br /&gt;
* You may use the NumPy, SciPy and Pandas libraries.  Be sure you are using the correct versions.&lt;br /&gt;
* You may reuse sections of code (up to 5 lines) that you collected from other students or the internet.&lt;br /&gt;
* Code provided by the instructor, or allowed by the instructor to be shared.&lt;br /&gt;
&lt;br /&gt;
Prohibited:&lt;br /&gt;
* Any libraries not listed in the &amp;quot;allowed&amp;quot; section above.&lt;br /&gt;
* Any code you did not write yourself (except for the 5 line rule in the &amp;quot;allowed&amp;quot; section).&lt;br /&gt;
* Any Classes (other than Random) that create their own instance variables for later use (e.g., learners like kdtree).&lt;br /&gt;
* Camels and other dromedaries.&lt;/div&gt;</summary>
		<author><name>Tucker</name></author>
		
	</entry>
</feed>