Diagnosing Invalid Inputs in the Leisen-Reimer Binomial Option Model
Summary
The document presents a C++ implementation of a Leisen-Reimer binomial tree for pricing American options and describes cases where its output becomes NaN. The example computes transformed probabilities from two standardized option inputs, then uses those probabilities to calculate up and down factors before stepping backward through the tree and comparing continuation value with immediate exercise value. In the reported case, one transformed probability evaluates to zero, making subsequent calculations invalid.
The question asks how such cases should be handled in practice and whether frequent invalid outputs indicate a flaw in a commonly used model. The excerpt supplies an input example and the relevant formulas, but no answer or diagnosis. It therefore does not establish whether the cause is an implementation error, a numerical limitation of the probability approximation, or parameters outside the method’s supported range. Readers would need to check the original Leisen-Reimer conditions and validate the implementation before drawing conclusions about the model’s reliability.
Key ideas
- The Leisen-Reimer tree uses transformed probabilities to set its up and down factors.
- The example reports a transformed probability of zero, which leads to invalid later calculations.
- The tree values American options by stepping backward and comparing continuation with exercise value.
- The excerpt poses the handling question but offers no diagnosis or recommended remedy.
Tags
Full text
# How does LR binomial Tree Model handle input values which would cause NA result?
# How does LR binomial Tree Model handle input values which would cause NA result?
I am using C++ to implement a LR binomial Tree algorithm to price American options, but I find it would constantly generate invalid output, which is "nan" value in C++, although the input value seems quite reasonable.
My code:
```
double lr_price(IN int putcall, double s,double k, double r, double vol, double bizt, ouble cldt, int steps)
{
if (steps % 2 == 0)
{
steps += 1;
}
double dt = cldt / steps;
double d1 = (std::log(s / k) + (r + vol * vol * 0.5) * bizt) / (vol * std::sqrt(bizt));
double d2 = d1 - vol * std::sqrt(bizt);
double hd1 = peizerpratt2(d1, steps); //* <== 0 here when using the following input
double hd2 = peizerpratt2(d2, steps);
double p = hd2;
double u = std::exp(r * dt) * hd1 / hd2;
double d = (std::exp(r * dt) - p * u) / (1 - p);
for (int i = 0; i <= steps; i++)
{
asset_prices[steps][i] = s * std::pow(u, steps - i) * std::pow(d, i);
option_values[steps][i] = payoff(asset_prices[steps][i], k, putcall);
}
for (int step = steps - 1; step >= 0; step--)
{
for (int i = 0; i <= step; i++)
{
asset_prices[step][i] = asset_prices[step + 1][i] / u;
option_values[step][i] = std::max(
(option_values[step + 1][i] * p + option_values[step + 1][i + 1] * (1 - p)) * std::exp(0 - r * dt),
payoff(asset_prices[step][i], k, putcall));
}
}
return option_values[0][0];
}
double peizerpratt2(double z, double n)
{
return 0.5 + sgn(z) * std::sqrt(
0.25 - 0.25 * std::exp(0 - std::pow(z / (n + 1.0 / 3.0 + 0.1 / (n + 1.0)), 2) * (n + 1.0 / 6.0)));
}
```
And look at this group of input values:
s = 3328, k = 4100, bizt = 0.0932, cldt = 0.1328, vol = 0.0156, r=0.0011, steps = 10
it would make hd1 to the value of 0, and then the following steps are unable to compute.
I can easily provide such groups of input values. It occurs quite often when I running my tests.
I am wondering if there is some good way to handle such conditions in practice. It is unbelievable to me that a commonly used model has so many invalid points.Shown 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.