Search code examples
rrolling-average

How to calculate three year rolling return using R


I need to get a 3-year rolling return working (3-year return for each id, for each year).

I have tried to use the PerformanceAnalytics package but I keep getting an error that my data is not a time series.

When I use the function it says TRUE so I am completely stuck as to how to get the 3-year rolling return to work. So I just need someone to provide me with the R code that will produce the 3-year returns.

Here's a sample dataset

ppd_id   FY   TF_1YR
1      2001  -0.0636
1      2002  -0.0929
1      2003  0.1648
1      2004  0.1006
1      2005  0.1098
1      2006  0.0837
1      2007  0.1792
1      2008  -0.1521
1      2009  -0.1003
1      2010  0.0847
1      2011  0.0221
1      2012  0.1801
1      2013  0.146
1      2014  0.1202
1      2015  0.0105
1      2016  0.1022
1      2017  0.1286
1      2018  0.0929

Here's link to dataset

Here's my code

library(smooth)
library(readr)
pensionreturns <- read_csv("pensionreturns.csv")
sma(pensionreturns, h=

Solution

  • Assuming that:

    • we are starting out with the data frame DF2 in the Note at the end which is the data in question duplicated so that there are 2 id's
    • the third column represents returns so the 3 year returns are the product of one plus each of the last 3 values (current value and prior 2) all minus 1, i.e. (1 + r0) * (1 + r1) * (1 + r2) - 1 where r0, is the current year's return, r1 is the prior year's return and r2 is the return in the year prior to that.

    convert the data to the wide form zoo series z and then use rollapplyr. Omit the fill= argument if the NA's at the beginning are not needed. The result will be a zoo series of returns. (We could use fortify.zoo, see ?fortify.zoo, to convert it to a data frame although it will be easier to perform further time series manipulations if you leave it as a time series.)

    library(zoo)
    
    z <- read.zoo(DF2, index = 2, split = 1, FUN = c)
    rollapplyr(z + 1, 3, prod, fill = NA) - 1
    

    giving this zoo series:

                    1            2
    2001           NA           NA
    2002           NA           NA
    2003 -0.010609049 -0.010609049
    2004  0.162883042  0.162883042
    2005  0.422740161  0.422740161
    2006  0.323680900  0.323680900
    2007  0.418212355  0.418212355
    2008  0.083530596  0.083530596
    2009 -0.100440641 -0.100440641
    2010 -0.172530498 -0.172530498
    2011 -0.002527919 -0.002527919
    2012  0.308343674  0.308343674
    2013  0.382282521  0.382282521
    2014  0.514952431  0.514952431
    2015  0.297228567  0.297228567
    2016  0.247648627  0.247648627
    2017  0.257004321  0.257004321
    2018  0.359505217  0.359505217
    

    Note

    DF <- structure(list(ppd_id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), FY = 2001:2018, TF_1YR = c(-0.0636, 
    -0.0929, 0.1648, 0.1006, 0.1098, 0.0837, 0.1792, -0.1521, -0.1003, 
    0.0847, 0.0221, 0.1801, 0.146, 0.1202, 0.0105, 0.1022, 0.1286, 
    0.0929)), class = "data.frame", row.names = c(NA, -18L))
    
    DF2 <- rbind(DF, transform(DF, ppd_id = 2))