Need some help creating an On Balance Volume indicator
-
Hi I'd like some help trying to understand why my indicator isn't being accepted into the rest of backtrader. I'm trying to make an OBV indicator, but get stopped with python giving me this error:
TypeError: must be real number, not LinesOperation
Here is my code:
There's probably a few places to look, but I'd greatly appreciate knowing what went wrong.
Thank you,
Tag
-
Please show the whole error message to understand what is going on.
At first glance:
- I would use
class OnBalanceVolume(bt.Indicator)
()
are used for indexing in the__init__
,[]
are used for indexing in thenext
- I doubt that
self.data
haslines
,self.data.volume
is more appropriate
- I would use
-
@tagteam69 said in Need some help creating an On Balance Volume indicator:
Here is my code:
If you post text as opposed to posting an image, people may even be able to quote and point out where you went wrong.
-
Thanks for the quick suggestions. I made some edits to the indicator and seem to have made it further along this time.
Here is my code:
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt class OnBalanceVolume(bt.Indicator): lines = ('obv',) params = (('period', 1),) plotinfo = dict(subplot=False) # plot in same axis as the data def __init__(self): self.x = self.data.volume self.lines.obv = bt.If(self.data.close(0) > self.data.close(-1), (self.x + self.data.volume), self.x - self.data.volume)
The error now comes when I try to log my closing prices in the strategies file I also have.
~\Anaconda3\envs\Oanda v20\lib\site-packages\testStrategy\HighLowOBV.py in next(self) 87 def next(self): 88 # Simply log the closing price of the series from the reference ---> 89 self.log('Close, %.2f' % self.dataclose[0]) 90 91 # Check if an order is pending ... if yes, we cannot send a 2nd one TypeError: 'float' object is not subscriptable
My guess is that this has something to do with self.x and how I want to save my volume sum/diff to it. The value of the data is a float rather than a subscriptable data feed.
Please let me know if there is anymore info that I should be sharing!Thanks again,
Tag -
Hard to say something since no code defining self.dataclose are shown.
-
@tagteam69 said in Need some help creating an On Balance Volume indicator:
My guess is that this has something to do with self.x
It doesn't seem so. Yo have a
float
inself.dataclose
and you are trying to treat is as an array.@tagteam69 said in Need some help creating an On Balance Volume indicator:
---> 89 self.log('Close, %.2f' % self.dataclose[0]) 90 91 # Check if an order is pending ... if yes, we cannot send a 2nd one TypeError: 'float' object is not subscriptable
As @ab_trader points out, we don't really know how you have defined
self.dataclose
and how you are managing it, so it is impossible to say why you have afloat
and are expecting aniterable
@tagteam69 said in Need some help creating an On Balance Volume indicator:
def __init__(self): self.x = self.data.volume self.lines.obv = bt.If(self.data.close(0) > self.data.close(-1), (self.x + self.data.volume), self.x - self.data.volume)
In any case, using
self.x
doesn't seem useful (unless you need for something else we don't know) because:self.x + self.data.volume
is also2.0 * self.data.volume
and
self.x - self.data.volume
is always0.0
The thing could simply be written as
self.lines.obv = bt.If(bt.ind.UpDayBool(self.data), 2.0 * self.data.volume, 0.0)
(This shows that there is a pre-canned indicator giving you the boolean you look for with
self.data > self.data(-1)
, and it even takes aperiod
parameter if you need a distance longer than1
)But this can be even simplified to:
self.lines.obv = 2.0 * self.data.volume * (self.data > self.data(-1))
Because if the current price is greater than the previous price the boolean will be a
1
in the multiplication and it will be a0
if the price is not greater than the previous one.