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