rivella50 / talib-ruby

Ruby Wrapper for the Technical Analysis Library ta-lib
55 stars 31 forks source link

It isn't possible to use OBV indicator #15

Open vertis opened 8 years ago

vertis commented 8 years ago

Running the following example code:

close = [26.0, 54.0, 8.0, 77.0, 61.0, 39.0, 44.0, 91.0, 98.0, 17.0]
volume = [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]

func = TaLib::Function.new("OBV")
len = close.length
func.in_real(0, close)
#func.in_real(1, volume)
func.in_volume(0,volume)

out_real = Array.new(len)
@func.out_real(0, out_real)
@func.call(0, len - 1)

I get either:

undefined method `in_volume' for #<TaLib::Function:0x007ff19bbd5440 @name="OBV", @result=[]>

if I use func.in_volume or

RuntimeError: unsuccess return code TA_SetInputParamRealPtr
    from (irb):151:in `in_real'
    from (irb):151
    from /Users/vertis/.rbenv/versions/2.1.6/bin/irb:11:in `<main>'

if I try to use in_real(1,...)

Looking at the talib code seems to suggest there should be an in_volume (unless I'm misunderstanding something)

rivella50 commented 8 years ago

Thank you for your comment! Interesting, i thought that volumes are treated as floats, therefore i don't have a clue how to solve this. Since i don't have much time at the moment i encourage you to fork the project and find a solution.

PierreNicolasL commented 6 years ago

Having the same problem here. Did you figure it out ?

Thanks !

chainum commented 6 years ago

Just run into this as well. @PierreNicolasL: did you manage to figure it out?

chainum commented 6 years ago

Decided to implement my own solution in pure Ruby instead of trying to figure out the Ruby/C interop and patch the library.

So if anyone else runs into this issue, here's a Ruby implementation of OBV. Note: data is a hash containing an array of close prices in :close and an array of volumes in :volume

    def obv(data)
      obvs              =   []
      prev_closes   =   []

      data[:volume].each_with_index do |vol, index|
        current_close   =     data[:close][index]
        prev_close        =     prev_closes.last

        if index == 0
          obvs         <<   vol
        else
          if current_close > prev_close
            obvs       <<   (obvs.last + vol)
          elsif current_close < prev_close
            obvs       <<   (obvs.last - vol)
          elsif current_close == prev_close
            obvs       <<   obvs.last
          end
        end

        prev_closes    <<   current_close
      end

      return obvs
    end