Navigation

    Backtrader Community

    • Register
    • 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/

    indicator on resampled data

    Indicators/Strategies/Analyzers
    1
    1
    164
    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.
    • J T
      J T last edited by

      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

      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
      $(document).ready(function () { app.coldLoad(); }); }