Analyse stock portfolio

Analyse stock portfolio

The primary goal of this assignment is to introduce you to this form of portfolio analysis. You will use pandas for reading in data, calculating various statistics and plotting a comparison graph.

Task

For this assignment: Create a function called assess_portfolio() that takes as input a description of a portfolio and computes important statistics about it.

You are given the following inputs for analyzing a portfolio:

  • A date range to select the historical data to use (specified by a start and end date). You should consider performance from close of the start date to close of the end date.
  • Symbols for equities (e.g., GOOG, AAPL, GLD, XOM). Note: You should support any symbol in the data directory.
  • Allocations to the equities at the beginning of the simulation (e.g., 0.2, 0.3, 0.4, 0.1), should sum to 1.0.
  • Total starting value of the portfolio (e.g. $1,000,000)

Your goal is to compute the daily portfolio value over given date range, and then the following statistics for the overall portfolio:

  • Cumulative return
  • Average period return (if sampling frequency == 252 then this is average daily return)
  • Standard deviation of daily returns
  • Sharpe ratio of the overall portfolio, given daily risk free rate (usually 0), and yearly sampling frequency (usually 252, the no. of trading days in a year)
  • Ending value of the portfolio 

“””Analyze a portfolio.”””

import pandas as pd

import numpy as np

import datetime as dt

from util import get_data, plot_data

# This is the function that will be tested by the autograder

# The student must update this code to properly implement the functionality

defassess_portfolio(sd = dt.datetime(2008,1,1), ed = dt.datetime(2009,1,1), \

syms = [‘GOOG’,’AAPL’,’GLD’,’XOM’], \

allocs=[0.1,0.2,0.3,0.4], \

sv=1000000, rfr=0.0, sf=252.0, \

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

# Get daily portfolio value

port_val = prices_SPY # add code here to compute daily portfolio values

# Get portfolio statistics (note: std_daily_ret = volatility)

cr, adr, sddr, sr = [0.25, 0.001, 0.0005, 2.1] # add code here to compute stats

# Compare daily portfolio value with SPY using a normalized plot

if gen_plot:

# add code to plot here

df_temp = pd.concat([port_val, prices_SPY], keys=[‘Portfolio’, ‘SPY’], axis=1)

pass

# Add code here to properly compute end value

ev = sv

return cr, adr, sddr, sr, ev

deftest_code():

# This code WILL NOT be tested by the auto grader

# 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’]

allocations = [0.2, 0.3, 0.4, 0.1]

start_val = 1000000

risk_free_rate = 0.0

sample_freq = 252

# Assess the portfolio

cr, adr, sddr, sr, ev = assess_portfolio(sd = start_date, ed = end_date,\

“analysis.py” 72L, 2411C 

Solution

# coding: utf-8

# In[6]:

import pandas as pd

import numpy as np

import datetime as dt

from util import get_data, plot_data

# The below two functions namely – symbol_to_path and get_data are optional. As it was mentioned in your code, you can use get_data function from util directly

defnormalize_data(df):

“””Normalize stock prices using the first row of the dataframe.”””

return df / df.ix[0, :]

defassess_portfolio(sd, ed, syms, allocs, sv, rfr, sf, gen_plot):

# 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

# Get daily portfolio value

prices_all_normalised = normalize_data(prices)

pos_val = (pd.DataFrame(prices_all_normalised.values*allocs, columns=prices_all_normalised.columns, index=dprices_all_normalised.index))*sv

port_val = pd.DataFrame(pos_val.sum(axis=1))

# Get portfolio statistics (note: std_daily_ret = volatility)

for x in port_val.values:

cr = (x/(port_val.values[0]))-1

daily_return = port_val.copy()

daily_return[1:] = (port_val[1:]/port_val[:-1].values)-1

daily_return.ix[0,:]=0

adr = daily_return.mean()

sddr = adr.std()

sr = adr/sddr

# Compare daily portfolio value with SPY using a normalized plot

if gen_plot:

port_val_norm = normalize_data(port_val)

prices_SPY_norm = normalize_data(prices_SPY)

df_temp = pd.concat([port_val_norm, prices_SPY_norm], keys=[‘Portfolio’, ‘SPY’], axis=1)

df_temp_x = df_temp.ix[sd:ed]

plot_data(df_temp_x,”Portfolio Analysis”, “Date”, “Prices” )

pass

# Add code here to properly compute end value

for x in port_val.values:

ev = x

return cr, adr, sddr, sr, ev

deftest_code():

# This code WILL NOT be tested by the auto grader

# 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’]

allocations = [0.2, 0.3, 0.4, 0.1]

start_val = 1000000

risk_free_rate = 0.0

sample_freq = 252

# Assess the portfolio

cr, adr, sddr, sr, ev = assess_portfolio(sd, ed,symbols,allocations,start_val,risk_free_rate,sample_freq,”True”)

print (“Sharpe Ratio:” + sr)

print (“Volatility:” + sddr)

print (“Average Daily Return:”+adr)

print (“Cumulative Return:”+cr)