top of page
  • Nikhil Adithyan

Top 3 Best-Performing Technical Indicators Implemented in Python

Efficient indicators that are necessary to trade the market successfully with its implementation in Python



The market is strangled itself with tons and tons of technical indicators and it’s gonna be a nightmare for a beginner trader to choose the right one. Since I spent a pretty good amount of time roaming around these indicators and implementing them in the market, I decided to create a list of the top 3 best-performing indicators along with their implementation in Python to help out the beginners with a great kickstart into the technical analysis realm. Without further ado, let’s dive into the article!


Note: The upcoming indicators are not randomly chosen but picked based on the results obtained by backtesting them on the historical data of Apple.


1. Disparity Index


The Disparity Index is a momentum indicator that measures the distance between the current closing price of a stock and its moving average for a specified number of periods and interprets the readings in the form of percentages. Unlike other momentum oscillators, the Disparity Index does not bound between certain levels and hence is an unbounded oscillator.

Traders often use the Disparity Index to determine the current momentum of a market. Upward momentum in the market can be observed if the readings of the Disparity Index are above zero, and similarly, the market is considered to be in a downward momentum if the readings of the indicator are below zero.


Math


The calculation of the Disparity Index is pretty much straightforward. First, we have to find the difference between the closing of the price of a stock and the moving average for a specified number of periods and divide the difference by the moving average, then multiply it by 100. The calculation of the Disparity Index with a typical setting of 14 as the lookback period can be represented as follows:



DI 14 = [ C.PRICE - MOVING  AVG 14 ] / [ MOVING AVG 14 ] * 100

where,
DI 14 = 14-day Disparity Index
MOVING AVG 14 = 14-day Moving Average
C.PRICE = Closing price of the stock

Python Implementation


Now, let’s implement the above-discussed math practically using Python to calculate the indicator.



def get_di(data, lookback):
    ma = data.rolling(lookback).mean()
    di = ((data - ma) / ma) * 100
    return di

Code Explanation


First, we are defining a function named ‘get_di’ that takes a stock’s closing price (‘data’) and the lookback period (‘lookback’) as parameters. Inside the function, we are first calculating the Moving Average of the closing price data for the specified number of lookback periods. Then, we are substituting the determined values into the Disparity Index formula to calculating the readings. Finally, we are returning the calculated readings as output.


2. Know Sure Thing


The Know Sure Thing indicator (shortly known as KST) is an unbounded momentum oscillator that is widely used by traders to understand the readings of the ROC indicator feasibly. The KST indicator is based on four different timeframes of smoothed ROC and combines the collective data into one oscillator.


Components & Math


The Know Sure Thing indicator is composed of two components:


KST line: The first component is the KST line itself. To calculate the readings of the KST line, we have to first determine four ROCs with 10, 15, 20, 30 as the ’n’ values respectively. Then each ROC is smoothed using a Simple Moving Average with 10, 10, 10, 15 as the lookback period respectively. This smoothed ROC is known as ROCSMA. After attaining the ROCSMA for four different timeframes, we have to multiply the first ROCSMA with one, the second ROCSMA with two, the third ROCSMA with three, and the fourth with four. Finally, these four products are added to each other. The calculation of the KST line can be mathematically represented as follows:



KL = (ROCSMA1 * 1) + (ROCSMA2 * 2) + (ROCSMA3 * 3) + (ROCSMA4 * 4)

where,
KL = KST Line
ROCSMA1 = ROC 10 smoothed with SMA 10
ROCSMA2 = ROC 15 smoothed with SMA 10
ROCSMA3 = ROC 20 smoothed with SMA 10
ROCSMA4 = ROC 30 smoothed with SMA 15

Signal line: Now, the second component of the Know Sure Thing indicator is the Signal line component. This component is nothing but the smoothed version of the KST line. To smooth the values of the KST line, the Simple Moving Average with 9 as the lookback period is widely used. The calculation of the Signal line looks something as follows:



SIGNAL LINE = SMA9 ( KST LINE )

Python Implementation


Now it’s time to implement the indicator in Python to obtain its components’ readings.



def get_roc(close, n):
    difference = close.diff(n)
    nprev_values = close.shift(n)
    roc = (difference / nprev_values) * 100
    return roc

