Collision of colnames in PerformanceAnalytics

96 views Asked by At

I have recently discovered PerformanceAnalytics and find it very useful for my research. However, I've spotted a strange behaviour. I'm trying to extend InformationRatio() to accept zero benchmark return:

InformationRatio <- function(Ra, Rb=NULL, scale=NA) {
  if (is.null(Rb)) {
    Rb <- Ra[, 1, FALSE]
    Rb[] <- 0
  }
  PerformanceAnalytics::InformationRatio(Ra, Rb, scale)
}

InformationRatio(managers[, 1:6])

returns

                        HAM1     HAM2    HAM3      HAM4      HAM5    HAM6
Information Ratio: HAM1  Inf 1.373211 1.19553 0.6592017 0.2355561 1.66417

Inf is not what I'd expect. Turns out (after browsing the source), that the origin of this is contained in Return.excess():

    coln.Rf = colnames(Rf)
    Rft = cbind(R, Rf)
    Rft = na.locf(Rft[, make.names(coln.Rf)])
    Rf = Rft[which(index(R) %in% index(Rft))]

If there's a collision in colnames between asset returns (Ra==R) and benchmark returns (Rb==Rf), then Rf is assigned to R, which eventually leads to division by zero.

Here's a workaround:

InformationRatio <- function(Ra, Rb=NULL, scale=NA) {
  if (is.null(Rb)) {
    Rb <- Ra[, 1, FALSE]
    Rb[] <- 0
    colnames(Rb) <- "zero"
  }
  PerformanceAnalytics::InformationRatio(Ra, Rb, scale)
}

InformationRatio(managers[, 1:6])

returns

                            HAM1     HAM2    HAM3      HAM4      HAM5    HAM6
Information Ratio: zero 1.549119 1.373211 1.19553 0.6592017 0.2355561 1.66417

Is this a bug or am I missing something? If it is, how do I report it? I couldn't get past this page, no bugtracker whatsoever. I thought of writing an email, but I've seen developers here, so SO post is probably a good option, isn't it?

1

There are 1 answers

0
Brian G. Peterson On BEST ANSWER

Rb is not supposed to be a scalar, it should be a time series.

Rb is described in the documentation as

Rb: return vector of the benchmark asset

So I suppose that documentation could be more clear, I'll look to improve that to specifiy a time series. We need to merge the time series of benchmark returns to the time series of asset returns to do the calculation.

here is a working example with time series input for Rb:

data(managers)
rb<-xts( rep(0,nrow(managers)), order.by=index(managers) )
colnames(rb)<-'zero'
InformationRatio(managers,rb)

produces:

                            HAM1     HAM2    HAM3      HAM4      HAM5    HAM6 EDHEC LS EQ  SP500 TR US 10Y TR US 3m TR
Information Ratio: zero 1.549119 1.373211 1.19553 0.6592017 0.2355561 1.66417    1.665694 0.6448502 0.7265079 7.620057

As for Return.excess, I think it makes sense to not allow colnames collisions there, as you're trying to determine excess returns of one series to another series. the code you pasted above is aimed at merging the series and creating an output series with the same index as the input series. That operation could be done more efficiently now than it could when the function was originally written (before xts), and I'll take a look at that too.

Generally, bug reports for an R package should go to the package website or to the package maintainer. email would have been fine. SO should be for questions of usage, not bug reports, in general, as bugs get fixed, and SO remains with stale data.