Let’s Explore ADX, SMA, KC, RSI, And MACD Using Python

These days I even have new Python documentation only for fun! after you browse one thing at leisure, you tend to note exciting facts that…

Let’s Explore ADX, SMA, KC, RSI, And MACD Using Python

These days I even have new Python documentation only for fun! after you browse one thing at leisure, you tend to note exciting facts that you simply would have uncomprehensible otherwise.

Average Directional Index (ADX)

ADX is a scientific index used extensively to measure market strength. Now, whether it’s bullish or bearish, the ADX doesn’t assess trend direction, it only shows how strong the trend is. Therefore, for the determination of trend, direction ADX is coupled with a positive management index (+ DI) and a negative management index (- DI). As the name implies, + DI measures the bullish or positive market trend, whereas -DI measures the bearish or negative market trend. All parts have 0 to 100 values, so they are an oscillation. As a lookback, ADX’s typical setting is 14. The formula for ADX is:

ADX= (Prior ADX * 13) + Current ADX/ 14

CODE

From my point of view, when accompanied by a specific index especially with RSI, the full potential of ADX will be unleashed to achieve great entry and exit points for your trade. Thus, it’s strongly advised that this post be improvised by tweaking and backtesting the ADX method together with other technical indications. By doing so, better outcomes might be achieved in the actual world market.

import pandas as pd
import numpy as np
import requests
import matplotlib.pyplot as plt
from math import floor
from termcolor import colored as cl
plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20,10)
def get_historical_data(symbol, start_date):
api_key = 'YOUR API KEY'
api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
raw_df = requests.get(api_url).json()
df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
df = df[df.index >= start_date]
df.index = pd.to_datetime(df.index)
return df
aapl = get_historical_data('AAPL', '2020-01-01')
aapl
def get_adx(high, low, close, lookback):
plus_dm = high.diff()
minus_dm = low.diff()
plus_dm[plus_dm < 0] = 0
minus_dm[minus_dm > 0] = 0

tr1 = pd.DataFrame(high - low)
tr2 = pd.DataFrame(abs(high - close.shift(1)))
tr3 = pd.DataFrame(abs(low - close.shift(1)))
frames = [tr1, tr2, tr3]
tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)
atr = tr.rolling(lookback).mean()