def get_kst(close, sma1, sma2, sma3, sma4, roc1, roc2, roc3, roc4, signal):
    rcma1 = get_roc(close, roc1).rolling(sma1).mean()
    rcma2 = get_roc(close, roc2).rolling(sma2).mean()
    rcma3 = get_roc(close, roc3).rolling(sma3).mean()
    rcma4 = get_roc(close, roc4).rolling(sma4).mean()
    kst = (rcma1 * 1) + (rcma2 * 2) + (rcma3 * 3) + (rcma4 * 4)
    signal = kst.rolling(signal).mean()
    return kst, signal

Code Explanation


The above code can be classified into two different parts: ROC calculation, and KST calculation.


ROC calculation: We are first defining a function named ‘get_roc’ that takes the stock’s closing price (‘close’) and the ’n’ value (’n’) as parameters. Inside the function, we are first taking the difference between the current closing price and the closing price for a specified number of periods ago using the ‘diff’ function provided by the Pandas package. With the help of the ‘shift’ function, we are taking into account the closing price for a specified number of periods ago and stored it into the ‘nprev_values’ variable. Then, we are substituting the determined values into the ROC indicator formula we discussed before to calculate the values and finally returned the data.


KST calculation: Firstly, we are defining a function named ‘get_kst’ that takes the closing price of the stock (‘close’), four lookback periods for smoothing the ROC values (‘sma1’, ‘sma2’, ‘sma3’, ‘sma4’), four ’n’ values of ROC (‘roc1’, ‘roc2’, ‘roc3’, ‘roc4’), and the lookback period for the signal line (‘signal’) as parameters. Inside the function, we are first calculating the four ROCSMA values using the ‘rolling’ function provided by the Pandas package and the ‘get_roc’ function we created previously. Then, we are substituting the calculated ROCSMAs into the formula we discussed before to determine the readings of the KST line. Then, we are smoothing the KST line values with the ‘rolling’ function to get the values of the Signal line and stored them into the ‘signal’ variable. Finally, we are returning both the calculated components of the KST indicator.


3. True Strength Index


The True Strength Index (TSI) is a momentum oscillator that is primarily used by traders to determine whether a market is an upward or a downward momentum and trade along with it. It is also used to identify the current state of the market, overbought or oversold but, this is not the indicator’s main forte.


Components & Math


Like the Know Sure Thing indicator, the True Strength Index is also composed of two components:


TSI Line: The first component is the TSI line itself which is calculated by first determining the actual price change (current closing price minus the previous closing price) and the absolute price change (absolute values of the actual price change). Then an EMA with 25 as the number of periods (long) is taken for both the actual price change and the absolute price change. These two EMAs are then again smoothed by a 13-day period (short) Exponential Moving Average. This process of smoothing a data series with two EMAs is known as double smoothing and the goal of doing this is to eliminate noise from the data. Now, the double-smoothed actual price change is divided by the double-smoothed absolute price change and then multiplied by 100 to obtain the readings of the TSI line. Note that the parameters (25, 13) we took into consideration are the typical setting but can be tuned accordingly. The calculation might be fuzzy but can be easily understood if we interpret it in the form of a formula or representation:



TSI LINE = [ DS. ACTUAL PC / DS. ABSOLUTE PC ] * 100

where,
DS. ACTUAL PC = Double smoothed actual price change with the length of 25 and 13
DS. ABSOLUTE PC = Double smoothed absolute price change with the length of 25 and 13

Signal line: The next component is the Signal line component which is nothing but an Exponential Moving Average of the TSI for a specified number of periods (falls within 7 to 12 periods). Most traders prefer periods near to 7 for day trading purposes and close to 12 for long-term investing. In this article, we are going with 12 as the number of periods since we will be dealing with a daily timeframe stock data rather than a minute timeframe. The calculation can be represented as follows:



SIGNAL LINE = EXP.MA 13 [ TSI LINE ]

Python Implementation


Unlike the other two indicators, the True Strength Index has a pretty long code given its complex mathematical formulas to calculate its components. Now, let’s code the indicator in Python.



