Correcting Branch Ordering in a Binomial Lookback Call
Summary
The document describes a binomial tree implementation for pricing floating-strike lookback options and investigates unusually slow convergence for European calls. The author reports that Monte Carlo estimates approached an analytical benchmark for European calls and puts, while the binomial method behaved acceptably for puts but appeared to stall for calls. The posted code applies up and down stock multipliers to continuation values in its rollback step.
The response identifies the cause as reversed branch ordering in the call rollback. It recommends pairing the down move with the down-state value and the up move with the up-state value, with the stated ordering reversed for the put version. This is a targeted correction to the recurrence rather than evidence that lookback calls inherently converge slowly because their payoff can become unbounded. The exchange supplies no rerun, convergence table, or independent benchmark comparison after the change, so the fix is suggested but its numerical effect is not documented in the material.
Key ideas
- The reported binomial lookback call convergence problem is attributed to mismatched up and down branches in the rollback step.
- Each branch multiplier should be paired with the continuation value from the corresponding successor state.
- The answer says the call rollback uses the normal branch ordering and the put version uses the inverse ordering.
- The document reports convergence behavior but does not provide numerical comparisons after applying the correction.
- The proposed fix addresses the recurrence and does not establish that unbounded call payoffs prevent convergence.
Tags
Full text
# Convergence of Numerical Methods on Lookback Options in R
# Convergence of Numerical Methods on Lookback Options in R
I have been practicing using R code for my Quant course and I came across an issue when testing the convergence of numerical methods for lookback options to the analytical solutions provided by Hull in Derivagem for example.
So I tested both Monte Carlo Methods and Binomial Tree Methods for European & American Floating Strike Calls & Puts.
Monte Carlo methods converged eventually to Hull for European Calls & Puts and Binomial Methods converged relatively quickly to Hull for European Puts and then American Puts appeared to follow closely as I would expect.
My issue came with Binomial Methods for EU (+ by extension AM) Calls... The convergence was so incredible slow and almost stalling when I was running out of computer power and available memory in R.
Here is the code used - I couldn't see an issue with it and it is basically the same as that used for the puts.
Has anyone else had this experience? Is it something to do with the fact that the call can grow to infinity and so testing convergence for lookbacks doesn't work? Any ideas / reasons why? Or am I missing something stupid in the code?
```
lookback_european_floating_call_hw <- function(S0, r, sigma, T, n, q = 0, verbose = FALSE) {
if (n <= 0 || round(n) != n) stop("n must be a positive integer.")
dt <- T / n
u <- exp(sigma * sqrt(dt))
d <- 1 / u
a <- exp((r - q) * dt)
p <- (a - d) / (u - d)
discount <- exp(-r * dt)
if (!(p > 0 && p < 1)) warning("Risk-neutral probability p not in (0,1). Check parameters.")
f <- matrix(NA_real_, nrow = n + 1, ncol = n + 1)
# Terminal payoff for floating-strike CALL: max(1 - 1/Y, 0) = max(1 - u^{-j}, 0)
for (j in 0:n) {
f[n + 1, j + 1] <- max(1 - 1 / (u^j), 0)
}
# Rollback (European = discounted expectation only)
for (i in seq(n - 1, 0, by = -1)) {
for (j in 0:i) {
col_cur <- j + 1
col_up <- j + 2
col_dn <- if (j == 0) 1 else (j - 1) + 1
f_up <- f[i + 2, col_up]
f_dn <- f[i + 2, col_dn]
f[i + 1, col_cur] <- discount * ((1 - p) * d * f_up + p * u * f_dn)
}
}
price_stock_units <- f[1, 1]
price_dollars <- S0 * price_stock_units
if (verbose) {
cat(sprintf("u=%.6f d=%.6f p=%.6f\n", u, d, p))
cat(sprintf("Option value (stock units)=%.6g ; dollar price=%.6g\n", price_stock_units, price_dollars))
}
return(price_dollars)
}
# -------------------------
# Example test (same parameters as before)
# -------------------------
S0 <- 50; r <- 0.1; sigma <- 0.4; T <- 0.25; n <- 20000
price_call <- lookback_european_floating_call_hw(S0, r, sigma, T, n)
print(price_call)
```
## Answer by Andrew Richardson (score 0)
https://quant.stackexchange.com/a/85177
yes changing to:
```
f[i + 1, col_cur] <- discount * ((1 - p) * d * f_dn + p * u * f_up)
```
solves the problem. It should be the normal way around for the call version and inverse for the putShown 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.