I'm learning to use backtrader and I've come across a problem when trying to print out the datafeed. It correctly prints the day, open, high, low, close and volume but the hour and minutes data seems to default to 23:59:59.999989 on every line.
Here is a sample of the data source:
datetime,open,high,low,close,volume,,
11/2/2020 9:30,330.187,330.188,329.947,330.038,4.79,,
11/2/2020 9:31,330.038,330.438,329.538,329.677,5.49,,
11/2/2020 9:32,329.667,330.248,329.577,330.117,5.8,,
11/2/2020 9:33,330.128,330.328,329.847,329.948,5.59,,
11/2/2020 9:34,329.967,330.308,329.647,329.698,6.24,,
and the code I use to add the data to backtrader is:
data = bt.feeds.GenericCSVData(
dataname = 'SPY_11_2020_1M.txt',
name= 'SPY',
datetime = 0,
dtformat = ('%m/%d/%Y %H:%M'),
period = bt.TimeFrame.Ticks,
compression = 1,
fromdate = params['fromdate'],
todate = params['todate'],
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1,
)
cerebro.adddata(data)
my code for the trategy, which is a simple buy and hold strategy, is:
import backtrader as bt
from datetime import datetime as dt
class BuyHold(bt.Strategy):
def __init__(self):
# self.time = self.datas[0].datetime.datetime(0),
self.open = self.datas[0].open
self.high = self.datas[0].high
self.low = self.datas[0].low
self.close = self.datas[0].close
self.volume = self.datas[0].volume
def next(self):
print('{0} {1}\t{2}\t{3}\t{4}\t{5}\t{6}'.format(
self.datas[0].datetime.date(0),
self.datas[0].datetime.time(0),
self.open[0],
self.high[0],
self.low[0],
self.close[0],
self.volume[0]
))
# print('{0}\t{1}\t{2}\t{3}\t{4}\t{5}'.format(
# self.time,
# self.open[0],
# self.high[0],
# self.low[0],
# self.close[0],
# self.volume[0]
# ))
if self.position.size == 0:
size = int(self.broker.getcash() / self.data)
self.buy(size = size)
The printout I get is as:
2020-11-02 23:59:59.999989 330.187 330.188 329.947 330.038 4.79
2020-11-02 23:59:59.999989 330.038 330.438 329.538 329.677 5.49
2020-11-02 23:59:59.999989 329.667 330.248 329.577 330.117 5.8
2020-11-02 23:59:59.999989 330.128 330.328 329.847 329.948 5.59
2020-11-02 23:59:59.999989 329.967 330.308 329.647 329.698 6.24
I also tried it with the commented out self.time
with the commented out print
line which provides similar result in a slightly different format as:
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.187 330.188 329.947 330.038 4.79
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.038 330.438 329.538 329.677 5.49
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.667 330.248 329.577 330.117 5.8
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.128 330.328 329.847 329.948 5.59
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.967 330.308 329.647 329.698 6.24
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.698 330.198 329.568 329.948 6.51
I don't know what I'm missing here.
This problem also took me few hours. And I find the solution from another web. Here.
For minute data tell cerebro that you are using minute data (timeframe) and how many minutes per bar (compression).