import pandas as pd
import quandl
start = pd.to_datetime('2012-01-01')
end = pd.to_datetime('2017-01-01')
# Grabbing a bunch of tech stocks for our portfolio
# Adjusted Close column only (11)
aapl = quandl.get('WIKI/AAPL.11',start_date=start,end_date=end)
cisco = quandl.get('WIKI/CSCO.11',start_date=start,end_date=end)
ibm = quandl.get('WIKI/IBM.11',start_date=start,end_date=end)
amzn = quandl.get('WIKI/AMZN.11',start_date=start,end_date=end)
Alternative: from CSV file
# aapl = pd.read_csv('AAPL_CLOSE',index_col='Date',parse_dates=True)
# cisco = pd.read_csv('CISCO_CLOSE',index_col='Date',parse_dates=True)
# ibm = pd.read_csv('IBM_CLOSE',index_col='Date',parse_dates=True)
# amzn = pd.read_csv('AMZN_CLOSE',index_col='Date',parse_dates=True)
aapl.to_csv('AAPL_CLOSE')
cisco.to_csv('CISCO_CLOSE')
ibm.to_csv('IBM_CLOSE')
amzn.to_csv('AMZN_CLOSE')
This is the same as Cumulative Daily Returns
# Example
aapl.iloc[0]['Adj. Close']
for stock_df in (aapl,cisco,ibm,amzn):
stock_df['Normed Return'] = stock_df['Adj. Close']/stock_df.iloc[0]['Adj. Close']
aapl.head()
aapl.tail()
Let's pretend we had the following allocations for our total portfolio:
Let's have these values be reflected by multiplying our Norme Return by out Allocations
# zip([aapl,cisco,ibm,amzn],[.3,.2,.4,.1])
# Argument after in: can be a tuple or list
for stock_df, allo in zip([aapl,cisco,ibm,amzn],[.3,.2,.4,.1]):
# tuple unpacking
stock_df['Allocation'] = stock_df['Normed Return']*allo
aapl.head()
Let's pretend we invested a million dollars in this portfolio
for stock_df in [aapl,cisco,ibm,amzn]:
stock_df['Position Values'] = stock_df['Allocation']*1000000
Use concat()
to add up portfolio values
portfolio_val = pd.concat([aapl['Position Values'],cisco['Position Values'],ibm['Position Values'],amzn['Position Values']], axis=1)
portfolio_val.head()
Change the column names by using member variable columns
portfolio_val.columns = ['AAPL Pos','CISCO Pos','IBM Pos','AMZN Pos']
portfolio_val.head()
Use aggregate function sum()
to get the Total Portfolio Value
portfolio_val['Total Pos'] = portfolio_val.sum(axis=1)
portfolio_val.head()
import matplotlib.pyplot as plt
%matplotlib inline
portfolio_val['Total Pos'].plot(figsize=(10,8))
plt.title('Total Portfolio Value')
Note the use of drop()
when plotting indvidual portfolio
portfolio_val.drop('Total Pos',axis=1).plot(kind='line', figsize=(10,8))
portfolio_val.tail()
portfolio_val['Daily Return'] = portfolio_val['Total Pos'].pct_change(1)
cum_ret = 100 * (portfolio_val['Total Pos'][-1]/portfolio_val['Total Pos'][0] -1 )
total_pos = portfolio_val['Total Pos'][-1]
print('Our cumulative return {} was percent! Our portfolio grew to ${}'.format(cum_ret, total_pos))
portfolio_val['Daily Return'].mean()
portfolio_val['Daily Return'].std()
portfolio_val['Daily Return'].plot(kind='hist', bins=100, figsize=(8,5))
portfolio_val['Daily Return'].plot(kind='kde', figsize=(8,5))
aapl['Adj. Close'].pct_change(1).plot('kde', figsize=(8,5), label='AAPL')
ibm['Adj. Close'].pct_change(1).plot('kde', label='IBM')
amzn['Adj. Close'].pct_change(1).plot('kde', label='AMZN')
cisco['Adj. Close'].pct_change(1).plot('kde', label='CISCO')
plt.legend()
The Sharpe Ratio is a measure for calculating risk-adjusted return, and this ratio has become the industry standard for such calculations.
$SR = \frac{R_p - R_f}{\sigma_p}$
Sharpe ratio = (Mean portfolio return − Risk-free rate)/Standard deviation of portfolio return
The original Sharpe Ratio
Annualized Sharpe Ratio = K-value * SR
K-values for various sampling rates:
Since I'm based in the USA, I will use a very low risk-free rate (the rate you would get if you just put your money in a bank, its currently very low in the USA, let's just say its ~0% return). If you are in a different country with higher rates for your trading currency, you can use this trick to convert a yearly rate with a daily rate:
daily_rate = ((1.0 + yearly_rate)**(1/252))-1
Other values people use are things like the 3-month treasury bill or LIBOR.
Read more: Sharpe Ratio http://www.investopedia.com/terms/s/sharperatio
import numpy as np
np.sqrt(252)* (np.mean(.001-0.0002)/.001)
Sharpe Ratio (SR): risk-free rate of zero is used
SR = portfolio_val['Daily Return'].mean()/portfolio_val['Daily Return'].std()
SR
Annualized Sharpe Ratio (ASR):
ASR = (252**0.5)*SR
ASR
Generally speaking, a Sharpe Ratio greater than 1 is considered acceptable. A ratio greater than 2 is considered very good.