Question

I designed my own function called SharpeRatio(data)

Where data is an nx2 matrix.

The function works fine for a given matrix dat, however when I try to use rollapply(dat, 20, SharpeRatio) I get the following error: Error in dat[, 1] : incorrect number of dimensions

The following is the function definition:

SharpeRatio <- function(dat){
  Returns = dat[,1]
  RiskFree = dat[,2]

  ER = (Returns - RiskFree)/100
  Volatility = sd(Returns/100)
  return((exp(mean(log(1+ER))) - 1)/Volatility)
}
Was it helpful?

Solution 2

rollapply works by column unless the by.column=FALSE argument is used so try this:

rollapply(dat, 20, SharpeRatio, by.column = FALSE)

OTHER TIPS

rollapply applies a function to rolling margins of an array. But it does this column-by-column. That is, it does not present an array to your function, but presents vectors N times over (N=2 in your case).

Here's an example:

(m <- matrix(1:10, ncol=2))
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10

We'll rollapply a mean, and see what gets passed in at each iteration:

y <- rollapply(m, width=2, FUN=function(x) {print(x); mean(x)})
## [1] 1 2
## [1] 2 3
## [1] 3 4
## [1] 4 5
## [1] 6 7
## [1] 7 8
## [1] 8 9
## [1]  9 10

No matrices are passed to the function, just individual vectors. rollapply then packages the result up as an array in the correct shape:

y
##      [,1] [,2]
## [1,]  1.5  6.5
## [2,]  2.5  7.5
## [3,]  3.5  8.5
## [4,]  4.5  9.5

The fix is in Mr. Grothendieck's comment, to pass by.column=FALSE to rollapply:

z <- rollapply(m, width=2, by.column=FALSE, FUN=function(x) {print(x); colMeans(x)})
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
##      [,1] [,2]
## [1,]    2    7
## [2,]    3    8
##      [,1] [,2]
## [1,]    3    8
## [2,]    4    9
##      [,1] [,2]
## [1,]    4    9
## [2,]    5   10

Here, matrices of two rows each are being passed to the function. The result is the same as above:

z
##      [,1] [,2]
## [1,]  1.5  6.5
## [2,]  2.5  7.5
## [3,]  3.5  8.5
## [4,]  4.5  9.5

Since the current roll apply taking a matrix returns "incorrect number of dimension", because it is not meant to take a matrix. I wrote my own one

rollmatapply <- function(m,by=100,FUN)
{
  v = vector()  
  for(i in 1:(nrow(m)-by))
  {
    v[i] = do.call(FUN,list(m[i:(by+i-1),]))
  }
  v
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top