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/

    Issue with custom indicator and 2 timeframes

    Indicators/Strategies/Analyzers
    3
    7
    224
    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.
    • duni4i
      duni4i last edited by

      Hi to everyone!
      I've got a problem that i can't resolve for some time.
      I use custon indicator in my code. It works perfectly with one time frame data, but it completely does not work with two of them.
      I initialize both timeframes in init

          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose1 = self.datas[0].close
              self.dataclose30 = self.datas[1].close
      
              # To keep track of pending orders
              self.order = None
              #это расчет зигзага по таймфрейму 1 минута
              self.zigzag1 = Zigzag1.ZigZag(self.dataclose1)
              self.SMA = bt.indicators.SmoothedMovingAverage(self.dataclose1, period=10)
              #это расчет зигзага по таймфрейму 30 минут
              self.zigzag30 = Zigzag1.ZigZag(self.dataclose30)
              self.SMA30 = bt.indicators.SmoothedMovingAverage(self.dataclose30, period=30)
              self.ZZLevels1 = pd.DataFrame(columns = ['ZZ1','Index_in_Data1'])
              self.ZZLevels30 = pd.DataFrame(columns = ['ZZ30','Index_in_Data30'])
      

      After that i try to call lines of zigzag in my next part:

         def next(self):
              if self.order:
                  return
      
              df1 = pd.DataFrame({'ZZ1': [self.zigzag1.lines.zigzag_peak[0]],'Index_in_Data1': [self.zigzag1.lines.last_pivot_t[0]]})
              df30 = pd.DataFrame({'ZZ30': [self.zigzag30.lines.zigzag_peak[0]],'Index_in_Data30': [self.zigzag30.lines.last_pivot_t[0]]})
      

      and here is when i print result I've got nothing. I thought that the problem is with data and i've checked everything with SMA indicator, and SMA was calculated correctly for both timeframes.

      And here is I create two timeframes data.

      cerebro = bt.Cerebro()
      
          # Add a strategy
          cerebro.addstrategy(TestStrategy)
          ticker = 'RTS'
          exporter = Exporter()
          asset = exporter.lookup(name=ticker, market=Market.FUTURES)
          asset_id = asset[asset['name'] == ticker].index[0]
          fromdate1=datetime.date(2021, 7, 1)
          data = exporter.download(asset_id, market=Market.FUTURES, timeframe=Timeframe.MINUTES1, start_date=fromdate1)
          data['<DATE>'] = data['<DATE>'].apply(lambda x: str(x))
          data['<TIME>'] = data['<TIME>'].apply(lambda x: str(x))
          data['<DATE>'] =data['<DATE>']+' '+ data['<TIME>']
          data['<DATE>'] = data['<DATE>'].apply(lambda x: pd.to_datetime(str(x), format='%Y-%m-%d %H:%M:%S.%f'))
          rts = pd.DataFrame(data)
          rts = rts.set_index('<DATE>')
          rts= rts.loc[:,['<OPEN>','<HIGH>', '<LOW>', '<CLOSE>','<VOL>']]
          rts.index.names = ['Date']
          rts.columns=['Open','High','Low','Close','Volume']
          #print(rts)
          data1 = bt.feeds.PandasData(dataname=rts)
          print(data1)
          cerebro.adddata(data1,name = '1M')
          data30 = cerebro.resampledata(data1, name='data30', timeframe=bt.TimeFrame.Minutes, compression = 30)
          print(data30)
          # Add the Data Feed to Cerebro
          cerebro.adddata(data30,name = '30M')
      

      I think that also you may need my code of zigzag:

      import backtrader as bt
      import datetime
      import math
      
      class ZigZag(bt.ind.PeriodN):
          '''
            Identifies Peaks/Troughs of a timeseries
          '''
          lines = (
              'trend', 'last_pivot_t', 'last_pivot_x', 'last_pivot_ago',
              'zigzag_peak', 'zigzag_valley', 'zigzag', 'last_zigzag',
          )
      
          # Fancy plotting name
          # plotlines = dict(logreturn=dict(_name='log_ret'))
          plotinfo = dict(
              subplot=False,
              plotlinelabels=True, plotlinevalues=True, plotvaluetags=True,
          )
      
          plotlines = dict(
              trend=dict(marker='', markersize=0.0, ls='', _plotskip=True),
              last_pivot_t=dict(marker='', markersize=0.0, ls='', _plotskip=True),
              last_pivot_x=dict(marker='', markersize=0.0, ls='', _plotskip=True),
              last_pivot_ago=dict(marker='', markersize=0.0, ls='', _plotskip=True),
              zigzag_peak=dict(marker='*', markersize=4.0, color='blue',
                               fillstyle='full', ls=''),
              zigzag_valley=dict(marker='*', markersize=4.0, color='green',
                                 fillstyle='full', ls=''),
              zigzag=dict(_name='zigzag', color='blue', ls='-', _skipnan=True),
              last_zigzag=dict(_name='last_zigzag', color='blue', ls='--', _skipnan=True),
          )
      
          # update value to standard for Moving Averages
          params = (
              ('period', 9),
              ('up_retrace', 0.1),
              ('dn_retrace', 0.1),
              ('bardist', 0.02),  # distance to max/min in absolute perc
          )
      
          def __init__(self):
              super(ZigZag, self).__init__()
      
              if not self.p.up_retrace:
                  raise ValueError('Upward retracement should not be zero.')
      
              if not self.p.dn_retrace:
                  raise ValueError('Downward retracement should not be zero.')
      
              if self.p.up_retrace < 0:
                  self.p.up_retrace = -self.p.up_retrace
      
              if self.p.dn_retrace > 0:
                  self.p.dn_retrace = -self.p.dn_retrace
      
              self.p.up_retrace = self.p.up_retrace / 100
              self.p.dn_retrace = self.p.dn_retrace / 100
      
              self.missing_val = float('Nan')
      
          def prenext(self):
              self.lines.trend[0] = 0
              self.lines.last_pivot_t[0] = 0
              self.lines.last_pivot_x[0] = self.data[0]
              self.lines.last_pivot_ago[0] = 0
              self.lines.zigzag_peak[0] = self.missing_val
              self.lines.zigzag_valley[0] = self.missing_val
              self.lines.zigzag[0] = self.missing_val
              self.lines.last_zigzag[0] = self.missing_val
      
          def next(self):
              data = self.data
              trend = self.lines.trend
              last_pivot_t = self.lines.last_pivot_t
              last_pivot_x = self.lines.last_pivot_x
              last_pivot_ago = self.lines.last_pivot_ago
              zigzag_peak = self.lines.zigzag_peak
              zigzag_valley = self.lines.zigzag_valley
              zigzag = self.lines.zigzag
              last_zigzag = self.lines.last_zigzag
      
              x = data[0]
              r = x / last_pivot_x[-1] - 1
              curr_idx = len(data) - 1
      
              trend[0] = trend[-1]
              last_pivot_x[0] = last_pivot_x[-1]
              last_pivot_t[0] = last_pivot_t[-1]
              last_pivot_ago[0] = curr_idx - last_pivot_t[0]
              zigzag_peak[0] = self.missing_val
              zigzag_valley[0] = self.missing_val
              zigzag[0] = self.missing_val
              last_zigzag[0] = x
      
      
              if trend[-1] == 0:
                  if r >= self.p.up_retrace:
                      piv = last_pivot_x[0] * (1 - self.p.bardist)
                      zigzag_peak[-int(last_pivot_ago[0])] = piv
                      zigzag[-int(last_pivot_ago[0])] = last_pivot_x[0]
                      trend[0] = 1
                      last_pivot_x[0] = x
                      last_pivot_t[0] = curr_idx
      
                  elif r <= self.p.dn_retrace:
                      piv = last_pivot_x[0] * (1 + self.p.bardist)
                      zigzag_peak[-int(last_pivot_ago[0])] = piv
                      zigzag[-int(last_pivot_ago[0])] = last_pivot_x[0]
                      trend[0] = -1
                      last_pivot_x[0] = x
                      last_pivot_t[0] = curr_idx
      
              elif trend[-1] == -1:
                  if r >= self.p.up_retrace:
                      piv = last_pivot_x[0] * (1 - self.p.bardist)
                      zigzag_peak[-int(last_pivot_ago[0])] = piv
                      zigzag[-int(last_pivot_ago[0])] = last_pivot_x[0]
                      trend[0] = 1
                      last_pivot_x[0] = x
                      last_pivot_t[0] = curr_idx
                  elif x < last_pivot_x[-1]:
                      last_pivot_x[0] = x
                      last_pivot_t[0] = curr_idx
              elif trend[-1] == 1:
                  if r <= self.p.dn_retrace:
                      piv = last_pivot_x[0] * (1 + self.p.bardist)
                      zigzag_peak[-int(last_pivot_ago[0])] = piv
                      zigzag[-int(last_pivot_ago[0])] = last_pivot_x[0]
                      trend[0] = -1
                      last_pivot_x[0] = x
                      last_pivot_t[0] = curr_idx
      
                  elif x > last_pivot_x[-1]:
                      last_pivot_t[0] = curr_idx
                      last_pivot_x[0] = x
      
              idx = 1
              while idx < len(self.zigzag) and math.isnan(zigzag[-idx]):
                  last_zigzag[-idx] = self.missing_val
                  idx += 1
      
              if idx < len(self.data):
                  last_zigzag[-idx] = zigzag[-idx]
      
      

      It would be great if you can advice me what to do to make my two dataframes zigzag working.
      Please notice that you might have issue with loading data if you do not use FInam explorer. It is loaded easily with pip finamexporter:

      from finam import Exporter, Market, LookupComparator,Timeframe

      D 1 Reply Last reply Reply Quote 0
      • D
        dasch @duni4i last edited by

        @duni4i you did not define the timeframe and compression for data1 when adding it, for data30 you did it by defining resample data to be 30 minutes (your code resamples from 1 day data, which will not work). I hope this is your issue, since i did not run your code.

        D 1 Reply Last reply Reply Quote 1
        • D
          dasch @dasch last edited by

              #print(rts)
              data1 = bt.feeds.PandasData(dataname=rts)
              print(data1)
              cerebro.adddata(data1,name = '1M', timeframe=bt.TimeFrame.Minutes, compression = 1)
              data30 = cerebro.resampledata(data1, name='data30', timeframe=bt.TimeFrame.Minutes, compression = 30)
              print(data30)
              # Add the Data Feed to Cerebro
              # no need to add since already added with resampledata: cerebro.adddata(data30,name = '30M')
          duni4i 1 Reply Last reply Reply Quote 0
          • duni4i
            duni4i @dasch last edited by

            @dasch thanks for your respond, but it did not f1555888-ed13-4b9f-bb5c-2ccd3dcffa99-image.png help me. Now python does not understand what i do

            vladisld 1 Reply Last reply Reply Quote 0
            • vladisld
              vladisld @duni4i last edited by

              @duni4i timeframe parameter may be specified during PandasData instantiation:

              data = bt.feeds.PandasData(dataname=df,timeframe=...
              
              duni4i 2 Replies Last reply Reply Quote 0
              • duni4i
                duni4i @vladisld last edited by

                @vladisld Thank you. Now data is loaded but indicator still does not work and make all data 'Nan'

                10ccfccc-95f3-436d-8868-402f1056e2e0-image.png

                1 Reply Last reply Reply Quote 0
                • duni4i
                  duni4i @vladisld last edited by

                  @vladisld perhaps I'm not pretty correct but after loading 2 timeframes i see correct data for my indicator when I debug each step and I see an array with correct calculations but it is zero because when i add second timeframe indicator starts to recalculate every time when next starts and all previous data are Nan. SO my question is how to call proper calculations from my indicator and not allow it to recalculate?
                  54330bb6-77b0-42ef-baa2-be70b93d10a9-image.png

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