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

indicator on resampled data



  • Hi
    I am having some trouble on resampled data and custom indicator.

    class BaseStrategy(bt.Strategy): 
        def __init__(self):
            self.zz = ZigZag(self.data0, period=2, retrace=0.05, minbars=2)
        
        def next(self):
            print('{},{:.5f},{:.5f},{:.5f}'.format(self.data0.datetime.datetime(0),
                   self.zz.l.zigzag[0], self.zz.l.last_high[0], self.zz.l.last_low[0]))    
    
    def main():
        cerebro = bt.Cerebro(oldtrades=True)
        cerebro.addstrategy(BaseStrategy)
        df = pd.read_csv('datas\\EURUSD.csv', sep=',', header=0, index_col=0, parse_dates=True)
        data0 = bt.feeds.PandasData(dataname=df, timeframe=bt.TimeFrame.Minutes)
        cerebro.adddata(data0)
        cerebro.resampledata(data0, timeframe=bt.TimeFrame.Minutes, compression=240)
        cerebro.run(maxcpus=3, stdstats=False, runonce=True)
    
    if __name__ == '__main__':
        main()
    

    Simple enough code that passes in 2 datas. Run an indicator on init and run it on data0 and print out the line values in the next() method. However, the above code does not work. The zz.l.zigzag[0] are always nan. If I remove resampleddata() line, it works and it works with only this single change.
    Code of the indicator is below, courtesy of Nikolai. https://community.backtrader.com/topic/1771/zigzag-indicator-for-live-trading/25

    class ZigZag(bt.ind.PeriodN):  # periodN controls number lines to skip i think, so period is 2 so curr_idx start at 2
        lines = ('trend', 'last_high', 'last_low', 'zigzag',)
    
        plotinfo = dict(
            subplot=False,
            plotlinelabels=True, plotlinevalues=True, plotvaluetags=True,
        )
    
        plotlines = dict(
            trend=dict(_plotskip=True),
            last_high=dict(color='green', ls='-', _plotskip=True),
            last_low=dict(color='black', ls='-', _plotskip=True),
            zigzag=dict(_name='zz', color='lightblue', ls='-', _skipnan=True),  # linewidth=2.0, ls='-',
        )
    
        params = (dict(period=2, retrace=0.25, minbars=2, _autoplot=True))
    
        def __init__(self):
            super(ZigZag, self).__init__()
    
            assert self.p.retrace > 0, 'Retracement should be above zero.'
            assert self.p.minbars >= 0, 'Minimal bars should be >= zero.'
    
            self.ret = self.data.close * self.p.retrace / 100
            self.minbars = self.p.minbars
            self.count_bars = 0
            self.last_pivot_t = 0
            self.last_pivot_ago = 0
    
        def prenext(self):  # prenext called before the minimum period required for the indicator, this case 2. So called just once.
            self.l.trend[0] = 0
            self.l.last_high[0] = self.data.high[0]
            self.l.last_low[0] = self.data.low[0]
            self.l.zigzag[0] = (self.data.high[0] + self.data.low[0]) / 2
            # print('prenext: ', self.l.trend[0], self.l.last_high[0], self.l.last_low[0], self.l.zigzag[0] )
    
        def next(self):  # this starts at 2nd line of data
    
            curr_idx = len(self.data)
            self.ret = self.data.close[0] * self.p.retrace / 100
            self.last_pivot_ago = curr_idx - self.last_pivot_t
            self.l.trend[0] = self.l.trend[-1]
            self.l.last_high[0] = self.l.last_high[-1]
            self.l.last_low[0] = self.l.last_low[-1]
            self.l.zigzag[0] = float('nan')
            # print('next1:',curr_idx,self.data.close[0], self.ret, self.last_pivot_t,self.last_pivot_ago,self.l.trend[0],self.l.last_high[0],self.l.last_low[0])
    
            # Search for trend
            if self.l.trend[-1] == 0:
                if self.l.last_low[0] < self.data.low[0] and self.l.last_high[0] < self.data.high[0]:  # if current bar is higher than last high and last low
                    self.l.trend[0] = 1
                    self.l.last_high[0] = self.data.high[0]
                    self.last_pivot_t = curr_idx
    
                elif self.l.last_low[0] > self.data.low[0] and self.l.last_high[0] > self.data.high[0]:  # if current bar is higher than last high and last low
                    self.l.trend[0] = -1
                    self.l.last_low[0] = self.data.low[0]
                    self.last_pivot_t = curr_idx
    
            # Up trend
            elif self.l.trend[-1] == 1:
                if self.data.high[0] > self.l.last_high[-1]:
                    self.l.last_high[0] = self.data.high[0]
                    self.count_bars = self.minbars
                    self.last_pivot_t = curr_idx
    
                elif self.count_bars <= 0 and self.l.last_high[0] - self.data.low[0] > self.ret and self.data.high[0] < self.l.last_high[0]:
                    self.l.trend[0] = -1
                    self.count_bars = self.minbars
                    self.l.last_low[0] = self.data.low[0]
                    self.l.zigzag[-self.last_pivot_ago] = self.l.last_high[0]
                    self.last_pivot_t = curr_idx
    
                elif self.count_bars < self.minbars and self.data.close[0] < self.l.last_low[0]:
                    self.l.trend[0] = -1
                    self.count_bars = self.minbars
                    self.l.last_low[0] = self.data.low[0]
                    self.l.zigzag[-self.last_pivot_ago] = self.l.last_high[0]
                    self.last_pivot_t = curr_idx
    
            # Down trend
            elif self.l.trend[-1] == -1:
                if self.data.low[0] < self.l.last_low[-1]:
                    self.l.last_low[0] = self.data.low[0]
                    self.count_bars = self.minbars
                    self.last_pivot_t = curr_idx
    
                elif self.count_bars <= 0 and self.data.high[0] - self.l.last_low[0] > self.ret and self.data.low[0] > self.l.last_low[0]:
                    self.l.trend[0] = 1
                    self.count_bars = self.minbars
                    self.l.last_high[0] = self.data.high[0]
                    self.l.zigzag[-self.last_pivot_ago] = self.l.last_low[0]
                    self.last_pivot_t = curr_idx
    
                elif self.count_bars < self.minbars and self.data.close[0] > self.l.last_high[-1]:
                    self.l.trend[0] = 1
                    self.count_bars = self.minbars
                    self.l.last_high[0] = self.data.high[0]
                    self.l.zigzag[-self.last_pivot_ago] = self.l.last_low[0]
                    self.last_pivot_t = curr_idx
    
            # Decrease minbars counter
            self.count_bars -= 1
    

    Need some advice why this is happening, even though I have specified that the indicator run on data0. And how can I change the indicator code so that it can run even if resampled data is passed (no need to run on resampled data, but even just running on lower timeframe data would be great!) ?

    Thanks


Log in to reply
 

});