Dates output in backtrader not matching with dates in dataframe?
-
I was wondering if there is some rational behind why dates on my Dataframes and dates in the output of backtrader differ especially when an order is placed. I know that the order will get executed on the opening of the next candle and that's not the issue.
There seems to be some issue attaching the image of the screenshot so will just have to explain it.
The Dataframes has dates 2017-03-02 in YYYYMMDD format. My logic says that whenever volume is more than the avg volume over the last 10 days I buy if there is no open position already. Now the buy gets created on 2017-03-02 and gets executed on 2017-03-05. But there is no date in my Dataframes that is 2017-03-05 the next date after 2017-03-02 is 2017-03-03. After this it is basically shifting all the subsequent lines to 1 day prior for e.g close and volume of 2017-03-06 shows as close and volume of 2017-03-05 and so on. I am not sure if I missed something in the documentation with respect to dates.
My Code:
class MyFirstStrategy(bt.Strategy): params = (('rsi', 14), ('vol', 10)) def __init__(self): self.dataclose = self.datas[0].close self.vol = self.datas[0].volume # self.fma = bt.indicators.EMA(self.datas[0], period = self.params.fastma) # self.sma = bt.indicators.EMA(self.datas[0], period = self.params.slowma) # self.signal = bt.indicators.CrossOver(self.fma, self.sma) self.volavg = bt.indicators.SMA(self.vol, period = self.params.vol) self.order = None self.buyprice=None self.buycomm=None def log(self, txt, dt=None): dt = self.datas[0].datetime.date() print(f'{dt}, {txt}') 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(f'BUY EXECUTED: Price: {order.executed.price}, Cost: {order.executed.value}, Comms: {order.executed.comm}') elif order.issell(): self.log(f'SELL EXECUTED: Price: {order.executed.price}, Cost: {order.executed.value}, Comms: {order.executed.comm}') elif order.status in [order.Rejected, order.Margin, order.Cancelled]: self.log('Order rejected/cancelled by broker or insufficient margin') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log(f'OPERATION PROFIT: GROSS {trade.pnl}, NET {trade.pnlcomm}') def next(self): self.log(f'Close: {self.dataclose[0]}, Volume: {self.vol[0]}, Avg Vol: {self.volavg[0]}') if self.order: return if not self.position: if self.vol[0] > self.volavg[0]: self.log(f'BUY CREATED: {self.dataclose[0]}') self.order = self.buy() else: if self.vol[0] < (self.volavg[0] - (0.10 * self.volavg[0])): self.log(f'LONG POSITION CLOSED: {self.dataclose[0]}') self.order = self.sell() cerebro = bt.Cerebro() cerebro.broker.set_cash(1000000) print(f'Starting Portfolio Value: {cerebro.broker.getvalue()}') data = bt.feeds.PandasData(dataname=hdfc, datetime=None, open=-1, high=-1, low=-1, close=-1, volume=-1) cerebro.adddata(data) cerebro.addstrategy(MyFirstStrategy) cerebro.addsizer(bt.sizers.FixedSize, stake=10) cerebro.broker.setcommission(commission=0.001) cerebro.run() print(f'Final Portfolio Value: {cerebro.broker.getvalue()}')
-
@vypy1 For future reference to anyone reading this, I realised that this issue was occurring mainly because the actual datetime format was time zone aware. I just converted it to a YYYYMMDD format and now I am not facing this issue. If anything does arise later, I will update it here.