In: Finance
Follow a public traded stock and analyze the changes in stock price. Write a presentation and an executive memo of your findings. Choose one of the following companies:
In your presentation you should:
Stock selected: Microsoft (MSFT)
Trend analysis using RSI and MACD
Moving Average Convergence Divergence
(MACD):
shows relationship between two Moving Averages (MA) for a
security's price.
Calculated by subtracting 26-period EMA from 12-period EMA. (EMA - Exponential Moving Average)
Inference- MACD > Signal Line - Buy suggestion; MACD < Signal Line - Sell suggestion
It is advised to use MACD with another indicator such as Relative Strength Index (RSI) to analyse patterns more effectively.
Relative Strength Index (RSI):
measures price change in relation to recent price highs and
lows.
Calculated in 2 steps:
RSI(step one) = 100 - [100/(1 + (Avg gain/ Avg loss))]
RSI(step two) = 100 - [100/(1 + (Previous Avg gain * n + current
gain/ Previous Avg loss * n + current loss))] n = period - 1 (in
above code, period is 14, n will be 13)
Inference- It is a momentum indicator | Overbought > 70% ; Oversold < 30% During downtrend, peak can be considered near 50%.
Limitations of both these indicators is they can give False Positive. One has to be careful and not to be completely reliable on the indicators when making investment decisions.
# Import necessary libraries
import yfinance as yf
import datetime as dt
import matplotlib.pyplot as plt
import numpy as np
# Download historical data for MSFT and S&P500 (benchmark)
ticker1 = "MSFT" #MICROSOFT
ohlcv1 = yf.download(ticker1,dt.date.today()-dt.timedelta(500),dt.datetime.today())
ticker2 = "^GSPC" #S&P 500
ohlcv2 = yf.download(ticker2,dt.date.today()-dt.timedelta(500),dt.datetime.today())
#Define Data Points for time period (in days)
t = 44 #for 2 months, means trading days approx 44
#Define function for MACD, a,b,c are parameteres for different periods to calculate EMA
#ewm is used with mean () to calculate exponential weighted moving average for MACD and Signal Line
def MACD(DF,a,b,c):
"""typical values a = 12; b =26, c =9"""
df = DF.copy()
df["MA_Fast"]=df["Adj Close"].ewm(span=a,min_periods=a).mean() #Adj Close column taken from ohlcv data, downloaded from yFinance
df["MA_Slow"]=df["Adj Close"].ewm(span=b,min_periods=b).mean()
df["MACD"]=df["MA_Fast"]-df["MA_Slow"] #formula to calculate MACD
df["Signal"]=df["MACD"].ewm(span=c,min_periods=c).mean() #Calculation of Signal line
df.dropna(inplace=True) #removing NaN values
return df #return entire dataframe
def RSI(DF,n):
"function to calculate RSI"
df = DF.copy()
df['delta']=df['Adj Close'] - df['Adj Close'].shift(1) #day over day in close price
df['gain']=np.where(df['delta']>=0,df['delta'],0) #np.where function is similar to IF function in excel
df['loss']=np.where(df['delta']<0,abs(df['delta']),0)
avg_gain = [] #creating empty list
avg_loss = []
gain = df['gain'].tolist() #convert data series to list
loss = df['loss'].tolist()
for i in range(len(df)): #range is length of Dataframe
if i < n:
avg_gain.append(np.NaN) #for first n = 14, it is definitely NaN value
avg_loss.append(np.NaN) #hence used append(np.NaN)
elif i == n:
avg_gain.append(df['gain'].rolling(n).mean().tolist()[n]) #calculate average first, then convert into list
avg_loss.append(df['loss'].rolling(n).mean().tolist()[n]) #append them to empty lists created above
elif i > n: #when row is greater than 14
avg_gain.append(((n-1)*avg_gain[i-1] + gain[i])/n) #formula
avg_loss.append(((n-1)*avg_loss[i-1] + loss[i])/n) #formula
df['avg_gain']=np.array(avg_gain) #convert list to array in the dataframe
df['avg_loss']=np.array(avg_loss) #convert list to array in the dataframe
df['RS'] = df['avg_gain']/df['avg_loss'] #Relative Strength Index
df['RSI'] = 100 - (100/(1+df['RS'])) #Relative Strength Index
df.dropna(inplace=True)
return df #return entire dataframe
# Visualization - plotting MACD/signal along with close price and volume for last 40 data points
df = MACD(ohlcv1, 12, 26, 9) #calling MACD function for ticker1
df1 = RSI(ohlcv1, 14) #calling RSI function for ticker1
df2 = MACD(ohlcv2, 12, 26, 9) #calling MACD function for ticker2
df3 = RSI(ohlcv2, 14) #calling RSI function for ticker2
fig, axs = plt.subplots(4,2, sharex=True, sharey=False, figsize=(30,15)) #creating subplot figure
#ticker1 Stock graphs
axs[0,0].plot(df.iloc[-t:,4]) #plotting Adj Close price of ticker1
axs[0,0].set(ylabel='Adj Close')
axs[0,0].set_title(ticker1)
axs[1,0].plot(df.iloc[-t:,-2], label='MACD') #plotting MACD line for ticker1
axs[1,0].plot(df.iloc[-t:,-1], label='Signal') #plotting Signal line for ticker1
axs[1,0].legend(loc='lower left')
axs[1,0].set(ylabel='MACD/Signal')
axs[2,0].plot(df1.iloc[-t:,-1]) #plotting RSI line for ticker1
axs[2,0].axhline(70,color='green',ls='--') #plotting overbought indicator line
axs[2,0].axhline(30,color='red',ls='--') #plotting oversold indicator line
axs[2,0].set(ylabel='RSI')
axs[3,0].bar(df.iloc[-t:,5].index, df.iloc[-t:,5].values) #plotting Volume chart for ticker1
axs[3,0].set(xlabel='Date',ylabel='Volume')
#ticker2 Stock graphs
axs[0,1].plot(df2.iloc[-t:,4]) #plotting Adj Close price of ticker2
axs[0,1].set(ylabel='Adj Close')
axs[0,1].set_title(ticker2)
axs[1,1].plot(df2.iloc[-t:,-2], label='MACD') #plotting MACD line for ticker2
axs[1,1].plot(df2.iloc[-t:,-1], label='Signal') #plotting Signal line for ticker2
axs[1,1].legend(loc='lower left')
axs[1,1].set(ylabel='MACD/Signal')
axs[2,1].plot(df3.iloc[-t:,-1]) #plotting RSI line for ticker2
axs[2,1].axhline(70,color='green',ls='--') #plotting overbought indicator line
axs[2,1].axhline(30,color='red',ls='--') #plotting oversold indicator line
axs[2,1].set(ylabel='RSI')
axs[3,1].bar(df2.iloc[-t:,5].index, df2.iloc[-t:,5].values)#plotting Volume chart for ticker2
axs[3,1].set(xlabel='Date',ylabel='Volume')
Output for the above code:
From the above charts; we can infer that
- MSFT is trading along in the direction of the Benchmark.
- From last 3 weeks, MSFT is coming down from its high, as
indicated by chart
- At the same time, RSI was above 70, meaning stock is overbought
and hence coming down for correction
- In MACD chart, despite of coming down, signal line is above the
MACD, meaning the stock can be bought at this time; this is also
supported by RSI level at 40, stock is oversold, and there are
chances that it will gain momentum in the near future.
*Disclaimer: ALL VIEWS ARE PERSONAL. NO STOCK RECOMMENDATION IS
PROVIDED.