# OBV indicator calculation in R

Here is a few references about OBV calculations:

When I navigate to the source code of OBV function in TTR package, I see this:

"OBV" <-
function(price, volume) {
# On Balance Volume
price <- try.xts(price, error=as.matrix)
volume <- try.xts(volume, error=as.matrix)

if(!(is.xts(price) && is.xts(volume))) {
price <- as.vector(price)
volume <- as.vector(volume)
}
obv <- c( volume, ifelse( ROC(price) > 0, volume, -volume )[-1] )
obv <- cumsum( obv )
if(is.xts(obv)) {
obv <- xts(obv,index(price))
colnames(obv) <- 'obv'
}
reclass( obv, price )
}


I see that the equality case (I mean the case occurs when today’s close is equal to yesterday’s close) in the reference web pages does not exist in OBV function implementation.

Is it a bug or an acceptance of the package? If it is a bug, where can I report the issue?

Yes, the function does not consider cases when the price is flat. The solution is very simple. Look at the OBV2 function below. The series from OBV and OBV2 are highly correlated, but the strict definition would be higher (smaller) depending on the market evolution. In the QQQ case that difference is about 50% 1. You could find the maintainer here: http://cran.r-project.org/web/packages/TTR/index.html

    OBV2 <-  function(price, volume) { #
# On Balance Volume 2
price <- try.xts(price, error=as.matrix)
volume <- try.xts(volume, error=as.matrix)

if(!(is.xts(price) && is.xts(volume))) {
price <- as.vector(price)
volume <- as.vector(volume)
}
obv <- c( volume, ifelse(ROC(price) > 0, volume, -volume)[-1] )
obv[ROC(price)==0]<-0
obv <- cumsum( obv )
if(is.xts(obv)) {
obv <- xts(obv,index(price))
colnames(obv) <- 'obv2'
}
reclass( obv, price )
}

require("quantmod")

getSymbols('QQQ', src='yahoo',from='2012-01-01')
chartSeries(QQQ,TA = NULL)