require(combinat)
## Loading required package: combinat
##
## Attaching package: 'combinat'
##
## The following object is masked from 'package:utils':
##
## combn
@title Asian Option Price @description Returns the price of an asian option using a binomial tree approach @param S the initial stock price @param K the strike price @param r the risk free interest rate (continuously compounded) @param delta the annual dividend rate @param sigma the volatility @param t the expiration time (default one year) @param call TRUE if option is a call, FALSE if option is a put @param arithmetic TRUE if arithemetic average is used, FALSE is geometric average is used @param price TRUE if average price, FALSE is average strike @param h the number of subdivisions between 0 and t @details Uses a forward tree to compute u and d. p in the function is a risk-neutral probability @examples asianOption(S=40, K=39, r=0.05, sigma=0.3, t=1, call=TRUE, arithmetic=TRUE, price=TRUE, h=5) @export
asianOption <- function(S, K, r, delta, sigma, t = 1, call=TRUE, arithmetic=TRUE, price=TRUE, h=10) {
#u = exp( (r-delta)*h + sigma*sqrt(h))
#d = exp( (r-delta)*h - sigma*sqrt(h))
u = 1.1
d = 0.9
p = (exp((r-delta)*(t/h)) - d)/(u-d)
p<<-p
paths <-numeric(0) # compute the possible (ordered) paths
for(i in 0:h) {
path = c(rep(0,i),rep(1,(h-i)))
paths = c(paths, unique(permn(path)))
}
payoffs <- numeric(0) # determine the payoff for each path
probabilities <- numeric(0) # determine the probability for each path
averages <- numeric(0)
for(path in paths) {
previousPrice = S
probability = 1
avg <- numeric(0)
payoff <- numeric(0)
prices <- numeric(0)
for(num in path) {
if(num==1) { # u
prices = c(prices, previousPrice*u)
previousPrice = previousPrice * u
probability = probability * p
} else { # d
prices = c(prices, previousPrice*d)
previousPrice = previousPrice * d
probability = probability * (1-p)
}
}
if(arithmetic==TRUE) {
avg = mean(prices)
} else { # geometric average
avg = exp(mean(log(prices)))
}
if(price==TRUE) {
if(call==TRUE) {
payoff=max(0, avg-K)
} else { # call == FALSE
payoff = max(0, K-avg)
}
} else { # strike option (K=avg, S = prices[h])
if(call==TRUE) {
payoff=max(0, prices[h]-avg)
} else {
payoff=max(0, avg-prices[h])
}
}
payoffs = c(payoffs, payoff)
probabilities = c(probabilities, probability)
averages = c(averages, avg)
}
payoffs <<- payoffs
averages <<- averages
probabilities <<- probabilities
exp(-r*t)*sum(probabilities*payoffs)
}
# price of arithmetic average price put
print(asianOption(40, 39, 0.05, 0, 0.3, 3/12, call=FALSE, arithmetic=TRUE, price=TRUE, h=3))
## [1] 1.441
# price of geometric average strike call
print(asianOption(40, 39, 0.05, 0, 0.3, 3/12, call=TRUE, arithmetic=FALSE, price=FALSE, h=3))
## [1] 1.458