Hello and welcome back everyone to our second part of the new blog series Python for Stock Market Analysis. In the last part, we explored different types of moving averages like Simple Moving Average (SMA), Exponential Moving Average (EMA), Weighted Moving Average (WMA) and explored other moving metrics like Moving Median and Moving Variance. Until now we were looking only into the trend over the time and trend over the period of time. These simple metrics are used under the hood to make some assumptions in the stock markets. In this blog, we will explore some of popular metrics that are used in the stock markets which are based on Moving Averages.
Disclaimer: This blog is for educational purpose only and we do not recommend taking the knowledge gained from this blog to implement in real financial exercises.
Technical indicators in stock markets are categorized in many ways and some of the most common are:
All above 4 are used to either predict or alert us about the future of the stock. The indicators are often viewed in the terms of leading and lagging. Leading indicators give some kind of predictions about the price rise or trend by using short term moving averages (like EMA of period 12 in MACD (Moving Average Convergence Divergence)). Lagging indicators give the information that has happened and might continue to do so. Like EMA of different periods.
Before diving into the coding part, lets read our data.
import pandas as pd
import numpy as np
import plotly.express as px
import cufflinks
import plotly.io as pio
import yfinance as yf
import warnings
warnings.filterwarnings("ignore")
cufflinks.go_offline()
cufflinks.set_config_file(world_readable=True, theme='pearl')
pio.renderers.default = "notebook" # should change by looking into pio.renderers
pd.options.display.max_columns = None
symbols = ["AAPL"]
df = yf.download(tickers=symbols)
df.head()
[*********************100%***********************] 1 of 1 completed
Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|
Date | ||||||
1980-12-12 | 0.128348 | 0.128906 | 0.128348 | 0.128348 | 0.100326 | 469033600 |
1980-12-15 | 0.122210 | 0.122210 | 0.121652 | 0.121652 | 0.095092 | 175884800 |
1980-12-16 | 0.113281 | 0.113281 | 0.112723 | 0.112723 | 0.088112 | 105728000 |
1980-12-17 | 0.115513 | 0.116071 | 0.115513 | 0.115513 | 0.090293 | 86441600 |
1980-12-18 | 0.118862 | 0.119420 | 0.118862 | 0.118862 | 0.092911 | 73449600 |
# convert column names into lowercase
df.columns = [c.lower() for c in df.columns]
df.rename(columns={"adj close":"adj_close"},inplace=True)
Trend indicators are used as a basic way to visualize the flow of the stock's performance over the course of the time (daily, monthly, weekly, in last 3 weeks etc). We can apply these indicators in stocks's performances like volume, price and transactions. Trend indicators are different in kinds and we have explored some of them in the previous blog where have explored trend of Open, High, Low and Volume of the Apple's Floorsheet data. The trend itself doesnot predict anything about the price rise or fall on the future but we can make some kind of analogy based on the recent performance of the stock.
Despite the price being high/low throughout the day, most traders find the closing price to be most important to describe the performance of the stock on that day. So, we will calculate most single variate indicators based on Closing Price of that day.
Some of popular trend indicators are:
We will calculate these in our data next.
Moving Averages are common trend indicators that are a building blocks of popular indicators like GMMA (Guppy Multiple Moving Average), MACD (Moving Average Convergence Divergence)and PPO (Percentage Price Oscillator). But first lets write a simple function that could give us moving average of given window.
def moving_average(series, window=5, kind="sma"):
if kind=="sma":
return series.rolling(window=window, min_periods=window).mean()
elif kind=="ema":
return series.rolling(window=window, min_periods=window).mean()
elif kind=="wma":
return series.rolling(window=window, min_periods=window).apply(lambda x: np.average(x, weights=np.arange(1, window+1,1)))
tdf = df.copy()
window=30
tdf[f"close_sma_{window}"] = moving_average(tdf.close, window=window)
tdf[f"close_ema_{window}"] = moving_average(tdf.close, window=window, kind="ema")
tdf[f"close_wma_{window}"] = moving_average(tdf.close, window=window, kind="wma")
tdf
open | high | low | close | adj_close | volume | close_sma_30 | close_ema_30 | close_wma_30 | |
---|---|---|---|---|---|---|---|---|---|
Date | |||||||||
1980-12-12 | 0.128348 | 0.128906 | 0.128348 | 0.128348 | 0.100326 | 469033600 | NaN | NaN | NaN |
1980-12-15 | 0.122210 | 0.122210 | 0.121652 | 0.121652 | 0.095092 | 175884800 | NaN | NaN | NaN |
1980-12-16 | 0.113281 | 0.113281 | 0.112723 | 0.112723 | 0.088112 | 105728000 | NaN | NaN | NaN |
1980-12-17 | 0.115513 | 0.116071 | 0.115513 | 0.115513 | 0.090293 | 86441600 | NaN | NaN | NaN |
1980-12-18 | 0.118862 | 0.119420 | 0.118862 | 0.118862 | 0.092911 | 73449600 | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2022-02-28 | 163.059998 | 165.419998 | 162.429993 | 165.119995 | 165.119995 | 94869100 | 168.273667 | 168.273667 | 168.313550 |
2022-03-01 | 164.699997 | 166.600006 | 161.970001 | 163.199997 | 163.199997 | 83474400 | 167.944667 | 167.944667 | 167.986216 |
2022-03-02 | 164.389999 | 167.360001 | 162.949997 | 166.559998 | 166.559998 | 79724800 | 167.836667 | 167.836667 | 167.896883 |
2022-03-03 | 168.470001 | 168.910004 | 165.550003 | 166.229996 | 166.229996 | 76335600 | 167.836667 | 167.836667 | 167.793226 |
2022-03-04 | 164.490005 | 165.550003 | 162.110001 | 162.539993 | 162.539993 | 29556127 | 167.771000 | 167.771000 | 167.451506 |
cols = [c for c in tdf.columns if "close" in c and "adj" not in c]
tdf[cols].iplot(kind="line")