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

Exception has occurred: ValueError day is out of range for month File "F:\IBBackTradeLiveDataEx.py", line 165, in <module> cerebro.run()



  • Getting above error. Trying to replay data, higherTF=Daily, LowerTimeFrame=5 min
    Code below:

    from future import absolute_import, division, print_function, unicode_literals
    import backtrader as bt
    from backtrader import Order
    import matplotlib as plt
    import datetime
    import pytz
    import ta

    cerebro = bt.Cerebro()
    store = bt.stores.IBStore(host="127.0.0.1", port=7496, clientId= 4)
    cerebro.addstrategy(IntraTrendStrategy)
    stockkwargs = dict(
    timeframe=bt.TimeFrame.Minutes,
    compression=5,
    rtbar=False, # use RealTime 5 seconds bars
    historical=True, # only historical download
    qcheck=0.5, # timeout in seconds (float) to check for events
    fromdate=datetime.datetime(2020, 1, 1), # get data from..
    todate=datetime.datetime(2020, 9, 20), # get data from..
    latethrough=False, # let late samples through
    tradename=None, # use a different asset as order target
    tz="Asia/Kolkata"
    )

    data0 = store.getdata(dataname="TCS-STK-NSE-INR", **stockkwargs)
    cerebro.replaydata(data0, timeframe=bt.TimeFrame.Days, compression=1)
    cerebro.broker.setcash(100000.0)
    cerebro.broker.setcommission(commission=0.001)
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    cerebro.run()

    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())



  • Seems to be an embarrassing bug in the way the IBStore calculates the minimal possible number of historical requests.

    BTW it doesn't crash if you just use the different fromdate like datetime(2020,1,2) for example.

    The problem is with the following code in IBStore.py:

        def dt_plus_duration(self, dt, duration):
            size, dim = duration.split()
            size = int(size)
            if dim == 'S':
                return dt + timedelta(seconds=size)
    
            if dim == 'D':
                return dt + timedelta(days=size)
    
            if dim == 'W':
                return dt + timedelta(days=size * 7)
    
            if dim == 'M':
                month = dt.month - 1 + size  # -1 to make it 0 based, readd below
                years, month = divmod(month, 12)
                try:
                    return dt.replace(year=dt.year + years, month=month + 1)  # <=-- the bug is here
                except:
                    pass
    
            if dim == 'Y':
                return dt.replace(year=dt.year + size)
    
            return dt  # could do nothing with it ... return it intact
    

    It's plain wrong to replace the month of the date without taking care of the day of the month. In our case the date '2019.12.31' was replaced with '2020.02.31' which is definitely wrong.





  • Thank you!


Log in to reply
 

});