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



  • 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)
    
    




  • Many thanks, much appreciated!


Log in to reply
 

});