For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Can BT resample the data in the user defined Indicator?



  • For example, I would define a Indicator with 5-mins bar data, but in the indicator I need the day time frame ATR(100days),then I would compare the 5-min bar data with the Day time frame ATR(100). how can I get the day timeframe ATR with the 5min bar?



    • define 2 data feeds - 5 min data1 and daily data2.
    • calculate ATR using daily data feed
    self.atr = bt.indicators.ATR(self.datas[1], period=100)
    
    • use self.atr in the other indicator
    self.other_indicator = bt.indicators.SMA(self.datas[0], period=50) + self.atr
    

    This can be done in the strategy __init__ or other indicator __init__.



  • @ab_trader Thanks, I knew this method, and I used the resampling method with one data feed.It worked well. I think Both methods are coupling the indicators with different time frame.

    But is it possible to define a new indicator to including the logic, not as your logic in the user defined Strategy?


  • administrators

    Can BT resample the data in the user defined Indicator?

    The direct answer to the question posed in the title: No.

    Indicators DO NOT touch the data, they calculate something using the provided data feeds.

    You can always pass two data feeds to the indicator (one 5-min and another 1-day) and create indicators on each of them and compare things (directly between indicators or data-vs-indicator)



  • @backtrader Thanks.

    How can I implement below logic(in the TradingView) in the BT, I know I can use ab_trader's method, but seems too much logic in the Strategy, How can I put these logic in a Indicator instead of Strategy? The ATR is a Day timeframe indicator, the others are mins:
    code ref from link

    study(title='[RS]MTF Volatility Stop V0', shorttitle='mtfVS', overlay=true)
    multiplier = input(title='True Range Multiplier', type=float, defval=1.618)
    tf = input(title='Timeframe to pool ATR:', type=string, defval='D', confirm=false)
    length = input(title='ATR Length', type=integer, defval=20, minval=1)
    range = security(tickerid, tf, atr(length))
    
    trend = na(trend[1]) ? +1 : close > vstop[1] ? +1 : close < vstop[1] ? -1 : trend[1]
    max_close = change(trend) != 0 ? close : close >= max_close[1] ? close : max_close[1]
    min_close = change(trend) != 0 ? close : close <= min_close[1] ? close : min_close[1]
    vstop = na(vstop[1]) ? hl2 :
             change(trend) > 0 ? close - (multiplier * range) : 
             trend > 0 ? max(vstop[1], max_close - (multiplier * range)) :
             change(trend) < 0 ? close + (multiplier * range) : 
             trend < 0 ? min(vstop[1], min_close + (multiplier * range)) : 
             vstop[1]
    
    plot(title='mtfVS', series=vstop, style=circles, color=close>=vstop?lime:red, transp=0, linewidth=2)
    plot(title='mtfVS', series=vstop, style=line, color=black, transp=0, linewidth=1)
    


  • @backtrader @ab_trader
    I finally implement the Indicator as below code, it seems work. but two small questions, when the ATR is coupled? and how do I set the minperiod when data with different time frames, I worked around by using len(self.l.art)>0, else it would raise errors.

    import numpy as np
    import backtrader as bt
    from ext.ult.ult import *
    from ext.Ind.OCHLInd import OCHLInd
    
    
    # https://www.tradingview.com/script/mtWhbCRf-RS-MTF-Volatility-Stop-V0/
    class MtfVSInd(bt.Indicator):
        """
    
        """
        lines = ('trend', 'vs', 'max_close', 'min_close', 'atr')
        params = (
            ('period', 5),
            ('factor', 1.618),
            ('mode', 0) # debug modes
        )
        plotinfo = dict(subplot=False)
        plotlines = dict(vs=dict(_plotskip=False),
                         trend=dict(_plotskip=True, _method='bar', alpha=0.50, width=1.0),
                         max_close=dict(_plotskip=True, color='black'),
                         min_close=dict(_plotskip=True, color='red'),
                         atr=dict(_plotskip=True),
                         )
    
        def _plotinit(self):
            if self.p.mode == 1:
                self.plotinfo.subplot = True
                self.plotlines.vs._plotskip = True
                self.plotlines.trend._plotskip = True
                self.plotlines.max_close._plotskip = True
                self.plotlines.min_close._plotskip = True
                self.plotlines.atr._plotskip = False
            elif self.p.mode == 2:
                self.plotinfo.subplot = True
                self.plotlines.vs._plotskip = True
                self.plotlines.trend._plotskip = False
                self.plotlines.max_close._plotskip = True
                self.plotlines.min_close._plotskip = True
                self.plotlines.atr._plotskip = True
            elif self.p.mode == 3:
                self.plotinfo.subplot = True
                self.plotlines.vs._plotskip = True
                self.plotlines.trend._plotskip = True
                self.plotlines.max_close._plotskip = False
                self.plotlines.min_close._plotskip = False
                self.plotlines.atr._plotskip = True
    
        def __init__(self):
            # the ATR is Day time frame
            self.l.atr = bt.ind.ATR(self.data1, period=self.p.period)
            # get the avg(high+low)
            self.hl = OCHLInd(self.data0, type='hl')
            super(MtfVSInd, self).__init__()
    
        def next(self):
            if len(self.l.atr) > 0:
                if np.isnan(self.l.trend[-1]):
                    self.l.trend[0] = 1
                elif self.data0.l.close[0] > self.l.vs[-1]:
                    self.l.trend[0] = 1
                elif self.data0.l.close[0] < self.l.vs[-1]:
                    self.l.trend[0] = -1
                else:
                    self.l.trend[0] = self.l.trend[-1]
    
                chg_trend = self.l.trend[0] - self.l.trend[-1]
                if chg_trend != 0:
                    self.l.max_close[0] = self.data0.l.close[0]
                elif self.data0.l.close[0] >= self.l.max_close[-1]:
                    self.l.max_close[0] = self.data0.l.close[0]
                else:
                    self.l.max_close[0] = self.l.max_close[-1]
    
                if chg_trend != 0:
                    self.l.min_close[0] = self.data0.l.close[0]
                elif self.data0.l.close[0] <= self.l.min_close[-1]:
                    self.l.min_close[0] = self.data0.l.close[0]
                else:
                    self.l.min_close[0] = self.l.min_close[-1]
    
                if np.isnan(self.l.vs[-1]):
                    self.l.vs[0] = self.hl[0]
                elif chg_trend > 0:
                    self.l.vs[0] = self.data0.l.close[0] - self.p.factor * self.l.atr[0]
                elif self.l.trend[0] > 0:
                    self.l.vs[0] = max(self.l.vs[-1], self.l.max_close[0] - self.p.factor * self.l.atr[0])
                elif chg_trend < 0:
                    self.l.vs[0] = self.data0.l.close[0] + self.p.factor * self.l.atr[0]
                elif self.l.trend[0] < 0:
                    self.l.vs[0] = min(self.l.vs[-1], self.l.min_close[0] + self.p.factor * self.l.atr[0])
                else:
                    self.l.vs[0] = self.l.vs[-1]
    
    

    0_1559799532122_6b674096-f85b-4b39-8c0e-bfd8e7479bcc-image.png


Log in to reply
 

});