Combining the SuperTrend With Moving Averages.

Share:
Indexes
  1. Join Medium with my referral link — Sofien Kaabar
  2. The Book of Trading Strategies
  3. All About Trading!

The Concept of Moving Averages

Moving averages help us confirm and ride the trend. They are the most known technical indicator and this is because of their simplicity and their proven track record of adding value to the analyses. We can use them to find support and resistance levels, stops and targets, and to understand the underlying trend. This versatility makes them an indispensable tool in our trading arsenal.

As the name suggests, this is your plain simple mean that is used everywhere in statistics and basically any other part in our lives. It is simply the total values of the observations divided by the number of observations. Mathematically speaking, it can be written down as:

The code for the moving average can be written down as the following:

# The function to add a number of columns inside an array
def adder(Data, times):

for i in range(1, times + 1):

new_col = np.zeros((len(Data), 1), dtype = float)
Data = np.append(Data, new_col, axis = 1)

return Data
# The function to delete a number of columns starting from an index
def deleter(Data, index, times):

for i in range(1, times + 1):

Data = np.delete(Data, index, axis = 1)

return Data

# The function to delete a number of rows from the beginning
def jump(Data, jump):

Data = Data[jump:, ]

return Data
# Example of adding 3 empty columns to an array
my_ohlc_array = adder(my_ohlc_array, 3)
# Example of deleting the 2 columns after the column indexed at 3
my_ohlc_array = deleter(my_ohlc_array, 3, 2)
# Example of deleting the first 20 rows
my_ohlc_array = jump(my_ohlc_array, 20)
# Remember, OHLC is an abbreviation of Open, High, Low, and Close and it refers to the standard historical data filedef ma(data, lookback, close, where):

data = adder(data, 1)

for i in range(len(data)):

try:

data[i, where] = (data[i - lookback + 1:i + 1, close].mean())

except IndexError:

pass

data = jump(data, lookback)

return data
100-period moving average applied on EURGBP.

Medium is a hub to many interesting reads. I read a lot of articles before I decided to start writing. Consider joining Medium using my referral link!

The SuperTrend Indicator

The first concept we should understand before creating the SuperTrend indicator is volatility. We sometimes measure volatility using the average true range. Although the ATR is considered a lagging indicator, it gives some insights as to where volatility is right now and where has it been last period (day, week, month, etc.). But before that, we should understand how the true range is calculated (the ATR is just the average of that calculation). The true range is simply the greatest of the three price differences:

  • High — Low
  • | High — Previous close |
  • | Previous close — Low |

Once we have gotten the maximum out of the above three, we simply take an average of n periods of the true ranges to get the average true range. Generally, since in periods of panic and price depreciation we see volatility go up, the ATR will most likely trend higher during these periods, similarly in times of steady uptrends or downtrends, the ATR will tend to go lower.

One should always remember that this indicator is lagging and therefore has to be used with extreme caution. Below is the function code that calculates the ATR. Make sure you have an OHLC array of historical data.

def atr(data, lookback, high, low, close, where):

data = adder(data, 1)

for i in range(len(data)):

try:

data[i, where] = max(data[i, high] - data[i, low], abs(data[i, high] - data[i - 1, close]), abs(data[i, low] - data[i - 1, close]))

except ValueError:

pass

data[0, where] = 0

data = ema(data, 2, (lookback * 2) - 1, where, where + 1)
data = deleter(data, where, 1)

data = jump(data, lookback)

return data

Now that we have understood what the ATR is and how to calculate it, we can proceed further with the SuperTrend indicator. The indicator seeks to provide entry and exit levels for trend followers. You can think of it as a moving average or an MACD. Its uniqueness is its main advantage and although its calculation method is much more complicated than the other two indicators, it is intuitive in nature and not that hard to understand. Basically, we have two variables to choose from. The ATR lookback and the multiplier’s value. The former is just the period used to calculated the ATR while the latter is generally an integer (usually 2 or 3).

The first thing to do is to average the high and low of the price bar, then we will either add or subtract the average with the selected multiplier multiplied by the ATR as shown in the above formulas. This will give us two arrays, the basic upper band and the basic lower band which form the first building blocks in the SuperTrend indicator. The next step is to calculate the final upper band and the final lower band using the below formulas.

