Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Add Supertrend Indicator to Backtrader

    Indicators/Strategies/Analyzers
    4
    5
    4484
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N
      nicostro last edited by

      Dear all,

      I would like to incorporate the supertrend indicator to backtrader (function is shown below). I'm new to backtrader / python, and I'm not sure how to code it to make it work properly with a calling like this:

      self.supertrend = supertrend(self.datas)
      

      Would be much appreciated if someone could provide guidance on how to implement it.

      Many thanks in advance!

      import backtrader as bt
      import numpy as np
      from pandas import DataFrame
      import talib.abstract as ta
      
      def supertrend(dataframe, multiplier=3, period=10):
          df = dataframe.copy()
      
          df['TR'] = ta.TRANGE(df)
          df['ATR'] = df['TR'].ewm(alpha=1 / period).mean()
      
          # atr = 'ATR_' + str(period)
          st = 'ST_' + str(period) + '_' + str(multiplier)
          stx = 'STX_' + str(period) + '_' + str(multiplier)
      
          # Compute basic upper and lower bands
          df['basic_ub'] = (df['high'] + df['low']) / 2 + multiplier * df['ATR']
          df['basic_lb'] = (df['high'] + df['low']) / 2 - multiplier * df['ATR']
      
          # Compute final upper and lower bands
          df['final_ub'] = 0.00
          df['final_lb'] = 0.00
          for i in range(period, len(df)):
              df['final_ub'].iat[i] = df['basic_ub'].iat[i] if df['basic_ub'].iat[i] < df['final_ub'].iat[i - 1] or \
                                                               df['close'].iat[i - 1] > df['final_ub'].iat[i - 1] else \
              df['final_ub'].iat[i - 1]
              df['final_lb'].iat[i] = df['basic_lb'].iat[i] if df['basic_lb'].iat[i] > df['final_lb'].iat[i - 1] or \
                                                               df['close'].iat[i - 1] < df['final_lb'].iat[i - 1] else \
              df['final_lb'].iat[i - 1]
      
          # Set the Supertrend value
          df[st] = 0.00
          for i in range(period, len(df)):
              df[st].iat[i] = df['final_ub'].iat[i] if df[st].iat[i - 1] == df['final_ub'].iat[i - 1] and df['close'].iat[
                  i] <= df['final_ub'].iat[i] else \
                  df['final_lb'].iat[i] if df[st].iat[i - 1] == df['final_ub'].iat[i - 1] and df['close'].iat[i] > \
                                           df['final_ub'].iat[i] else \
                      df['final_lb'].iat[i] if df[st].iat[i - 1] == df['final_lb'].iat[i - 1] and df['close'].iat[i] >= \
                                               df['final_lb'].iat[i] else \
                          df['final_ub'].iat[i] if df[st].iat[i - 1] == df['final_lb'].iat[i - 1] and df['close'].iat[i] < \
                                                   df['final_lb'].iat[i] else 0.00
      
              # Mark the trend direction up/down
          df[stx] = np.where((df[st] > 0.00), np.where((df['close'] < df[st]), 'down', 'up'), np.NaN)
      
          # Remove basic and final bands from the columns
          df.drop(['basic_ub', 'basic_lb', 'final_ub', 'final_lb'], inplace=True, axis=1)
      
          df.fillna(0, inplace=True)
      
          return DataFrame(index=df.index, data={
              'ST': df[st],
              'STX': df[stx]
          })
      
      
      class TestStrategy(bt.Strategy):
      
          def log(self, txt, dt=None):
              date = self.data.datetime.datetime()
              print('%s, %s' % (date, txt))
      
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
              self.dataopen = self.datas[0].open
              self.datahigh = self.datas[0].high
              self.datalow = self.datas[0].low
              self.datavolume = self.datas[0].volume
      
              # To keep track of pending orders and buy price/commission
              self.order = None
      
              self.supertrend = supertrend(self.datas)
      
      
      M 1 Reply Last reply Reply Quote 1
      • M
        mudassar031 @nicostro last edited by

        @nicostro
        Here is Supertrend indicator
        https://github.com/mementum/backtrader/pull/374/files

        toinou222 1 Reply Last reply Reply Quote 1
        • N
          nicostro last edited by

          Many thanks, much appreciated!

          1 Reply Last reply Reply Quote 1
          • toinou222
            toinou222 @mudassar031 last edited by

            @mudassar031
            Hello,

            Thanks for your indicator!

            How do you use it in order to compute a backtest?
            Do you use it with cerebro.addstrategy or cerebro.add_signal?

            I tried both but can't manage to make it work...
            Thanks for your help!

            1 Reply Last reply Reply Quote 0
            • lihaideqianggege
              lihaideqianggege last edited by

              谢谢大哥,非常感谢

              1 Reply Last reply Reply Quote 0
              • 1 / 1
              • First post
                Last post
              Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors