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/

    Must be real number, not LinesOperation

    General Code/Help
    3
    7
    1331
    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.
    • E
      eastatlantasanta last edited by eastatlantasanta

      Hi there, I'm attempting to make a custom stochastic of my own after browsing a couple on these forums. I'm gonna jump straight into the code.

      class MyStochastic(bt.Indicator):
          lines = ('Stoc', 'MyStoch',)
      
          def __init__(self):
          
              self.f = math.degrees(1.44 * 3.14159 / 10)
              self.a1 = math.exp(-self.f)
              self.b1 = 2 * self.a1 * math.cos(self.f)
              self.c2 = self.b1
              self.c3 = -self.a1 * self.a1
              self.c1 = 1 - self.c2 - self.c3
          
              super(MyStochastic,self).__init__()
          
          def prenext(self):
              self.HighestC = bt.indicators.Highest(period=9)
              self.LowestC = bt.indicators.Lowest(period=9)
              self.l.Stoc[0] = (self.data[0]-self.LowestC/(self.HighestC-self.LowestC))
              self.lines.MyStoch[0] = self.c1*(self.l.Stoc[0]+self.l.Stoc[0])/2 + self.c2*self.l.Stoc[0] + self.c3*self.l.Stoc[0]
         
          def nextstart(self):
              self.HighestC = bt.indicators.Highest(period=9)
              self.LowestC = bt.indicators.Lowest(period=9)
              self.l.Stoc[0] = (self.data[0]-self.LowestC/(self.HighestC-self.LowestC))
              self.lines.MyStoch[0] = self.c1*(self.l.Stoc[0]+self.l.Stoc[-1])/2 + self.c2*self.l.MyStoch[-1] + self.c3*self.l.MyStoch[-1]
             
          def next(self):
              self.HighestC = bt.indicators.Highest(period=9)
              self.LowestC = bt.indicators.Lowest(period=9)
              self.l.Stoc[0] = (self.data[0]-self.LowestC/(self.HighestC-self.LowestC))
              self.lines.MyStoch[0] = self.c1*(self.l.Stoc[0]+self.l.Stoc[-1])/2 + self.c2*self.l.MyStoch[-1] + self.c3*self.l.MyStoch[-2]
      

      Here's just a quick description of why I have it setup the way it is:
      Using the three sections (prenext, nextstart, next) allow me to initialize the lines properly. This is a fix that the user @Guwop seemed unable to find. I have confirmed the effectiveness of this method with other recursive indicators before this one.

      I use the super(MyStochastic,self).init() because I also utilize the Highest and Lowest indicators, and it is my understanding that under these circumstances that including super() is necessary.

      Here is the error message I receive upon running...

      <ipython-input-12-4e36424d155e> in prenext(self)
           75         self.HighestC = bt.indicators.Highest(period=9)
           76         self.LowestC = bt.indicators.Lowest(period=9)
      ---> 77         self.l.Stoc[0] = ((self.data[0]-self.LowestC)/(self.HighestC-self.LowestC))
           78         self.lines.MyStoch[0] = self.c1*(self.l.Stoc[0]+self.l.Stoc[0])/2 + self.c2*self.l.Stoc[0] + self.c3*self.l.Stoc[0]
           79 
      
      ~\Anaconda3\lib\site-packages\backtrader\linebuffer.py in __setitem__(self, ago, value)
          220             value (variable): value to be set
          221         '''
      --> 222         self.array[self.idx + ago] = value
          223         for binding in self.bindings:
          224             binding[ago] = value
      
      TypeError: must be real number, not LinesOperation 
      

      I'm not quite sure what it is that separates the values of self.l.Stoc[0] from self.l.MyStoch[0], because as I have mentioned previously, in other recursive indicators of mine, setting values to a lines object in the same manner as MyStoch has been no problem. Additionally, I have swapped out self.data[0] for an integer and receive the same error. I'd appreciate any help. Love the platform by the way. Thanks!

      1 Reply Last reply Reply Quote 0
      • adrtod
        adrtod last edited by adrtod

        Consider declaring indicators once in __init__:

        self.HighestC = bt.indicators.Highest(self.data, period=9)
        self.LowestC = bt.indicators.Lowest(self.data, period=9)
        

        and then use

        self.l.Stoc[0] = (self.data[0]-self.LowestC[0])/(self.HighestC[0]-self.LowestC[0])
        1 Reply Last reply Reply Quote 2
        • adrtod
          adrtod last edited by

          Alternatively in __init__ only:

          HighestC = bt.indicators.Highest(self.data, period=9)
          LowestC = bt.indicators.Lowest(self.data, period=9)
          self.l.Stoc = (self.data-LowestC)/(HighestC-LowestC)
          E 1 Reply Last reply Reply Quote 1
          • E
            eastatlantasanta @adrtod last edited by

            @adrtod Yes that worked! Thank you very much. If it isn't too much to ask, would you mind explaining why it works that way? From what I had thought, init is a def that is only called once, and so the values for Highest/Lowest would only be calculated once, and not change with new data. Obviously this is not the case... does this mean that init is in fact called more than once?

            1 Reply Last reply Reply Quote 0
            • adrtod
              adrtod last edited by

              __init__ is called only once and only declares the indicators as objects, no computation is done during __init__ but they are handled automatically.
              The same applies when using operators to combine indicators, see https://www.backtrader.com/docu/concepts.html#operators-using-natural-constructs
              See also https://www.backtrader.com/docu/induse.html and https://www.backtrader.com/docu/inddev.html

              E 1 Reply Last reply Reply Quote 1
              • E
                eastatlantasanta @adrtod last edited by

                @adrtod, Thank you for the explanation it's all making sense now - especially considering how the declarative approach to indicators is setup.

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

                  Overtaken by @adrtod. Glad to see someone with such an intimate knowledge of things.

                  1 Reply Last reply Reply Quote 0
                  • 1 / 1
                  • First post
                    Last post
                  Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                  $(document).ready(function () { app.coldLoad(); }); }