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 :
- the indicator is based on hourly data instead of the daily data
- 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()
-
@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
? (orself.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
-
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).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
'sCrossUp
andCrossDown
indicators to generateBuy
andSell
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 :)
-
@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 !!
-
@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 completedatetime
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 for2017-04-18
and the daily data is still frozen on the previous day2017-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 for2017-04-18
, the dailyAnd 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?
-
@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 :)
-
Hi @KT ! Could you paste the full source code with all the modifications?
thanks a lot! and good work!