avatarSofien Kaabar, CFA

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

9289

Abstract

"hljs-keyword">data</span>[i, <span class="hljs-keyword">where</span>] = <span class="hljs-built_in">max</span>(<span class="hljs-keyword">data</span>[i, high] - <span class="hljs-keyword">data</span>[i, low], <span class="hljs-built_in">abs</span>(<span class="hljs-keyword">data</span>[i, high] - <span class="hljs-keyword">data</span>[i - <span class="hljs-number">1</span>, close]), <span class="hljs-built_in">abs</span>(<span class="hljs-keyword">data</span>[i, low] - <span class="hljs-keyword">data</span>[i - <span class="hljs-number">1</span>, close]))

    except ValueError:
        
        <span class="hljs-keyword">pass</span>
    
<span class="hljs-keyword">data</span>[<span class="hljs-number">0</span>, <span class="hljs-keyword">where</span>] = <span class="hljs-number">0</span>   
  
<span class="hljs-keyword">data</span> = ema(<span class="hljs-keyword">data</span>, <span class="hljs-number">2</span>, (lookback * <span class="hljs-number">2</span>) - <span class="hljs-number">1</span>, <span class="hljs-keyword">where</span>, <span class="hljs-keyword">where</span> + <span class="hljs-number">1</span>)</pre></div><div id="63ce"><pre><span class="hljs-class"><span class="hljs-keyword">data</span> = deleter(<span class="hljs-title">data</span>, <span class="hljs-title">where</span>, 1)</span>

<span class="hljs-class"><span class="hljs-keyword">data</span> = jump(<span class="hljs-title">data</span>, <span class="hljs-title">lookback</span>)</span>

return <span class="hljs-class"><span class="hljs-keyword">data</span></span></pre></div><p id="3622">Now that we have understood what the ATR is and how to calculate it, we can proceed further with the SuperTrend. The latter seeks to provide entry and exit levels for trend followers.</p><p id="f499">You can think of it as a moving average. Its uniqueness is its main advantage and although its calculation method is much more complicated than moving averages, it is intuitive in nature and not that hard to understand. Basically, we have two variables to choose from.</p><p id="551f">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 3).</p><figure id="4fd8"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*GFg92MTicPLoloB-.png"><figcaption></figcaption></figure><p id="c657">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.</p><p id="c478">This will give us two arrays, the basic upper band and the basic lower band which form the first building blocks in the SuperTrend. The next step is to calculate the final upper band and the final lower band using the below formulas.</p><figure id="6cfc"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*BYJpF90UBUds2L_S.png"><figcaption></figcaption></figure><figure id="2bd4"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*xBfnZiJuWpAzv6bu.png"><figcaption></figcaption></figure><p id="0382">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.</p><figure id="b510"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*KzADtAIn-jGnQx9C.png"><figcaption></figcaption></figure><div id="a59e"><pre><span class="hljs-attribute">def</span> supertrend(data, multiplier, high, low, close, atr_col, where):

<span class="hljs-attribute">data</span> = adder(data, <span class="hljs-number">6</span>)

<span class="hljs-attribute">for</span> i in range(len(data)):
    
        <span class="hljs-attribute">data</span>[i, where] = (data[i, high] + data[i, low]) / <span class="hljs-number">2</span>
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">1</span>] = data[i, where] + (multiplier * data[i, atr_col])
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">2</span>] = data[i, where] - (multiplier * data[i, atr_col])

<span class="hljs-attribute">for</span> i in range(len(data)):
    
    <span class="hljs-attribute">if</span> i == <span class="hljs-number">0</span>:
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">3</span>] = <span class="hljs-number">0</span>
        
    <span class="hljs-attribute">else</span>:  
        
        <span class="hljs-attribute">if</span> (data[i, where + <span class="hljs-number">1</span>] &lt; data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">3</span>]) or (data[i - <span class="hljs-number">1</span>, close] &gt; data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">3</span>]):
            
            <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">3</span>] = data[i, where + <span class="hljs-number">1</span>]
        
        <span class="hljs-attribute">else</span>:
            
            <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">3</span>] = data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">3</span>]

<span class="hljs-attribute">for</span> i in range(len(data)):
    
    <span class="hljs-attribute">if</span> i == <span class="hljs-number">0</span>:
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">4</span>] = <span class="hljs-number">0</span>
        
    <span class="hljs-attribute">else</span>:  
        
        <span class="hljs-attribute">if</span> (data[i, where + <span class="hljs-number">2</span>] &gt; data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">4</span>]) or (data[i - <span class="hljs-number">1</span>, close] &lt; data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">4</span>]):
            
            <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">4</span>] = data[i, where + <span class="hljs-number">2</span>]
        
        <span class="hljs-attribute">else</span>:
            
            <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">4</span>] = data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">4</span>]
  
