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/

    Dynamic values for strategy

    Indicators/Strategies/Analyzers
    3
    5
    796
    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.
    • A
      agog last edited by

      Hi,
      I'm new to Backtrader and am really enjoying it! I searched the documentation, articles, and forum for anything about dynamically changing the strategy parameters after initialization. I could only find one example on dynamically changing the an indicator which I could not figure out...
      I am probably misunderstanding the Dynamic Indicators article. If this is the case, could someone please explain it to me with the example below.

      I am trying to add another indicator (EMA3cross) to the strategy - I want this indicator to be dynamically changed between the EMA1cross and EMA2cross proportionally according to the SMA indicator.

      class Test(bt.Strategy):
      
          params = (('ema1fast', 20), ('ema1slow', 40), ('ema2fast', 50), ('ema2slow', 100), ('sma', 50))
      
          def __init__(self):
              # EMAcross1
              self.e1f = btind.EMA(self.data, period=self.p.ema1fast)
              self.e1s = btind.EMA(self.data, period=self.p.ema1slow)
              # EMAcross2
              self.e2f = btind.EMA(self.data, period=self.p.ema2fast)
              self.e2s = btind.EMA(self.data, period=self.p.ema2slow)
              # SMA
              self.sma = btind.SMA(self.data, period=self.p.sma)
      
          def next(self):
              # EMA3cross
              self.ema3fast = (self.e1f._minperiod * self.sma)
              self.ema3slow = (self.e1s._minperiod * self.sma)
              EMA3fast = btind.EMA(self.data, period=self.ema3fast)
              EMA3slow = btind.EMA(self.data, period=self.ema3slow)
              self.buysig = btind.CrossOver(EMA3fast, EMA3slow)
              
              # Buy/Sell
              if self.buysig < 0:
                  self.sell()
              elif self.buysig > 0:
                  self.buy()
      
      

      Error:

      Traceback (most recent call last):
        File "dynamic1.py", line 97, in <module>
          thestrats = cerebro.run()
        File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
        File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1293, in runstrategies
          self._runonce(runstrats)
        File "/home/user1/.local/lib/python3.8/site-packages/backtrader/cerebro.py", line 1695, in _runonce
          strat._oncepost(dt0)
        File "/home/user1/.local/lib/python3.8/site-packages/backtrader/strategy.py", line 311, in _oncepost
          self.nextstart()  # only called for the 1st value
        File "/home/user1/.local/lib/python3.8/site-packages/backtrader/lineiterator.py", line 347, in nextstart
          self.next()
        File "dynamic1.py", line 47, in next
          if self.buysig < 0:
      TypeError: __bool__ should return bool, returned LineOwnOperation
      
      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @agog last edited by

        @agog Try [0] to get the line at the current date.

        self.buysig[0]
        

        RunBacktest.com

        1 Reply Last reply Reply Quote 0
        • A
          agog last edited by

          @run-out, thanks for the help, but that did not work...

          Has anyone implemented something like this?

          I have some new code trying to make a MACD (MACD2) parameters dynamic:

          class Test(bt.Strategy):
          
              params = (('macdfast', 50), ('macdslow', 200),('macdsignal', 500), \
                        ('bbtimeperiod', 50), ('nbdevup', 1),('nbdevdn', 1))
          
              def __init__(self):
                  # MACD1
                  self.talib_macd = bt.talib.MACD(self.data, fastperiod=int(self.p.macdfast), slowperiod=int(self.p.macdslow), signalperiod=int(self.p.macdsignal))
                  
                  # BBANDS
                  self.bb = bt.talib.BBANDS(self.data, timeperiod=self.p.bbtimeperiod, nbdevup=float(self.p.nbdevup), nbdevdn=float(self.p.nbdevdn), plot=True)
          
              def next(self):
                  # MACD2 (Dynamic)
                  macd2fast = self.p.macdfast * self.bb.upperband-self.bb.lowerband
                  macd2slow = self.p.macdslow + self.p.macdslow * self.bb.upperband-self.bb.lowerband
                  macd2signal = self.p.macdsignal + self.p.macdsignal * self.bb.upperband-self.bb.lowerband
          
                  talib_macd2 = bt.talib.MACD(self.data, fastperiod=int(macd2fast), slowperiod=int(macd2slow), signalperiod=int(macd2signal), plot=False)
                  
          # Getting MACD2 plotlines
                  macd_line = talib_macd2.macd[0]
                  signal_line = talib_macd2.macdsignal[0]
          
                  # Buy/Sell
                  if macd_line > signal_line:
                      self.sell()
                  elif macd_line < signal_line:
                      self.buy()
          

          The error I am getting is this:

            File "dynamic3.py", line 41, in next
              macd_line = talib_macd2.macd[0]
            File "/home/user1/.local/lib/python3.8/site-packages/backtrader/linebuffer.py", line 163, in __getitem__
              return self.array[self.idx + ago]
          IndexError: array index out of range
          
          M run-out 2 Replies Last reply Reply Quote 0
          • M
            mudassar031 @agog last edited by

            @agog
            i am also facing same kind of issue "array index out of range" you were able to fix it

            1 Reply Last reply Reply Quote 0
            • run-out
              run-out @agog last edited by

              @agog said in Dynamic values for strategy:

              MACD2 (Dynamic)

                  macd2fast = self.p.macdfast * self.bb.upperband-self.bb.lowerband
                  macd2slow = self.p.macdslow + self.p.macdslow * self.bb.upperband-self.bb.lowerband
                  macd2signal = self.p.macdsignal + self.p.macdsignal * self.bb.upperband-self.bb.lowerband
              
                  talib_macd2 = bt.talib.MACD(self.data, fastperiod=int(macd2fast), slowperiod=int(macd2slow), signalperiod=int(macd2signal), plot=False)
              

              I think all of this needs to be in your init sections.

              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