Some Useful Stock Analysis Functions & Stock Class
This is mostly visualization.
Here's the imports:
import statsmodels.api as sm
import pandas_datareader.data as pdr
import numpy as np
import matplotlib.pyplot as plt
Get data, btc and eth in this case:
btc = pdr.DataReader('BTC-USD', 'yahoo', start='2018-06-30', end='2022-06-30')
btc = btc[['Close']]
eth = pdr.DataReader('ETH-USD', 'yahoo', start='2018-06-30', end='2022-06-30')
eth = eth[['Close']]
Function 1: Plot price with moving averages:
def plot_price_ma(df, ma1=14, ma2=50):
fig, ax = plt.subplots(figsize=(10,6))
plt.title('Price and Moving Averages')
ax.plot(df.index,df['Close'],label='BTC', color='black', alpha=0.7)
df.rolling(window=ma1).mean()['Close'].plot(label=str(ma1)+' Day MA',
color='green', linewidth=2, alpha=0.7)
df.rolling(window=ma2).mean()['Close'].plot(label=str(ma2)+' Day MA',
color='red', linewidth=2, alpha=0.7)
ax.set_xlabel('Date')
ax.set_ylabel('Price')
plt.legend()
plt.grid()
plt.show()
Function 2: Plot pct return histogram
def plot_returns_hist(returns):
fig, ax = plt.subplots(figsize=(10,6))
plt.title('Histagram of Returns ')
ax.hist(returns, bins=100)
ax.set_xlabel('Returns (%)')
ax.set_ylabel('Frequency')
plt.grid()
plt.show()
Function 3: Print basic performance metrics
def print_basic_perf(returns, days=252):
ret = round(returns.mean()*days,2)
std = round(returns.std()*np.sqrt(days),2)
sharpe = round(ret / std,2)
print('Annual avg return:', str(ret))
print('Annual avg std:', str(std))
print('Sharpe :', str(sharpe))
Annual avg return: 54.16
Annual avg std: 72.34
Sharpe : 0.75
Function 3: Plot rolling standard deviation
def plot_rolling_std(returns,window):
ma_std = returns.rolling(window=window).std() * np.sqrt(window)
ma_std.plot()
plt.title(f'STD rolling {window} day')
plt.ylabel('Std')
plt.show()
Function 4: Plot rolling Min Max
def plot_rolling_minmax(Prices, window):
ma_max = Prices.rolling(window=window).max()
ma_min = Prices.rolling(window=window).min()
ma_max.plot(label='max')
ma_min.plot(label='min')
plt.title(f'Rolling {window} Min-Max Prices')
plt.show()
Function 5: Plot Rolling Correlation
def plot_rolling_corr(Returns1, Returns2, window):
Returns1.rolling(window=window).corr(Returns2).plot()
plt.title(f'Rolling {window} Days Correlations')
plt.ylabel('Corr')
plt.show()
def plot_ols_returns(Returns1, Returns2, names):
"""
names X first, y second
coefs beta first, const second
"""
X = sm.add_constant(Returns1.dropna())
model = sm.OLS(Returns2.dropna(),X).fit()
plt.scatter(Returns1, Returns2, alpha=0.6)
plt.plot(Returns1,(Returns1*model.params[1])+model.params[0], c='r')
plt.xlabel(names[0])
plt.ylabel(names[1])
plt.title(f'{names[0]} vs. {names[1]} Returns')
plt.show()
It is meaningful to build a Stock class with these function. Here's the Stock class:
(There may be small differences between the functions below and above, I wrote them at different times without cross-checking)
import pandas_datareader.data as pdr
import numpy as np
import matplotlib.pyplot as plt
class Asset:
def __init__(self, df, Name):
self.df = df
self.pctret = df['Close'].pct_change()
self.cumret = (self.pctret+1).cumprod()
self.Name = Name
def print_basic_perf(self, Days=252):
avgret = round(self.pctret.mean()*Days,4)
std = round(self.pctret.std()*np.sqrt(Days),4)
sharpe = round((avgret / std),4)
print(f'Daily Mean Return: {avgret}, \n' +
f'Daily Mean Std: {std} \n'+
f'Yearly Sharpe: {sharpe}')
def print_return_hist(self, bins=50, figsize=(8,6)):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(f"{self.Name} Daily % Return Frequency")
ax.hist(self.pctret*100, bins=bins)
ax.set_xlabel('Daily Returns')
ax.set_ylabel('Frequency')
ax.grid()
plt.show()
def print_price_ma(self, ma1=14, ma2=50, figsize=(8,6)):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(f'{self.Name} Daily Price and Moving Averages')
ax.plot(self.df.index, self.df['Close'],label='Price', color='black', alpha=0.7)
self.df.rolling(window=ma1).mean()['Close'].plot(label=str(ma1)+'_sma',
color='green', linewidth=2, alpha=0.7)
self.df.rolling(window=ma2).mean()['Close'].plot(label=str(ma2)+'_sma',
color='red', linewidth=2, alpha=0.7)
ax.set_xlabel('Date')
ax.set_ylabel('Price')
ax.legend()
ax.grid()
plt.show()
def print_roll_std(self, window=50, figsize=(8,6)):
rollstd = self.pctret.rolling(window=window).std() * np.sqrt(window)
fig, ax = plt.subplots(figsize=figsize)
ax.plot(rollstd.index, rollstd)
ax.set_title(f"{self.Name} {window} day rolling std")
ax.set_xlabel("Date")
ax.set_ylabel("Std")
aapl_data = pdr.DataReader('AAPL', 'yahoo', start='2018-07-12', end='2022-06-30')
tsla_data = pdr.DataReader('TSLA', 'yahoo', start='2018-07-12', end='2022-06-30')
AAPL = Asset(aapl_data, 'APPLE')
TSLA = Asset(tsla_data, 'TESLA')