Рассчитать доходность за период времени

Я пытаюсь получить временные ряды доходов от владения определенным активом в течение определенного времени.

Мой фрейм данных выглядит так:

Date          Price
1998-01-01     20
1998-01-02     22
1998-01-03     21
1998-01-04     25
...
1998-01-20     25
1998-01-21     19
1998-01-21     20
....
1998-02-01     30
1998-02-02     28
1998-02-03     25
1998-02-04     26
etc.

У меня есть одно наблюдение на каждый день, и мой временной ряд идет с 1998 по 1999 год.

Что я хотел бы сделать сейчас, так это рассчитать доходность владения моим активом в течение 20 дней (т.е. купить его в первый день и продать на 20-й день) и делать это каждый день. Итак, я хотел бы рассчитать это:

1. день: Возврат (20 дней) = журнал (Цена (t = 20) / Цена (t = 0)),

2. день: Возврат (20 дней) = журнал (Цена (t = 21) / Цена (t = 1)),

3. день: Возврат (20 дней) = журнал (Цена (t = 22) / Цена (t = 2))

и т. д., т.е. делать это каждый день в моей выборке.

Итак, мой результирующий фрейм данных будет выглядеть так:

Date          Return
1998-01-01     0.2
1998-01-02     0.4
1998-01-03     0.6
1998-01-04     0.1
...
1998-01-20     0.1
1998-01-21     0.2
1998-01-21     0.5
....
1998-02-01     0.1
1998-02-02     0.2
1998-02-03     0.5
1998-02-04     0.01
etc.

Есть ли способ в R сказать: возьмите первые 20 наблюдений, вычислите отдачу. Возьмите наблюдение 2-21, рассчитайте отдачу. Возьмите наблюдение 3-22, рассчитайте доход и т. Д.?

Я полностью застрял и был бы признателен за помощь. Спасибо! Дэни


person Dani    schedule 17.12.2010    source источник


Ответы (6)


Я предлагаю переключиться на класс временных рядов, например xts или zoo. Но если вы просто хотите сделать это и узнать больше позже, вы можете сделать это довольно легко в виде фрейма данных. Обратите внимание, что я должен дополнить векторы возврата с помощью NAs, чтобы они выровнялись правильно, и что hold из 20 действительно покупает на 1 и продает на 1 + 20:

> library(xts) 
> set.seed(2001)
> n <- 50
> hold <- 20
> price <- rep(55, n)
> walk <- rnorm(n)
> for (i in 2:n) price[i] <- price[i-1] + walk[i]
> data <- data.frame(date=as.Date("2001-05-25") + seq(n), price=price)
> data <- transform(data, return=c(diff(log(price), lag=hold), rep(NA, hold)))

Если вы готовы к xts или zoo (это должно работать в любом из них), то я предлагаю использовать rollapply, чтобы получить прогноз (при условии, что вы хотите получить прогнозируемый доход, что значительно упрощает формирование портфелей сегодня и позволяет увидеть, как это сделать. работает в будущее):

> data.xts <- xts(data[, -1], data[, 1])
> f <- function(x) log(tail(x, 1)) - log(head(x, 1))
> data.xts$returns.xts <- rollapply(data.xts$price, FUN=f, width=hold+1, align="left", na.pad=T)

Два подхода одинаковы:

> head(data.xts, hold+2)
         price       return  returns.xts
 [1,] 55.00000  0.026746496  0.026746496
 [2,] 54.22219  0.029114744  0.029114744
 [3,] 53.19811  0.047663206  0.047663206
 [4,] 53.50088  0.046470723  0.046470723
 [5,] 53.85202  0.041843116  0.041843116
 [6,] 54.75061  0.018464467  0.018464467
 [7,] 55.52704 -0.001105607 -0.001105607
 [8,] 56.15930 -0.024183803 -0.024183803
 [9,] 56.61779 -0.010757559 -0.010757559