<span class="hljs-attribute">for</span> i in range(len(data)):
    
    <span class="hljs-attribute">if</span> i == <span class="hljs-number">0</span>:
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">5</span>] = <span class="hljs-number">0</span>
    
    <span class="hljs-attribute">elif</span> (data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">5</span>] == data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">3</span>]) and (data[i, close] &lt;= data[i, where + <span class="hljs-number">3</span>]):
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">5</span>] = data[i, where + <span class="hljs-number">3</span>]
    
    <span class="hljs-attribute">elif</span> (data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">5</span>] == data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">3</span>]) and (data[i, close] &gt;  data[i, where + <span class="hljs-number">3</span>]):
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">5</span>] = data[i, where + <span class="hljs-number">4</span>]
    
    <span class="hljs-attribute">elif</span> (data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">5</span>] == data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">4</span>]) and (data[i, close] &gt;= data[i, where + <span class="hljs-number">4</span>]):
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">5</span>] = data[i, where + <span class="hljs-number">4</span>]
    
    <span class="hljs-attribute">elif</span> (data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">5</span>] == data[i - <span class="hljs-number">1</span>, where + <span class="hljs-number">4</span>]) and (data[i, close] &lt;  data[i, where + <span class="hljs-number">4</span>]):
        
        <span class="hljs-attribute">data</span>[i, where + <span class="hljs-number">5</span>] = data[i, where + <span class="hljs-number">3</span>]   
        
<span class="hljs-attribute">data</span> = deleter(data, where, <span class="hljs-number">5</span>)</pre></div><div id="3741"><pre><span class="hljs-class"><span class="hljs-keyword">data</span> = jump(<span class="

Options

hljs-title">data</span>, 1) </span>

return <span class="hljs-class"><span class="hljs-keyword">data</span></span></pre></div><figure id="d9cc"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*msBv74vlSqM0nHZqWqUsig.png"><figcaption><b>EURUSD hourly values with the SuperTrend(10, 3).</b></figcaption></figure><p id="b68e">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.00.</p><p id="7c17">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.</p><figure id="a657"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*toU4F3LJ1IYyCPPRzq9IEA.png"><figcaption><b>S&amp;P500 hourly values with the SuperTrend(10, 3).</b></figcaption></figure><p id="3d0c" type="7">Make sure to focus on the concepts and not the code. You can find the codes of most of my strategies in my books. The most important thing is to comprehend the techniques and strategies.</p><p id="9cfd">Check out my weekly market sentiment report to understand the current positioning and to estimate the future direction of several major markets through complex and simple models working side by side. Find out more about the report through this link:</p><div id="2082" class="link-block">
      <a href="https://coalescence.substack.com/p/coalescence-report-1st-may-8th-may?s=w">
        <div>
          <div>
            <h2>Coalescence Report 1st May — 8th May 2022</h2>
            <div><h3>This report covers the weekly market sentiment and positioning and any changes that have occurred which might present…</h3></div>
            <div><p>coalescence.substack.com</p></div>
          </div>
          <div>
            <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*vrb7fnc7Tudo3UNe)"></div>
          </div>
        </div>
      </a>
    </div><h1 id="9a1c">Creating the Strategy</h1><p id="c94f">A pull-back happens whenever the market surpasses or breaks the SuperTrend line and then comes back to to test it before continuing the initial move. The below are the rules of the strategy:</p><ul><li><b>A long (Buy) signal is generated whenever the market surpasses the SuperTrend line and comes back to touch it on the condition that the line is flat.</b></li><li><b>A short (Sell) signal is generated whenever the market surpasses the SuperTrend line and comes back to touch it on the condition that the line is flat.</b></li></ul><blockquote id="da0e"><p>The reason we are looking for a flat line is that it signals a ranging condition which improves the possibility of a better reaction.</p></blockquote><div id="cd47"><pre><span class="hljs-attribute">my_data</span> = atr(my_data, lookback, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>)    

<span class="hljs-attribute">my_data</span> = supertrend(my_data, multiplier, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)</pre></div><figure id="c83d"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*FNhZkfLHoEV_qS8FnMR4-Q.png"><figcaption><b>Signal chart.</b></figcaption></figure><p id="5b32">The code to create the pull-back signals can be written as follows:</p><div id="10ad"><pre><span class="hljs-title">def</span> signal(<span class="hljs-class"><span class="hljs-keyword">data</span>, high_price, low_price, close_price, supertrend_column, buy_column, sell_column):</span>

<span class="hljs-class"><span class="hljs-keyword">data</span> = adder(<span class="hljs-title">data</span>, 2)</span>

for i <span class="hljs-keyword">in</span> range(len(<span class="hljs-class"><span class="hljs-keyword">data</span>)):</span>
    
   <span class="hljs-keyword">if</span> <span class="hljs-class"><span class="hljs-keyword">data</span>[i, close_price] &gt; <span class="hljs-keyword">data</span>[i, supertrend_column] and <span class="hljs-keyword">data</span>[i - 1, close_price] &lt; <span class="hljs-keyword">data</span>[i - 1, supertrend_column]:</span>
       
       for a <span class="hljs-keyword">in</span> range(i + <span class="hljs-number">1</span>, len(<span class="hljs-class"><span class="hljs-keyword">data</span>)):</span>
           
           <span class="hljs-keyword">if</span> <span class="hljs-class"><span class="hljs-keyword">data</span>[a, low_price] &lt;= <span class="hljs-keyword">data</span>[a, supertrend_column] and \</span>
              <span class="hljs-class"><span class="hljs-keyword">data</span>[a, supertrend_column] == <span class="hljs-keyword">data</span>[a - 1, supertrend_column] and \</span>
              <span class="hljs-class"><span class="hljs-keyword">data</span>[a, close_price] &gt; <span class="hljs-keyword">data</span>[a, supertrend_column]:</span>
               
               <span class="hljs-class"><span class="hljs-keyword">data</span>[a, buy_column] = 1</span>
               break</pre></div><div id="d267"><pre>elif data<span class="hljs-selector-attr">[i, close_price]</span> &lt; data<span class="hljs-selector-attr">[i, supertrend_column]</span> and data<span class="hljs-selector-attr">[i - 1, close_price]</span> &gt; data<span class="hljs-selector-attr">[i - 1, supertrend_column]</span>:
       
       <span class="hljs-keyword">for</span> <span class="hljs-selector-tag">a</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-selector-tag">i</span> + <span class="hljs-number">1</span>, <span class="hljs-built_in">len</span>(data)):
           
           <span class="hljs-keyword">if</span> data<span class="hljs-selector-attr">[a, high_price]</span> &gt;= data<span class="hljs-selector-attr">[a, supertrend_column]</span> and \
              data<span class="hljs-selector-attr">[a, supertrend_column]</span> == data<span class="hljs-selector-attr">[a - 1, supertrend_column]</span> and \
              data<span class="hljs-selector-attr">[a, close_price]</span> &lt; data<span class="hljs-selector-attr">[a, supertrend_column]</span>:
               
               data<span class="hljs-selector-attr">[a, sell_column]</span> = -<span class="hljs-number">1</span>
               break           
               
return data</pre></div><figure id="b18a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*q1wfVjsxkR00N3U6Y4kdoA.png"><figcaption><b>Signal chart.</b></figcaption></figure><p id="d609">We must combine the strategy with an indicator that confirms the direction, preferably an RSI or a Stochastic oscillator.</p><figure id="28f2"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*zlTLw4uMQMtLhv3Z66qoiA.png"><figcaption><b>Signal chart.</b></figcaption></figure><h1 id="e420">Summary</h1><p id="05a4">To sum up, what I am trying to do is to simply contribute to the world of objective technical analysis which is promoting more transparent techniques and strategies that need to be back-tested before being implemented.</p><p id="5161">This way, technical analysis will get rid of the bad reputation of being a subjective and scientifically unfounded.</p><p id="570c">Medium is a hub to interesting reads. I read a lot of articles before I decided to start writing. Consider joining Medium using my referral link (at <b>NO </b>additional cost to you).</p><div id="de8c" class="link-block">
      <a href="https://kaabar-sofien.medium.com/membership">
        <div>
          <div>
            <h2>Join Medium with my referral link — Sofien Kaabar</h2>
            <div><h3>As a Medium member, a portion of your membership fee goes to writers you read, and you get full access to every story…</h3></div>
            <div><p>kaabar-sofien.medium.com</p></div>
          </div>
          <div>
            <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*XBqK-oHjNF_4ydU8)"></div>
          </div>
        </div>
      </a>
    </div><p id="5d41">I recommend you always follow the the below steps whenever you come across a trading technique or strategy:</p><ul><li>Have a critical mindset and get rid of any emotions.</li><li>Back-test it using real life simulation and conditions.</li><li>If you find potential, try optimizing it and running a forward test.</li><li>Always include transaction costs and any slippage simulation in your tests.</li><li>Always include risk management and position sizing in your tests.</li></ul><p id="beb3">Finally, even after making sure of the above, stay careful and monitor the strategy because market dynamics may shift and make the strategy unprofitable.</p></article></body>

