применять функции для xts

Мои данные в настоящее время представляют собой объект xts или zoo с ежедневными ценами на акции в строке, а каждый столбец - это отдельная компания.

library(quantmod)
getSymbols("AAPL;MSFT;YHOO")
closePrices <- merge(Cl(AAPL),Cl(MSFT),Cl(YHOO))

Я все еще новичок в R, и мне нужна помощь в воспроизведении этой функции Excel. Моей первой мыслью было разделить функцию на числитель и знаменатель, а затем вычислить индекс:

dailyDiff <- abs(diff(closePrices,1))
numerJ <- diff(closePrices,10)
denomJ <- as.xts(rollapply(dailyDiff,11, sum))
idx <- abs(numerJ/denomJ)

Это было здорово, потому что значения для каждой части были точными, но выровнены по неверным датам для denomJ. Например, хвост numerJ соответствует 21.06.2012, а хвост denomJ — 14.06.2012.

Результат, который я ищу:

  • 6/21/2012 = .11
  • 6/20/2012 = .27
  • 6/19/2012 = .46
  • 6/18/2012 = .39
  • 6/15/2012 = .22

person jonnie    schedule 21.07.2012    source источник
comment
Теперь, когда я сделал ваш пример воспроизводимым, не могли бы вы вернуться к своему вопросу и предоставить ожидаемый результат? Кроме того, пожалуйста, опишите, что вы имеете в виду под неправильными датами и неправильными значениями idx.   -  person Joshua Ulrich    schedule 21.07.2012
comment
Спасибо! внесены правки. надеюсь, это прояснит, что два моих объекта xts/zoo, numerJ и denomJ, производят точные числа (numerJ @ 6/21 = 5,95 и denomJ @ 6/21 = 53,25). но, как следствие функции rollapply, выравнивает значения даты, которые мне не нужны.   -  person jonnie    schedule 21.07.2012
comment
Я вообще не понимаю вашего вопроса. Ваша функция Excel делает ее еще более запутанной для меня, потому что она так плохо помечена. Re: ваш недавний комментарий, я нигде не вижу числа 53,25. Тем не менее, основываясь на вашей жалобе на выравнивание даты, я почти уверен, что ответ заключается в том, что вам нужно использовать align=right в вашем вызове rollapply (или использовать оболочку rollapplyr). См. ?rollapply   -  person GSee    schedule 21.07.2012
comment
Извините, если я неясен. align = right у меня не сработало. Пожалуйста, позвольте мне уточнить. Для каждого дня числитель представляет собой разницу между сегодняшней ценой и ценой акции десятью предыдущими днями (closePrice[i] - closePrice[i-10]). Знаменатель представляет собой сумму ежедневных различий в диапазоне дат; сумма(dailyDiff[i]-dailyDiff[i-10]). Таким образом, для последнего наблюдения в denomJ значение равно 53,25, потому что (8,07 + 1,67 + 1,63 + 11,65 + 2,60 + 0,63 + 4,00 + 4,99 + 9,15 + 8,60 + 0,26) = 53,25. Я думаю, что решение заключается в написании функции, которая принимает (x, y), но не уверен. Спасибо, что заглянули!   -  person jonnie    schedule 21.07.2012
comment
также изменил ссылку на функцию в исходном сообщении. может это поможет.   -  person jonnie    schedule 21.07.2012
comment
Это по-прежнему нелегко воспроизвести, поэтому нельзя быть уверенным, что требуется, но может быть проблема в том, что ваш код не указал выравнивание в rollapply, поэтому по умолчанию вы получили align = "center". Может быть, вы хотите align="left" или align="right" в rollapply или, может быть, вы хотите lag на какую-то другую сумму.   -  person G. Grothendieck    schedule 22.07.2012


Ответы (2)


Трудно точно сказать, в чем проблема, без точных данных, но проблема, похоже, связана с rollapply. rollapply будет применять функцию только к целым интервалам, если только аргумент partial не установлен на TRUE. Рассмотрим следующий пример

require(zoo)
#make up some data
mat <- matrix(1:100,ncol=2)
colnames(mat) <- c("x1","x2")
dates <- seq.Date(from=as.Date("2010-01-01"),length.out=50,by="1 day")
zoo.obj <- zoo(mat,dates)
#apply the funcitons
numerJ <- diff(zoo.obj,10)  #dates okay
denomJ <- rollapply(zoo.obj,11, sum,partial=TRUE)  #right dates
denomJ2 <- rollapply(zoo.obj,11,sum) #wrong dates
index <- abs(numerJ/denomJ)  #right dates
person chandler    schedule 21.07.2012
comment
Спасибо! Я думаю, что проблема и с rollapply. я думаю, что наиболее подходящее решение будет в виде функции, которая принимает (x, y), но я все еще не уверен... - person jonnie; 21.07.2012

Вы можете использовать комбинацию diff и либо runSum, либо rollapplyr

#Get the data
library(quantmod)
getSymbols("AAPL")

Я думаю, это то, что вы пытаетесь сделать (обратите внимание на использование аргумента lag для diff.xts и аргумента n для runSum)

out <- diff(Cl(AAPL), lag=10) / runSum(abs(diff(Cl(AAPL))), n=11)
tail(out['/2012-06-21'])
#           AAPL.Close
#2012-06-14 -0.1047297
#2012-06-15  0.2176938
#2012-06-18  0.3888185
#2012-06-19  0.4585821
#2012-06-20  0.2653782
#2012-06-21  0.1117371

Изменить

При более внимательном рассмотрении вашего вопроса я не понимаю, почему rollapplyr не тот ответ, который вы ищете. Если я возьму ваш код в точности как есть, за исключением того, что я заменю rollapply на rollapplyr, мне покажется, что это именно тот результат, который вы ищете.

dailyDiff <- abs(diff(closePrices,1))
numerJ <- diff(closePrices,10)
denomJ <- as.xts(rollapplyr(dailyDiff,11, sum))
idx <- abs(numerJ/denomJ)
#           AAPL.Close MSFT.Close YHOO.Close
#2012-06-14  0.1047297 0.03826531 0.06936416
#2012-06-15  0.2176938 0.35280899 0.25581395
#2012-06-18  0.3888185 0.33161954 0.31372549
#2012-06-19  0.4585821 0.47096774 0.34375000
#2012-06-20  0.2653782 0.32644628 0.23750000
#2012-06-21  0.1117371 0.18997912 0.10256410

Кроме того, обратите внимание, что и numerJ, и denomJ заканчиваются на одну и ту же дату, если вы используете rollapplyr (что аналогично использованию rollapply с align="right").

end(numerJ); end(denomJ)
#[1] "2012-07-20"
#[1] "2012-07-20"

Ошибка Yahoo

Возможно, проблема, с которой вы столкнулись, связана с ошибкой Yahoo, из-за которой иногда — например, прямо сейчас — Yahoo дублирует последнюю (в хронологическом порядке) строку данных. Если это так, попробуйте удалить повторяющуюся строку, прежде чем пытаться использовать данные для своих расчетов.

tidx <- tail(index(closePrices), 2)
if(tidx[1] == tidx[2]) {
  closePrices <- closePrices[-NROW(closePrices), ]
}
person GSee    schedule 21.07.2012