Must be real number, not LinesOperation
-
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!
-
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])
-
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)
-
@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?
-
__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 -
@adrtod, Thank you for the explanation it's all making sense now - especially considering how the declarative approach to indicators is setup.
-
Overtaken by @adrtod. Glad to see someone with such an intimate knowledge of things.