Как рассчитать скользящие корреляции между несколькими столбцами и одним столбцом в rollapply? - PullRequest
0 голосов
/ 07 июня 2018

Задача

Если я хочу вычислить скользящую корреляцию между каждым из моих 39 акций в их столбцах в stock_returns (объект xts) и market_return (отдельный объект xts, только один столбец с рыночными доходами) со сворачиванием:

rolling_3yearcor <- rollapply(stock_returns,width=750,FUN=cor,y=market_return)

Я получаю эту ошибку:

Error in FUN(.subset_xts(data, (i - width + 1):i, j), ...) : incompatible dimensions

Даже если я подставлю один столбец в market_return с

rolling_3yearcor <- rollapply(stock_returns,width=750,FUN=cor,y=market_return$market)

, я получаю ошибку, даже если они имеют одинаковые размеры?!(1 столбец, такое же количество строк).

Что бы я хотел иметь:

Я хочу объект xts с корреляциями акции [i] сРынок в каждой из 39 биржевых колонок в скользящем окне 750 дней вместо дневной доходности в stock_returns.

Разве разворачивание не должно делать именно это?

РЕДАКТИРОВАТЬ 1: выборка данных для проблемы однодневного смещения назад

Returns StockA
1997-01-03 -0.0054065397
1997-01-06  0.0024139001
1997-01-07 -0.0030085614
1997-01-08  0.0054329941
1997-01-09 -0.0005990317
1997-01-10 -0.0102205387
...

с кодом:

ind <- market_return
ind[] <- seq_along(market_return)
rolling_3yearcor <- function(x,y,ind){
  rollapply(ind,width=5,function(i) cor(x[i],y[i]))
}
rollcor_3year <- lapply(stock_returns,rolling_3yearcor,market_return,ind)
rollcor_3year <- as.data.frame(rollcor_3year,col.names=names(stock_returns))
colnames(rollcor_3year) <- colnames(stock_returns)
rollcor_3year <- as.xts(rollcor_3year)

дает мне:

dput(head(rollcor_3year$StockA.N))
structure(c(NA, NA, NA, NA, 0.30868769358199, 0.576490782746284
), .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", 
"POSIXt"), .indexTZ = "", tzone = "", class = c("xts", "zoo"), index = 
structure(c(852246000, 
852505200, 852591600, 852678000, 852764400, 852850800), tzone = "", tclass = 
c("POSIXct", 
"POSIXt")), .Dim = c(6L, 1L), .Dimnames = list(NULL, "StockA.N"))

тогда с:

indexTZ(rollcor_3year) <- "UTC"
dput(head(rollcor_3year$StockA.N))

structure(c(NA, NA, NA, NA, 0.30868769358199, 0.576490782746284
), .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", 
"POSIXt"), .indexTZ = c(TZ = "UTC"), tzone = c(TZ = "UTC"), class = c("xts", 
"zoo"), index = structure(c(852246000, 852505200, 852591600, 
852678000, 852764400, 852850800), tzone = c(TZ = "UTC"), tclass = 
c("POSIXct", 
"POSIXt")), .Dim = c(6L, 1L), .Dimnames = list(NULL, "StockA.N"))

это дает мне:

head(rollcor_3year$StockA.N)
1997-01-02 23:00:00        NA
1997-01-05 23:00:00        NA
1997-01-06 23:00:00        NA
1997-01-07 23:00:00        NA
1997-01-08 23:00:00 0.3086877
1997-01-09 23:00:00 0.5764908

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Используйте rollapplyr с указанной функцией и by.column = FALSE.

# test data
stock_returns <- xts(anscombe[6:8], as.Date("2000-01-01") + seq(0, length=nrow(anscombe)))
market <- xts(anscombe[, 5], time(stock_returns))

x <- cbind(market, stock_returns)   
rollapplyr(x, 5, function(x) cor(x[, 1], x[, -1]), by.column = FALSE)

подача:

2000-01-01         NA          NA         NA
2000-01-02         NA          NA         NA
2000-01-03         NA          NA         NA
2000-01-04         NA          NA         NA
2000-01-05  0.6912899 -0.19831742  0.8437913
2000-01-06 -0.0904641 -0.08067339  0.3773026
2000-01-07  0.3714166 -0.05974574  0.3604551
2000-01-08  0.9013902  0.90672036 -0.6537459
2000-01-09  0.9059692  0.91388127 -0.7673776
2000-01-10  0.7996265  0.89299770 -0.7032847
2000-01-11  0.7812519  0.89427224 -0.6959074
0 голосов
/ 07 июня 2018

Проблема в том, что вы пытаетесь вычислить корреляцию между векторами разной длины.Попробуйте cor(1:10, 1:9), чтобы увидеть это напрямую.rollapply только прокручивает свой первый аргумент, поэтому market_return$market используется полностью.

Один из способов справиться с этим - пролистать индекс векторов (при условии, что оба они изначально имеют одинаковую длину).У меня нет доступа к вашим данным, поэтому некоторые данные:

set.seed(2)
df1 <- as.data.frame(replicate(5, runif(10), simplify=FALSE))
names(df1) <- paste0("V", 1:5)
vec2 <- runif(10)

Глядя на первый столбец фрейма, мы можем показать подтверждение концепции:

rollapply(seq_along(vec2), 3, function(i) cor(df1$V1[i], vec2[i]))
# [1]  0.2873624 -0.8522555 -0.9859923 -0.6394554 -0.4626926  0.4939377  0.5590373  0.9994124

Чтобы легко применить это ко всем столбцам кадра, мы можем сделать вспомогательную функцию:

rollcor <- function(v1,v2) {
  rollapply(seq_along(v1), 3, function(i) cor(v1[i], v2[i]))
}

lapply(df1, rollcor, vec2)
# $V1
# [1]  0.2873624 -0.8522555 -0.9859923 -0.6394554 -0.4626926  0.4939377  0.5590373  0.9994124
# $V2
# [1]  0.79602807  0.16857013 -0.24970680  0.01997719  0.96922386 -0.99937633 -0.32920929
# [8] -0.34819538
# $V3
# [1]  0.78978134 -0.08632500 -0.13991114 -0.26078798 -0.05284222  0.24405994 -0.68231437
# [8] -0.48694537
# $V4
# [1]  0.9850739  0.9823811  0.9743629  0.8470096  0.7337313 -0.9617746 -0.7033091 -0.4968143
# $V5
# [1] -0.6696637 -0.8672182 -0.9074534 -0.7671002 -0.3954844 -0.9864078 -0.2806075 -0.5689732

РЕДАКТИРОВАТЬ

Поскольку вы говорите, что это временной ряд,хотя нам все еще нужно использовать индексы (а не сам вектор временных рядов), мы можем сохранить временные ряды двумя способами:

  1. Использование zoo:::rollapply.ts в неизмененном коде(до этого редактировать).Это немного не рекомендуется, так как он полагается на неизвестную функцию.Я думаю, что в целом это безопасно, но в долгосрочной перспективе это не очень хорошая форма.

  2. Примените те же временные ряды к индексам, которые мы перевернем.

    ind <- vec2
    ind[] <- seq_along(vec2)
    rollapply(ind, 3, function(i) cor(df1$V1[i], vec2[i]))
    rollcor <- function(v1,v2,ind) {
      rollapply(ind, 3, function(i) cor(v1[i], v2[i]))
    }
    lapply(df1, rollcor, vec2, ind)
    
...