Question

I'm trying to do something similar I was asking for here and unfortunately I cannot work it out.

This is my data frame (data), a time series of prices:

Date          Price   Vol
1998-01-01     200      0.3
1998-01-02     400      0.4
1998-01-03     600     -0.2
1998-01-04     100      0.1
...
1998-01-20     100      0.1
1998-01-21     200     -0.4
1998-01-21     500      0.06
....
1998-02-01     100      0.2
1998-02-02     200      0.4
1998-02-03     500      0.3
1998-02-04     100      0.1
etc.

I would like to tell R, to

  • take the 1st value of "Vol" and divide it by the 20th value of "Price", then
  • take the 2st value of "Vol" and divide it by the 21th value of "Price", then.
  • take the 3st value of "Vol" and divide it by the 22th value of "Price", then
  • etc.

In my other post, I was able to use this function to calculate a return over a holding period of 20 days:

> data.xts <- xts(data[, -1], data[, 1])
> hold <- 20
> 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)

Is there a way to do something very similar for the problem stated above? So something like

f1 <- function(x,y) head(x, 1) / tail(y,1)

where x is "Vol" and y is "Price" and then apply "rollapply"?

Thank you very much

UPDATE: @ Dr G: Thanks for your suggestions. With a slight change, it did what I wanted!

data.xts <- xts(data[, -1], data[, 1])
hold <- 20
data.xts$quo <- lag(data.xts[,2], hold) / data.xts[,1]

Now my problem is, that the resulting data frame looks like this:

    Date          Price   Vol     quo
1 1998-01-01     200      0.3     NA
2 1998-01-02     400      0.4     NA
3 1998-01-03     600     -0.2     NA
4 1998-01-04     100      0.1     NA
...
21 1998-01-20    180      0.2     0.003 

I know that there must be NA's as an outcome, but only for the last 20 observations, not the first 20 ones. The formula stated above calculates the correct values, however puts them starting at the 21st row instead of the first row. Do you know how I could change that?

Was it helpful?

Solution

It's actually easier than that. Just do this:

data.xts <- xts(data[, -1], data[, 1])
hold <- 20
returns.xts = data.xts[,2] / lag(data.xts[,1], hold)

Actually for this using zoo instead of xts would work as well:

data.zoo<- zoo(data[, -1], data[, 1])
hold <- 20
returns.zoo = data.zoo[,2] / lag(data.zoo[,1], -hold)

Only thing that changes is the sign of the lags (zoo convention is different than xts)

OTHER TIPS

Use by.column = FALSE in rollapply. In order to use the posted data we will divide the volume in the first row by the price in the 3rd row and so on for purposes of reproducible illustration:

library(zoo)

Lines <- "Date          Price   Vol
1998-01-01     200      0.3
1998-01-02     400      0.4
1998-01-03     600     -0.2
1998-01-04     100      0.1
1998-01-20     100      0.1
1998-01-21     200     -0.4
1998-01-21     500      0.06
1998-02-01     100      0.2
1998-02-02     200      0.4
1998-02-03     500      0.3
1998-02-04     100      0.1"


# read in and use aggregate to remove all but last point in each day.
# In reality we would replace textConnection(Lines) with something 
#  like "myfile.dat"

z <- read.zoo(textConnection(Lines), header = TRUE, 
       aggregate = function(x) tail(x, 1))

# divide Volume by the Price of the point 2 rows ahead using by.column = FALSE
# Note use of align = "left" to align with the volume.
# If we used align = "right" it would align with the price.

rollapply(z, 3, function(x) x[1, "Vol"] / x[3, "Price"], by.column = FALSE,
    align = "left")

# and this is the same as rollapply with align = "left" as above
z$Vol / lag(z$Price, 2)

# this is the same as using rollapply with align = "right"
lag(z$Vol, -2) / z$Price

By the way, note that zoo uses the same convention for the sign of lag as does R but xts uses the opposite convention so if you convert the above to xts you will have to negate the lags.

You just need to use

data.xts$quo <- data.xts[,2] / lag( data.xts[,1], -hold)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top