[英]Calculate Returns over Period of Time
I'm trying to get a time series of returns for holding a certain asset for a specific time. 我正试图获得一段时间的回报,以便在特定时间内持有某项资产。
My dataframe looks like this: 我的数据框看起来像这样:
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.
I have 1 observation for each day and my time series goes from 1998-1999. 我每天都有1次观察,我的时间序列从1998年到1999年。
What I would like to do now is calculate a return for holding my asset for 20 days (ie buying it at the first day and selling it at day 20), and do this for each day. 我现在要做的是计算持有我的资产20天的回报(即在第一天购买并在第20天出售),并且每天都这样做。 So I would like to calculate this: 所以我想计算一下:
1.day: Return(20days) = log (Price(t=20) / Price (t=0)), 1.day:返回(20天)= log(价格(t = 20)/价格(t = 0)),
2.day: Return(20days) = log (Price(t=21) / Price (t=1)), 2.day:返回(20天)= log(价格(t = 21)/价格(t = 1)),
3.day: Return(20days) = log (Price(t=22) / Price (t=2)) 3.day:返回(20天)= log(价格(t = 22)/价格(t = 2))
etc., ie do this for every day in my sample. 等,即在我的样本中每天都这样做。
So, my resulting dataframe would look like this: 所以,我的结果数据框看起来像这样:
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.
Is there a way in R to say: take the first 20 observations, calculate the return. 在R中有没有办法说:取前20个观察值,计算回报。 Take observation 2-21, calculate the return. 观察2-21,计算回报。 Take observation 3-22, calculate the return etc.? 观察3-22,计算回报等?
I'm totally stuck and would appreciate some help. 我完全陷入困境,并希望得到一些帮助。 Thanks! 谢谢! Dani 达尼
I suggest switching to a time series class, like xts
or zoo
. 我建议切换到时间序列类,如xts
或zoo
。 But if you just want to get it done, and learn more later, you can do it pretty easily as a data frame. 但是如果你只是想完成它,并在以后学习更多,你可以很容易地做它作为一个数据框。 Note that I have to pad the return vectors with NA
s to make it line up correctly and that a hold
of 20 really buy on 1 and sells on 1 + 20: 请注意,我必须使用NA
s填充返回向量以使其正确排列,并且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)))
If you're ready for xts
or zoo
(this should work in either), then I suggest using rollapply
to get the forward look (assuming you want the forward looking return, which makes it a lot easier to form portfolios today and see how it works into the future): 如果你准备好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)
The two approaches are the same: 两种方法是相同的:
> 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
Alternatively, if you are using the package xts, then life is made incredibly simple. 或者,如果您使用的是xts包,那么生活将非常简单。 This is a straight copy-paste of a function I wrote myself a while ago: 这是我刚才写的一个函数的直接复制粘贴:
ret<-function(x,k=1){
return(diff(log(x),k))
}
You can use the ROC
function in the TTR package, or you can just create your own function. 您可以在TTR包中使用ROC
功能,也可以只创建自己的功能。
> 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
You can just use offset indices by subtracting from a range. 您可以通过从范围中减去来使用偏移索引。 (.... but remember that R does not use 0 as a valid index.) Let's say your prices are the second column in a dataframe named prcs2 the first three returns with an interval of 19 days with your data would be : (....但请记住,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
The following function should do it: 以下函数应该这样做:
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)
}
Sample input and output: 样本输入和输出:
> 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
Sample Data 样本数据
price <- matrix(c(20,22,21,25,25,19,20,30,28,25,26,27,30,32,31,30),ncol= 1);
Calculate 1 day Log Return 计算1天的日志返回
OneDayLogReturn <- c(diff(log(price)));
Calculate 10 days Log Return 计算10天日志返回
TenDaysLogReturn <- c(diff(log(price),10))
results: 结果:
0.2623643 0.2047944 0.3566749 0.2468601 0.2151114 0.4567584
verify by : 验证:
for (i in 1:6) {print(log(price[10+i]/price[i]))}
Similarly, 20 Days return can be calculated using larger sample date and use 同样,可以使用更大的样本日期和使用来计算20天的回报
c(diff(log(price),20))
or in your case 或者在你的情况下
c(diff(log(price$Return),20))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.