You are right there was a known issue a few years a back with this. There is an easy work-around though. Instead of using the backtrader resampling facility, use Interactive Brokers.
You can bypass resample and call the data directly from IB. Just remember that you must add the shortest timeframe first to Backtrader.
for tf_com in [(bt.TimeFrame.Minutes, 1), (bt.TimeFrame.Days, 1)]:
stockkwargs = dict(
timeframe=tf_com[0],
compression=tf_com[1],
rtbar=False,
historical=True,
qcheck=0.5,
fromdate=_FROMDATE,
todate=_TODATE,
latethrough=False,
tradename=None
)
data0 = store.getdata(dataname=_TICKER, **stockkwargs)
cerebro.adddata(data0)
You can adjust your timeframe and compression in the tuples in the first line. I will adjust it to 5 and 15 minutes so you can see the output.
for tf_com in [(bt.TimeFrame.Minutes, 5), (bt.TimeFrame.Minutes, 15)]:
************ OUTPUT ************
2021-03-25 12:00:00 636.77 632.71
2021-03-25 12:05:00 634.69 632.71
2021-03-25 12:10:00 632.71 632.71
2021-03-25 12:15:00 640.39 643.00
2021-03-25 12:20:00 640.68 643.00
2021-03-25 12:25:00 643.00 643.00
2021-03-25 12:30:00 641.33 640.00
2021-03-25 12:35:00 637.84 640.00
2021-03-25 12:40:00 640.00 640.00
2021-03-25 12:45:00 640.34 633.95
2021-03-25 12:50:00 636.15 633.95
2021-03-25 12:55:00 633.95 633.95
2021-03-25 13:00:00 633.50 637.43
2021-03-25 13:05:00 634.95 637.43
2021-03-25 13:10:00 637.43 637.43
EDIT: IN RESPONSE TO OP COMMENT
I beg to differ. The days are sampled by Interactive Brokers so you will have daily information. You must be sure when using 5 minute data at the same time not to go back too far with your start date. IB is not a historical data provider.
Here is the entire code for your reference.
import backtrader as bt
import backtrader.stores.ibstore as ibstore
import datetime
import os
from dotenv import load_dotenv
load_dotenv()
class St(bt.Strategy):
def __init__(self):
self.data_live = False
self.timeframes = {4: "minute", 5: "day"}
def next(self):
time = self.data.datetime.time()
start_day = datetime.time(4, 20, 0)
end_day = datetime.time(19, 40, 0)
if time < start_day or time > end_day:
print_date = True
else:
print_date = False
if not self.data_live and print_date:
print(
f"{self.data.datetime.datetime()} "
f"data0: tf: {self.timeframes[self.datas[0]._timeframe]} "
f"comp: {self.datas[0]._compression}, "
f"{self.datas[0].close[0]:5.2f} "
f"data1: tf: {self.timeframes[self.datas[1]._timeframe]} "
f"comp: {self.datas[1]._compression} "
f"{self.datas[1].close[0]:5.2f} "
)
return
_TICKER = "TSLA-STK-SMART-USD"
_FROMDATE = datetime.datetime(2021, 3, 10)
_TODATE = datetime.datetime(2021, 3, 24)
_HAS_STATS = False
_CLIENTID = os.getenv("CLIENTID")
_PORT = os.getenv("SOCKET_PORT")
def run():
cerebro = bt.Cerebro(stdstats=_HAS_STATS)
cerebro.addstrategy(St)
store = ibstore.IBStore(host="127.0.0.1", port=int(_PORT), clientId=_CLIENTID)
cerebro.broker = store.getbroker()
for tf_com in [(bt.TimeFrame.Minutes, 5), (bt.TimeFrame.Days, 1)]:
stockkwargs = dict(
timeframe=tf_com[0],
compression=tf_com[1],
rtbar=False,
historical=True,
qcheck=0.5,
fromdate=_FROMDATE,
todate=_TODATE,
latethrough=False,
tradename=None,
)
data = store.getdata(dataname=_TICKER, **stockkwargs)
cerebro.adddata(data)
cerebro.run()
if __name__ == "__main__":
run()
Here is the output with the middle of the days removed.
Please note that backtrader will set the next day value at the end of the last bar of the previous day.
2021-03-10 19:55:00 data0: tf: minute comp: 5, 664.56 data1: tf: day comp: 1 664.56
2021-03-11 04:00:00 data0: tf: minute comp: 5, 699.10 data1: tf: day comp: 1 664.56
2021-03-11 04:05:00 data0: tf: minute comp: 5, 701.50 data1: tf: day comp: 1 664.56
2021-03-11 04:10:00 data0: tf: minute comp: 5, 699.00 data1: tf: day comp: 1 664.56
2021-03-11 04:15:00 data0: tf: minute comp: 5, 701.00 data1: tf: day comp: 1 664.56
2021-03-11 19:45:00 data0: tf: minute comp: 5, 698.05 data1: tf: day comp: 1 664.56
2021-03-11 19:50:00 data0: tf: minute comp: 5, 698.09 data1: tf: day comp: 1 664.56
2021-03-11 19:55:00 data0: tf: minute comp: 5, 698.50 data1: tf: day comp: 1 664.56
2021-03-11 19:55:00 data0: tf: minute comp: 5, 698.50 data1: tf: day comp: 1 698.50
2021-03-12 04:00:00 data0: tf: minute comp: 5, 674.25 data1: tf: day comp: 1 698.50
2021-03-12 04:05:00 data0: tf: minute comp: 5, 676.00 data1: tf: day comp: 1 698.50
2021-03-12 04:10:00 data0: tf: minute comp: 5, 669.00 data1: tf: day comp: 1 698.50
2021-03-12 04:15:00 data0: tf: minute comp: 5, 669.46 data1: tf: day comp: 1 698.50
2021-03-12 19:45:00 data0: tf: minute comp: 5, 693.30 data1: tf: day comp: 1 698.50
2021-03-12 19:50:00 data0: tf: minute comp: 5, 692.80 data1: tf: day comp: 1 698.50
2021-03-12 19:55:00 data0: tf: minute comp: 5, 692.99 data1: tf: day comp: 1 698.50
2021-03-12 19:55:00 data0: tf: minute comp: 5, 692.99 data1: tf: day comp: 1 692.99
2021-03-15 04:00:00 data0: tf: minute comp: 5, 689.00 data1: tf: day comp: 1 692.99
2021-03-15 04:05:00 data0: tf: minute comp: 5, 692.13 data1: tf: day comp: 1 692.99
2021-03-15 04:10:00 data0: tf: minute comp: 5, 692.12 data1: tf: day comp: 1 692.99
2021-03-15 04:15:00 data0: tf: minute comp: 5, 692.31 data1: tf: day comp: 1 692.99
2021-03-15 19:45:00 data0: tf: minute comp: 5, 702.00 data1: tf: day comp: 1 692.99
2021-03-15 19:50:00 data0: tf: minute comp: 5, 702.00 data1: tf: day comp: 1 692.99
2021-03-15 19:55:00 data0: tf: minute comp: 5, 702.00 data1: tf: day comp: 1 692.99
2021-03-15 19:55:00 data0: tf: minute comp: 5, 702.00 data1: tf: day comp: 1 702.00
2021-03-16 04:00:00 data0: tf: minute comp: 5, 704.01 data1: tf: day comp: 1 702.00
2021-03-16 04:05:00 data0: tf: minute comp: 5, 704.98 data1: tf: day comp: 1 702.00
2021-03-16 04:10:00 data0: tf: minute comp: 5, 704.99 data1: tf: day comp: 1 702.00
2021-03-16 04:15:00 data0: tf: minute comp: 5, 706.20 data1: tf: day comp: 1 702.00
2021-03-16 19:45:00 data0: tf: minute comp: 5, 673.65 data1: tf: day comp: 1 702.00
2021-03-16 19:50:00 data0: tf: minute comp: 5, 674.00 data1: tf: day comp: 1 702.00
2021-03-16 19:55:00 data0: tf: minute comp: 5, 674.10 data1: tf: day comp: 1 702.00
2021-03-16 19:55:00 data0: tf: minute comp: 5, 674.10 data1: tf: day comp: 1 674.10
2021-03-17 04:00:00 data0: tf: minute comp: 5, 672.00 data1: tf: day comp: 1 674.10
2021-03-17 04:05:00 data0: tf: minute comp: 5, 675.80 data1: tf: day comp: 1 674.10
2021-03-17 04:10:00 data0: tf: minute comp: 5, 677.19 data1: tf: day comp: 1 674.10
2021-03-17 04:15:00 data0: tf: minute comp: 5, 676.03 data1: tf: day comp: 1 674.10
2021-03-17 19:45:00 data0: tf: minute comp: 5, 699.66 data1: tf: day comp: 1 674.10
2021-03-17 19:50:00 data0: tf: minute comp: 5, 699.90 data1: tf: day comp: 1 674.10
2021-03-17 19:55:00 data0: tf: minute comp: 5, 699.74 data1: tf: day comp: 1 674.10
2021-03-17 19:55:00 data0: tf: minute comp: 5, 699.74 data1: tf: day comp: 1 699.74
2021-03-18 04:00:00 data0: tf: minute comp: 5, 685.00 data1: tf: day comp: 1 699.74
2021-03-18 04:05:00 data0: tf: minute comp: 5, 686.35 data1: tf: day comp: 1 699.74
2021-03-18 04:10:00 data0: tf: minute comp: 5, 688.32 data1: tf: day comp: 1 699.74
2021-03-18 04:15:00 data0: tf: minute comp: 5, 692.50 data1: tf: day comp: 1 699.74
2021-03-18 19:45:00 data0: tf: minute comp: 5, 652.10 data1: tf: day comp: 1 699.74
2021-03-18 19:50:00 data0: tf: minute comp: 5, 651.00 data1: tf: day comp: 1 699.74
2021-03-18 19:55:00 data0: tf: minute comp: 5, 650.56 data1: tf: day comp: 1 699.74
2021-03-18 19:55:00 data0: tf: minute comp: 5, 650.56 data1: tf: day comp: 1 650.56
2021-03-19 04:00:00 data0: tf: minute comp: 5, 661.00 data1: tf: day comp: 1 650.56
2021-03-19 04:05:00 data0: tf: minute comp: 5, 663.00 data1: tf: day comp: 1 650.56
2021-03-19 04:10:00 data0: tf: minute comp: 5, 663.60 data1: tf: day comp: 1 650.56
2021-03-19 04:15:00 data0: tf: minute comp: 5, 666.48 data1: tf: day comp: 1 650.56
2021-03-19 19:45:00 data0: tf: minute comp: 5, 652.50 data1: tf: day comp: 1 650.56
2021-03-19 19:50:00 data0: tf: minute comp: 5, 652.02 data1: tf: day comp: 1 650.56
2021-03-19 19:55:00 data0: tf: minute comp: 5, 652.20 data1: tf: day comp: 1 650.56
2021-03-19 19:55:00 data0: tf: minute comp: 5, 652.20 data1: tf: day comp: 1 652.20
2021-03-22 04:00:00 data0: tf: minute comp: 5, 665.97 data1: tf: day comp: 1 652.20
2021-03-22 04:05:00 data0: tf: minute comp: 5, 664.00 data1: tf: day comp: 1 652.20
2021-03-22 04:10:00 data0: tf: minute comp: 5, 665.00 data1: tf: day comp: 1 652.20
2021-03-22 04:15:00 data0: tf: minute comp: 5, 663.94 data1: tf: day comp: 1 652.20
2021-03-22 19:45:00 data0: tf: minute comp: 5, 668.39 data1: tf: day comp: 1 652.20
2021-03-22 19:50:00 data0: tf: minute comp: 5, 668.56 data1: tf: day comp: 1 652.20
2021-03-22 19:55:00 data0: tf: minute comp: 5, 669.35 data1: tf: day comp: 1 652.20
2021-03-22 19:55:00 data0: tf: minute comp: 5, 669.35 data1: tf: day comp: 1 669.35
2021-03-23 04:00:00 data0: tf: minute comp: 5, 670.25 data1: tf: day comp: 1 669.35
2021-03-23 04:05:00 data0: tf: minute comp: 5, 665.33 data1: tf: day comp: 1 669.35
2021-03-23 04:10:00 data0: tf: minute comp: 5, 664.11 data1: tf: day comp: 1 669.35
2021-03-23 04:15:00 data0: tf: minute comp: 5, 662.93 data1: tf: day comp: 1 669.35
2021-03-23 19:45:00 data0: tf: minute comp: 5, 661.00 data1: tf: day comp: 1 669.35
2021-03-23 19:50:00 data0: tf: minute comp: 5, 661.08 data1: tf: day comp: 1 669.35
2021-03-23 19:55:00 data0: tf: minute comp: 5, 663.00 data1: tf: day comp: 1 669.35
2021-03-23 19:55:00 data0: tf: minute comp: 5, 663.00 data1: tf: day comp: 1 663.00
=== OP Verification ===
Here is what the data0 and data1 plot look like, adding a cerebro.plot()
after the cerebro.run()
.

That's good looking daily data.