# American options and Greeks

    library(greeks)

American options can be exercised at any time before maturity. The package prices American calls and puts with a binomial tree via `Binomial_American_Greeks()`. The fair value is computed by the tree, and the Greeks are computed by finite differences around that fair value.

The tests verify the binomial implementation against an independent tree and check finite-difference Greeks. The examples below show the same ideas on small, readable inputs.

## Pricing an American option

    american_put <- Binomial_American_Greeks(
      initial_price = 100,
      exercise_price = 100,
      r = 0.03,
      time_to_maturity = 1,
      dividend_yield = 0,
      volatility = 0.3,
      payoff = "put",
      greek = c("fair_value", "delta", "gamma", "vega", "theta", "rho"),
      steps = 200
    )

    round(american_put, 4)
    #> fair_value      delta      gamma       vega      theta        rho
    #>    10.6149    -0.4281     0.0108    38.6709    -4.6290   -39.0559

The generic `Greeks()` wrapper can be used for the same option by setting `option_type = "American"`.

    round(
      Greeks(
        initial_price = 100,
        exercise_price = 100,
        r = 0.03,
        time_to_maturity = 1,
        dividend_yield = 0,
        volatility = 0.3,
        payoff = "put",
        option_type = "American",
        greek = c("fair_value", "delta", "rho"),
        steps = 200
      ),
      4
    )
    #> fair_value      delta        rho
    #>    10.6149    -0.4281   -39.0559

## Early-exercise premium

For a put option, the American value can exceed the corresponding European Black-Scholes value because early exercise may be beneficial.

    european_put_value <- BS_European_Greeks(
      initial_price = 100,
      exercise_price = 100,
      r = 0.03,
      time_to_maturity = 1,
      dividend_yield = 0,
      volatility = 0.3,
      payoff = "put",
      greek = "fair_value"
    )

    american_put_value <- Binomial_American_Greeks(
      initial_price = 100,
      exercise_price = 100,
      r = 0.03,
      time_to_maturity = 1,
      dividend_yield = 0,
      volatility = 0.3,
      payoff = "put",
      greek = "fair_value",
      steps = 400
    )

    round(
      c(
        european_put = european_put_value,
        american_put = american_put_value,
        early_exercise_premium = american_put_value - european_put_value
      ),
      4
    )
    #>           european_put.fair_value           american_put.fair_value
    #>                           10.3279                           10.6118
    #> early_exercise_premium.fair_value
    #>                            0.2839

## Choosing the number of tree steps

A larger number of tree steps generally gives a more accurate binomial approximation, at the cost of more computation.

    steps <- c(25, 50, 100, 200, 400)

    prices <- vapply(
      steps,
      function(n_steps) {
        Binomial_American_Greeks(
          initial_price = 100,
          exercise_price = 100,
          r = 0.03,
          time_to_maturity = 1,
          dividend_yield = 0,
          volatility = 0.3,
          payoff = "put",
          greek = "fair_value",
          steps = n_steps
        )
      },
      numeric(1)
    )

    data.frame(steps = steps, fair_value = round(prices, 4))
    #>   steps fair_value
    #> 1    25    10.6098
    #> 2    50    10.6331
    #> 3   100    10.6212
    #> 4   200    10.6149
    #> 5   400    10.6118

## A finite-difference delta

The implementation computes American Greeks by perturbing one model parameter at a time. This reproduces the calculation for delta.

    fair_value_at <- function(initial_price) {
      Binomial_American_Greeks(
        initial_price = initial_price,
        exercise_price = 100,
        r = 0.03,
        time_to_maturity = 1,
        dividend_yield = 0,
        volatility = 0.3,
        payoff = "put",
        greek = "fair_value",
        steps = 200
      )
    }

    step_size <- 0.01
    finite_difference_delta <-
      (fair_value_at(100 + step_size) - fair_value_at(100 - step_size)) /
      (2 * step_size)

    reported_delta <- Binomial_American_Greeks(
      initial_price = 100,
      exercise_price = 100,
      r = 0.03,
      time_to_maturity = 1,
      dividend_yield = 0,
      volatility = 0.3,
      payoff = "put",
      greek = "delta",
      steps = 200,
      eps = step_size
    )

    round(
      c(
        reported_delta = reported_delta,
        finite_difference_delta = finite_difference_delta,
        absolute_error = abs(reported_delta - finite_difference_delta)
      ),
      8
    )
    #>               reported_delta.delta finite_difference_delta.fair_value
    #>                         -0.4280888                         -0.4280888
    #>               absolute_error.delta
    #>                          0.0000000

## Reference

The binomial option pricing model is presented in Hull (2022).