Monte Carlo Pricing of Arithmetic Asian Options and Negative Time Value
Summary
The document presents R code that simulates geometric Brownian motion price paths and estimates vanilla, arithmetic Asian, or geometric Asian option values by averaging discounted payoffs. It also estimates delta with a finite difference, reusing the same simulated random shocks for the perturbed paths. The example raises a question about simulated option values falling below intrinsic value.
The code is a method example, not a resolved analysis: it provides no reported results or explanation of the negative values. Its estimate is based on a finite number of simulations, so sampling variation can affect the comparison. The meaning of intrinsic value also depends on the Asian option’s averaging schedule and which past prices are included; the code averages the supplied history together with simulated prices. These details need checking before treating a below-intrinsic estimate as a feature of the contract or a coding error.
Key ideas
- The code estimates option value by averaging discounted simulated payoffs across price paths.
- It supports terminal-price, arithmetic-average, and geometric-average references.
- Delta is approximated by perturbing the starting price while reusing the same random shocks.
- The averaging schedule and treatment of past prices affect an Asian option’s payoff definition.
- A finite simulation can produce estimation noise, and the document does not diagnose its reported issue.
Tags
Full text
# Asian option numerical pricing method generates a negative time value
# Asian option numerical pricing method generates a negative time value
I use R to write a function which simulates price path and calculates the value of an arithmetic Asian option. I found sometimes the value of the option can be lower than its intrinsic value, i.e., negative time value. I am wondering if this is a feature of arithmetic Asian option, or is there anything wrong with my code.
```
###############################################################################
OptionMC = function (style, type, S, X, r, q, tDays, volatility, nSims) {
# drift term
mu = r - q
# underlying price, S can be a vector with previous prices
S0 = tail(S, n=1)
# every trading day increment
dt = 1 / 252
# time to maturity express in fraction of years
tMaturity = tDays / 252
# standard normal distribution random number
z = rnorm(tDays*nSims, mean=0, sd=1)
# generate log-normal return matrix
return_matrix = matrix(exp((mu - 0.5 * volatility ^ 2) * dt + volatility * sqrt(dt) * z), ncol=nSims)
# return value: price path matrix
path = rbind(matrix(rep(S,nSims),ncol=nSims), S0*apply(return_matrix,2,cumprod))
# calculate option delta, generate a new price path, with the same brownian motion term "z"
path_delta = rbind(matrix(rep(S,nSims),ncol=nSims), S0*1.0001*apply(return_matrix,2,cumprod))
path_delta[length(S),] = path_delta[length(S),] * 1.0001
# different option style
if (style == "vanilla") {
# plain vanilla option, use the final price as settlement price
ref = tail(path, n=1)
ref_delta = tail(path_delta, n=1)
} else if (style == "arithmetic") {
# arithmetic mean of the entire price path, fixed strike price
ref = apply(path, 2, mean)
ref_delta = apply(path_delta, 2, mean)
} else if (style == "geometric") {
# geometric mean of the entire price path, fixed strike price
ref = apply(path, 2, function(x){exp(mean(log(x)))})
ref_delta = apply(path_delta, 2, function(x){exp(mean(log(x)))})
} else {
}
# option's value, average of difference between terminal value and strike price, then discount back to present value
value = exp(- r * tMaturity) * sum(pmax(ifelse(type=="call",1,-1) * (ref - X), 0)) / nSims
# option's value with "path_delta", i.e., values calculated for calculating delta
value_delta = exp(- r * tMaturity) * sum(pmax(ifelse(type=="call",1,-1) * (ref_delta - X), 0)) / nSims
# delta is defined as the change of option value w.r.t. change of underlying price (S0)
delta = (value_delta - value) / (S0 * 0.0001)
# return value:
list(path=path, value=value, delta=delta)
}
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.