It may seem complicated but most of these conditions are repetitive and in any case, I will provide the Python code below so that you can play with the function and optimize it to your trading preferences. Finally, using the previous two calculations, we can find the SuperTrend.

def supertrend(data, multiplier, high, low, close, atr_col, where):

data = adder(data, 6)

for i in range(len(data)):

data[i, where] = (data[i, high] + data[i, low]) / 2

data[i, where + 1] = data[i, where] + (multiplier * data[i, atr_col])

data[i, where + 2] = data[i, where] - (multiplier * data[i, atr_col])

for i in range(len(data)):

if i == 0:

data[i, where + 3] = 0

else:

if (data[i, where + 1] < data[i - 1, where + 3]) or (data[i - 1, close] > data[i - 1, where + 3]):

data[i, where + 3] = data[i, where + 1]

else:

data[i, where + 3] = data[i - 1, where + 3]

for i in range(len(data)):

if i == 0:

data[i, where + 4] = 0

else:

if (data[i, where + 2] > data[i - 1, where + 4]) or (data[i - 1, close] < data[i - 1, where + 4]):

data[i, where + 4] = data[i, where + 2]

else:

data[i, where + 4] = data[i - 1, where + 4]

for i in range(len(data)):

if i == 0:

data[i, where + 5] = 0

elif (data[i - 1, where + 5] == data[i - 1, where + 3]) and (data[i, close] <= data[i, where + 3]):

data[i, where + 5] = data[i, where + 3]

elif (data[i - 1, where + 5] == data[i - 1, where + 3]) and (data[i, close] > data[i, where + 3]):

data[i, where + 5] = data[i, where + 4]

elif (data[i - 1, where + 5] == data[i - 1, where + 4]) and (data[i, close] >= data[i, where + 4]):

data[i, where + 5] = data[i, where + 4]

elif (data[i - 1, where + 5] == data[i - 1, where + 4]) and (data[i, close] < data[i, where + 4]):

data[i, where + 5] = data[i, where + 3]

data = deleter(data, where, 5)
data = jump(data, 1)

return data
EURUSD hourly values with the SuperTrend(10, 3).

The above chart shows the hourly values of the EURUSD with a 10-period SuperTrend (represented by the ATR period) and a multiplier of 3. The way we should understand the indicator is that when it goes above the market price, we should be looking to short and when it goes below the market price, we should be looking to go long as we anticipate a bullish trend. Remember that the SuperTrend is a trend-following indicator. The aim here is to capture trends at the beginning and to close out when they are over.

If you are also interested by more technical indicators and strategies, then my book might interest you:

Creating the Combined Strategy

Combining indicators and techniques is the first step towards a robust trading system as getting a confluence of signals around a time period reinforces the conviction. There are many ways to create such structured strategies namely, scorecards, indices, and simultaneous conditions. The strategy we will be discussing will revolve around the simultaneous conditions and it is when certain conditions are met at the same time thus giving us a trading trigger.

The conditions for the combined strategy are as follows:

  • Long (Buy) whenever the market price turns above the SuperTrend indicator while being above the moving average.
  • Short (Sell) whenever the market price turns below the SuperTrend indicator while being below the moving average.
Signal chart on the EURUSD following the strategy.
def signal(Data, close, super_trend_col, ma_col, buy, sell):

for i in range(len(Data)):

if Data[i, close] > Data[i, super_trend_col] and Data[i - 1, close] < Data[i - 1, super_trend_col] and Data[i, close] > Data[i, ma_col]:
Data[i, buy] = 1

if Data[i, close] < Data[i, super_trend_col] and Data[i - 1, close] > Data[i - 1, super_trend_col] and Data[i, close] < Data[i, ma_col]:
Data[i, sell] = -1
return Data
Signal chart on the USDCHF following the strategy.

If you want to see more articles, consider subscribing to my DAILY Newsletter (A Free Plan is Available) via the below link. It features my Medium articles, more trading strategies, coding lessons related to research and analysis, also, subscribers get a free PDF copy of my first book. You can expect 5–7 articles per week with your paid subscription and 1–2 articles per week with the free plan. This would help me continue sharing my research. Thank you!