1

I need to fill backwards the historical prices knowing the returns (in real situation they are simulated). So far I have this code:

library(quantmod)
getSymbols("AAPL")
df = AAPL["2014-01-01/2015-01-01", "AAPL.Close"]
df_ret = diff(log(df),1)
# imagine the half of the past prices are missing
df["2014-01-01/2014-07-01"] = NA
df_tot = cbind(df, df_ret)

fillBackwards = function(data, range_to_fill){
  index_array = index(data[range_to_fill,])
  data_out = data
  for (i in (length(index_array)-1):1){
    inx = index_array[i]
    inx_0 = index_array[i+1]
    data_out[inx,1] = exp(-(data_out[inx_0,2]))*(data_out[inx_0,1])
  }
  return (data_out)
}

df_filled = fillBackwards(df_tot,"2014-01-01/2014-07-02")

sum(AAPL["2014-01-01/2015-01-01", "AAPL.Close"] - df_filled[,1]) # zero up to computation error, i.e. identical

This works perfect, but a bit slow. Could you please suggest something using build-in rollapply()

# i want something like this 
df_filled = rollapply(df_tot["2014-07-02/2014-01-01",], by=-1, function(x) {....})
stkubr
  • 371
  • 1
  • 5
  • 15
  • You could study the source code rollapply with `zoo:::rollapply.zoo`. It is rather long, but it might just be a wrapper around `mapply`? But where they use `seq_along(...)` you want `rev(seq_along(...))` (This is a comment, not an answer, as I don't have time to confirm that guess.) – Darren Cook Nov 26 '15 at 21:19

1 Answers1

1

You don't need rollapply, or a loop. You can use cumprod on the returns. Here's a version of fillBackwards that uses cumprod:

fillBackwards <- function(data, range_to_fill) {
  data_range <- data[range_to_fill,]

  returns <- rev(coredata(data_range[-1L, 2L]))
  last_price <- drop(coredata(last(data_range[, 1L])))

  new_prices <- rev(last_price * cumprod(exp(-returns)))
  data[range_to_fill, 1L] <- c(last_price, new_prices)

  return(data)
}
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418