1
votes

I have the following zoo object, Z, representing a time series of daily stock returns:

     structure(c(NA, 0.00559252442304969, 0.00654699049630403, -0.00398657154846838, 
-0.00624956112632535, -0.00777275296777835, -0.017518871955562, 
0.0108002319512903, -0.00709931875224101, -0.0104723385815398, 
0.0148894241296256, 0.00287666307083789, 0.00107565435640011, 
-0.0126790830945559, -0.000145106290357688, 0.00928815035193398, 
-0.00582356747429735, 0.00665316748625977, 0.00933908045977017, 
0.0151601423487544, -0.00371590829418778, 0.00570021111893038, 
0.00412847246518799, -0.00689895470383284, 0.00456108343274164, 
-0.00523889354568319, 0.0019661540622149, 0.012684841264279, 
0.0114186851211073, -0.00520013684570642), .Names = c("1986-01-01", 
"1986-01-02", "1986-01-03", "1986-01-06", "1986-01-07", "1986-01-08", 
"1986-01-09", "1986-01-10", "1986-01-13", "1986-01-14", "1986-01-15", 
"1986-01-16", "1986-01-17", "1986-01-20", "1986-01-21", "1986-01-22", 
"1986-01-23", "1986-01-24", "1986-01-27", "1986-01-28", "1986-01-29", 
"1986-01-30", "1986-01-31", "1986-02-03", "1986-02-04", "1986-02-05", 
"1986-02-06", "1986-02-07", "1986-02-10", "1986-02-11"), index = structure(c(5844, 
5845, 5846, 5849, 5850, 5851, 5852, 5853, 5856, 5857, 5858, 5859, 
5860, 5863, 5864, 5865, 5866, 5867, 5870, 5871, 5872, 5873, 5874, 
5877, 5878, 5879, 5880, 5881, 5884, 5885), class = "Date"), class = "zoo")

I need to calculate the average return of the first 10 days of each month. I used the following code (where apply.rolling is a function in the PerformanceAnalytics package):

apply.rolling(Z, 10)

However, this gives the return of 10 days on a rolling base without ignoring the rest days of the month.

Any ideas how to perform that?

3
Please provide a reproducible example (dput). - Sven Hohenstein
@SvenHohenstein I have changed the example. Would you please confirm that this is a good way to write my example as this is my first time to use dput - salhin
Yes, this is the right way to provide a reproducible example. - Sven Hohenstein

3 Answers

3
votes

Here's an approach with tapply:

# Some example data:
library(zoo)
set.seed(1)
dates <- as.Date("2014-01-01") + seq(0, 58)
Z <- zoo(rnorm(59), dates)

# Calculate mean of days 1-10 for each month:
tapply(Z, format(time(Z), "%Y-%m"), 
       function(x) mean(x[as.integer(format(time(x), "%d")) <= 10]))

#     2014-01     2014-02 
#  0.13220278 -0.03159011 
0
votes

A slightly different approach using lubridate and rollapply from zoo rather than apply.rolling:

library(zoo)
library(lubridate)
##
set.seed(123)
Df <- data.frame(
  Date=seq.Date(
    from=as.Date("1986-01-01"),
    by="day",
    length.out=365),
  Value=c(NA,rnorm(364)))
##
Z <- zoo(Df$Value,Df$Date)
##
## ath thru bth days of month
fDays <- function(x,a=1,b=10)
{
  x[(mday(x) %in% a:b)]
}
##
> rollapply(fDays(Z),FUN=mean,width=10,by=10,na.rm=TRUE,align="left")
   1986-01-01    1986-02-01    1986-03-01    1986-04-01    1986-05-01    1986-06-01    1986-07-01    1986-08-01 
 1.324354e-01  3.220446e-01 -1.401720e-01  6.546170e-01 -2.057204e-01  1.273702e-01  6.596781e-05 -2.615902e-01 
   1986-09-01    1986-10-01    1986-11-01    1986-12-01 
-4.955370e-02 -5.366626e-02  6.447457e-02  2.297708e-01

Where the align="left" doesn't affect the values, it just displays the 1st day of the month rather than the 5th day (align="center", the default) or the 10th day (align="right").

0
votes

Try this:

aggregate(Z, as.yearmon, function(x) mean(head(x, 10), na.rm = TRUE))