R: преобразовать дневную доходность в ежемесячную

У меня есть xts ежедневных возвратов, и я хотел бы преобразовать их в ежемесячные.

Я могу найти тонны потоков для преобразования ежедневных цен в доходность за период, но мне нужно конвертировать ежедневные доходности.

Следуя советам в этом поток, который работает хорошо, я заметил, что результаты не геометрические, а арифметические.

Поэтому мне нужно что-то вроде cumprod (x + 1) ^ (365/12) -1.

Однако замена sum (cx) на это не работает.

Вот мой код в его нынешнем виде:

 # 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))
   }

Любая помощь приветствуется!

РЕДАКТИРОВАТЬ - выходные данные должны быть в том же формате, что и входные - таблица ежемесячных доходов вместо ежедневных. Либо xts, либо dataframe / matrix.

РЕДАКТИРОВАТЬ. Для тех, кто интересуется происхождением матрицы возвратов, я использую функцию Return.annualized из пакета Performance Analytics, как показано здесь. (На самом деле я изменил его, используя Return.cumulative, что намного быстрее). Итак, да, хотя у меня есть матрица цен и я могу легко рассчитать из нее ежемесячную доходность, у меня есть дополнительные столбцы в моей матрице ежедневной доходности из других расчетов, поэтому мне нужно преобразовать дневную доходность, а не дневные цены.


person Jimbo Mahoney    schedule 09.04.2020    source источник
comment
Можете ли вы поделиться тем, как вы хотите, чтобы результат выглядел?   -  person Gautam    schedule 09.04.2020
comment
Обновлен исходный пост. В основном вывод должен быть таким же, как ввод, за исключением месяца, а не дня.   -  person Jimbo Mahoney    schedule 09.04.2020
comment
Чтобы уточнить returns, это уже рассчитано по отношению к basis? Думаю, здесь будет полезен dput ().   -  person Chris    schedule 09.04.2020


Ответы (2)


В качестве альтернативы принятому решению гораздо более быстрый способ (> 5 раз быстрее) получать ежемесячную прибыль - это объединить функцию aggregate с 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 

данные:

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))
person hvollmeier    schedule 26.04.2020
comment
Отлично, спасибо! На моих данных это в 2,5 раза быстрее - помогает каждая мелочь! - person Jimbo Mahoney; 27.04.2020
comment
7 раз на моем ноутбуке, лол. (Alienware M17) user system elapsed 0.02 0.00 0.02 против user system elapsed 0.14 0.00 0.14 - person tchevrier; 18.11.2020

Поскольку вам нужна ежемесячная совокупная дневная доходность, мы можем применять функцию Return.cumulative из PerformanceAnalytics на ежемесячной основе, используя функцию apply.monthly из xts. Это дает вам то, что вы хотите. Хорошее простое решение, не нужно писать собственную функцию.

library(PerformanceAnalytics) # for Return.cumulative function
library(quantmod) # loads xts which has apply.monthly function 

MonthlyReturns <- apply.monthly(testdata, Return.cumulative)
MonthlyReturns
                  [,1]         [,2]
2020-01-31 -0.09507546 -0.090607862
2020-02-29  0.04056104  0.001859122
2020-03-31  0.01451002  0.117231568
2020-04-12  0.01502248  0.026660881
person Mr.Rlover    schedule 12.04.2020
comment
Хех, я такая тупица! Я использовал эту функцию в другом месте, поэтому не знаю, почему я не подумал использовать ее и здесь ... Спасибо! - person Jimbo Mahoney; 13.04.2020