For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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 and todate parameters to YahooFinanceCSVData as strings. Please try to pass it as a python datetime objects.



  • Thank you so much, that was the error. I should have noticed it myself.


Log in to reply
 

});