FinancePy BAW pricing divides by zero at a zero rate
The Barone–Adesi–Whaley coefficient has a finite limit as the risk-free rate tends to zero. FinancePy 1.0.1 forms its numerator and denominator separately, so exact zero becomes 0/0; a nearby put can also exceed the boundary solver's iteration limit.
A one-minute explanation
Synthetic English narration using macOS Samantha. Original motion cards, no music or third-party imagery. Download the script, source ledger, renderer and QA record.
Released-wheel reproduction
The BAW path uses the coefficient
mm / kk = (2r / v²) / (1 - exp(-rt)).
For synthetic S=K=100, T=1 and v=20%, the official FinancePy 1.0.1 wheel produces:
American call, r=0, q=2% ZeroDivisionError
American put, r=0, q=0 ZeroDivisionError
American put, r=1e-12, q=0 FinError: Failed to converge
The wheel SHA-256 is 110e784122f485ae207239f44af473334f418d81bcbb958f5eda4e76956feca5. The same direct quotient remains at upstream base commit 2b9227fea9d832c4033421d6cd53a54316414fca.
The limit is finite
Since 1-exp(-rt) ~ rt, the quotient has the ordinary limit
(2r/v²) / (1-exp(-rt)) → 2/(v²t).
Pull request #261 uses -expm1(-rt) away from zero and the analytic limit at zero. For a zero-rate put with a non-negative dividend yield, the European put already dominates immediate exercise, so that exact case returns the European value. The nearby put boundary receives 100 rather than 50 secant iterations; the tolerance and solver are otherwise unchanged.
Independent controls
A separate 2,000-step Cox–Ross–Rubinstein implementation imports no FinancePy code. For the zero-rate call with a 2% dividend yield it gives 7.110251189598. Corrected BAW gives 7.098257767528, a difference of about 0.012. BAW remains an approximation; the relevant result is that its value is finite and continuous at zero.
At r=q=0, the corrected BAW put equals FinancePy's European value 7.965579241666. A standard-erf Black–Scholes control gives 7.965567455406. That roughly 1.18e-5 normal-CDF approximation difference predates this change and is outside the finding.
Validation and falsification
- The focused model file reports 4 passes.
- The complete local unit suite reports 959 passes, with four pre-existing LSMC conditioning warnings.
- The unmodified released wheel reproduces two division errors and the near-zero convergence failure.
- After the correction, zero and near-zero call values agree within
1.1e-7; zero and near-zero put values agree within5.4e-11. - Both official upstream workflows report success on commit
03b31c40976c907729b05a0e32ead0fe706ccd51.
At publication time the pull request remains open and unmerged. Passing checks establish the state of the submitted code, not maintainer acceptance.
Evidence and limits
Four bounded searches of FinancePy issue and pull-request history found no matching report. This is duplicate screening, not a worldwide priority guarantee.
All prices and market inputs are synthetic. The report establishes a library-level singularity and convergence boundary. It does not establish institutional use, a customer position, production deployment, financial loss, or the exactness of the BAW approximation.
- Complete public reproducer
- Submitted correction: FinancePy PR #261
- FinancePy 1.0.1 on PyPI
- Download the reproducible evidence ZIP — SHA-256
5e614363e7f60adea7f1f2b024a92e48896fe812fc41aa228660bfdc668de31d
The public reproducer and report are supplied under GPL-3.0-or-later.
