AttributeError: 'str' object has no attribute 'toordinal'
-
I just tried running the multi-data strategy example on jupyter notebook multi example and there is this error which I am not able to sort at all. I would be grateful if anyone could help.
The error is:<ipython-input-14-5a64cb8aa48a> in <module> 32 33 # Execute ---> 34 cerebro.run() 35 36 cerebro.plot() ~/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py in run(self, **kwargs) 1125 # let's skip process "spawning" 1126 for iterstrat in iterstrats: -> 1127 runstrat = self.runstrategies(iterstrat) 1128 self.runstrats.append(runstrat) 1129 if self._dooptimize: ~/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py in runstrategies(self, iterstrat, predata) 1208 if self._exactbars < 1: # datas can be full length 1209 data.extend(size=self.params.lookahead) -> 1210 data._start() 1211 if self._dopreload: 1212 data.preload() ~/anaconda3/lib/python3.7/site-packages/backtrader/feed.py in _start(self) 204 205 if not self._started: --> 206 self._start_finish() 207 208 def _timeoffset(self): ~/anaconda3/lib/python3.7/site-packages/backtrader/feed.py in _start_finish(self) 181 self.fromdate = float('-inf') 182 else: --> 183 self.fromdate = self.date2num(self.p.fromdate) 184 185 if self.p.todate is None: ~/anaconda3/lib/python3.7/site-packages/backtrader/feed.py in date2num(self, dt) 248 return date2num(self._tz.localize(dt)) 249 --> 250 return date2num(dt) 251 252 def num2date(self, dt=None, tz=None, naive=True): ~/anaconda3/lib/python3.7/site-packages/backtrader/utils/dateintern.py in date2num(dt, tz) 214 dt -= delta 215 --> 216 base = float(dt.toordinal()) 217 if hasattr(dt, 'hour'): 218 # base += (dt.hour / HOURS_PER_DAY + AttributeError: 'str' object has no attribute 'toordinal'
And the code is:
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime import backtrader as bt class TestSizer(bt.Sizer): params = dict(stake=1) def _getsizing(self, comminfo, cash, data, isbuy): dt, i = self.strategy.datetime.date(), data._id s = self.p.stake * (1 + (not isbuy)) print('{} Data {} OType {} Sizing to {}'.format( dt, data._name, ('buy' * isbuy) or 'sell', s)) return s class St(bt.Strategy): params = dict( enter=[1, 3, 4], # data ids are 1 based hold=[7, 10, 15], # data ids are 1 based usebracket=True, rawbracket=True, pentry=0.015, plimits=0.03, valid=10, ) def notify_order(self, order): if order.status == order.Submitted: return dt, dn = self.datetime.date(), order.data._name print('{} {} Order {} Status {}'.format( dt, dn, order.ref, order.getstatusname()) ) whichord = ['main', 'stop', 'limit', 'close'] if not order.alive(): # not alive - nullify dorders = self.o[order.data] idx = dorders.index(order) dorders[idx] = None print('-- No longer alive {} Ref'.format(whichord[idx])) if all(x is None for x in dorders): dorders[:] = [] # empty list - New orders allowed def __init__(self): self.o = dict() # orders per data (main, stop, limit, manual-close) self.holding = dict() # holding periods per data def next(self): for i, d in enumerate(self.datas): dt, dn = self.datetime.date(), d._name pos = self.getposition(d).size print('{} {} Position {}'.format(dt, dn, pos)) if not pos and not self.o.get(d, None): # no market / no orders if dt.weekday() == self.p.enter[i]: if not self.p.usebracket: self.o[d] = [self.buy(data=d)] print('{} {} Buy {}'.format(dt, dn, self.o[d][0].ref)) else: p = d.close[0] * (1.0 - self.p.pentry) pstp = p * (1.0 - self.p.plimits) plmt = p * (1.0 + self.p.plimits) valid = datetime.timedelta(self.p.valid) if self.p.rawbracket: o1 = self.buy(data=d, exectype=bt.Order.Limit, price=p, valid=valid, transmit=False) o2 = self.sell(data=d, exectype=bt.Order.Stop, price=pstp, size=o1.size, transmit=False, parent=o1) o3 = self.sell(data=d, exectype=bt.Order.Limit, price=plmt, size=o1.size, transmit=True, parent=o1) self.o[d] = [o1, o2, o3] else: self.o[d] = self.buy_bracket( data=d, price=p, stopprice=pstp, limitprice=plmt, oargs=dict(valid=valid)) print('{} {} Main {} Stp {} Lmt {}'.format( dt, dn, *(x.ref for x in self.o[d]))) self.holding[d] = 0 elif pos: # exiting can also happen after a number of days self.holding[d] += 1 if self.holding[d] >= self.p.hold[i]: o = self.close(data=d) self.o[d].append(o) # manual order to list of orders print('{} {} Manual Close {}'.format(dt, dn, o.ref)) if self.p.usebracket: self.cancel(self.o[d][1]) # cancel stop side print('{} {} Cancel {}'.format(dt, dn, self.o[d][1])) if __name__ == '__main__': cerebro = bt.Cerebro() folder_path = '/home/aviral/backtrader-master/datas/' data0_path = folder_path + 'orcl-1995-2014.txt' data1_path = folder_path + 'nvda-1999-2014.txt' data2_path = folder_path + 'yhoo-1996-2014.txt' fdate = '2001-01-01' todate = '2007-01-01' # Data feed data0 = bt.feeds.YahooFinanceCSVData(dataname=data0_path, fromdate=fdate, todate=todate) cerebro.adddata(data0, name='d0') data1 = bt.feeds.YahooFinanceCSVData(dataname=data1_path, fromdate=fdate, todate=todate) data1.plotinfo.plotmaster = data0 cerebro.adddata(data1, name='d1') data2 = bt.feeds.YahooFinanceCSVData(dataname=data2_path, fromdate=fdate, todate=todate) data2.plotinfo.plotmaster = data0 cerebro.adddata(data2, name='d2') # Broker cerebro.broker.setcommission(commission=0.001) # Sizer # cerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')')) cerebro.addsizer(TestSizer) # Strategy cerebro.addstrategy(St) # Execute cerebro.run() cerebro.plot()
I have not made any changes to the function, and just copying it from the post but I am unable to run it.
-
I had a similar attribute error and I was also using Jupyter Notebook
-
@Aviral_ said in AttributeError: 'str' object has no attribute 'toordinal':
fdate = '2001-01-01'
todate = '2007-01-01'
# Data feed
data0 = bt.feeds.YahooFinanceCSVData(dataname=data0_path, fromdate=fdate, todate=todate)It seems you are passing the
fromdate
andtodate
parameters to YahooFinanceCSVData as strings. Please try to pass it as a pythondatetime
objects. -
Thank you so much, that was the error. I should have noticed it myself.