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

Bug: can't get attribute on lineseries.



  • If I use optstrategy and use more than one adddata, then I get this exception:

    Exception in thread Thread-3:
    Traceback (most recent call last):
      File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
        self.run()
      File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 864, in run
        self._target(*self._args, **self._kwargs)
      File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 463, in _handle_results
        task = get()
      File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/connection.py", line 251, in recv
        return _ForkingPickler.loads(buf.getbuffer())
    AttributeError: Can't get attribute 'Lines_LineSeries_LineIterator_DataAccessor_ObserverBase_Observer_DataTrades_fa578223e8c04a48bdb681098956aac8' on <module 'backtrader.lineseries' from '/usr/local/lib/python3.6/site-packages/backtrader/lineseries.py'>
    

    If I change either of the above things (either add only one data or use addstrategy), I don't get this error.

    Here's my code:

    from __future__ import (absolute_import, division, print_function, unicode_literals)
    
    import backtrader as bt
    
    from strategies.sma_crossover import SMA_CrossOver
    from strategies.strategy_container import StrategyContainer
    from api import crypto_data
    
    data_spec = [
            {"symbol": "BTC/USD", "exchange": "CCCAGG", "res": "day", "length": 365},
            {"symbol": "ETH/USD", "exchange": "CCCAGG", "res": "day", "length": 365},
    ]
    
    StrategyContainer.register(SMA_CrossOver)
    
    # cerebro
    cerebro = bt.Cerebro()
    cerebro.broker.setcash(100000.0)
    cerebro.broker.setcommission(commission=0.001)
    cerebro.addanalyzer(bt.analyzers.PyFolio)
    cerebro.optstrategy(StrategyContainer, strategy_index=StrategyContainer.indices())
    
    # data
    for d in data_spec:
        data = crypto_data.get_feed(d["symbol"], exchange=d["exchange"], resolution=d["res"], length=d["length"])
        cerebro.adddata(data, name=d["symbol"])
    results = cerebro.run()
    

    What could be the reason for this?


  • administrators

    Where is the bug?



  • Yes, that's what I'm asking.



  • It might be in backtrader or more likely in my code. Any ideas?



  • I get the same problem if I switch optreturn of Cerebro from the default of True to False.



  • I simplified the example so it's really easy to read and follows most of the conventions that the Backtrader's samples also take.

    Here's the simplified code with the same problems as above. Why does this happen?

    from __future__ import (absolute_import, division, print_function, unicode_literals)
    
    import datetime
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import backtrader.indicators as btind
    
    
    def run():
        cerebro = bt.Cerebro(optreturn=False)
        StrategyContainer.register(SMA_CrossOver)
        cerebro.optstrategy(StrategyContainer, strategy_index=StrategyContainer.indices())
    
        data0 = btfeeds.YahooFinanceCSVData(dataname='../../datas/daily-PEP.csv', fromdate=datetime.datetime(1997, 1, 1), todate=datetime.datetime(1998, 1, 1))
        cerebro.adddata(data0)
        cerebro.adddata(data0)
    
        # run
        results = cerebro.run()
    
    
    class StrategyContainer(object):
        _strategies = []
        @classmethod
        def register(cls, strategy):
            cls._strategies.append(strategy)
        @classmethod
        def indices(cls):
            return range(len(cls._strategies))
        def __new__(cls, *args, **kwargs):
            strategy_index = kwargs.pop('strategy_index')
            obj = cls._strategies[strategy_index](*args, **kwargs)
            return obj
    
    
    class SMA_CrossOver(bt.Strategy):
        pass
    
    
    run()