One of the Best Trend-Following Strategies

Creating a Strategy Based on the SuperTrend Pull-Back

The SuperTrend is a wonderful indicator that gives rise to many opportunities of strategies. Trend-following is a complex method that looks simple on books but needs a lot of care. This article discusses the flat pull-back SuperTrend strategy.

I have released a new book after the success of my previous one “Trend Following Strategies in Python”. It features a lot of advanced contrarian indicators and strategies with a GitHub page dedicated to the continuously updated code. If you are interested, you could buy the PDF version directly through a PayPal payment of 9.99 EUR.

Please include your email in the note before paying so that you receive it on the right address. Also, once you receive it, make sure to download it through google drive.

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 (ATR). 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 (TR) is calculated (the ATR is the average of that calculation).

The TR 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 a smoothed average of the true ranges to get the ATR. 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.

# 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 file
def 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
            
    # Cleaning
    Data = jump(Data, lookback)
    
    return Data
def ema(Data, alpha, lookback, what, where):
    
    alpha = alpha / (lookback + 1.0)
    beta  = 1 - alpha
    
    # First value is a simple SMA
    Data = ma(Data, lookback, what, where)
    
    # Calculating first EMA
    Data[lookback + 1, where] = (Data[lookback + 1, what] * alpha) + (Data[lookback, where] * beta)