[10,] 55.51042  0.005494771  0.005494771
[11,] 55.17217  0.044864991  0.044864991
[12,] 56.07005  0.025411005  0.025411005
[13,] 55.47287  0.052408720  0.052408720
[14,] 56.10754  0.034089602  0.034089602
[15,] 56.35584  0.075726190  0.075726190
[16,] 56.40290  0.072824657  0.072824657
[17,] 56.05761  0.070589032  0.070589032
[18,] 55.93916  0.069936575  0.069936575
[19,] 56.50367  0.081570964  0.081570964
[20,] 56.12105  0.116041931  0.116041931
[21,] 56.49091  0.095520517  0.095520517
[22,] 55.82406  0.137245367  0.137245367
person Richard Herron    schedule 17.12.2010

В качестве альтернативы, если вы используете пакет xts, жизнь становится невероятно простой. Это прямая копия функции, которую я написал недавно:

ret<-function(x,k=1){
  return(diff(log(x),k))
}
person Chris Taylor    schedule 17.12.2010
comment
Я думаю, вы хотите, чтобы k применялся как lag для функции diff, а не base для функции log. Это сделает простой сдвиг скобок. - person shabbychef; 28.08.2011

Вы можете использовать функцию ROC в пакете TTR или просто создать свою собственную функцию.

> library(quantmod)  # loads TTR
> getSymbols("SPY")
> tail(ROC(Cl(SPY),20))
            SPY.Close
2010-12-09 0.01350383
2010-12-10 0.02307920
2010-12-13 0.03563051
2010-12-14 0.03792853
2010-12-15 0.04904805
2010-12-16 0.05432540
> tail(log(Cl(SPY)/lag(Cl(SPY),20)))
            SPY.Close
2010-12-09 0.01350383
2010-12-10 0.02307920
2010-12-13 0.03563051
2010-12-14 0.03792853
2010-12-15 0.04904805
2010-12-16 0.05432540
person Joshua Ulrich    schedule 17.12.2010

Вы можете просто использовать индексы смещения, вычитая их из диапазона. (.... но помните, что R не использует 0 в качестве допустимого индекса.) Допустим, ваши цены - это второй столбец в фрейме данных с именем prcs2, первые три возвращаются с интервалом в 19 дней с вашими данными:

prcs2[ (20:22)-19, 2] <-c(20,22,21)
prcs2[ (20:22), 2] <-c(25,19,20)
log(prcs2[20:22, 2]/prcs2[ (20:22)-19, 2])
#[1]  0.22314355 -0.14660347 -0.04879016
person IRTFM    schedule 17.12.2010

Это должна делать следующая функция:

getReturn <- function(data, n=20) {

    #Assumes 'data' is a two-column data frame with date in the first column, price in the second

     num.rows <- nrow(data)

     output.range <- 1:(num.rows-20)

     buy.price  <- data[output.range,2]
     sell.price <- data[output.range+20,2]

     returns <- data.frame(log(sell.price) - log(buy.price))
     returns <- cbind(data[output.range,],returns)
     names(returns) <- c("Date","Price","Return")

     return(returns)

}

Пример ввода и вывода:

> head(data)
        Date Price
1 2001-01-01    20
2 2001-01-02    19
3 2001-01-03    19
4 2001-01-04    18
5 2001-01-05    18
6 2001-01-06    18
> return<-getReturn(data)
> head(return)
        Date Price     Return
1 2001-01-01    20 0.09531018
2 2001-01-02    19 0.14660347
3 2001-01-03    19 0.14660347
4 2001-01-04    18 0.20067070
5 2001-01-05    18 0.24512246
6 2001-01-06    18 0.20067070
person Chris Taylor    schedule 17.12.2010

Образец данных

price <- matrix(c(20,22,21,25,25,19,20,30,28,25,26,27,30,32,31,30),ncol= 1);

Рассчитать возврат журнала за 1 день

OneDayLogReturn <- c(diff(log(price)));

Рассчитать возврат журнала за 10 дней

TenDaysLogReturn <- c(diff(log(price),10))

полученные результаты:

0.2623643 0.2047944 0.3566749 0.2468601 0.2151114 0.4567584

проверить:

for (i in 1:6) {print(log(price[10+i]/price[i]))}

Аналогичным образом, возврат за 20 дней можно рассчитать, используя более крупную дату выборки и используя

c(diff(log(price),20))

или в вашем случае

c(diff(log(price$Return),20))
person CK TUNG    schedule 14.04.2014