Asian options and Greeks

library(greeks)

Asian options are path-dependent: their payoff depends on an average of the underlying asset price over time. The package supports two related cases:

The package tests compare exact formulas, Monte Carlo estimates, and finite differences. This vignette turns those checks into small reproducible examples.

Geometric Asian options

BS_Geometric_Asian_Greeks() computes exact Black-Scholes values for geometric Asian calls and puts.

geometric_exact <- BS_Geometric_Asian_Greeks(
  initial_price = 110,
  exercise_price = 100,
  r = 0.02,
  time_to_maturity = 1.5,
  dividend_yield = 0.01,
  volatility = 0.25,
  payoff = "call",
  greek = c("fair_value", "delta", "rho", "vega", "theta", "gamma")
)

round(geometric_exact, 4)
#> fair_value      delta        rho       vega      theta      gamma 
#>    13.0195     0.7123    39.2393    19.8534    -1.7859     0.0164

The tests check the formulas by comparing each Greek with a finite difference. Here is that idea for vega, the derivative with respect to volatility.

geometric_price_at <- function(volatility) {
  BS_Geometric_Asian_Greeks(
    initial_price = 110,
    exercise_price = 100,
    r = 0.02,
    time_to_maturity = 1.5,
    dividend_yield = 0.01,
    volatility = volatility,
    payoff = "call",
    greek = "fair_value"
  )
}

step_size <- 1e-4
finite_difference_vega <-
  (geometric_price_at(0.25 + step_size) -
     geometric_price_at(0.25 - step_size)) /
  (2 * step_size)

round(
  c(
    exact_vega = geometric_exact["vega"],
    finite_difference_vega = finite_difference_vega,
    absolute_error = abs(geometric_exact["vega"] - finite_difference_vega)
  ),
  8
)
#>                   exact_vega.vega finite_difference_vega.fair_value 
#>                        19.8534213                        19.8534207 
#>               absolute_error.vega 
#>                         0.0000006

Malliavin_Geometric_Asian_Greeks() can estimate the same quantities by simulation. A moderate number of paths is enough for a vignette example; for production work, increase paths and check stability.

greeks_to_compare <- c("fair_value", "delta", "rho", "vega")

geometric_monte_carlo <- Malliavin_Geometric_Asian_Greeks(
  initial_price = 110,
  exercise_price = 100,
  r = 0.02,
  time_to_maturity = 1.5,
  dividend_yield = 0.01,
  volatility = 0.25,
  payoff = "call",
  greek = greeks_to_compare,
  paths = 20000,
  steps = 24,
  seed = 42,
  antithetic = TRUE
)

round(
  rbind(
    exact = geometric_exact[greeks_to_compare],
    malliavin_monte_carlo = geometric_monte_carlo
  ),
  4
)
#>                       fair_value  delta     rho    vega
#> exact                    13.0195 0.7123 39.2393 19.8534
#> malliavin_monte_carlo    13.0679 0.7104 39.0092 18.3485

Arithmetic Asian options

For arithmetic Asian options the package uses Malliavin Monte Carlo estimators. BS_Malliavin_Asian_Greeks() is optimized for the Black-Scholes model and the most common Greeks.

arithmetic_asian <- BS_Malliavin_Asian_Greeks(
  initial_price = 110,
  exercise_price = 100,
  r = 0.02,
  time_to_maturity = 1.5,
  dividend_yield = 0.01,
  volatility = 0.25,
  payoff = "call",
  greek = c("fair_value", "delta", "rho", "vega"),
  paths = 10000,
  steps = 24,
  seed = 42
)

round(arithmetic_asian, 4)
#> fair_value      delta        rho       vega 
#>    13.5856     0.7278    40.9563    23.9036

The generic Greeks() wrapper dispatches to the Asian implementation when option_type = "Asian".

round(
  Greeks(
    initial_price = 110,
    exercise_price = 100,
    r = 0.02,
    time_to_maturity = 1.5,
    dividend_yield = 0.01,
    volatility = 0.25,
    payoff = "call",
    option_type = "Asian",
    greek = c("fair_value", "delta", "rho", "vega")
  ),
  4
)
#> fair_value      delta        rho       vega 
#>    13.5696     0.7304    40.8725    23.9372

Vectorized inputs and custom payoffs

The Malliavin Asian functions can vary one scalar parameter over a vector. This is useful for plotting how values change with the current underlying price.

price_grid <- Malliavin_Geometric_Asian_Greeks(
  initial_price = c(95, 100, 105),
  exercise_price = 100,
  r = 0.02,
  time_to_maturity = 1,
  volatility = 0.25,
  payoff = "put",
  greek = c("fair_value", "delta"),
  paths = 5000,
  steps = 12,
  seed = 42
)

round(price_grid, 4)
#>      fair_value   delta
#> [1,]     7.9716 -0.5881
#> [2,]     5.3935 -0.4492
#> [3,]     3.4654 -0.3210

Custom payoff functions are also accepted. The payoff function receives the averaged underlying value and the exercise price.

digital_call <- function(x, exercise_price) {
  ifelse(x >= exercise_price, 1, 0)
}

invisible(capture.output(
  custom_digital <- Malliavin_Geometric_Asian_Greeks(
    initial_price = 100,
    exercise_price = 100,
    r = 0.02,
    time_to_maturity = 1,
    volatility = 0.25,
    payoff = digital_call,
    greek = c("fair_value", "delta"),
    paths = 5000,
    steps = 12,
    seed = 42
  )
))

round(custom_digital, 4)
#> fair_value      delta 
#>     0.4766     0.0277

References

Asian option pricing and Greeks are discussed in Hull (2022). The Malliavin Monte Carlo estimators used here are described in Hudde and Rueschendorf (2023).