0

I'm dealing right now with a valuation of Option prices for my university thesis. We need to program some things in R. It's the first time I'm working with a programming software like R. I've been doing this for the last 2 weeks and this is where I went so far:

s <- 120
#Value of the stock today
sd <- 0.1
#standard deviation
d <- 0.003
#Drift

N <- 365
T <-1
dt <-T/N
t <- seq(0,T, length=N+1)
W <- c(0, cumsum(sqrt(dt)*rnorm(N)))
#plot( t, W, type="l", main="Wiener process", ylim=c(-1,1))

S <- s*exp(d+sd*W)
S

This is a simple generalized Wiener process which I want to turn into a Monte Carlo simulation. For S there are now 366 (N+1) Values of the Stock path. What I need is a "for loop" which takes the last Value of S and allocates it into a vector (list vector), so that I can run the loop for example 10000 times, collect every last Value of S and get the average of the vector.

I have no idea how I can program such a for loop. I would really appreciate if you could help me or give me some good hints.

Greetings from Germany Christian

David
  • 11,245
  • 3
  • 41
  • 46
Monte
  • 1
  • Step 1: Turn your code into a function, `my_wiener_process`. Only `return()` the last value of `S`. Step 2: `n = 10000; results = rep(NA, n); for (i in 1:n) results[i] <- my_wiener_process()`. – Gregor Thomas Nov 28 '16 at 20:20
  • Thanks alot. The problem is, i don't even know how i can turn my code into a function – Monte Nov 28 '16 at 20:26
  • Put `my_wiener_process <- function () {` before all your code, and put `return(tail(S, 1)) }` at the end of all your code. See, e.g, most anything at [how to write a function in R](https://www.google.com/search?q=how+to+write+a+function+in+R&ie=utf-8&oe=utf-8) – Gregor Thomas Nov 28 '16 at 20:32
  • Wow it worked, thank you very much! You saved my day. – Monte Nov 28 '16 at 20:41
  • plus one for the giggles at my_wiener_process – Carl Boneri Nov 28 '16 at 20:43

2 Answers2

0

I never studied Wiener Processes, but I think this would be a simple outline of the code you're trying to achieve:

stock_prices <- s    #Initialise vector of stock prices
numIter <- 10^4      #Set number of iterations in the for loop

for(i in 1:numIter) {
  s <- stock_prices[i]  #This is the current stock price (for ith iteration / time step)

  #Calculate the next stock price here, call it next_price

  #Add price of next iteration / time step to your vector:
  stock_prices <- c(stock_prices, next_price)
}

stock_prices will be a vector of the 10,000 stock prices you simulated.

I don't know how you calculate the next stock price from S, but if you draw from the values of S randomly, then it might be useful to check out the function sample (type ?sample for help on it).

Hope that helps

hodgenovice
  • 624
  • 3
  • 14
  • 1
    "Growing" the vector inside the loop like that is very bad practice - needless inefficiency. See [Circle 2 of the R Inferno](http://www.burns-stat.com/pages/Tutor/R_inferno.pdf). – Gregor Thomas Nov 28 '16 at 20:56
  • I agree that it's not the most efficient, but it's easy to grasp. Since when I started writing this, he'd just said he didn't know how to write a function, I thought basic / easy code was more important than efficiency. I'm glad your comments sorted him out. – hodgenovice Nov 29 '16 at 18:46
0

If you just want to run code repeatedly, putting it in a function is nice (but not absolutely necessary). I will refer to all the code in your question as <your code>.

To make a function that runs your code,

my_function = function() {
    <your code>
}

The function will, by default, return its last line, in this case S. You only want the last element of S, tail(S, 1). So we can modify the function to return only that:

my_function = function() {
    <your code>
    return(tail(S, 1))
}

We can then call it in a for loop n times and assign the result. It is best to pre-allocate the vector for the results so that an appropriately sized block of memory can be set aside for it up front:

n = 10000
results = rep(NA, n)
for (i in 1:n) {
    results[i] <- my_function()
}

This is equivalent to

n = 10000
results = rep(NA, n)
for (i in 1:n) {
    <your code>
    results[i] <- tail(S, 1)
}

And, for that matter, it is also equivalent to

results = replicate(n, my_function())

which is a handy shortcut.

If you want to be fancy, you could parameterize your function:

my_nice_function = function(s = 120, sd = 0.1, d = 0.003, N = 365) {
    T <- 1
    dt <- T / N
    t <- seq(0, T, length = N + 1)
    W <- c(0, cumsum(sqrt(dt) * rnorm(N)))
    S <- s * exp(d + sd * W)
    return(tail(S, 1))
}

Now my_nice_function has default values as in your code, but you can easily adjust them, e.g., to run the 50 simulations with sd = 0.2 you can do this:

replicate(50, my_nice_function(sd = 0.2))
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294