Donchian Channel



  • 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()
    
    

  • administrators

    @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.



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


  • administrators

    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.



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


  • @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 :)


  • administrators

    @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.



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


  • administrators

    @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.



  • @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?


  • administrators

    @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



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


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.