Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Trying to run from latest source code

    General Code/Help
    2
    4
    1903
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      sfkiwi last edited by sfkiwi

      I am trying to run backtrader from the latest source code but am getting an error when I execute cerebro.run()

      AttributeError: 'NoneType' object has no attribute '_next_stid'
      

      Update & Solution: I resolved this issue, so posting the solution here. I have left the original question below for context. The issue was occurring because in my Jupyter Notebook I was importing from libs.backtrader to make sure that I was importing the source code and not the installed pip install version. The source code, however uses import backtrader as bt throughout which was pulling in the install version. There is a function called findowner which attempts to search the call stack for the owner of the strategy and because of the different imports the stack frames were different and couldn't find the cerebro instance and hence findowner returned None which triggered the error.
      Solution: I modified my Jupyter Notebook so that it too had import backtrader as bt but before the import statement I added sys.path = ['libs/backtrader'] + sys.path which prepended my local directory to the sys.path which caused both my Jupyter Notebook and the source code to find the backtrader module in the local directory before searching the pip install paths.


      Original Question:

      I have been successfully running backtrader from a pip install inside a conda env and am running inside a Jupyter Notebook environment. Everything has been working fine using the installed version of backtrader.

      I have made a couple of minor changes to the source code so I have cloned the backtrader repo to a local folder and have simlinked the folder inside my Jupyter Notebook folder.

      # common root folder is 'code'
      cd code/
      
      # clone backtrader into code/backtrader
      git clone https://github.com/backtrader/backtrader.git
      
      # code/project is where the jupyter notebook is
      # change directory to libs/ directory inside project directory
      cd project/libs/
      
      #inside libs/ directory create a symlink to backtrader folder
      ln -s ~/.../code/backtrader backtrader
      
      # /code/backtrader - backtrader project folder
      # /code/project - my jupyter notebook folder
      # /code/project/libs/backtrader - symlinked backtrader folder
      # /code/project/data/equities - folder containing dataset
      

      Inside my jupyter notebook I am importing the project as

      from libs.backtrader import backtrader as bt
      from libs.backtrader.backtrader import indicators as btind
      from libs.backtrader.backtrader import feeds as btfeeds
      

      I am using one of the example strategies and sample data sets

      class TestStrategy(bt.Strategy):
      
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              dt = dt or self.datas[0].datetime.date(0)
              print('%s, %s' % (dt.isoformat(), txt))
      
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
      
          def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.2f' % self.dataclose[0])
      
              if self.dataclose[0] < self.dataclose[-1]:
                  # current close less than previous close
      
                  if self.dataclose[-1] < self.dataclose[-2]:
                      # previous close less than the previous close
      
                      # BUY, BUY, BUY!!! (with all possible default parameters)
                      self.log('BUY CREATE, %.2f' % self.dataclose[0])
                      self.buy()
      

      Then I run the strategy as

      cerebro = bt.Cerebro()
      
      # Add the strategy
      cerebro.addstrategy(TestStrategy)
      
      # path to data
      datapath = 'data/equities/orcl-1995-2014.txt'
      
      # Create a Data Feed
      data = bt.feeds.YahooFinanceCSVData(
          dataname=datapath,
          # Do not pass values before this date
          fromdate=datetime.datetime(2000, 1, 1),
          # Do not pass values before this date
          todate=datetime.datetime(2000, 12, 31),
          # Do not pass values after this date
          reverse=False)
      
      # Add the Data Feed to Cerebro
      cerebro.adddata(data)
      
      # Set up broker
      cerebro.broker.setcash(100000.0)
      
      # Run 
      cerebro.run()
      

      Running this produces the following error. Running the exact same code using the pip installed version of backtrader does not cause the error

      ---------------------------------------------------------------------------
      AttributeError                            Traceback (most recent call last)
      <ipython-input-40-166ad5063c49> in <module>()
      ----> 1 cerebro.run(runonce=False)
      
      ~/Dropbox/Work/Code/Trading/strategies/libs/backtrader/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:
      
      ~/Dropbox/Work/Code/Trading/strategies/libs/backtrader/backtrader/cerebro.py in runstrategies(self, iterstrat, predata)
         1215             sargs = self.datas + list(sargs)
         1216             try:
      -> 1217                 strat = stratcls(*sargs, **skwargs)
         1218             except bt.errors.StrategySkipError:
         1219                 continue  # do not add strategy to the mix
      
      ~/Dropbox/Work/Code/Trading/strategies/libs/backtrader/backtrader/metabase.py in __call__(cls, *args, **kwargs)
           84     def __call__(cls, *args, **kwargs):
           85         cls, args, kwargs = cls.doprenew(*args, **kwargs)
      ---> 86         _obj, args, kwargs = cls.donew(*args, **kwargs)
           87         _obj, args, kwargs = cls.dopreinit(_obj, *args, **kwargs)
           88         _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
      
      ~/Dropbox/Work/Code/Trading/strategies/libs/backtrader/backtrader/strategy.py in donew(cls, *args, **kwargs)
           70         # Find the owner and store it
           71         _obj.env = _obj.cerebro = cerebro = findowner(_obj, bt.Cerebro)
      ---> 72         _obj._id = cerebro._next_stid()
           73 
           74         return _obj, args, kwargs
      
      AttributeError: 'NoneType' object has no attribute '_next_stid'
      

      It seems like findowner is not finding the cerebro instance. I am wondering if this is because of the way strategy.py it is importing backtrader and instead of using the local code, is importing the pip installed version

      # strategy.py 
         32   from .utils.py3 import (filter, keys, integer_types, iteritems, itervalues,
         33       map, MAXINT, string_types, with_metaclass)
       
      >> 34   import backtrader as bt
         35   from .lineiterator import LineIterator, StrategyBase
      
      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @sfkiwi last edited by

        @sfkiwi said in Trying to run from latest source code:

        from libs.backtrader import backtrader as bt
        from libs.backtrader.backtrader import indicators as btind
        from libs.backtrader.backtrader import feeds as btfeeds
        

        It's not clear what you are trying to achieve, but that's clearly wrong and bound to break things.

        S 1 Reply Last reply Reply Quote 0
        • S
          sfkiwi @backtrader last edited by

          @backtrader What I was trying to do was have my project import the library from the source directly rather than from the installed package. I'm fairly new to python so if there is a standard way to achieve this then please enlighten me.

          For now I have just added my local source code path to the front of sys.path which works and doesn't break things.

          B 1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators @sfkiwi last edited by

            @sfkiwi It's not about enlightening ... if the standard snippets using backtrader show (for example, there are additional import forms of course)

            import backtrader as bt
            from backtrader import indicators as btind
            

            and your script shows

            from libs.backtrader import backtrader as bt
            from libs.backtrader.backtrader import indicators as btind
            from libs.backtrader.backtrader import feeds as btfeeds
            

            It seems like if you want to have backtrader in backtrader, like if you were trying to override things by having a backtrader package inside another backtrader package. I cannot tell you what this breaks or of if it breaks something, but it is for sure the wrong approach and it probably breaks things (as you have experienced)

            There is no magic as to how to use the source, from the README in the repository:

            From source:

            • Place the backtrader directory found in the sources inside your project

            This is just like this for any Python package if you don't want to use pip or pipenv or easy_install (no longer trendy these days). Of course there may be exceptions for packages which manipulate the path and do dirty things during initialization, but these are the exception and backtrader is for sure not amongts them.

            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors