# Profitable Future Backtesting of KST Trading Strategy in Python

Written on

## Understanding the KST Trading Indicator

The KST (Know Sure Thing) indicator serves as a momentum oscillator designed to detect significant trend shifts within the market. Developed by Martin J. Pring, it relies on four distinct time frames: 10, 15, 20, and 30 periods.

The KST is determined through a weighted moving average of the rate of change (ROC) values derived from these four time frames. ROC measures the percentage change in price over a defined timeframe. To refine the KST, a secondary moving average is applied for smoothing.

The KST can signal buying or selling opportunities based on the interaction between two lines: the KST line and the signal line. An upward cross of the KST line over the signal line indicates a buying opportunity, whereas a downward cross suggests a selling opportunity.

### Backtesting the KST Trading Strategy

Backtesting is an essential phase in crafting any trading strategy, enabling traders to assess their strategies against historical data. This guide will detail how to backtest a trading strategy utilizing the KST indicator.

To initiate the process, we will import historical price data for our chosen asset and compute the KST indicator using the following code:

def calculate_KST(df, roc_periods=(10, 15, 20, 30), sma_periods=(10, 10, 10, 15)):

for i, r in enumerate(roc_periods):

df[f'ROC{i+1}'] = ((df['Close'] - df['Close'].shift(r)) / df['Close'].shift(r)) * 100weights = [1, 2, 3, 4]

for i, s in enumerate(sma_periods):

df[f'WMA{i+1}'] = df[[f'ROC{j+1}' for j in range(i+1)]] @ weights[:i+1] / sum(weights[:i+1])df['KST'] = df[[f'WMA{j+1}' for j in range(4)]] @ weights / sum(weights)

df['KSTS'] = df['KST'].rolling(window=9).mean()

return df

This function processes a DataFrame containing historical price data, along with two tuples—roc_periods and sma_periods—that define the periods for rate of change and moving average calculations. The function returns the DataFrame augmented with additional columns for each ROC value, weighted moving averages, the KST, and the KSTS (KST smoothed with a 9-period moving average).

Next, we will establish our trading strategy, generating buy signals when the KST line crosses above the KSTS line, and sell signals when it crosses below. The code for this is as follows:

def generate_signals(df):

signals = []

for i in range(1, len(df)-1):

if df.iloc[i]['KSTS'] > df.iloc[i]['KST']:

signals.append(-1)elif df.iloc[i]['KST'] > df.iloc[i]['KSTS']:

signals.append(1)else:

signals.append(0)return signals

This function takes the DataFrame containing the KST and KSTS columns and produces a list of signals based on their intersections.

Finally, we will backtest our strategy using the historical price data alongside the signals generated by our trading strategy. For this test, we'll assume an initial capital of $1,000 and employ the following code to simulate trades:

df["signal"] = signals

print(signals)

investment = 1000

current_investment = 1000

invested_amount = 0

fees = 0

profit = 0

is_invested = 0

best_trade = -99999999

worst_trade = 99999999

largest_loss = 0

largest_gain = 0

total_trades = 0

for i in range(500, len(df)):

signal = df.iloc[i]['signal']

close = df.iloc[i]['close']

if signal == 1 and is_invested == 0: # Long signal and no position

entry_point = close

quantity = (current_investment / close)

invested_amount = quantity * close

is_invested = 1

elif signal == -1 and is_invested == 0: # Short signal and no position

entry_point = close

quantity = (current_investment / close)

invested_amount = quantity * close

is_invested = -1

elif signal == -1 and is_invested == 1: # Close long position for short signal

profit = quantity * (-entry_point + close)

current_investment += profit

invested_amount = 0

total_trades += 1

if profit > largest_gain:

largest_gain = profitif profit < largest_loss:

largest_loss = profitif profit > best_trade:

best_trade = profitif profit < worst_trade:

worst_trade = profitentry_point = close

quantity = (current_investment / close)

invested_amount = quantity * close

is_invested = -1

elif signal == 1 and is_invested == -1: # Close short position for long signal

profit = quantity * (-close + entry_point)

current_investment += profit

invested_amount = 0

total_trades += 1

if profit > largest_gain:

largest_gain = profitif profit < largest_loss:

largest_loss = profitif profit > best_trade:

best_trade = profitif profit < worst_trade:

worst_trade = profitentry_point = close

quantity = (current_investment / close)

invested_amount = quantity * close

is_invested = 1

else:

pass

final_profit = current_investment - investment

print("Final Profit: ", final_profit)

print("Best Trade: ", best_trade)

print("Worst Trade: ", worst_trade)

print("Largest Loss: ", largest_loss)

print("Largest Gain: ", largest_gain)

print("Total Trades: ", total_trades)

After conducting the backtest on historical data, I achieved a final portfolio value of $3,519,043. This outcome suggests that the strategy was successful, indicating its potential for generating positive returns in future trading endeavors.

Now, let's dive into some instructional videos.

### How To Backtest A Trading Strategy in Python

This video will guide you through the process of backtesting a trading strategy using Python, providing valuable insights and practical examples.

### Backtesting a Trading Strategy in Python With AI Generated Code

In this video, discover how to leverage AI-generated code for backtesting your trading strategies effectively in Python.