Finish project 2.
parent
a7e17c6059
commit
927c5eb9de
|
@ -36,5 +36,7 @@ unzip -n zips/19fall_optimize_something.zip -d ./
|
|||
# Reports
|
||||
|
||||
- [Report 1](./martingale/martingale.md)
|
||||
- [Report 2](#)
|
||||
- [Report 2](./optimize_something/readme.md)
|
||||
- [Report 3](#)
|
||||
|
||||
|
||||
|
|
|
@ -30,8 +30,42 @@ import pandas as pd
|
|||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import datetime as dt
|
||||
import math
|
||||
import scipy.optimize as opt
|
||||
from util import get_data, plot_data
|
||||
|
||||
|
||||
def get_sharpe_ratio(daily_returns):
|
||||
SR = daily_returns.mean() / daily_returns.std()
|
||||
k = math.sqrt(252) # daily sampling
|
||||
SR = k * SR
|
||||
return SR
|
||||
|
||||
|
||||
def get_daily_returns(df):
|
||||
daily_returns = df.copy()
|
||||
daily_returns[1:] = (df[1:] / df[:-1].values) - 1
|
||||
daily_returns = daily_returns.iloc[1:]
|
||||
return daily_returns
|
||||
|
||||
|
||||
def get_daily_portfolio_value(prices, allocs):
|
||||
normed = prices / prices.iloc[0, :]
|
||||
alloced = normed * allocs
|
||||
port_values = alloced.sum(axis=1)
|
||||
return port_values
|
||||
|
||||
|
||||
def calculate_stats(prices, allocs):
|
||||
port_value = get_daily_portfolio_value(prices, allocs)
|
||||
cum_ret = (port_value.iloc[-1] / port_value.iloc[0]) - 1
|
||||
daily_returns = get_daily_returns(port_value)
|
||||
avg_daily_ret = daily_returns.mean()
|
||||
std_daily_ret = daily_returns.std()
|
||||
sharpe_ratio = get_sharpe_ratio(daily_returns)
|
||||
return [cum_ret, avg_daily_ret, std_daily_ret, sharpe_ratio]
|
||||
|
||||
|
||||
# This is the function that will be tested by the autograder
|
||||
# The student must update this code to properly implement the functionality
|
||||
def optimize_portfolio(sd=dt.datetime(2008,1,1), ed=dt.datetime(2009,1,1), \
|
||||
|
@ -43,41 +77,52 @@ def optimize_portfolio(sd=dt.datetime(2008,1,1), ed=dt.datetime(2009,1,1), \
|
|||
prices = prices_all[syms] # only portfolio symbols
|
||||
prices_SPY = prices_all['SPY'] # only SPY, for comparison later
|
||||
|
||||
plot_data(prices_all)
|
||||
def calc_sr(allocs):
|
||||
port_value = get_daily_portfolio_value(prices, allocs)
|
||||
cum_ret = (port_value.iloc[-1] / port_value.iloc[0]) - 1
|
||||
daily_returns = get_daily_returns(port_value)
|
||||
sharpe_ratio = get_sharpe_ratio(daily_returns)
|
||||
return sharpe_ratio * -1
|
||||
|
||||
# find the allocations for the optimal portfolio
|
||||
# note that the values here ARE NOT meant to be correct for a test case
|
||||
allocs = np.asarray([0.2, 0.2, 0.3, 0.3]) # add code here to find the allocations
|
||||
cr, adr, sddr, sr = [0.25, 0.001, 0.0005, 2.1] # add code here to compute stats
|
||||
|
||||
# Get daily portfolio value
|
||||
port_val = prices_SPY # add code here to compute daily portfolio values
|
||||
len_syms = len(syms)
|
||||
allocs = np.asarray([1 / len_syms for _ in range(len_syms)])
|
||||
bounds = [(0, 1) for _ in range(len_syms)]
|
||||
consts = ({'type': 'eq', 'fun': lambda inputs: 1.0 - np.sum(inputs)})
|
||||
result = opt.minimize(calc_sr, x0=allocs, bounds=bounds, constraints=consts)
|
||||
print(result)
|
||||
allocs = result.x
|
||||
cr, adr, sddr, sr = calculate_stats(prices, allocs)
|
||||
|
||||
# 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
|
||||
port_val = get_daily_portfolio_value(prices, allocs)
|
||||
prices_SPY_normed = prices_SPY / prices_SPY.iloc[0]
|
||||
df_temp = pd.concat([port_val, prices_SPY_normed], keys=['Portfolio', 'SPY'], axis=1)
|
||||
ax = df_temp.plot(title="SPY and Portfolio Normed", fontsize=12)
|
||||
plt.savefig('plot.png')
|
||||
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
|
||||
|
||||
def report():
|
||||
start_date = dt.datetime(2008,6,1)
|
||||
end_date = dt.datetime(2009,6,1)
|
||||
symbols = ['IBM', 'X', 'GLD', 'JPM']
|
||||
allocations, cr, adr, sddr, sr = optimize_portfolio(sd = start_date, ed = end_date,\
|
||||
syms = symbols, gen_plot = True)
|
||||
|
||||
|
||||
def test_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)
|
||||
syms = symbols, gen_plot = True)
|
||||
|
||||
# Print statistics
|
||||
print(f"Start Date: {start_date}")
|
||||
|
@ -90,6 +135,5 @@ def test_code():
|
|||
print(f"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()
|
||||
# test_code()
|
||||
report()
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
|
@ -0,0 +1,7 @@
|
|||
# Report
|
||||
|
||||
IBM, X, GLD, JPM portfolio optimization for the timeframe from 08-06-01 till
|
||||
09-06-01.
|
||||
|
||||
![](plot.png)
|
||||
|
Loading…
Reference in New Issue