JBR
JBR

Reputation: 21

R - Start with initial investment at first row, then multiply by price return if condition is met

I have a price time series, and I'm trying to create a function that will, in a new given column :

Here is my code :

inv <- function(x){
if(length(x) <2  ){x = 100} 
  else if(data$ma10 > data$ma30 && length(x) > 1){x = shift(x, 1L, type ="lag") * data$price / shift(data$price, 1L, type = "lag")}
  else if(data$ma10 < data$ma30 && length(x) > 1){x = shift(x, 1L, type = "lag")}
 }
data$invest = inv(data$invest)

And here is how to reproduce the data :

# Random prices 
data = data.table(price = rnorm(1:300, mean = 100))
#Moving average function 
mav <- function(x,n=30) if(length(x) >= n)stats::filter(x,rep(1/n,n), sides=1) else NA_real_ 
data$ma30 = as.numeric(mav(data$price, n = 30))
data$ma10 = as.numeric(mav(data$price, n = 10))
#Remove NAs 
data = subset(data, ma30 != "NA")

Unfortunately my function does not work and only yields value around 1 accross all observations.

Any tips :) ?

Upvotes: 0

Views: 98

Answers (1)

Andrew Gustar
Andrew Gustar

Reputation: 18435

From your data as defined, you could just do

data$invest = 100 * cumprod(c(1,ifelse(data$ma10 > data$ma30,                             
                    data$price / shift(data$price, 1, type="lag"),
                    1)[-1]))

basically this is creating a virtual column of year-by-year increase factors with the ifelse statement, removing the first value (NA due to the lag) and replacing it with 1, then taking the cumulative product of these and multiplying by your start value of 100.

Note that you need data.table loaded to use the shift function. Otherwise you could use lag to do the same thing.

Upvotes: 0

Related Questions