0

I am trying to build a simulation of a random walk process with a drift using a loop, however, I am not able to get any outputs and instead I get a length error (number of items to replace is not a multiple of replacement length) which I can't fully understand since I provide a length that will change with how any number of values (N). I am supposed to be able to provide with specific values and then simulate the random walk. Here's my code:

random_walk <- function(prices){
  

  prices <- as.vector(prices)
  
 
  ln_prices <- log(prices)
  
  
  N <- length(prices)
  
 
  phi0 <- (ln_prices[N] - ln_prices[1]) / N
  
  
  sigma <- sd(ln_prices) / sqrt(ln_prices)
  
 
  shock <- rnorm(ln_prices, 0, sigma)
  
 
  rw1 <- c(ln_prices[1])
  
 for (i in 2:N){
  # I calculate the rw value for day t:
  # rw <- drift + shock + rw of yesterday
  rw1 <- rw1 + phi0 + shock

 }
  
}```
  • You're example is not reproducible, so we can't do any in depth troubleshooting, but just calling your function on a random vector of prices between 1 and 10 does not throw an error for me. So please give a rep. example of a case where this throws an error – Julian_Hn Jun 03 '21 at 14:27
  • This is the example I am trying to use, I have no longer gotten the error but I get no output, I'm pretty sure I'm missing something but can't understand what it is: ```price <- c(10,11,9,10.6,10.2,9.8,8.5,8,8.8,11)´´´ – Santiago Vallejo Jun 03 '21 at 14:32

2 Answers2

0

You need to return something out of this functions, you can either use return or just call the name of what you want at the last line

random_walk <- function(prices){
  
  
  prices <- as.vector(prices)
  
  
  ln_prices <- log(prices)
  
  
  N <- length(prices)
  
  
  phi0 <- (ln_prices[N] - ln_prices[1]) / N
  
  
  sigma <- sd(ln_prices) / sqrt(ln_prices)
  
  
  shock <- rnorm(ln_prices, 0, sigma)
  
  
  rw1 <- c(ln_prices[1])
  
  for (i in 2:N){
    # I calculate the rw value for day t:
    # rw <- drift + shock + rw of yesterday
    rw1 <- rw1 + phi0 + shock
    
  }
  return(rw1)
}  

price <- c(10,11,9,10.6,10.2,9.8,8.5,8,8.8,11)  

random_walk(prices = price)
#>  [1] 2.5747813 2.2403036 1.8345087 2.9714599 1.4440819 0.8269357 2.0922631
#>  [8] 2.0563724 1.7999183 3.1020998

Created on 2021-06-03 by the reprex package (v2.0.0)

Session info
sessionInfo()
#> R version 4.1.0 (2021-05-18)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 21390)
#> 
#> Matrix products: default
#> 
#> locale:
#> [1] LC_COLLATE=Portuguese_Brazil.1252  LC_CTYPE=Portuguese_Brazil.1252   
#> [3] LC_MONETARY=Portuguese_Brazil.1252 LC_NUMERIC=C                      
#> [5] LC_TIME=Portuguese_Brazil.1252    
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> loaded via a namespace (and not attached):
#>  [1] ps_1.6.0          digest_0.6.27     withr_2.4.2       magrittr_2.0.1   
#>  [5] reprex_2.0.0      evaluate_0.14     highr_0.9         stringi_1.6.2    
#>  [9] rlang_0.4.11      cli_2.5.0         rstudioapi_0.13   fs_1.5.0         
#> [13] rmarkdown_2.8     tools_4.1.0       stringr_1.4.0     glue_1.4.2       
#> [17] xfun_0.23         yaml_2.2.1        compiler_4.1.0    htmltools_0.5.1.1
#> [21] knitr_1.33
Bruno
  • 4,109
  • 1
  • 9
  • 27
0

Let me try to refactor your code a bit, so that it actually returns something:


random_walk <- function(prices){

  #  prices <- as.vector(prices) # You don't need this since you're already passing a vector
  
  ln_prices <- log(prices)
  
  N <- length(prices)
    
  phi0 <- (ln_prices[N] - ln_prices[1]) / N
    
  sigma <- sd(ln_prices) / sqrt(ln_prices)
    
  shock <- rnorm(ln_prices, 0, sigma)
    
  rw1 <- ln_prices[1]
  
  # This for loop is also unnecessary. You're basically adding phi0 + shock N-1 times
  #for (i in 2:N){
  #  # I calculate the rw value for day t:
  #  # rw <- drift + shock + rw of yesterday
  #  rw1 <- rw1 + phi0 + shock
  #  
  #}
  rw.N <- rw1 + (N-1) * (phi0 + shock)
  
  rw.N # Call rw.N to actually return anything  
}

Julian_Hn
  • 2,086
  • 1
  • 8
  • 18
  • Just to understand why you're saying the for loop is unneccesary. A random walk model is : Yt = drift + Y(t-1) + shock. My idea which I now realize is missing in my loop, was to use that first value of rw1 and then have the rest of the vector be filled by that same model using the previous value in rw1. So it would have something like : ```rw[i] <- drift + rw[i-1] + shock ´´´ – Santiago Vallejo Jun 03 '21 at 14:53
  • I did not evaluate your model, but this code replicates your example. But I need more info to fix your code to do what you want to. Because `shock` and `drift` are themselves `N` long. So do you want to update all prices simultaneously? Or what is the goal? – Julian_Hn Jun 03 '21 at 15:17
  • Okay so the goal is to: create a function to simulate the price of a stock for N periods assuming that the log of prices behave like a random walk with a drift. I should be able to download stock price information from any stock and have my function simulate its random walk to which has to work for any number of observations. I hope that helps as explaining what my goal is. Thanks a lot ! – Santiago Vallejo Jun 03 '21 at 17:52