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/

    Need some help creating an On Balance Volume indicator

    General Code/Help
    3
    6
    1801
    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.
    • T
      TagTeam69 last edited by

      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:

      0_1536968421832_postToBacktraderOBV.PNG

      There's probably a few places to look, but I'd greatly appreciate knowing what went wrong.

      Thank you,

      Tag

      B 1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        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 the next
        • I doubt that self.data has lines, self.data.volume is more appropriate
        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        1 Reply Last reply Reply Quote 1
        • B
          backtrader administrators @TagTeam69 last edited by

          @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.

          1 Reply Last reply Reply Quote 0
          • T
            TagTeam69 last edited by

            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

            A B 2 Replies Last reply Reply Quote 0
            • A
              ab_trader @TagTeam69 last edited by

              @tagteam69

              Hard to say something since no code defining self.dataclose are shown.

              • If my answer helped, hit reputation up arrow at lower right corner of the post.
              • Python Debugging With Pdb
              • New to python and bt - check this out
              1 Reply Last reply Reply Quote 1
              • B
                backtrader administrators @TagTeam69 last edited by backtrader

                @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 in self.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 a float and are expecting an iterable

                @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 also 2.0 * self.data.volume

                and

                • self.x - self.data.volume is always 0.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 a period parameter if you need a distance longer than 1)

                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 a 0 if the price is not greater than the previous one.

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