Backtrader Community

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

    Donchian Channel

    Indicators/Strategies/Analyzers
    4
    13
    4506
    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.
    • K
      KT last edited by KT

      Hi, I have been trying to write donchian channel indicator using two sets of data: daily and hourly data. I referred to rorymack's post on simple channel indicator. However, I realised there are some errors in my code :

      1. the indicator is based on hourly data instead of the daily data
      2. consecutive buys and sells are executed instead of the desired selling after buying one stock.

      I would also like to know how to use data1 in the custom built indicator.

      Thanks for your help @backtrader and others :)

      Below is my code.

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      import os.path
      import argparse
      import datetime
      
      import backtrader as bt
      import backtrader.feeds as btfeeds
      
      class hilo6(bt.Indicator):
          lines = ('maxi','mini',)
          params = (
                  ('period', 6),
                  ('data',None),
                  )
      
          def __init__(self):
              self.addminperiod(self.p.period)
      
          def next(self):
              highs = self.data.high.get(size=self.p.period)
              lows = self.data.low.get(size=self.p.period)
              self.lines.maxi[0] = max(highs)
              self.lines.mini[0] = min(lows)
                      
      
      class St(bt.Strategy):
          
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              dt = dt or self.data0.datetime.date(0)
              dt1 = self.data0.datetime.time(0)
              print('%s,%s, %s' % (dt.isoformat(),dt1.isoformat(), txt))
              
          def __init__(self):
              self.dataclose = self.data0.close
              self.channel = hilo6(data=self.data1)
              
          def notify_order(self, order):
              if order.status in [order.Submitted, order.Accepted]:
                  return
              
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(
                          'BUY EXECUTED, Price: %.2f, Cost: %.2f' %
                          (order.executed.price,
                           order.executed.value))
                      
                      self.buyprice = order.executed.price
                      
                  else:  # Sell
                      self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f' %
                               (order.executed.price,
                                order.executed.value))
              
                  self.bar_executed = len(self)
                  
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
              
              self.order = None
              
          def notify_trade(self, trade):
              if not trade.isclosed:
                  return
      
              self.log('OPERATION PROFIT, GROSS %.5f, NET %.5f' %
                       (trade.pnl, trade.pnlcomm))
              
          def next(self):
              txt = ','.join(
                  ['%04d' % len(self.data0),
                   '%04d' % len(self.data1),
                   self.data0.datetime.date(0).isoformat(),
                   self.data0.datetime.time(0).isoformat(),
                   '%.5f' % self.data0.close[0],
                   '%.5f' % self.data1.close[0]]) 
              print(txt)
              
              if not self.position:
                   if self.data0.close[-1] < self.channel.lines.mini[0]:
                      if self.data0.close[0] > self.channel.lines.mini[0]:
                          self.log('BUY CREATE, %.5f' % self.data0.close[0])
                          self.order=self.buy(data=self.data0)
              
              else:
                  if self.data0.close[-1] > self.channel.lines.maxi[0]:
                      if self.data0.close[0] < self.channel.lines.maxi[0]:
                          self.log('SELL CREATE, %.5f' % self.data0.close[0])
                          self.order = self.sell(data=self.data0)
      
                          
      def runstrat():
          args = parse_args()
      
          cerebro = bt.Cerebro()
      
      data0 = btfeeds.GenericCSVData(dataname=datapath0,
                                         timeframe=bt.TimeFrame.Minutes,
                                        fromdate = datetime.datetime(2017,1,1),
                                        todate=datetime.datetime(2017,4,20),                                  
                                        nullvalue=0.0,
                                        dtformat=('%Y.%m.%d'),
                                        tmformat=('%H:%M'),
                                        datetime=0,
                                        time=1,
                                        high=2,
                                        low=3,
                                        open=4,
                                        close=5,
                                        volume=6,
                                        openinterest=-1)
          data1 = btfeeds.GenericCSVData(dataname=datapath1,
                                         timeframe = bt.TimeFrame.Days,
                                        fromdate =datetime.datetime(2017,1,1),
                                        todate= datetime.datetime(2017,4,20),
                                        nullvalue=0.0,
                                        dtformat=('%Y.%m.%d'),
                                        tmformat=('%H:%M'),
                                        datetime=0,
                                        time=1,
                                        high=2,
                                        low=3,
                                        open=4,
                                        close=5,
                                        volume=6,
                                        openinterest=-1)
          cerebro.adddata(data0,name ="data0")
          cerebro.adddata(data1,name="data1")
      
          cerebro.addstrategy(St)
          cerebro.broker.setcash(100000.0)
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
          cerebro.run(stdstats=False, runonce=False)
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
              
      def parse_args():
          parser = argparse.ArgumentParser(
              formatter_class=argparse.ArgumentDefaultsHelpFormatter,
              description='Sample for pivot point and cross plotting')
          parser.add_argument('--plot', required=False, action='store_true',
                              help=('Plot the result'))
      
          return parser.parse_args()
      
      
      if __name__ == '__main__':
          runstrat()
      
      
      B 2 Replies Last reply Reply Quote 0
      • B
        backtrader administrators @KT last edited by

        @KT said in Donchian Channel:

        the indicator is based on hourly data instead of the daily data

        Indicators don't care about the nature of the data unless they need to do something like looking at the time of day and the indicator then becomes only usable with data feeds which carry that payload, making it impossible to create something like this (SMA of an SMA)

        ma1 = bt.ind.SMA()
        ma2 = bt.ind.SMA(ma1)
        

        @KT said in Donchian Channel:

        I would also like to know how to use data1 in the custom built indicator.

        self.data1 ? (or self.datas[1])

        The indicator per-se seems fine. It's simply not written in the way the platform was envisioned, but an end user can do it. Actually this "channel" indicator is for sure in some of the samples.

        class hilo6(bt.ind.PeriodN):
            lines = ('maxi', 'mini',)
            params = (('period', 6),)
        
            def __init__(self):
                self.lines.maxi = bt.ind.Highest(self.data.high, period=self.p.period)
                self.lines.mini = bt.ind.Lowest(self.data.low, period=self.p.period)
        

        This would be the canonical way, which is declarative rather than imperative.

        K 1 Reply Last reply Reply Quote 0
        • K
          KT @backtrader last edited by KT

          @backtrader I tried using self.data1 to access the first data in the instantiation of the indicator. However, I get this error.

          AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute 'data1'.

          If I use self.datas[1], the following error occurs.

          IndexError: list index out of range

          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators @KT last edited by

            Ok, problem understood

            @KT said in Donchian Channel in __init__:

            self.channel = hilo6(data=self.data1)
            

            As you may see above in the reworked version of the indicator, there is no such thing as a data parameter defined. The data feeds are passed automatically (if none is specified) or explicitly (as unnamed arguments).

            See Docs - Platform Concepts

            As such, use:

            self.channel = hilo6(self.data1)
            

            Inside the indicator, this is in this case the only data feed. Which keeps the definition of the indicator generic.

            1 Reply Last reply Reply Quote 0
            • A
              ab_trader last edited by ab_trader

              You may want to use backtrader's CrossUp and CrossDown indicators to generate Buy and Sell signals. This will simplify your code:

                  def __init__(self):
                      self.dataclose = self.data0.close
                      self.channel = hilo6(data=self.data1)
              
                      self.buysig = bt.indicators.CrossUp(self.data0.close, self.channel.hilo6.mini)
                      self.sellsig = bt.indicators.CrossDown(self.data0.close, self.channel.hilo6.maxi)
              

              and then:

                  def next(self):
                      txt = ','.join(
                          ['%04d' % len(self.data0),
                           '%04d' % len(self.data1),
                           self.data0.datetime.date(0).isoformat(),
                           self.data0.datetime.time(0).isoformat(),
                           '%.5f' % self.data0.close[0],
                           '%.5f' % self.data1.close[0]]) 
                      print(txt)
                      
                      if not self.position:
                           if self.buysig[0]:
                                  self.log('BUY CREATE, %.5f' % self.data0.close[0])
                                  self.order=self.buy(data=self.data0)
                      
                      else:
                          if self.sellsig[0]:
                                  self.log('SELL CREATE, %.5f' % self.data0.close[0])
                                  self.order = self.sell(data=self.data0)
              
              • If my answer helped, hit reputation up arrow at lower right corner of the post.
              • Python Debugging With Pdb
              • New to python and bt - check this out
              1 Reply Last reply Reply Quote 0
              • K
                KT last edited by KT

                @ab_trader thanks for the suggestion :)

                @backtrader thanks, the code works. The indicator only uses the data from data1.

                However, I notice there are some errors. When I print out self.data0.datetime.date(0) and self.data1.datetime.date(1), the dates are different.

                The snippet below shows data in this format :
                len(self.data0),len(self.data1),self.data0.datetime.date(0).isoformat(),
                self.data1.datetime.date(0),self.data0.datetime.time(0).isoformat(),....

                0551,0024,2017-03-22,2017-03-21,21:00:00,1.24873,1.24707
                0552,0024,2017-03-22,2017-03-21,22:00:00,1.24830,1.24707
                0553,0024,2017-03-22,2017-03-21,23:00:00,1.24784,1.24707
                0553,0025,2017-03-22,2017-03-22,23:00:00,1.24784,1.24784
                0554,0025,2017-03-23,2017-03-22,00:00:00,1.24740,1.24784
                0555,0025,2017-03-23,2017-03-22,01:00:00,1.24708,1.24784
                0556,0025,2017-03-23,2017-03-22,02:00:00,1.24713,1.24784
                0557,0025,2017-03-23,2017-03-22,03:00:00,1.24833,1.24784
                0558,0025,2017-03-23,2017-03-22,04:00:00,1.24830,1.24784
                0559,0025,2017-03-23,2017-03-22,05:00:00,1.24837,1.24784
                0560,0025,2017-03-23,2017-03-22,06:00:00,1.24862,1.24784
                0561,0025,2017-03-23,2017-03-22,07:00:00,1.24863,1.24784
                0562,0025,2017-03-23,2017-03-22,08:00:00,1.25070,1.24784
                0563,0025,2017-03-23,2017-03-22,09:00:00,1.24771,1.24784
                0564,0025,2017-03-23,2017-03-22,10:00:00,1.24751,1.24784
                0565,0025,2017-03-23,2017-03-22,11:00:00,1.24918,1.24784
                0566,0025,2017-03-23,2017-03-22,12:00:00,1.25096,1.24784
                0567,0025,2017-03-23,2017-03-22,13:00:00,1.24957,1.24784
                0568,0025,2017-03-23,2017-03-22,14:00:00,1.24990,1.24784
                0569,0025,2017-03-23,2017-03-22,15:00:00,1.25181,1.24784
                0570,0025,2017-03-23,2017-03-22,16:00:00,1.25220,1.24784
                0571,0025,2017-03-23,2017-03-22,17:00:00,1.25257,1.24784
                0572,0025,2017-03-23,2017-03-22,18:00:00,1.25267,1.24784
                0573,0025,2017-03-23,2017-03-22,19:00:00,1.25146,1.24784
                0574,0025,2017-03-23,2017-03-22,20:00:00,1.25130,1.24784
                0575,0025,2017-03-23,2017-03-22,21:00:00,1.25212,1.24784
                0576,0025,2017-03-23,2017-03-22,22:00:00,1.25199,1.24784
                0577,0025,2017-03-23,2017-03-22,23:00:00,1.25160,1.24784
                0577,0026,2017-03-23,2017-03-23,23:00:00,1.25160,1.25160
                0578,0026,2017-03-24,2017-03-23,00:00:00,1.25167,1.25160
                

                If i change it to self.data0.datetime.date(-1) and self.data1.datetime.date(1), the date does not tally too.

                The snippet below shows data in this format :
                len(self.data0),len(self.data1),self.data0.datetime.date(-1).isoformat(),
                self.data1.datetime.date(0),self.data0.datetime.time(0).isoformat(),....

                0558,0025,2017-03-23,2017-03-22,04:00:00,1.24830,1.24784
                0559,0025,2017-03-23,2017-03-22,05:00:00,1.24837,1.24784
                0560,0025,2017-03-23,2017-03-22,06:00:00,1.24862,1.24784
                0561,0025,2017-03-23,2017-03-22,07:00:00,1.24863,1.24784
                0562,0025,2017-03-23,2017-03-22,08:00:00,1.25070,1.24784
                0563,0025,2017-03-23,2017-03-22,09:00:00,1.24771,1.24784
                0564,0025,2017-03-23,2017-03-22,10:00:00,1.24751,1.24784
                0565,0025,2017-03-23,2017-03-22,11:00:00,1.24918,1.24784
                0566,0025,2017-03-23,2017-03-22,12:00:00,1.25096,1.24784
                0567,0025,2017-03-23,2017-03-22,13:00:00,1.24957,1.24784
                0568,0025,2017-03-23,2017-03-22,14:00:00,1.24990,1.24784
                0569,0025,2017-03-23,2017-03-22,15:00:00,1.25181,1.24784
                0570,0025,2017-03-23,2017-03-22,16:00:00,1.25220,1.24784
                0571,0025,2017-03-23,2017-03-22,17:00:00,1.25257,1.24784
                0572,0025,2017-03-23,2017-03-22,18:00:00,1.25267,1.24784
                0573,0025,2017-03-23,2017-03-22,19:00:00,1.25146,1.24784
                0574,0025,2017-03-23,2017-03-22,20:00:00,1.25130,1.24784
                0575,0025,2017-03-23,2017-03-22,21:00:00,1.25212,1.24784
                0576,0025,2017-03-23,2017-03-22,22:00:00,1.25199,1.24784
                0577,0025,2017-03-23,2017-03-22,23:00:00,1.25160,1.24784
                0577,0026,2017-03-23,2017-03-23,23:00:00,1.25160,1.25160
                0578,0026,2017-03-23,2017-03-23,00:00:00,1.25167,1.25160
                

                Is there anyway to rectify the error such that the dates are synchronized? How do I change such that the time frame is on hourly basis? For now, i am using bt.TimeFrame.Minutes.

                Thanks for all your help :)

                B 1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators @KT last edited by

                  @KT said in Donchian Channel:

                  However, I notice there are some errors. When I print out self.data0.datetime.date(0) and self.data1.datetime.date(1), the dates are different.

                  The error seems to be on your side. date(0) is the date of the actual moment in time. date(1) is the date of the future next moment in time (which is unknown, but which due to python arithmetic in arrays gives you something)

                  If i change it to self.data0.datetime.date(-1) and self.data1.datetime.date(1), the date does not tally too.

                  It shouldn't. One is the previous date, the other is a non-existent date in the future.

                  Is there anyway to rectify the error such that the dates are synchronized?

                  With the given information there is for sure not an error. There isn't enough information to actually interpret something really, but it seems you have a daily feed, which moves slower and an intraday feed which moves faster. The daily feed remains static until the next day kicks in. Everything seems perfectly in order.

                  A daily feed is one that is complete. It cannot be delivered if the intraday feed is from the same day and at the beginning of the day. Or you'd else be cheating.

                  How do I change such that the time frame is on hourly basis? For now, i am using bt.TimeFrame.Minutes.

                  60 minutes.

                  1 Reply Last reply Reply Quote 0
                  • K
                    KT last edited by

                    Sorry there is a typo there.

                        def next(self):
                            txt = ','.join(
                                ['%04d' % len(self.data0),
                                 '%04d' % len(self.data1),
                                 self.data0.datetime.date(-1).isoformat(),
                                 self.data1.datetime.date(0).isoformat(),
                                 '%.5f' % self.data0.close[0],
                                 '%.5f' % self.data1.close[0]]) 
                            print(txt)
                    

                    The output is

                    1853,0079,2017-04-19,2017-04-18,1.28273,1.28400
                    1854,0079,2017-04-19,2017-04-18,1.28217,1.28400
                    1855,0079,2017-04-19,2017-04-18,1.28276,1.28400
                    1856,0079,2017-04-19,2017-04-18,1.28249,1.28400
                    1857,0079,2017-04-19,2017-04-18,1.28270,1.28400
                    1858,0079,2017-04-19,2017-04-18,1.28257,1.28400
                    1859,0079,2017-04-19,2017-04-18,1.28220,1.28400
                    1860,0079,2017-04-19,2017-04-18,1.28176,1.28400
                    1861,0079,2017-04-19,2017-04-18,1.28311,1.28400
                    1862,0079,2017-04-19,2017-04-18,1.28389,1.28400
                    1863,0079,2017-04-19,2017-04-18,1.28510,1.28400
                    1864,0079,2017-04-19,2017-04-18,1.28332,1.28400
                    1865,0079,2017-04-19,2017-04-18,1.28200,1.28400
                    1866,0079,2017-04-19,2017-04-18,1.28108,1.28400
                    1867,0079,2017-04-19,2017-04-18,1.27881,1.28400
                    1868,0079,2017-04-19,2017-04-18,1.27852,1.28400
                    1869,0079,2017-04-19,2017-04-18,1.27893,1.28400
                    1870,0079,2017-04-19,2017-04-18,1.27841,1.28400
                    1871,0079,2017-04-19,2017-04-18,1.27865,1.28400
                    1872,0079,2017-04-19,2017-04-18,1.27772,1.28400
                    1872,0080,2017-04-19,2017-04-19,1.27772,1.27772
                    1873,0080,2017-04-19,2017-04-19,1.27824,1.27772
                    

                    If i change it to,

                        def next(self):
                            txt = ','.join(
                                ['%04d' % len(self.data0),
                                 '%04d' % len(self.data1),
                                 self.data0.datetime.date(0).isoformat(),
                                 self.data1.datetime.date(0).isoformat(),
                                 '%.5f' % self.data0.close[0],
                                 '%.5f' % self.data1.close[0]]) 
                            print(txt)
                    

                    The output will change into

                    1837,0078,2017-04-18,2017-04-17,1.25564,1.25631
                    1838,0078,2017-04-18,2017-04-17,1.26521,1.25631
                    1839,0078,2017-04-18,2017-04-17,1.26682,1.25631
                    1840,0078,2017-04-18,2017-04-17,1.27188,1.25631
                    1841,0078,2017-04-18,2017-04-17,1.27387,1.25631
                    1842,0078,2017-04-18,2017-04-17,1.27641,1.25631
                    1843,0078,2017-04-18,2017-04-17,1.27670,1.25631
                    1844,0078,2017-04-18,2017-04-17,1.27662,1.25631
                    1845,0078,2017-04-18,2017-04-17,1.28302,1.25631
                    1846,0078,2017-04-18,2017-04-17,1.28490,1.25631
                    1847,0078,2017-04-18,2017-04-17,1.28434,1.25631
                    1848,0078,2017-04-18,2017-04-17,1.28400,1.25631
                    1848,0079,2017-04-18,2017-04-18,1.28400,1.28400
                    1849,0079,2017-04-19,2017-04-18,1.28426,1.28400
                    1850,0079,2017-04-19,2017-04-18,1.28428,1.28400
                    1851,0079,2017-04-19,2017-04-18,1.28435,1.28400
                    1852,0079,2017-04-19,2017-04-18,1.28359,1.28400
                    1853,0079,2017-04-19,2017-04-18,1.28273,1.28400
                    1854,0079,2017-04-19,2017-04-18,1.28217,1.28400
                    1855,0079,2017-04-19,2017-04-18,1.28276,1.28400
                    

                    Based on these two outputs, the dates between data0 and data1 are not synchronized. As such, it will result in an error in terms of the signal generated from the indicator.

                    Data0 is an intraday feed with hourly observations while data1 is a daily feed with daily observations of high low open close and volume.

                    Thanks @backtrader !!

                    B 1 Reply Last reply Reply Quote 0
                    • B
                      backtrader administrators @KT last edited by

                      @KT said in Donchian Channel:

                      Based on these two outputs, the dates between data0 and data1 are not synchronized

                      Sorry but it would seem you fail to understand how resampling works.

                      • A resampled bar can only be delivered when the bar is complete.

                      As such

                      • The intraday feed will deliver timestamps from the current day (2017-04-19 in your example ... although being it an intraday feed, printing the complete datetime would probably be better)

                      • The daily feed will be paused in the previous day (2017-04-18 in your example) until resampling is complete and the new complete bar can be delivered (2017-04-19)

                      In any case there are many missing factors in the code snippets to conclude anything:

                      • Missing input sample data (the data is actually different in your examples)
                      • A simple sample which reproduces (with the input data) what you think is wrong.

                      @KT said in Donchian Channel:

                      self.data0.datetime.date(-1).isoformat(),
                      

                      That's in any case pointless, because printing the previous intraday bar is not going to be of much help when comparing to a paused (non-delivering) daily feed.

                      @KT said in Donchian Channel:

                      ...
                      1848,0078,2017-04-18,2017-04-17,1.28400,1.25631
                      1848,0079,2017-04-18,2017-04-18,1.28400,1.28400
                      1849,0079,2017-04-19,2017-04-18,1.28426,1.28400
                      ...

                      Even without intraday times, the synchronization seems fine

                      • In length 1848 of the intraday data (1st on the left), the feed is delivering for 2017-04-18 and the daily data is still frozen on the previous day 2017-04-17

                        This seems to be the last price for 2017-04-18

                      • The intraday feed is frozen (hence the length remaining at 1848) because it was the last price for 2017-04-18, the daily

                        And the daily data delivers for 2017-04-18, now that the prices are complete.

                        Had you printed the length of the strategy and of data1, both would have advanced in this case.

                      • Once the daily data has synchronized itself by delivering, the intraday data delivers the 1st price for 2017-04-19 and the daily data remains frozen on the previous day, awaiting for completion.

                      Everything seems perfectly fine.

                      1 Reply Last reply Reply Quote 0
                      • K
                        KT last edited by

                        @backtrader Thank you for your help so far :) Appreciate it.

                                txt = ','.join(
                                    ['%04d' % len(self.data0),
                                     '%04d' % len(self.data1),
                                     self.data0.datetime.date(0).isoformat(),
                                     self.data0.datetime.time(0).isoformat(),
                                     self.data1.datetime.date(0).isoformat(),
                                     '%.5f' % self.data0.close[0],
                                     '%.5f' % self.data1.close[0]]) 
                                print(txt)
                        

                        The data are imported in this way.

                        data0 = btfeeds.GenericCSVData(dataname=datapath0,
                                                           timeframe=bt.TimeFrame.Minutes,
                                                          fromdate = datetime.datetime(2017,1,1),
                                                          todate=datetime.datetime(2017,4,20),                                  
                                                          nullvalue=0.0,
                                                          dtformat=('%Y.%m.%d'),
                                                          tmformat=('%H:%M'),
                                                          datetime=0,
                                                          time=1,
                                                          open=2,
                                                          high=3,
                                                          low=4,
                                                          close=5,
                                                          volume=6,
                                                          openinterest=-1)
                            data1 = btfeeds.GenericCSVData(dataname=datapath1,
                                                           timeframe = bt.TimeFrame.Days,
                                                          fromdate =datetime.datetime(2017,1,1),
                                                          todate= datetime.datetime(2017,4,20),
                                                          nullvalue=0.0,
                                                          dtformat=('%Y.%m.%d'),
                                                          tmformat=('%H:%M'),
                                                          datetime=0,
                                                          time=1,
                                                          open=2,
                                                          high=3,
                                                          low=4,
                                                          close=5,
                                                          volume=6,
                                                          openinterest=-1)
                            cerebro.adddata(data0,name ="Hourly Data")
                            cerebro.adddata(data1,name="Daily Data")
                        

                        The output is printed as below.

                        1770,0075,2017-04-13,17:00:00,2017-04-12,1.25171,1.25387
                        1771,0075,2017-04-13,18:00:00,2017-04-12,1.25210,1.25387
                        1772,0075,2017-04-13,19:00:00,2017-04-12,1.25155,1.25387
                        1773,0075,2017-04-13,20:00:00,2017-04-12,1.25104,1.25387
                        1774,0075,2017-04-13,21:00:00,2017-04-12,1.25097,1.25387
                        1775,0075,2017-04-13,22:00:00,2017-04-12,1.25053,1.25387
                        1776,0075,2017-04-13,23:00:00,2017-04-12,1.25008,1.25387
                        1776,0076,2017-04-13,23:00:00,2017-04-13,1.25008,1.25008
                        1777,0076,2017-04-14,00:00:00,2017-04-13,1.25060,1.25008
                        1778,0076,2017-04-14,01:00:00,2017-04-13,1.25068,1.25008
                        1779,0076,2017-04-14,02:00:00,2017-04-13,1.25040,1.25008
                        1780,0076,2017-04-14,03:00:00,2017-04-13,1.25047,1.25008
                        1781,0076,2017-04-14,04:00:00,2017-04-13,1.25071,1.25008
                        1782,0076,2017-04-14,05:00:00,2017-04-13,1.25043,1.25008
                        1783,0076,2017-04-14,06:00:00,2017-04-13,1.25065,1.25008
                        1784,0076,2017-04-14,07:00:00,2017-04-13,1.25099,1.25008
                        1785,0076,2017-04-14,08:00:00,2017-04-13,1.25054,1.25008
                        1786,0076,2017-04-14,09:00:00,2017-04-13,1.25142,1.25008
                        1787,0076,2017-04-14,10:00:00,2017-04-13,1.25124,1.25008
                        1788,0076,2017-04-14,11:00:00,2017-04-13,1.25114,1.25008
                        1789,0076,2017-04-14,12:00:00,2017-04-13,1.25115,1.25008
                        1790,0076,2017-04-14,13:00:00,2017-04-13,1.25095,1.25008
                        1791,0076,2017-04-14,14:00:00,2017-04-13,1.25084,1.25008
                        1792,0076,2017-04-14,15:00:00,2017-04-13,1.25299,1.25008
                        1793,0076,2017-04-14,16:00:00,2017-04-13,1.25271,1.25008
                        1794,0076,2017-04-14,17:00:00,2017-04-13,1.25325,1.25008
                        1795,0076,2017-04-14,18:00:00,2017-04-13,1.25272,1.25008
                        1796,0076,2017-04-14,19:00:00,2017-04-13,1.25264,1.25008
                        1797,0076,2017-04-14,20:00:00,2017-04-13,1.25262,1.25008
                        1798,0076,2017-04-14,21:00:00,2017-04-13,1.25257,1.25008
                        1799,0076,2017-04-14,22:00:00,2017-04-13,1.25273,1.25008
                        1800,0076,2017-04-14,23:00:00,2017-04-13,1.25172,1.25008
                        1800,0077,2017-04-14,23:00:00,2017-04-14,1.25172,1.25172
                        1801,0077,2017-04-17,00:00:00,2017-04-14,1.25331,1.25172
                        1802,0077,2017-04-17,01:00:00,2017-04-14,1.25301,1.25172
                        1803,0077,2017-04-17,02:00:00,2017-04-14,1.25352,1.25172
                        1804,0077,2017-04-17,03:00:00,2017-04-14,1.25416,1.25172
                        1805,0077,2017-04-17,04:00:00,2017-04-14,1.25370,1.25172
                        1806,0077,2017-04-17,05:00:00,2017-04-14,1.25423,1.25172
                        1807,0077,2017-04-17,06:00:00,2017-04-14,1.25410,1.25172
                        1808,0077,2017-04-17,07:00:00,2017-04-14,1.25357,1.25172
                        1809,0077,2017-04-17,08:00:00,2017-04-14,1.25323,1.25172
                        1810,0077,2017-04-17,09:00:00,2017-04-14,1.25369,1.25172
                        1811,0077,2017-04-17,10:00:00,2017-04-14,1.25351,1.25172
                        1812,0077,2017-04-17,11:00:00,2017-04-14,1.25386,1.25172
                        1813,0077,2017-04-17,12:00:00,2017-04-14,1.25470,1.25172
                        1814,0077,2017-04-17,13:00:00,2017-04-14,1.25440,1.25172
                        1815,0077,2017-04-17,14:00:00,2017-04-14,1.25472,1.25172
                        1816,0077,2017-04-17,15:00:00,2017-04-14,1.25531,1.25172
                        1817,0077,2017-04-17,16:00:00,2017-04-14,1.25678,1.25172
                        1818,0077,2017-04-17,17:00:00,2017-04-14,1.25933,1.25172
                        1819,0077,2017-04-17,18:00:00,2017-04-14,1.25863,1.25172
                        1820,0077,2017-04-17,19:00:00,2017-04-14,1.25855,1.25172
                        1821,0077,2017-04-17,20:00:00,2017-04-14,1.25816,1.25172
                        1822,0077,2017-04-17,21:00:00,2017-04-14,1.25630,1.25172
                        1823,0077,2017-04-17,22:00:00,2017-04-14,1.25620,1.25172
                        1824,0077,2017-04-17,23:00:00,2017-04-14,1.25631,1.25172
                        1824,0078,2017-04-17,23:00:00,2017-04-17,1.25631,1.25631
                        1825,0078,2017-04-18,00:00:00,2017-04-17,1.25649,1.25631
                        1826,0078,2017-04-18,01:00:00,2017-04-17,1.25590,1.25631
                        1827,0078,2017-04-18,02:00:00,2017-04-17,1.25565,1.25631
                        1828,0078,2017-04-18,03:00:00,2017-04-17,1.25633,1.25631
                        1829,0078,2017-04-18,04:00:00,2017-04-17,1.25675,1.25631
                        1830,0078,2017-04-18,05:00:00,2017-04-17,1.25673,1.25631
                        1831,0078,2017-04-18,06:00:00,2017-04-17,1.25635,1.25631
                        1832,0078,2017-04-18,07:00:00,2017-04-17,1.25634,1.25631
                        1833,0078,2017-04-18,08:00:00,2017-04-17,1.25692,1.25631
                        1834,0078,2017-04-18,09:00:00,2017-04-17,1.25857,1.25631
                        1835,0078,2017-04-18,10:00:00,2017-04-17,1.25948,1.25631
                        1836,0078,2017-04-18,11:00:00,2017-04-17,1.25864,1.25631
                        1837,0078,2017-04-18,12:00:00,2017-04-17,1.25564,1.25631
                        1838,0078,2017-04-18,13:00:00,2017-04-17,1.26521,1.25631
                        1839,0078,2017-04-18,14:00:00,2017-04-17,1.26682,1.25631
                        1840,0078,2017-04-18,15:00:00,2017-04-17,1.27188,1.25631
                        1841,0078,2017-04-18,16:00:00,2017-04-17,1.27387,1.25631
                        1842,0078,2017-04-18,17:00:00,2017-04-17,1.27641,1.25631
                        1843,0078,2017-04-18,18:00:00,2017-04-17,1.27670,1.25631
                        1844,0078,2017-04-18,19:00:00,2017-04-17,1.27662,1.25631
                        1845,0078,2017-04-18,20:00:00,2017-04-17,1.28302,1.25631
                        1846,0078,2017-04-18,21:00:00,2017-04-17,1.28490,1.25631
                        1847,0078,2017-04-18,22:00:00,2017-04-17,1.28434,1.25631
                        1848,0078,2017-04-18,23:00:00,2017-04-17,1.28400,1.25631
                        1848,0079,2017-04-18,23:00:00,2017-04-18,1.28400,1.28400
                        1849,0079,2017-04-19,00:00:00,2017-04-18,1.28426,1.28400
                        1850,0079,2017-04-19,01:00:00,2017-04-18,1.28428,1.28400
                        1851,0079,2017-04-19,02:00:00,2017-04-18,1.28435,1.28400
                        1852,0079,2017-04-19,03:00:00,2017-04-18,1.28359,1.28400
                        1853,0079,2017-04-19,04:00:00,2017-04-18,1.28273,1.28400
                        1854,0079,2017-04-19,05:00:00,2017-04-18,1.28217,1.28400
                        1855,0079,2017-04-19,06:00:00,2017-04-18,1.28276,1.28400
                        1856,0079,2017-04-19,07:00:00,2017-04-18,1.28249,1.28400
                        1857,0079,2017-04-19,08:00:00,2017-04-18,1.28270,1.28400
                        1858,0079,2017-04-19,09:00:00,2017-04-18,1.28257,1.28400
                        1859,0079,2017-04-19,10:00:00,2017-04-18,1.28220,1.28400
                        1860,0079,2017-04-19,11:00:00,2017-04-18,1.28176,1.28400
                        1861,0079,2017-04-19,12:00:00,2017-04-18,1.28311,1.28400
                        1862,0079,2017-04-19,13:00:00,2017-04-18,1.28389,1.28400
                        1863,0079,2017-04-19,14:00:00,2017-04-18,1.28510,1.28400
                        1864,0079,2017-04-19,15:00:00,2017-04-18,1.28332,1.28400
                        1865,0079,2017-04-19,16:00:00,2017-04-18,1.28200,1.28400
                        1866,0079,2017-04-19,17:00:00,2017-04-18,1.28108,1.28400
                        1867,0079,2017-04-19,18:00:00,2017-04-18,1.27881,1.28400
                        1868,0079,2017-04-19,19:00:00,2017-04-18,1.27852,1.28400
                        1869,0079,2017-04-19,20:00:00,2017-04-18,1.27893,1.28400
                        1870,0079,2017-04-19,21:00:00,2017-04-18,1.27841,1.28400
                        1871,0079,2017-04-19,22:00:00,2017-04-18,1.27865,1.28400
                        1872,0079,2017-04-19,23:00:00,2017-04-18,1.27772,1.28400
                        1872,0080,2017-04-19,23:00:00,2017-04-19,1.27772,1.27772
                        1873,0080,2017-04-20,00:00:00,2017-04-19,1.27824,1.27772
                        

                        data0's day is one day faster than data1's day.

                        It seems that 23:00 is double counted for data1 (e.g. 0079 and 0080)

                        Is there any way to rectify the error?

                        B 1 Reply Last reply Reply Quote 0
                        • B
                          backtrader administrators @KT last edited by

                          @KT said in Donchian Channel:

                          It seems that 23:00 is double counted for data1 (e.g. 0079 and 0080)
                          Is there any way to rectify the error?

                          You keep talking about errors. There is none. And there is again no sample data and an incomplete snippet.

                          1776,0075,2017-04-13,23:00:00,2017-04-12,1.25008,1.25387
                          1776,0076,2017-04-13,23:00:00,2017-04-13,1.25008,1.25008
                          1777,0076,2017-04-14,00:00:00,2017-04-13,1.25060,1.25008
                          

                          Even in the absence of a complete snippet

                          • The bar is not repeated. The intraday data stream is frozen (hence the no change in length, which remains at 1776)
                          • Because the daily data stream can first deliver the daily resampled bar. The only signal available to the resampling filter is the change of the day

                          The platform cannot magically know when things come to an end. In this case the only signal is the change of date.

                          Use a trading calendar if you want to offer more information and a signal to the platform. See Docs - Trading Calendar

                          1 Reply Last reply Reply Quote 0
                          • K
                            KT last edited by

                            @backtrader Sorry for the misunderstanding. I got it alr. Thankss for the help :)

                            1 Reply Last reply Reply Quote 0
                            • Ariel Iván Ruiz Mateos
                              Ariel Iván Ruiz Mateos last edited by

                              Hi @KT ! Could you paste the full source code with all the modifications?

                              thanks a lot! and good work!

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