Backtrader Community

    • 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/

    Resolve this error!

    General Code/Help
    3
    6
    394
    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.
    • C
      curious_one last edited by

      Hi

      I am trying to run a bollinger band strategy on some prices. my dataframe is pretty simple. Only contains datetime (it is the index column) and the closing price. However, when I run this code, I am getting below error. What is the reason for that? What am I missing?

      Can anyone please guide me and I am happy to take on a lesson with anyone at a fair rate if needed!

      Thanks in advance.

      My data frame = df. The df.tail() is as per displayed below.

      Datetime close
      2020-11-18 09:51:38 13.855
      2020-11-18 09:52:25 13.855
      2020-11-18 09:52:25 13.855
      2020-11-18 09:52:27 13.855
      2020-11-18 09:52:27 13.855

      Code below:

      code_text
      ```class teststrat(bt.Strategy):
          
          params = (
              ('n',20),
              ('m',2),# Tuple of tuples containing any variable settings required by the strategy.
              ('printlog',False), # Stop printing the log of the trading strategy
              
          )
          
          def __init__(self):
              self.dataclose= self.datas[0].close    # Keep a reference to the "close" line in the data[0] dataseries
              self.order = None # Property to keep track of pending orders.  There are no orders when the strategy is initialized.
              self.buyprice = None
              self.buycomm = None
              self.redline = None
              self.blueline = None
              
              # Add Bband indicator for use in the trading strategy
              self.bband = bt.indicators.BBands( 
                  self.datas[0], period=self.params.n, devfactor=self.params.m)
          
          def log(self, txt, dt=None, doprint=False):
              if self.params.printlog or doprint: # Add if statement to only log of printlog or doprint is True
                  dt = dt or self.datas[0].datetime.date(0)
                  print('{0},{1}'.format(dt.isoformat(),txt))
          
          def notify_order(self, order):
              # 1. If order is submitted/accepted, do nothing 
              if order.status in [order.Submitted, order.Accepted]:
                  return
              # 2. If order is buy/sell executed, report price executed
              if order.status in [order.Completed]: 
                  if order.isbuy():
                      self.log('BUY EXECUTED, Price: {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm: {3:8.2f}'.format(
                          order.executed.price,
                          order.executed.size,
                          order.executed.value,
                          order.executed.comm))
                      
                      self.buyprice = order.executed.price
                      self.buycomm = order.executed.comm
                  else:
                      self.log('SELL EXECUTED, {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm{3:8.2f}'.format(
                          order.executed.price, 
                          order.executed.size, 
                          order.executed.value,
                          order.executed.comm))
                  
                  self.bar_executed = len(self) #when was trade executed
              # 3. If order is canceled/margin/rejected, report order canceled
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
                  
              self.order = None
          
          def notify_trade(self,trade):
              if not trade.isclosed:
                  return
              
              self.log('OPERATION PROFIT, GROSS {0:8.2f}, NET {1:8.2f}'.format(
                  trade.pnl, trade.pnlcomm))
          
      def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.2f' % self.dataclose[0])
      
              # Check if an order is pending ... if yes, we cannot send a 2nd one
              if self.order:
                  return
      
              if self.dataclose < self.bband.lines.bot and not self.position:
                  self.redline = True
      
              if self.dataclose > self.bband.lines.top and self.position:
                  self.blueline = True
      
              if self.dataclose > self.bband.lines.mid and not self.position and self.redline:        	
                  # BUY, BUY, BUY!!! (with all possible default parameters)
                  self.log('BUY CREATE, %.2f' % self.dataclose[0])
                  # Keep track of the created order to avoid a 2nd order
                  self.order = self.buy()
      
              if self.dataclose > self.bband.lines.top and not self.position:
                  # BUY, BUY, BUY!!! (with all possible default parameters)
                  self.log('BUY CREATE, %.2f' % self.dataclose[0])
                  # Keep track of the created order to avoid a 2nd order
                  self.order = self.buy()
      
              if self.dataclose < self.bband.lines.mid and self.position and self.blueline:
                  # SELL, SELL, SELL!!! (with all possible default parameters)
                  self.log('SELL CREATE, %.2f' % self.dataclose[0])
                  self.blueline = False
                  self.redline = False
                  # Keep track of the created order to avoid a 2nd order
                  self.order = self.sell()
      
      # Create a cerebro entity            
      cerebro = bt.Cerebro()
      
      # Add a strategy
      cerebro.addstrategy(teststrat)
      
      # Create a Data Feed
      data = bt.feeds.PandasData(dataname = df)
                                  #, openinterest=False,open=False,high=False,low=False,close=-1,volume=False)
      
      # Add the Data Feed to Cerebro
      cerebro.adddata(data)
                  
      
      
      # Datas are in a subfolder of the samples. Need to find where the script is
      # because it could have been called from anywhere
      #modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
      #datapath = os.path.join(modpath, 'TSLA-USD.csv')
      
      
      strats = cerebro.optstrategy(
          teststrat,
          n=range(10,50),
          m=range(1,5),
          printlog=False)
      
      # Set our desired cash start
      cerebro.broker.setcash(10000.0)
      
      # Add a FixedSize sizer according to the stake
      cerebro.addsizer(bt.sizers.FixedSize, stake=5)
      
      # Set the commission
      cerebro.broker.setcommission(commission=0.002)
      
      # Print out the starting conditions
      print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      # Run over everything
      cerebro.run()
      
      # Print out the final result
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      # Plot the result
      cerebro.plot()
      
      Starting Portfolio Value: 10000.00
      ---------------------------------------------------------------------------
      AttributeError                            Traceback (most recent call last)
      <ipython-input-78-2914091a02c7> in <module>
          137 
          138 # Run over everything
      --> 139 cerebro.run()
          140 
          141 # Print out the final result
      
      ~\AppData\Local\Continuum\anaconda3\lib\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:
      
      ~\AppData\Local\Continuum\anaconda3\lib\site-packages\backtrader\cerebro.py in runstrategies(self, iterstrat, predata)
         1210                 data._start()
         1211                 if self._dopreload:
      -> 1212                     data.preload()
         1213 
         1214         for stratcls, sargs, skwargs in iterstrat:
      
      ~\AppData\Local\Continuum\anaconda3\lib\site-packages\backtrader\feed.py in preload(self)
          436 
          437     def preload(self):
      --> 438         while self.load():
          439             pass
          440 
      
      ~\AppData\Local\Continuum\anaconda3\lib\site-packages\backtrader\feed.py in load(self)
          477 
          478             if not self._fromstack(stash=True):
      --> 479                 _loadret = self._load()
          480                 if not _loadret:  # no bar use force to make sure in exactbars
          481                     # the pointer is undone this covers especially (but not
      
      ~\AppData\Local\Continuum\anaconda3\lib\site-packages\backtrader\feeds\pandafeed.py in _load(self)
          266 
          267         # convert to float via datetime and store it
      --> 268         dt = tstamp.to_pydatetime()
          269         dtnum = date2num(dt)
          270         self.lines.datetime[0] = dtnum
      
      AttributeError: 'str' object has no attribute 'to_pydatetime'
      C ? 2 Replies Last reply Reply Quote 0
      • C
        curious_one @curious_one last edited by

        @curious_one said in Resolve this error!:

        code_text > 
        > # Datas are in a subfolder of the samples. Need to find where the script is
        > # because it could have been called from anywhere
        > #modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
        > #datapath = os.path.join(modpath, 'TSLA-USD.csv')
        > 
        

        ignore this section in the code pls unless you think it is relevant.. thx

        1 Reply Last reply Reply Quote 0
        • ?
          A Former User @curious_one last edited by

          @curious_one your datetime is a string, try converting it to datetime objects. Look at pandas to_datetime() method.

          df.Datetime = pandas.to_datetime(
                      df.Datetime, format='%Y-%m-%d  %H:%M:%S')
          
          C 1 Reply Last reply Reply Quote 3
          • C
            curious_one @Guest last edited by

            @dasch Appreciate the help ! It seems to fix the error and the code is running as I am typing this :)

            1 Reply Last reply Reply Quote 0
            • C
              curious_one last edited by

              Hi, after fixing the datetime such that it is datetimeindex, I can run the code with no errors. However, now the code does not stop running and it has technically no output other than this: "Starting Portfolio Value: 10000.00".

              The code has been running (as shown in image screenshot below with the * circled in pink) in Jupyter notebook for at least 15 minutes and I only have 3000 rows and 2 columns worth of data containing Date on the index and Close price in another column. Hence, I am very puzzled by this.

              I have copy and pasted the code below. Can someone help please? Thank you vm in advance~!

              a6b8f18f-9f4f-4ade-a963-b5fcc97e3419-image.png

              code_text 
              
              class teststrat(bt.Strategy):
                  
                  params = (
                      ('n',20),
                      ('m',2),# Tuple of tuples containing any variable settings required by the strategy.
                      ('printlog',False), # Stop printing the log of the trading strategy
                      
                  )
                  
                  def __init__(self):
                      self.dataclose= self.datas[0].close    # Keep a reference to the "close" line in the data[0] dataseries
                      self.order = None # Property to keep track of pending orders.  There are no orders when the strategy is initialized.
                      self.buyprice = None
                      self.buycomm = None
                      self.redline = None
                      self.blueline = None
                      
                      # Add Bband indicator for use in the trading strategy
                      self.bband = bt.indicators.BBands( 
                          self.datas[0], period=self.params.n, devfactor=self.params.m)
                  
                  def log(self, txt, dt=None, doprint=False):
                      if self.params.printlog or doprint: # Add if statement to only log of printlog or doprint is True
                          dt = dt or self.datas[0].datetime.date(0)
                          print('{0},{1}'.format(dt.isoformat(),txt))
                  
                  def notify_order(self, order):
                      # 1. If order is submitted/accepted, do nothing 
                      if order.status in [order.Submitted, order.Accepted]:
                          return
                      # 2. If order is buy/sell executed, report price executed
                      if order.status in [order.Completed]: 
                          if order.isbuy():
                              self.log('BUY EXECUTED, Price: {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm: {3:8.2f}'.format(
                                  order.executed.price,
                                  order.executed.size,
                                  order.executed.value,
                                  order.executed.comm))
                              
                              self.buyprice = order.executed.price
                              self.buycomm = order.executed.comm
                          else:
                              self.log('SELL EXECUTED, {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm{3:8.2f}'.format(
                                  order.executed.price, 
                                  order.executed.size, 
                                  order.executed.value,
                                  order.executed.comm))
                          
                          self.bar_executed = len(self) #when was trade executed
                      # 3. If order is canceled/margin/rejected, report order canceled
                      elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                          self.log('Order Canceled/Margin/Rejected')
                          
                      self.order = None
                  
                  def notify_trade(self,trade):
                      if not trade.isclosed:
                          return
                      
                      self.log('OPERATION PROFIT, GROSS {0:8.2f}, NET {1:8.2f}'.format(
                          trade.pnl, trade.pnlcomm))
                  
              def next(self):
                      # Simply log the closing price of the series from the reference
                      self.log('Close, %.2f' % self.dataclose[0])
              
                      # Check if an order is pending ... if yes, we cannot send a 2nd one
                      if self.order:
                          return
              
                      if self.dataclose < self.bband.lines.bot and not self.position:
                          self.redline = True
              
                      if self.dataclose > self.bband.lines.top and self.position:
                          self.blueline = True
              
                      if self.dataclose > self.bband.lines.mid and not self.position and self.redline:        	
                          # BUY, BUY, BUY!!! (with all possible default parameters)
                          self.log('BUY CREATE, %.2f' % self.dataclose[0])
                          # Keep track of the created order to avoid a 2nd order
                          self.order = self.buy()
              
                      if self.dataclose > self.bband.lines.top and not self.position:
                          # BUY, BUY, BUY!!! (with all possible default parameters)
                          self.log('BUY CREATE, %.2f' % self.dataclose[0])
                          # Keep track of the created order to avoid a 2nd order
                          self.order = self.buy()
              
                      if self.dataclose < self.bband.lines.mid and self.position and self.blueline:
                          # SELL, SELL, SELL!!! (with all possible default parameters)
                          self.log('SELL CREATE, %.2f' % self.dataclose[0])
                          self.blueline = False
                          self.redline = False
                          # Keep track of the created order to avoid a 2nd order
                          self.order = self.sell()
              
              # Create a cerebro entity            
              cerebro = bt.Cerebro()
              
              # Add a strategy
              cerebro.addstrategy(teststrat)
              
              # Create a Data Feed
              data = bt.feeds.PandasData(dataname = df_daily)
                                          #, openinterest=False,open=False,high=False,low=False,close=-1,volume=False)
              
              # Add the Data Feed to Cerebro
              cerebro.adddata(data)
                          
              
              
              # Datas are in a subfolder of the samples. Need to find where the script is
              # because it could have been called from anywhere
              #modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
              #datapath = os.path.join(modpath, 'TSLA-USD.csv')
              
              
              strats = cerebro.optstrategy(
                  teststrat,
                  n=range(10,50),
                  m=range(1,5),
                  printlog=False)
              
              # Set our desired cash start
              cerebro.broker.setcash(10000.0)
              
              # Add a FixedSize sizer according to the stake
              cerebro.addsizer(bt.sizers.FixedSize, stake=5)
              
              # Set the commission
              cerebro.broker.setcommission(commission=0.002)
              
              # Print out the starting conditions
              print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
              
              # Run over everything
              cerebro.run()
              
              # Print out the final result
              print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
              
              # Plot the result
              cerebro.plot()
              
              Starting Portfolio Value: 10000.00
              
              
              run-out 1 Reply Last reply Reply Quote 0
              • run-out
                run-out @curious_one last edited by

                @curious_one Posted again: https://community.backtrader.com/topic/3501/code-running-forever-but-no-output/2?_=1614168414082

                RunBacktest.com

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