NUMERICAL AUDIT · 1 NOVEMBER 2026
Vibe-Trading: Heston option prices are wrong for expiries of about a day or less
Vibe-Trading's heston_price truncates the pricing integral at u = 200 by default, which silently misprices options a day or less from expiry by up to +73% in the checked cases.
Xamit Kadirbekov, Daniyal Kadirbekov · AI-assisted investigation and writing
Checked 1 November 2026: PR #2140 is open and awaiting review; not merged or released. Local regression checks and limitations documented.
Authors: Xamit Kadirbekov and Daniyal Kadirbekov (GERO). Published 1 November 2026.
Status: Checked 1 November 2026: PR #2140 is open and awaiting review; not merged or released. Local regression checks and limitations documented.
Vibe-Trading's heston_price truncates the pricing integral at u = 200 by default, which silently misprices options a day or less from expiry by up to +73% in the checked cases.
Published proposal
- HKUDS/Vibe-Trading PR #2140 — head commit
74a7c66d5a9b8f1da0d6e19d46b1738ca568d239, OPEN at submission on 1 November 2026.
What the function does
Vibe-Trading is an open-source trading-agent project from HKUDS (about 37,000 GitHub stars when checked). Its quant library includes heston_price (agent/src/quantlib/volatility.py), which prices European options under the Heston model, where volatility itself moves randomly. There is no closed-form price: it is an integral over a frequency variable u from 0 to infinity (Lewis 2001). In code the integral is cut off somewhere, which is only safe if the remaining tail is negligible.
The discrepancy
By default integration_limit=200.0, and the integral is quad(integrand, 0.0, integration_limit, limit=2000). The integrand decays like the characteristic function, whose width in u grows as 1/√(v·T): the shorter the expiry and the lower the variance, the further one must integrate. For an expiry of a day or less the tail beyond u = 200 is still large, and the price is wrong without any warning.
S = K = 100, r = 0, κ = 2, θ = v0, σ_v = 0.3, ρ = −0.7 (commit 78fab6b3f998583f640820db60c155ffa5641a62):
| Expiry, volatility | Current default | Reference | integration_limit=2000 |
|---|---|---|---|
| 1 day, 10% | 0.239099 | 0.208613 | 0.208613 |
| 6 hours, 10% | 0.180470 | 0.104383 | 0.104383 |
| 1 day, 20%, K = 102 | 0.009192 | 0.010168 | 0.010168 |
| 3 days, 20%, K = 102 | 0.116934 | 0.116953 | 0.116953 |
| 7 days, 20% | 1.102658 | 1.102658 | 1.102658 |
The one-day at-the-money price is about 15% too high, the six-hour price about 73% too high, and the one-day K = 102 price about 10% too low. From about a week to expiry the two agree to 1e−8. Raising the limit to 2000 reproduces the reference, which confirms the truncation as the cause.
Reference and why this is not a convention
The reference is an independent Heston P1/P2 formula with the Albrecher et al. "little trap" characteristic function, integrated to infinity with scipy.integrate.quad. It was checked against a known limit: as σ_v → 0 with v0 = θ, Heston must reduce to Black–Scholes, and it does. A Heston price for given parameters is one number; the integration limit is a numerical device. Its documentation describes it only as the upper limit of the quadrature, without saying that the default is inaccurate for short expiries.
Fix and tests
integration_limit: float | None = None;Noneintegrates to infinity asquadon [0, 200] plusquadon [200, ∞). The first part is unchanged, so longer-dated prices do not change. An explicit limit keeps the old behaviour and its input checks.- New parametrised test
test_short_expiry_converges_to_black_scholeschecks short expiries in the σ_v → 0 limit againstbs_price. agent/tests/quantlib/test_volatility.py: 6 failed / 8 passed before, 14 passed after.agent/tests/test_heston_finite_inputs_regressions.py: 38 passed, 1 failed both before and after; the failing test needspydantic, which was not installed in the minimal environment.- Fuzz over 150 random short-expiry cases: 53 off by more than 1e−4 before, 0 after.
Upstream status
As of 1 November 2026, PR #2140 is open with review required and no review yet. Nothing has been merged or released.
Limits
The full repository test suite was not run; we used a sparse clone and a minimal environment. We did not check which users call the Heston pricer at short expiries, and we make no claim about trading losses. The characteristic function and the other volatility models were not changed. In the same repository bs_price, bs_greeks, eight barrier-option formulas and the VaR backtests agreed with their references; that is a bounded check, not a validation of the project. Novelty rests on a GitHub search for "heston" (PRs #1195 and #1719, neither about the integration limit) and the file's three-commit history.
The price table was re-computed in a separate session on 1 November before submission. No reproduction archive is attached to this page yet.
Attribution and license
AI tools (Claude) helped find the cases, build the reference calculations and draft the patches and tests; the examples were re-run independently before submission. Xamit Kadirbekov and Daniyal Kadirbekov are the report authors and reviewed the submitted diff; upstream software remains credited to its developers. Report: CC BY 4.0. Upstream patches retain their upstream licenses.