def get_tsi(close, long, short, signal):
    diff = close - close.shift(1)
    abs_diff = abs(diff)
    
    diff_smoothed = diff.ewm(span = long, adjust = False).mean()
    diff_double_smoothed = diff_smoothed.ewm(span = short, adjust = False).mean()
    abs_diff_smoothed = abs_diff.ewm(span = long, adjust = False).mean()
    abs_diff_double_smoothed = abs_diff_smoothed.ewm(span = short, adjust = False).mean()
    
    tsi = (diff_double_smoothed / abs_diff_double_smoothed) * 100
    signal = tsi.ewm(span = signal, adjust = False).mean()
    tsi = tsi[tsi.index >= '2020-01-01'].dropna()
    signal = signal[signal.index >= '2020-01-01'].dropna()
    
    return tsi, signal

Code Explanation


Firstly, we are defining a function named ‘get_tsi’ that takes a stock’s closing price data (‘close’), the lookback period for the long EMA (‘long’), the lookback period for the short EMA (‘short’), and the lookback period for the signal line (‘signal’) as parameters. Inside the function, we are first calculating and storing the actual price change (‘diff’) and the absolute price change (‘abs_diff’) into their respective variable.


Then, using the ‘ewm’ function provided by the Pandas package for determining the Exponential Moving Average, we are double smoothing the previously calculated price changes to obtain the double smoothed actual price change (‘diff_double_smoothed’) and the double smoothed absolute price change (‘abs_diff_double_smoothed’).


We are then substituting the double smoothed values into the formula of the TSI line to determine its readings. To calculate the signal line’s values, we are taking an EMA of the determined TSI line’s readings for a specified number of periods. Finally, we are returning the calculated components.


Honorable mentions: Coppock Curve, MACD, Aroon, and Awesome Oscillator


Final Thoughts!


One important aspect to keep in mind is that great indicators become obsolete if the constructed strategy is not efficient. So make sure that you don’t just have good-working indicators in your arsenal but also a trading strategy that is apt to the market. Also, don’t remember to backtest and evaluate the strategy to draw practical insights. Without these two processes, arriving at conclusions and deploying them into the real-world market are fatal.


With that being said, you’ve reached the end of the article. If you forgot to follow any of the coding parts, don’t worry. I’ve provided the full source code at the bottom of the article. Hope you learned something new and useful from this article.


Hang on! If you’re interested in learning about technical indicators and algorithmic trading with Python, it is highly recommended to take the online program Algorithmic Trading for Everyone which is a specialization conducted by Quantra (a python platform for quantitative finance). This program is well-structured and designed in a fashion that makes both beginners and advanced users enjoy and follow along with the concepts more easily and efficiently.


Full code:



# DISPARITY INDEX
def get_di(data, lookback):
    ma = data.rolling(lookback).mean()
    di = ((data - ma) / ma) * 100
    return di
# KNOW SURE THING
def get_roc(close, n):
    difference = close.diff(n)
    nprev_values = close.shift(n)
    roc = (difference / nprev_values) * 100
    return roc
def get_kst(close, sma1, sma2, sma3, sma4, roc1, roc2, roc3, roc4, signal):
    rcma1 = get_roc(close, roc1).rolling(sma1).mean()
    rcma2 = get_roc(close, roc2).rolling(sma2).mean()
    rcma3 = get_roc(close, roc3).rolling(sma3).mean()
    rcma4 = get_roc(close, roc4).rolling(sma4).mean()
    kst = (rcma1 * 1) + (rcma2 * 2) + (rcma3 * 3) + (rcma4 * 4)
    signal = kst.rolling(signal).mean()
    return kst, signal
# TRUE STRENGTH INDEX
def get_tsi(close, long, short, signal):
    diff = close - close.shift(1)
    abs_diff = abs(diff)
    
    diff_smoothed = diff.ewm(span = long, adjust = False).mean()
    diff_double_smoothed = diff_smoothed.ewm(span = short, adjust = False).mean()
    abs_diff_smoothed = abs_diff.ewm(span = long, adjust = False).mean()
    abs_diff_double_smoothed = abs_diff_smoothed.ewm(span = short, adjust = False).mean()
    
    tsi = (diff_double_smoothed / abs_diff_double_smoothed) * 100
    signal = tsi.ewm(span = signal, adjust = False).mean()
    tsi = tsi[tsi.index >= '2020-01-01'].dropna()
    signal = signal[signal.index >= '2020-01-01'].dropna()
    
    return tsi, signal

 

3 comments
bottom of page