plus_di = 100 * (plus_dm.ewm(alpha = 1/lookback).mean() / atr)
minus_di = abs(100 * (minus_dm.ewm(alpha = 1/lookback).mean() / atr))
dx = (abs(plus_di - minus_di) / abs(plus_di + minus_di)) * 100
adx = ((dx.shift(1) * (lookback - 1)) + dx) / lookback
adx_smooth = adx.ewm(alpha = 1/lookback).mean()
return plus_di, minus_di, adx_smooth
aapl['plus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[0]).rename(columns = {0:'plus_di'})
aapl['minus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[1]).rename(columns = {0:'minus_di'})
aapl['adx'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[2]).rename(columns = {0:'adx'})
aapl = aapl.dropna()
aapl.tail()
ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(aapl['close'], linewidth = 2, color = '#ff9800')
ax1.set_title('AAPL CLOSING PRICE')
ax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')
ax2.legend()
ax2.set_title('AAPL ADX 14')
plt.show()
def implement_adx_strategy(prices, pdi, ndi, adx):
buy_price = []
sell_price = []
adx_signal = []
signal = 0

for i in range(len(prices)):
if adx[i-1] < 25 and adx[i] > 25 and pdi[i] > ndi[i]:
if signal != 1:
buy_price.append(prices[i])
sell_price.append(np.nan)
signal = 1
adx_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
adx_signal.append(0)
elif adx[i-1] < 25 and adx[i] > 25 and ndi[i] > pdi[i]:
if signal != -1:
buy_price.append(np.nan)
sell_price.append(prices[i])
signal = -1
adx_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
adx_signal.append(0)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
adx_signal.append(0)

return buy_price, sell_price, adx_signal
buy_price, sell_price, adx_signal = implement_adx_strategy(aapl['close'], aapl['plus_di'], aapl['minus_di'], aapl['adx'])
ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(aapl['close'], linewidth = 3, color = '#ff9800', alpha = 0.6)
ax1.set_title('AAPL CLOSING PRICE')
ax1.plot(aapl.index, buy_price, marker = '^', color = '#26a69a', markersize = 14, linewidth = 0, label = 'BUY SIGNAL')
ax1.plot(aapl.index, sell_price, marker = 'v', color = '#f44336', markersize = 14, linewidth = 0, label = 'SELL SIGNAL')
ax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')
ax2.legend()
ax2.set_title('AAPL ADX 14')
plt.show()
position = []
for i in range(len(adx_signal)):
if adx_signal[i] > 1:
position.append(0)
else:
position.append(1)

for i in range(len(aapl['close'])):
if adx_signal[i] == 1:
position[i] = 1
elif adx_signal[i] == -1:
position[i] = 0
else:
position[i] = position[i-1]

close_price = aapl['close']
plus_di = aapl['plus_di']
minus_di = aapl['minus_di']
adx = aapl['adx']
adx_signal = pd.DataFrame(adx_signal).rename(columns = {0:'adx_signal'}).set_index(aapl.index)
position = pd.DataFrame(position).rename(columns = {0:'adx_position'}).set_index(aapl.index)
frames = [close_price, plus_di, minus_di, adx, adx_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)
strategy
strategy[25:30]
aapl_ret = pd.DataFrame(np.diff(aapl['close'])).rename(columns = {0:'returns'})
adx_strategy_ret = []
for i in range(len(aapl_ret)):
returns = aapl_ret['returns'][i]*strategy['adx_position'][i]
adx_strategy_ret.append(returns)

adx_strategy_ret_df = pd.DataFrame(adx_strategy_ret).rename(columns = {0:'adx_returns'})
investment_value = 100000
number_of_stocks = floor(investment_value/aapl['close'][-1])
adx_investment_ret = []
for i in range(len(adx_strategy_ret_df['adx_returns'])):
returns = number_of_stocks*adx_strategy_ret_df['adx_returns'][i]
adx_investment_ret.append(returns)
adx_investment_ret_df = pd.DataFrame(adx_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(adx_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the ADX strategy by investing $100k in AAPL : {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the ADX strategy : {}%'.format(profit_percentage), attrs = ['bold']))
def get_benchmark(start_date, investment_value):
spy = get_historical_data('SPY', start_date)['close']
benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})

investment_value = investment_value
number_of_stocks = floor(investment_value/spy[-1])
benchmark_investment_ret = []

for i in range(len(benchmark['benchmark_returns'])):
returns = number_of_stocks*benchmark['benchmark_returns'][i]
benchmark_investment_ret.append(returns)
    benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})
return benchmark_investment_ret_df
benchmark = get_benchmark('2020-01-01', 100000)
investment_value = 100000
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*100)
print(cl('Benchmark profit by investing $100k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))
print(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))
print(cl('ADX Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))

Simple Moving Average (SMA)

The SMA is nothing more than the average price of a defined length of time. It is a scientific index and is used extensively to develop business strategies. Two SMAs are usually computed to develop a trading strategy, one for a shorter period and the second one for a longer duration than the first. The formula for SMA is:

SMA = (A1 + A2 + ………. + An) / n

CODE

There are still many areas for improving our code and improving performance. Some techniques are used to discover the appropriate stock for the implementation of the trading strategies, adapt and enhance trade strategy, etc. with Machine Learning There are other many packages that can be used for scientific stock research, but we only utilised the preliminary packages in this post so that we could get insight into what we are aiming to construct exactly.

import pandas as pd 
import matplotlib.pyplot as plt
import requests
import math
from termcolor import colored as cl
import numpy as np

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (15, 8)

def get_historic_data(symbol):
ticker = symbol
iex_api_key = 'Tsk_30a2677082d54c7b8697675d84baf94b'
api_url = f'https://sandbox.iexapis.com/stable/stock/{ticker}/chart/max?token={iex_api_key}'
df = requests.get(api_url).json()

date = []
open = []
high = []
low = []
close = []

for i in range(len(df)):
date.append(df[i]['date'])
open.append(df[i]['open'])
high.append(df[i]['high'])
low.append(df[i]['low'])
close.append(df[i]['close'])

date_df = pd.DataFrame(date).rename(columns = {0:'date'})
open_df = pd.DataFrame(open).rename(columns = {0:'open'})
high_df = pd.DataFrame(high).rename(columns = {0:'high'})
low_df = pd.DataFrame(low).rename(columns = {0:'low'})
close_df = pd.DataFrame(close).rename(columns = {0:'close'})
frames = [date_df, open_df, high_df, low_df, close_df]
df = pd.concat(frames, axis = 1, join = 'inner')
return df

msft = get_historic_data('MSFT')
msft = msft.set_index('date')
msft = msft[msft.index >= '2020-01-01']
msft.index = pd.to_datetime(msft.index)
msft.to_csv('msft.csv')

msft = pd.read_csv('msft.csv').set_index('date')
msft.index = pd.to_datetime(msft.index)
def sma(data, n):
sma = data.rolling(window = n).mean()
return pd.DataFrame(sma)

n = [20, 50]
for i in n:
msft[f'sma_{i}'] = sma(msft['close'], i)

plt.plot(msft['close'], label = 'MSFT', linewidth = 5, alpha = 0.3)
plt.plot(msft['sma_20'], label = 'SMA 20')
plt.plot(msft['sma_50'], label = 'SMA 50')
plt.title('MSFT Simple Moving Averages (20, 50)')
plt.legend(loc = 'upper left')
plt.show()

def implement_sma_strategy(data, short_window, long_window):
sma1 = short_window
sma2 = long_window
buy_price = []
sell_price = []
sma_signal = []
signal = 0

for i in range(len(data)):
if sma1[i] > sma2[i]:
if signal != 1:
buy_price.append(data[i])
sell_price.append(np.nan)
signal = 1
sma_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
sma_signal.append(0)
elif sma2[i] > sma1[i]:
if signal != -1:
buy_price.append(np.nan)
sell_price.append(data[i])
signal = -1
sma_signal.append(-1)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
sma_signal.append(0)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
sma_signal.append(0)

return buy_price, sell_price, sma_signal

sma_20 = msft['sma_20']
sma_50 = msft['sma_50']

buy_price, sell_price, signal = implement_sma_strategy(msft['close'], sma_20, sma_50)

plt.plot(msft['close'], alpha = 0.3, label = 'MSFT')
plt.plot(sma_20, alpha = 0.6, label = 'SMA 20')
plt.plot(sma_50, alpha = 0.6, label = 'SMA 50')
plt.scatter(msft.index, buy_price, marker = '^', s = 200, color = 'darkblue', label = 'BUY SIGNAL')
plt.scatter(msft.index, sell_price, marker = 'v', s = 200, color = 'crimson', label = 'SELL SIGNAL')
plt.legend(loc = 'upper left')
plt.title('MSFT SMA CROSSOVER TRADING SIGNALS')
plt.show()

position = []
for i in range(len(signal)):
if signal[i] > 1:
position.append(0)
else:
position.append(1)

for i in range(len(msft['close'])):
if signal[i] == 1:
position[i] = 1
elif signal[i] == -1:
position[i] = 0
else:
position[i] = position[i-1]

sma_20 = pd.DataFrame(sma_20).rename(columns = {0:'sma_20'})
sma_50 = pd.DataFrame(sma_50).rename(columns = {0:'sma_50'})
buy_price = pd.DataFrame(buy_price).rename(columns = {0:'buy_price'}).set_index(msft.index)
sell_price = pd.DataFrame(sell_price).rename(columns = {0:'sell_price'}).set_index(msft.index)
signal = pd.DataFrame(signal).rename(columns = {0:'sma_signal'}).set_index(msft.index)
position = pd.DataFrame(position).rename(columns = {0:'sma_position'}).set_index(msft.index)

frames = [sma_20, sma_50, buy_price, sell_price, signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)
strategy = strategy.reset_index().drop('date', axis = 1)

msft_ret = pd.DataFrame(np.diff(msft['close'])).rename(columns = {0:'returns'})
sma_strategy_ret = []

for i in range(len(msft_ret)):
try:
returns = msft_ret['returns'][i]*strategy['sma_position'][i]
sma_strategy_ret.append(returns)
except:
pass

sma_strategy_ret_df = pd.DataFrame(sma_strategy_ret).rename(columns = {0:'sma_returns'})

investment_value = 100000
number_of_stocks = math.floor(investment_value/msft['close'][1])
sma_investment_ret = []

for i in range(len(sma_strategy_ret_df['sma_returns'])):
returns = number_of_stocks*sma_strategy_ret_df['sma_returns'][i]
sma_investment_ret.append(returns)

sma_investment_ret_df = pd.DataFrame(sma_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(sma_investment_ret_df['investment_returns']), 2)
print(cl('Profit gained from the strategy by investing $100K in MSFT : ${} in 1 Year'.format(total_investment_ret), attrs = ['bold']))

Keltner Channel (KC)

Keltner Channels, as with all scientific-analytical index, are a method for traders to recognise price or market psychoanalysis. Even before we recognise the market’s psychologists, we could much more easily take appropriate benefit of production and consumption issues. A slow recovery meant to recognise the predominant price trend is Keltner Channels. The midline of the Keltner Channel reflects the trend in pricing. An envelope that is a crossing of the top or bottom lines around the midline may be seen as a breakdown in price or a buy-over. The formula for KC is:

MiddleLine(Basis)=EMAUpperChannelLine=EMA+2∗ATRLowerChannelLine=EMA+2∗ATR

CODE

We may exceed the genuine market’s returns themselves. This is only one example of how a strategy may be defined and how the outcomes are affected, but a lot more has to be studied. The optimisation of the strategy involves, adjusting or changing the conventional tactics that have been around for a long time but building an optimum trading environment, including the broker you use for commercial reasons, the risk management system, etc. It is thus strongly advised that you look at these areas to bring your plans to a new standard.

import requests
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from termcolor import colored as cl
from math import floor
plt.rcParams['figure.figsize'] = (20,10)
plt.style.use('fivethirtyeight')
def get_historical_data(symbol, start_date):
api_key = 'YOUR API KEY'
api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
raw_df = requests.get(api_url).json()
df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
df = df[df.index >= start_date]
df.index = pd.to_datetime(df.index)
return df
intc = get_historical_data('INTC', '2020-01-01')
print(intc.tail())
def get_kc(high, low, close, kc_lookback, multiplier, atr_lookback):
tr1 = pd.DataFrame(high - low)
tr2 = pd.DataFrame(abs(high - close.shift()))
tr3 = pd.DataFrame(abs(low - close.shift()))
frames = [tr1, tr2, tr3]
tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)
atr = tr.ewm(alpha = 1/atr_lookback).mean()

kc_middle = close.ewm(kc_lookback).mean()
kc_upper = close.ewm(kc_lookback).mean() + multiplier * atr
kc_lower = close.ewm(kc_lookback).mean() - multiplier * atr

return kc_middle, kc_upper, kc_lower

intc = intc.iloc[:,:4]
intc['kc_middle'], intc['kc_upper'], intc['kc_lower'] = get_kc(intc['high'], intc['low'], intc['close'], 20, 2, 10)
print(intc.tail())
plt.plot(intc['close'], linewidth = 2, label = 'INTC')
plt.plot(intc['kc_upper'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC UPPER 20')
plt.plot(intc['kc_middle'], linewidth = 1.5, color = 'grey', label = 'KC MIDDLE 20')
plt.plot(intc['kc_lower'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC LOWER 20')
plt.legend(loc = 'lower right', fontsize = 15)
plt.title('INTC KELTNER CHANNEL 20')
plt.show()
def implement_kc_strategy(prices, kc_upper, kc_lower):
buy_price = []
sell_price = []
kc_signal = []
signal = 0

for i in range(len(prices)):
if prices[i] < kc_lower[i] and prices[i+1] > prices[i]:
if signal != 1:
buy_price.append(prices[i])
sell_price.append(np.nan)
signal = 1
kc_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
kc_signal.append(0)
elif prices[i] > kc_upper[i] and prices[i+1] < prices[i]:
if signal != -1:
buy_price.append(np.nan)
sell_price.append(prices[i])
signal = -1
kc_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
kc_signal.append(0)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
kc_signal.append(0)

return buy_price, sell_price, kc_signal
buy_price, sell_price, kc_signal = implement_kc_strategy(intc['close'], intc['kc_upper'], intc['kc_lower'])
plt.plot(intc['close'], linewidth = 2, label = 'INTC')
plt.plot(intc['kc_upper'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC UPPER 20')
plt.plot(intc['kc_middle'], linewidth = 1.5, color = 'grey', label = 'KC MIDDLE 20')
plt.plot(intc['kc_lower'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC LOWER 20')
plt.plot(intc.index, buy_price, marker = '^', color = 'green', markersize = 15, linewidth = 0, label = 'BUY SIGNAL')
plt.plot(intc.index, sell_price, marker = 'v', color= 'r', markersize = 15, linewidth = 0, label = 'SELL SIGNAL')
plt.legend(loc = 'lower right')
plt.title('INTC KELTNER CHANNEL 20 TRADING SIGNALS')
plt.show()
position = []
for i in range(len(kc_signal)):
if kc_signal[i] > 1:
position.append(0)
else:
position.append(1)

for i in range(len(intc['close'])):
if kc_signal[i] == 1:
position[i] = 1
elif kc_signal[i] == -1:
position[i] = 0
else:
position[i] = position[i-1]

close_price = intc['close']
kc_upper = intc['kc_upper']
kc_lower = intc['kc_lower']
kc_signal = pd.DataFrame(kc_signal).rename(columns = {0:'kc_signal'}).set_index(intc.index)
position = pd.DataFrame(position).rename(columns = {0:'kc_position'}).set_index(intc.index)
frames = [close_price, kc_upper, kc_lower, kc_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)
print(strategy)
print(strategy[14:19])
intc_ret = pd.DataFrame(np.diff(intc['close'])).rename(columns = {0:'returns'})
kc_strategy_ret = []
for i in range(len(intc_ret)):
returns = intc_ret['returns'][i]*strategy['kc_position'][i]
kc_strategy_ret.append(returns)

kc_strategy_ret_df = pd.DataFrame(kc_strategy_ret).rename(columns = {0:'kc_returns'})
investment_value = 100000
number_of_stocks = floor(investment_value/intc['close'][0])
kc_investment_ret = []
for i in range(len(kc_strategy_ret_df['kc_returns'])):
returns = number_of_stocks*kc_strategy_ret_df['kc_returns'][i]
kc_investment_ret.append(returns)
kc_investment_ret_df = pd.DataFrame(kc_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(kc_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the KC strategy by investing $100k in INTC : {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the KC strategy : {}%'.format(profit_percentage), attrs = ['bold']))
def get_benchmark(start_date, investment_value):
spy = get_historical_data('SPY', start_date)['close']
benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})

investment_value = investment_value
number_of_stocks = floor(investment_value/spy[-1])
benchmark_investment_ret = []

for i in range(len(benchmark['benchmark_returns'])):
returns = number_of_stocks*benchmark['benchmark_returns'][i]
benchmark_investment_ret.append(returns)
    benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})
return benchmark_investment_ret_df
benchmark = get_benchmark('2020-01-01', 100000)
investment_value = 100000
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*100)
print(cl('Benchmark profit by investing $100k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))
print(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))
print(cl('KC Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))

Relative Strength Index (RSI)

To build a programme using RSI, the RSI index must first be understood. RSI is the Relative Strength Index term. It is an indicator of momentum which utilises the magnitude to determine if a security is overbought or oversold. If the RSI value exceeds 70, the security is overbought, if the value is less than 30 then it is oversold. The bubble produced from the purchase may quickly be bubbled by overbought and the price thus drops. This gives a solid point of entry. However, it is good to order just when the RSI value crosses the overbought line because it is a more prudent method. The formula for RSI is:

RSIstep one​=100−[1+Average lossAverage gain​100​]

CODE

This software aims at using the talib library to connect the RSI line with the oversold and overbought line. The programme is largely not based on programming the indication, but on how the oversold and overbought regions may be employed for the making of the business.

import pandas as pd 
import matplotlib.pyplot as plt
import requests
import numpy as np
from math import floor
from termcolor import colored as cl

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20, 10)

def get_historical_data(symbol, start_date = None):
api_key = open(r'api_key.txt')
api_url = f'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol={symbol}&apikey={api_key}&outputsize=full'
raw_df = requests.get(api_url).json()
df = pd.DataFrame(raw_df[f'Time Series (Daily)']).T
df = df.rename(columns = {'1. open': 'open', '2. high': 'high', '3. low': 'low', '4. close': 'close', '5. adjusted close': 'adj close', '6. volume': 'volume'})
for i in df.columns:
df[i] = df[i].astype(float)
df.index = pd.to_datetime(df.index)
df = df.iloc[::-1].drop(['7. dividend amount', '8. split coefficient'], axis = 1)
if start_date:
df = df[df.index >= start_date]
return df

ibm = get_historical_data('IBM', '2020-01-01')
print(ibm)

def get_rsi(close, lookback):
ret = close.diff()
up = []
down = []
for i in range(len(ret)):
if ret[i] < 0:
up.append(0)
down.append(ret[i])
else:
up.append(ret[i])
down.append(0)
up_series = pd.Series(up)
down_series = pd.Series(down).abs()
up_ewm = up_series.ewm(com = lookback - 1, adjust = False).mean()
down_ewm = down_series.ewm(com = lookback - 1, adjust = False).mean()
rs = up_ewm/down_ewm
rsi = 100 - (100 / (1 + rs))
rsi_df = pd.DataFrame(rsi).rename(columns = {0:'rsi'}).set_index(close.index)
rsi_df = rsi_df.dropna()
return rsi_df[3:]

ibm['rsi_14'] = get_rsi(ibm['close'], 14)
ibm = ibm.dropna()
print(ibm)

ax1 = plt.subplot2grid((10,1), (0,0), rowspan = 4, colspan = 1)
ax2 = plt.subplot2grid((10,1), (5,0), rowspan = 4, colspan = 1)
ax1.plot(ibm['close'], linewidth = 2.5)
ax1.set_title('IBM CLOSE PRICE')
ax2.plot(ibm['rsi_14'], color = 'orange', linewidth = 2.5)
ax2.axhline(30, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.axhline(70, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.set_title('IBM RELATIVE STRENGTH INDEX')
plt.show()

def implement_rsi_strategy(prices, rsi):
buy_price = []
sell_price = []
rsi_signal = []
signal = 0

for i in range(len(rsi)):
if rsi[i-1] > 30 and rsi[i] < 30:
if signal != 1:
buy_price.append(prices[i])
sell_price.append(np.nan)
signal = 1
rsi_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
rsi_signal.append(0)
elif rsi[i-1] < 70 and rsi[i] > 70:
if signal != -1:
buy_price.append(np.nan)
sell_price.append(prices[i])
signal = -1
rsi_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
rsi_signal.append(0)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
rsi_signal.append(0)

return buy_price, sell_price, rsi_signal


buy_price, sell_price, rsi_signal = implement_rsi_strategy(ibm['close'], ibm['rsi_14'])

ax1 = plt.subplot2grid((10,1), (0,0), rowspan = 4, colspan = 1)
ax2 = plt.subplot2grid((10,1), (5,0), rowspan = 4, colspan = 1)
ax1.plot(ibm['close'], linewidth = 2.5, color = 'skyblue', label = 'IBM')
ax1.plot(ibm.index, buy_price, marker = '^', markersize = 10, color = 'green', label = 'BUY SIGNAL')
ax1.plot(ibm.index, sell_price, marker = 'v', markersize = 10, color = 'r', label = 'SELL SIGNAL')
ax1.set_title('IBM RSI TRADE SIGNALS')
ax2.plot(ibm['rsi_14'], color = 'orange', linewidth = 2.5)
ax2.axhline(30, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.axhline(70, linestyle = '--', linewidth = 1.5, color = 'grey')
plt.show()

position = []
for i in range(len(rsi_signal)):
if rsi_signal[i] > 1:
position.append(0)
else:
position.append(1)

for i in range(len(ibm['close'])):
if rsi_signal[i] == 1:
position[i] = 1
elif rsi_signal[i] == -1:
position[i] = 0
else:
position[i] = position[i-1]

rsi = ibm['rsi_14']
close_price = ibm['close']
rsi_signal = pd.DataFrame(rsi_signal).rename(columns = {0:'rsi_signal'}).set_index(ibm.index)
position = pd.DataFrame(position).rename(columns = {0:'rsi_position'}).set_index(ibm.index)

frames = [close_price, rsi, rsi_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)

print(strategy.head())

ibm_ret = pd.DataFrame(np.diff(ibm['close'])).rename(columns = {0:'returns'})
rsi_strategy_ret = []

for i in range(len(ibm_ret)):
returns = ibm_ret['returns'][i]*strategy['rsi_position'][i]
rsi_strategy_ret.append(returns)

rsi_strategy_ret_df = pd.DataFrame(rsi_strategy_ret).rename(columns = {0:'rsi_returns'})
investment_value = 100000
number_of_stocks = floor(investment_value/ibm['close'][-1])
rsi_investment_ret = []

for i in range(len(rsi_strategy_ret_df['rsi_returns'])):
returns = number_of_stocks*rsi_strategy_ret_df['rsi_returns'][i]
rsi_investment_ret.append(returns)

rsi_investment_ret_df = pd.DataFrame(rsi_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(rsi_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the RSI strategy by investing $100k in IBM : {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the RSI strategy : {}%'.format(profit_percentage), attrs = ['bold']))

Moving Average Convergence Divergence (MACD)

In many different trading circles, MACD is utilised and debated. The following indicator represents a trend: the Moving Average Convergence Divergence (MACD). By extracting 26 EMA periods from 12 EMA periods, the MACD may be calculated relatively simply. MACD may be utilised to provide the trader with a possible value and insight into its management decisions and can be understood in several ways. The formula for MACD is:

MACD=12-Period EMA − 26-Period EMA

CODE

MACD is one of the most strong and efficient techniques in the actual global market. There is one crucial factor to remember when you decide to utilise MACD in the real world market. MACD tends to provide misleading signals. In addition to MACD, it is thus strongly advised to employ a technical indicator to evaluate if the signal depicted is a true trade indication.

import requests
import pandas as pd
import numpy as np
from math import floor
from termcolor import colored as cl
import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = (20, 10)
plt.style.use('fivethirtyeight')

def get_historical_data(symbol, start_date = None):
api_key = open(r'api_key.txt')
api_url = f'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol={symbol}&apikey={api_key}&outputsize=full'
raw_df = requests.get(api_url).json()
df = pd.DataFrame(raw_df[f'Time Series (Daily)']).T
df = df.rename(columns = {'1. open': 'open', '2. high': 'high', '3. low': 'low', '4. close': 'close', '5. adjusted close': 'adj close', '6. volume': 'volume'})
for i in df.columns:
df[i] = df[i].astype(float)
df.index = pd.to_datetime(df.index)
df = df.iloc[::-1].drop(['7. dividend amount', '8. split coefficient'], axis = 1)
if start_date:
df = df[df.index >= start_date]
return df

googl = get_historical_data('GOOGL', '2020-01-01')
googl

def get_macd(price, slow, fast, smooth):
exp1 = price.ewm(span = fast, adjust = False).mean()
exp2 = price.ewm(span = slow, adjust = False).mean()
macd = pd.DataFrame(exp1 - exp2).rename(columns = {'close':'macd'})
signal = pd.DataFrame(macd.ewm(span = smooth, adjust = False).mean()).rename(columns = {'macd':'signal'})
hist = pd.DataFrame(macd['macd'] - signal['signal']).rename(columns = {0:'hist'})
frames = [macd, signal, hist]
df = pd.concat(frames, join = 'inner', axis = 1)
return df

googl_macd = get_macd(googl['close'], 26, 12, 9)
googl_macd

def plot_macd(prices, macd, signal, hist):
ax1 = plt.subplot2grid((8,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((8,1), (5,0), rowspan = 3, colspan = 1)

ax1.plot(prices)
ax2.plot(macd, color = 'grey', linewidth = 1.5, label = 'MACD')
ax2.plot(signal, color = 'skyblue', linewidth = 1.5, label = 'SIGNAL')

for i in range(len(prices)):
if str(hist[i])[0] == '-':
ax2.bar(prices.index[i], hist[i], color = '#ef5350')
else:
ax2.bar(prices.index[i], hist[i], color = '#26a69a')

plt.legend(loc = 'lower right')

plot_macd(googl['close'], googl_macd['macd'], googl_macd['signal'], googl_macd['hist'])

def implement_macd_strategy(prices, data):
buy_price = []
sell_price = []
macd_signal = []
signal = 0

for i in range(len(data)):
if data['macd'][i] > data['signal'][i]:
if signal != 1:
buy_price.append(prices[i])
sell_price.append(np.nan)
signal = 1
macd_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
macd_signal.append(0)
elif data['macd'][i] < data['signal'][i]:
if signal != -1:
buy_price.append(np.nan)
sell_price.append(prices[i])
signal = -1
macd_signal.append(signal)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
macd_signal.append(0)
else:
buy_price.append(np.nan)
sell_price.append(np.nan)
macd_signal.append(0)

return buy_price, sell_price, macd_signal

buy_price, sell_price, macd_signal = implement_macd_strategy(googl['close'], googl_macd)

ax1 = plt.subplot2grid((8,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((8,1), (5,0), rowspan = 3, colspan = 1)

ax1.plot(googl['close'], color = 'skyblue', linewidth = 2, label = 'GOOGL')
ax1.plot(googl.index, buy_price, marker = '^', color = 'green', markersize = 10, label = 'BUY SIGNAL', linewidth = 0)
ax1.plot(googl.index, sell_price, marker = 'v', color = 'r', markersize = 10, label = 'SELL SIGNAL', linewidth = 0)
ax1.legend()
ax1.set_title('GOOGL MACD SIGNALS')
ax2.plot(googl_macd['macd'], color = 'grey', linewidth = 1.5, label = 'MACD')
ax2.plot(googl_macd['signal'], color = 'skyblue', linewidth = 1.5, label = 'SIGNAL')

for i in range(len(googl_macd)):
if str(googl_macd['hist'][i])[0] == '-':
ax2.bar(googl_macd.index[i], googl_macd['hist'][i], color = '#ef5350')
else:
ax2.bar(googl_macd.index[i], googl_macd['hist'][i], color = '#26a69a')

plt.legend(loc = 'lower right')
plt.show()

position = []
for i in range(len(macd_signal)):
if macd_signal[i] > 1:
position.append(0)
else:
position.append(1)

for i in range(len(googl['close'])):
if macd_signal[i] == 1:
position[i] = 1
elif macd_signal[i] == -1:
position[i] = 0
else:
position[i] = position[i-1]

macd = googl_macd['macd']
signal = googl_macd['signal']
close_price = googl['close']
macd_signal = pd.DataFrame(macd_signal).rename(columns = {0:'macd_signal'}).set_index(googl.index)
position = pd.DataFrame(position).rename(columns = {0:'macd_position'}).set_index(googl.index)

frames = [close_price, macd, signal, macd_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)

strategy

googl_ret = pd.DataFrame(np.diff(googl['close'])).rename(columns = {0:'returns'})
macd_strategy_ret = []

for i in range(len(googl_ret)):
try:
returns = googl_ret['returns'][i]*strategy['macd_position'][i]
macd_strategy_ret.append(returns)
except:
pass

macd_strategy_ret_df = pd.DataFrame(macd_strategy_ret).rename(columns = {0:'macd_returns'})

investment_value = 100000
number_of_stocks = floor(investment_value/googl['close'][-1])
macd_investment_ret = []

for i in range(len(macd_strategy_ret_df['macd_returns'])):
returns = number_of_stocks*macd_strategy_ret_df['macd_returns'][i]
macd_investment_ret.append(returns)

macd_investment_ret_df = pd.DataFrame(macd_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(macd_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the MACD strategy by investing $100k in GOOGL : {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the MACD strategy : {}%'.format(profit_percentage), attrs = ['bold']))

def get_benchmark(start_date, investment_value):
spy = get_historical_data('SPY', start_date)['close']
benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})

investment_value = investment_value
number_of_stocks = floor(investment_value/spy[-1])
benchmark_investment_ret = []

for i in range(len(benchmark['benchmark_returns'])):
returns = number_of_stocks*benchmark['benchmark_returns'][i]
benchmark_investment_ret.append(returns)

benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})
return benchmark_investment_ret_df

benchmark = get_benchmark('2020-01-01', 100000)

investment_value = 100000
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*100)
print(cl('Benchmark profit by investing $100k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))
print(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))
print(cl('MACD Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))