Skip to content

Instantly share code, notes, and snippets.

@sshariff01
Created May 23, 2019 03:46
Show Gist options
  • Save sshariff01/db52042cf74cd2a5011391a831a03fa5 to your computer and use it in GitHub Desktop.
Save sshariff01/db52042cf74cd2a5011391a831a03fa5 to your computer and use it in GitHub Desktop.
ML4T - Project 2
"""MC1-P2: Optimize a portfolio.
Copyright 2018, Georgia Institute of Technology (Georgia Tech)
Atlanta, Georgia 30332
All Rights Reserved
Template code for CS 4646/7646
Georgia Tech asserts copyright ownership of this template and all derivative
works, including solutions to the projects assigned in this course. Students
and other users of this template code are advised not to share it with others
or to make it available on publicly viewable websites including repositories
such as github and gitlab. This copyright statement should not be removed
or edited.
We do grant permission to share solutions privately with non-students such
as potential employers. However, sharing with other current or future
students of CS 7646 is prohibited and subject to being investigated as a
GT honor code violation.
-----do not edit anything above this line---
Student Name: Shoabe Shariff
GT User ID: sshariff3
GT ID: 903272097
"""
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import datetime as dt
from util import get_data, plot_data
import scipy.optimize as spo
import math
import pdb
# This is the function that will be tested by the autograder
# The student must update this code to properly implement the functionality
def initial_allocations(syms):
number_of_syms = len(syms)
init_allocs = []
while len(init_allocs) < number_of_syms:
init_allocs.append(1.0 / number_of_syms)
return np.asarray(init_allocs)
def neg_sharpe_ratio(allocs, prices):
start_val = 1000000
normalized_prices = prices.apply(lambda x: x/x[0], axis=0)
alloced = normalized_prices * allocs
pos_vals = alloced * start_val
port_val = pos_vals.sum(axis=1)
daily_rets = port_val.diff()[1:]
return -1 * daily_rets.mean() / daily_rets.std()
def compute_daily_returns(df):
daily_returns = df.copy()
daily_returns[1:] = (df[1:] / df[:-1].values) - 1
return daily_returns.ix[1:]
def optimize_portfolio(sd=dt.datetime(2008,1,1), ed=dt.datetime(2009,1,1), \
syms=['GOOG','AAPL','GLD','XOM'], gen_plot=False):
# Read in adjusted closing prices for given symbols, date range
dates = pd.date_range(sd, ed)
prices_all = get_data(syms, dates) # automatically adds SPY
prices = prices_all[syms] # only portfolio symbols
prices_SPY = prices_all['SPY'] # only SPY, for comparison later
# find the allocations for the optimal portfolio
# note that the values here ARE NOT meant to be correct for a test case
init_allocs = initial_allocations(syms) # add code here to find the allocations
bnds = []
while len(bnds) < len(syms):
bnds.append((0.0, 1.0))
cnstrnts = ({ 'type': 'eq', 'fun': lambda inputs: 1.0 - np.sum(inputs) })
optimizer_result = spo.minimize(neg_sharpe_ratio, init_allocs, args=(prices,), constraints=cnstrnts, bounds=bnds)
allocs = optimizer_result.x
start_val = 1000000
normalized_prices = prices / prices.ix[0,:] # .apply(lambda x: x/x[0], axis=0)
alloced = normalized_prices * allocs
pos_vals = alloced * start_val
port_val = pos_vals.sum(axis=1)
daily_rets = compute_daily_returns(port_val)
cr = (port_val[-1]/port_val[0]) - 1
adr = daily_rets.mean()
sddr = daily_rets.std()
sr = math.sqrt(252) * daily_rets.mean() / daily_rets.std()
# Get daily portfolio value
# port_val = prices_SPY # add code here to compute daily portfolio values
# Compare daily portfolio value with SPY using a normalized plot
if gen_plot:
# add code to plot here
normalized_SPY = prices_SPY / prices_SPY.ix[0,:]
daily_portfolio_value = alloced.sum(axis=1).to_frame()
df_to_plot = daily_portfolio_value.join(normalized_SPY)
df_temp = pd.concat([df_to_plot], axis=1)
df_temp.columns=['Portfolio', 'SPY']
df_temp.plot()
plt.show()
return allocs, cr, adr, sddr, sr
def test_code():
# This function WILL NOT be called by the auto grader
# Do not assume that any variables defined here are available to your function/code
# It is only here to help you set up and test your code
# Define input parameters
# Note that ALL of these values will be set to different values by
# the autograder!
start_date = dt.datetime(2009,1,1)
end_date = dt.datetime(2010,1,1)
symbols = ['GOOG', 'AAPL', 'GLD', 'XOM', 'IBM']
# Assess the portfolio
allocations, cr, adr, sddr, sr = optimize_portfolio(sd = start_date, ed = end_date,\
syms = symbols, \
gen_plot = False)
# Print statistics
print "Start Date:", start_date
print "End Date:", end_date
print "Symbols:", symbols
print "Allocations:", allocations
print "Sharpe Ratio:", sr
print "Volatility (stdev of daily returns):", sddr
print "Average Daily Return:", adr
print "Cumulative Return:", cr
if __name__ == "__main__":
# This code WILL NOT be called by the auto grader
# Do not assume that it will be called
# test_code()
# optimize_portfolio()
optimize_portfolio(sd=dt.datetime(2008,6,1), ed=dt.datetime(2009,6,1), syms=['IBM','X','GLD','JPM'], gen_plot=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment