Algorithmic Trading with the Know Sure Thing indicator in Python

A complete guide on using and implementing the KST indicator in python



While I backtested a trading strategy with one of the most popular momentum oscillators, the Moving Average Convergence/Divergence (MACD), the results were amazing. Today, I found a clone of the MACD indicator whose performance is even more efficient. It’s none other than the Know Sure Thing, shortly known as the KST indicator.


In this article, we will first build some basic intuitions on what the KST indicator is all about, and methods to calculate the indicator. After that, we will proceed to the programming part where we use Python to build the indicator from scratch, construct a simple trading strategy based on the indicator, backtest the strategy on Tesla stock and compare its performance with that of SPY ETF (an ETF whose purpose is to track the movements of the S&P 500 market index). With that being said, let’s dive into the article!


Rate Of Change (ROC)


Before moving on to exploring the KST indicator, it is essential to know what the Rate Of Change indicator has got to offer since the Know Sure Thing indicator is based on ROC. The Rate Of Change indicator is a momentum indicator that is used by traders as an instrument to determine the percentage change in price from the current closing price and the price of a specified number of periods ago. Unlike other momentum indicators like the RSI and CCI, the Rate Of Change indicator is an unbounded oscillator whose values does not bound between certain limits.


To calculate the readings of ROC, we have to first determine the ’n’ value which is nothing but how many periods ago the current closing price is compared to. The determination of ’n’ varies from one trader to another but the traditional setting is 9 (widely used for short-term trading). With 9 as the ’n’ value, the readings of the ROC indicator are calculated as follows:


First, the closing price of 9 periods ago is subtracted from the current closing price. This difference is then divided by the closing price of 9 periods ago and multiplied by 100. The calculation can be mathematically represented as follows:



ROC 9 = [ ( C.CLOSE - PREV9.CLOSE ) / PREV9.CLOSE ] * 100

where,
C.CLOSE = Current Closing Price
PREV9.CLOSE = Closing Price of 9 Periods ago


Usually, the ROC is plotted below the plot of a stock’s closing price against a zero line. If the readings of the ROC indicator are observed to be above the zero line, then the market is considered to reveal a sturdy upward momentum, and similarly, if the values are below the zero line, the market is considered to reveal a strong downward momentum. This is one way of using the ROC indicator and other usages include generating potential buy and sell signals, identifying the market state (overbought or oversold), and detecting divergences.


That’s what the ROC and its calculation are all about. Now we are ready to jump on to exploring the main idea of this article, the Know Sure Thing indicator.


Know Sure Thing (KST)


The Know Sure Thing indicator 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. 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 )


There are many types of strategies that are built with the KST indicator like the divergence trading strategy, zero line crossover, and so on. Some suggest that it can also be used as an instrument to identify overbought and oversold levels but I personally think that it won’t be as efficient as other indicators like RSI since the KST indicator is an unbounded oscillator. In today's article, we are going to discuss and implement a basic strategy called the crossover strategy.


The crossover strategy reveals a buy signal whenever the KST line crosses from below to above the Signal line. A sell signal is revealed whenever the KST line crosses from above the below the Signal line. The strategy can be represented as follows:



IF P.KST LINE < P.SIGNAL LINE AND C.KST LINE > C.SIGNAL LINE => BUY
IF P.KST LINE > P.SIGNAL LINE AND C.KST LINE < C.SIGNAL LINE => SELL


This concludes our theory part on the Know Sure Thing indicator. Now, let’s proceed to the programming part where we are going to use python to build the indicator from scratch, construct the crossover trading strategy, backtest the strategy on Tesla stock, compare the crossover strategy returns with those of the SPY ETF. Without further ado, let’s jump into the programming part and do some coding! Before moving on, a note on disclaimer: This article’s sole purpose is to educate people and must be considered as an information piece but not as investment advice or so.


Implementation in Python


The coding part is classified into various steps as follows:



1. Importing Packages
2. Extracting Stock Data from Twelve Data
3. ROC Calculation
4. Know Sure Thing Calculation
5. Know Sure Thing indicator Plot
6. Creating the Trading Strategy
7. Plotting the Trading Lists
8. Creating our Position
9. Backtesting
10. SPY ETF Comparison


We will be following the order mentioned in the above list and buckle up your seat belts to follow every upcoming coding part.


Step-1: Importing Packages


Importing the required packages into the python environment is a non-skippable step. The primary packages are going to be Pandas to work with data, NumPy to work with arrays and for complex functions, Matplotlib for plotting purposes, and Requests to make API calls. The secondary packages are going to be Math for mathematical functions and Termcolor for font customization (optional).


Python Implementation:



# IMPORTING PACKAGES

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)


Now that we have imported all the required packages into our python. Let’s pull the historical data of Tesla with Twelve Data’s API endpoint.


Step-2: Extracting data from Twelve Data


In this step, we are going to pull the historical stock data of Tesla using an API endpoint provided by twelvedata.com. Before that, a note on twelvedata.com: Twelve Data is one of the leading market data providers having an enormous amount of API endpoints for all types of market data. It is very easy to interact with the APIs provided by Twelve Data and has one of the best documentation ever. Also, ensure that you have an account on twelvedata.com, only then, you will be able to access your API key (vital element to extract data with an API).


Python Implementation:



# EXTRACTING STOCK DATA

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

tsla = get_historical_data('TSLA', '2019-01-01')
tsla



Output:



Code Explanation: The first thing we did is to define a function named ‘get_historical_data’ that takes the stock’s symbol (‘symbol’) and the starting date of the historical data (‘start_date’) as parameters. Inside the function, we are defining the API key and the URL and stored them into their respective variable. Next, we are extracting the historical data in JSON format using the ‘get’ function and stored it into the ‘raw_df’ variable. After doing some processes to clean and format the raw JSON data, we are returning it in the form of a clean Pandas dataframe. Finally, we are calling the created function to pull the historic data of Tesla from the starting of 2019 and stored it into the ‘tsla’ variable.


Step-3: ROC Calculation


In this step, we are going to define a function to calculate the values of the Rate Of Change Indicator for a given series.


Python Implementation:



# ROC CALCULATION

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


Code Explanation: 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.


Step-4: Know Sure Thing Calculation


In this step, we are going to calculate the components of the Know Sure Thing indicator by following the methods and formula we discussed before.


Python Implementation:



# KST CALCULATION

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

tsla['kst'], tsla['signal_line'] = get_kst(tsla['close'], 10, 10, 10, 15, 10, 15, 20, 30, 9)
tsla = tsla[tsla.index >= '2020-01-01']
tsla.tail()


Output:



Code Explanation: 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 and calling the created function to store Tesla’s KST line and the Signal line readings.


Step-5: Know Sure Thing indicator Plot


In this step, we are going to plot the calculated components of the KST indicator values of Tesla to make more sense out of them. The main aim of this part is not on the coding section but instead to observe the plot to gain a solid understanding of the Know Sure Thing technical indicator.


Python Implementation:



# KST INDICATOR PLOT

ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(tsla['close'], linewidth = 2.5)
ax1.set_title('TSLA CLOSING PRICES')
ax2.plot(tsla['kst'], linewidth = 2, label = 'KST', color = 'orange')
ax2.plot(tsla['signal_line'], linewidth = 2, label = 'SIGNAL', color = 'mediumorchid')
ax2.legend()
ax2.set_title('TSLA KST')
plt.show()


Output:



The above chart is divided into two panels: The upper panel with the closing price of Tesla, and the lower panel with the components of the Know Sure Thing Indicator. It can be noticed that the readings of both the components are indefinite and not bounded between certain limits because the Know Sure Thing indicator is an unbounded oscillator. This is the reason for the absence of the overbought and oversold levels in the chart that is widely plotted in other momentum oscillators. But, some propose that this indicator can be used to determine overbought and oversold levels but differ from one stock to another. This means, unlike other momentum oscillators which have default overbought and oversold levels, it is necessary to analyze the movement and readings of KST’s components to determine the overbought and oversold levels. In our case, it would be optimal to spot the overbought level at 100 and the oversold level at -100.


One special characteristic feature of the KST indicator is that apart from determining the overbought and oversold levels or spotting divergence, it can be used as a tool to detect ranging markets (markets that show no trend or momentum but move back and forth between specific high and low price ranges). Whenever both the components cross back and forth to each other, then the market is considered to be ranging. As Tesla’s stock shows huge price movements, this phenomenon can be observed only a very few times (actually two: one around June and July in the previous year, the other at the starting of 2021).


Step-6: Creating the trading strategy


In this step, we are going to implement the discussed Know Sure Thing crossover trading strategy in python.


Python Implementation:



# KST CROSSOVER TRADING STRATEGY

def implement_kst_strategy(prices, kst_line, signal_line):
    buy_price = []
    sell_price = []
    kst_signal = []
    signal = 0
    
    for i in range(len(kst_line)):
        
        if kst_line[i-1] < signal_line[i-1] and kst_line[i] > signal_line[i]:
            if signal != 1:
                buy_price.append(prices[i])
                sell_price.append(np.nan)
                signal = 1
                kst_signal.append<