I have an xts of daily returns and I'd like to convert it to monthly returns.
I can find tonnes of threads to convert daily prices to period returns, but I need to convert daily returns.
Having followed the advice in this thread, which works well, I noticed that the returns are not geometric, they're arithmetic.
Therefore, I need something like cumprod(x+1)^(365/12)-1.
However, replacing sum(cx) with that doesn't work.
Here's my code as it stands:
# Generate data like the type I'm working with
testdata <- cbind(rnorm(100,0.0001,0.01),rnorm(100,0.0001,0.01))
testdata <- as.xts(testdata, order.by = seq(Sys.Date()-99,Sys.Date(),1))
myFun <- function(x) {
# need coredata, so c.xts will not be dispatched
cx <- coredata(x)
Return = sum(cx)
}
MonthlyReturns <- NULL
for (i in 1:ncol(testdata)){
MonthlyReturns <- cbind(MonthlyReturns,period.apply(testdata[,i], endpoints(testdata[,i], "months"),
myFun))
}
Any help appreciated!
EDIT - The output should be the same format as the input - a table of monthly returns instead of daily. Either xts or dataframe / matrix.
EDIT - For those interested in the origin of the returns matrix, I'm using the Return.annualized
function from the Performance Analytics package as shown here. (Actually, I've modified it by using Return.cumulative
, which is much faster). So yes, although I do have a price matrix and can easily calculate monthly returns from that, I have additional columns in my daily returns matrix from other calculations, hence I need to convert the daily returns, not the daily prices.
As an alternative to the accepted solution a much faster way ( > 5 times faster ) to get monthly returns is to combine the aggregate
function with cumprod
.
system.time(aggregate(testdata,as.yearmon,function(x) tail(cumprod(1 + x) -1,1)))
user system elapsed
0.021 0.002 0.023
system.time(apply.monthly(testdata, Return.cumulative))
user system elapsed
0.116 0.002 0.118
data:
testdata <- as.xts(cbind(rnorm(10000,0.0001,0.01),rnorm(100,0.0001,0.01)), order.by = seq(Sys.Date()-9999,Sys.Date(),1))