Calculate Returns over Period of Time

前端 未结 6 614
[愿得一人]
[愿得一人] 2021-02-04 09:51

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         


        
相关标签:
6条回答
  • 2021-02-04 10:26

    Alternatively, if you are using the package xts, then life is made incredibly simple. 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))
    }
    
    0 讨论(0)
  • 2021-02-04 10:32

    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
    
    0 讨论(0)
  • 2021-02-04 10:33

    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 :

    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
    
    0 讨论(0)
  • 2021-02-04 10:37

    You can use the ROC function in the TTR package, or you can just create your own function.

    > 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
    
    0 讨论(0)
  • 2021-02-04 10:37

    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

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

    Calculate 10 days Log Return

    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

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

    or in your case

    c(diff(log(price$Return),20))
    
    0 讨论(0)
  • 2021-02-04 10:41

    I suggest switching to a time series class, like xts or 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 NAs to make it line up correctly and that a hold of 20 really buy on 1 and sells on 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):

    > 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
    
    0 讨论(0)
提交回复
热议问题