Simulating a Random Walk with a drift (using a for loop)

437 Views Asked by At

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

 }
  
}```
2

There are 2 best solutions below

0
Bruno On BEST ANSWER

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
3
Julian_Hn On

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  
}