# Calculating the rest of EMA
    for i in range(lookback + 2, len(Data)):
            try:
                Data[i, where] = (Data[i, what] * alpha) + (Data[i - 1, where] * beta)
        
            except IndexError:
                pass
            
    return 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. The latter seeks to provide entry and exit levels for trend followers.

You can think of it as a moving average. Its uniqueness is its main advantage and although its calculation method is much more complicated than moving averages, 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 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. 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.00.

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.

S&P500 hourly values with the SuperTrend(10, 3).

Make sure to focus on the concepts and not the code. You can find the codes of most of my strategies in my books. The most important thing is to comprehend the techniques and strategies.

Check out my weekly market sentiment report to understand the current positioning and to estimate the future direction of several major markets through complex and simple models working side by side. Find out more about the report through this link:

Creating the Strategy

A pull-back happens whenever the market surpasses or breaks the SuperTrend line and then comes back to to test it before continuing the initial move. The below are the rules of the strategy:

  • A long (Buy) signal is generated whenever the market surpasses the SuperTrend line and comes back to touch it on the condition that the line is flat.
  • A short (Sell) signal is generated whenever the market surpasses the SuperTrend line and comes back to touch it on the condition that the line is flat.

The reason we are looking for a flat line is that it signals a ranging condition which improves the possibility of a better reaction.

my_data = atr(my_data, lookback, 1, 2, 3, 4)    
my_data = supertrend(my_data, multiplier, 1, 2, 3, 4, 5)
Signal chart.

The code to create the pull-back signals can be written as follows:

def signal(data, high_price, low_price, close_price, supertrend_column, buy_column, sell_column):
    
    data = adder(data, 2)
    
    for i in range(len(data)):
        
       if data[i, close_price] > data[i, supertrend_column] and data[i - 1, close_price] < data[i - 1, supertrend_column]:
           
           for a in range(i + 1, len(data)):
               
               if data[a, low_price] <= data[a, supertrend_column] and \
                  data[a, supertrend_column] == data[a - 1, supertrend_column] and \
                  data[a, close_price] > data[a, supertrend_column]:
                   
                   data[a, buy_column] = 1
                   break
elif data[i, close_price] < data[i, supertrend_column] and data[i - 1, close_price] > data[i - 1, supertrend_column]:
           
           for a in range(i + 1, len(data)):
               
               if data[a, high_price] >= data[a, supertrend_column] and \
                  data[a, supertrend_column] == data[a - 1, supertrend_column] and \
                  data[a, close_price] < data[a, supertrend_column]:
                   
                   data[a, sell_column] = -1
                   break           
                   
    return data
Signal chart.

We must combine the strategy with an indicator that confirms the direction, preferably an RSI or a Stochastic oscillator.

Signal chart.

Summary

To sum up, what I am trying to do is to simply contribute to the world of objective technical analysis which is promoting more transparent techniques and strategies that need to be back-tested before being implemented.

This way, technical analysis will get rid of the bad reputation of being a subjective and scientifically unfounded.

Medium is a hub to interesting reads. I read a lot of articles before I decided to start writing. Consider joining Medium using my referral link (at NO additional cost to you).

I recommend you always follow the the below steps whenever you come across a trading technique or strategy:

  • Have a critical mindset and get rid of any emotions.
  • Back-test it using real life simulation and conditions.
  • If you find potential, try optimizing it and running a forward test.
  • Always include transaction costs and any slippage simulation in your tests.
  • Always include risk management and position sizing in your tests.

Finally, even after making sure of the above, stay careful and monitor the strategy because market dynamics may shift and make the strategy unprofitable.

Trading
Investing
Finance
Cryptocurrency
Business
Recommended from ReadMedium