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/

    Change parameters dynamically according to time period

    General Discussion
    3
    8
    2993
    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.
    • dimitar-petrov
      dimitar-petrov last edited by

      Hello,

      I am trying to asses a strategy that is changing the paremeters every year.

      • 2000 - parameter x is 1
      • 2001 - parameter x is 2
      • 2002 - parameter x is 3
        ....

      What is a good approach to accomplish it in a single cerebro run, so I can analyze it as a single strategy.

      Thanks,
      dpetrov

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

        You either have:

        • Fixed values for each period

          In this case you pass an iterable and check what the current period is (or make it a dict and have the periods and values mapped)

        • A formula that gives you the value of the parameter with the period as input

          In this case you pass the formula as a parameter and calculate each time.

        1 Reply Last reply Reply Quote 0
        • dimitar-petrov
          dimitar-petrov last edited by

          Hello,

          Yes I do have fixed values for each period. Here is a simple example:

                InFrom       InTo  profit_mult  stoploss  bbands_period   
          0 2005-01-01 2006-01-01          2.5      0.02           25.0 
          1 2006-01-01 2007-01-01          2.0      0.01           25.0
          2 2007-01-01 2008-01-01          2.5      0.02           25.0
          3 2008-01-01 2009-01-01          2.5      0.01           25.0
          

          I guess I should get the correct parameter value in the next method, but what happens if the parameter is BBands period or any other technical indicator parameter.

          Those I am going to initialize only once in the __init__ method and cannot change them during next period.

          Could you please provide a brief example how to make it work with iterable?

          Thanks in advance!
          dpetrov

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

            The strategy keeps track of the current datetime, so there is no need to track it using any of the data feeds (which may have different speeds)

            As such:

            def next(self):
            
                while True.
                    if self.datetime.datetime().year == self.iterable[self.currentidx]:
                        myparam = self.iterable[self.currentidx]
                        break
                
                   self.currentidx += 1
            

            You keep the iterable synchronized with the current datetime

            1 Reply Last reply Reply Quote 1
            • dimitar-petrov
              dimitar-petrov last edited by

              Thanks, I will work with that.

              1 Reply Last reply Reply Quote 0
              • dimitar-petrov
                dimitar-petrov last edited by dimitar-petrov

                Hello again:

                I followed your hints and come up with the following code:

                    def next(self):
                        if self.iterable is not None:
                            for idx, period in self.iterable.iterrows():
                                if (
                                        period['InFrom'] < self.datetime.datetime() and
                                        self.datetime.datetime() < period['InTo'] and
                                        self.curr_per != idx
                                ):
                                    self.bbands = bt.talib.BBANDS(self.data,
                                                                  timeperiod=period['bbands_period'],
                                                                  plotname='TA_BANDS')
                                    self.buy_sig = btind.CrossOver(self.data, self.bbands.line2)
                                    self.sell_sig = btind.CrossOver(self.bbands.line0, self.data)
                                    self.p.stoploss = period['stoploss']
                                    self.p.profit_mult = period['profit_mult']
                                    self.curr_per = idx
                

                I am now facing a problem if I try to get sell and buy signals inside next method.
                Do you have an idea what might be the problem here?

                Here is a stack trace

                    self.buy_sig = btind.CrossOver(self.data, self.bbands.line2)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/indicator.py", line 53, in __call__
                    return super(MetaIndicator, cls).__call__(*args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/metabase.py", line 87, in __call__
                    _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/metabase.py", line 77, in doinit
                    _obj.__init__(*args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/indicators/crossover.py", line 99, in __init__
                    upcross = CrossUp(self.data, self.data1)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/indicator.py", line 53, in __call__
                    return super(MetaIndicator, cls).__call__(*args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/metabase.py", line 87, in __call__
                    _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/metabase.py", line 77, in doinit
                    _obj.__init__(*args, **kwargs)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/indicators/crossover.py", line 37, in __init__
                    after = self.data0 > self.data1
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/lineroot.py", line 260, in __gt__
                    return self._operation(other, operator.__gt__)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/lineroot.py", line 88, in _operation
                    return self._operation_stage2(other, operation, r=r)
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/lineroot.py", line 209, in _operation_stage2
                    other = other[0]
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/lineseries.py", line 435, in __getitem__
                    return self.lines[0][key]
                  File "/home/dpetrov/develop/python/py-envs/py2env/lib/python2.7/site-packages/backtrader/linebuffer.py", line 165, in __getitem__
                    return self.array[self.idx + ago]
                IndexError: array index out of range
                

                idx = -1
                ago = 0

                when crashing

                BR,
                dpetrov

                B 1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators @dimitar-petrov last edited by

                  @dimitar-petrov said in Change parameters dynamically according to time period:

                                  self.bbands = bt.talib.BBANDS(self.data,
                                                                timeperiod=period['bbands_period'],
                                                                plotname='TA_BANDS')
                                  self.buy_sig = btind.CrossOver(self.data, self.bbands.line2)
                                  self.sell_sig = btind.CrossOver(self.bbands.line0, self.data)
                  

                  Yes, these (and similar) are only meant for __init__ with lazy evaluation. During next evaluation takes place and operator overloading is switched to support the actually evaluated values.

                  You are not changing parameters, you want to change the indicators and that's for sure not going to work. You need to have multiple indicators running and then select for the logic those that apply to the period in question.

                  1 Reply Last reply Reply Quote 0
                  • dimitar-petrov
                    dimitar-petrov last edited by

                    Alright,
                    I got you.

                    Thanks for the prompt response.

                    BR,
                    dpetrov

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