Skip to content

Double no-touch series truncation produces prices outside the cash-payment bounds #266

Description

@kadyrbekovhamit-cyber

FXDoubleOneTouchOption.value can price a nonnegative double-touch payoff below zero and its complementary no-touch payoff above the discounted cash payment. Tested through the real Numba-backed public API on source 2b9227fea9d832c4033421d6cd53a54316414fca and PyPI 1.1.2. The current master target file still matches the tested bytes when fetched today.

from financepy.products.fx.fx_double_one_touch_option import FXDoubleOneTouchOption
from financepy.utils.date import Date
from financepy.utils.global_types import DoubleBarrierTypes
from financepy.utils.day_count import DayCountTypes
from financepy.utils.frequency import FrequencyTypes
from financepy.market.curves.discount_curve_flat import DiscountCurveFlat
from financepy.models.black_scholes import BlackScholes

vdt = Date(1, 1, 2026)
expiry = vdt.add_days(30)
sigma = 0.2
d = DiscountCurveFlat(vdt, 0.5*sigma*sigma,
                      FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F)
f = DiscountCurveFlat(vdt, 0.0,
                      FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F)
for kind in DoubleBarrierTypes:
    price = FXDoubleOneTouchOption(expiry, kind, 80., 125., 1.).value(
        vdt, 100., d, f, BlackScholes(sigma))
    print(kind.name, price)
print("discounted cash", d.df(expiry))
# KNOCK_IN  -0.17335157473444152
# KNOCK_OUT  1.1717090894757467
# discounted cash 0.9983575147413052

Both prices must be in [0, discounted cash]. Their sum is correct even in the failing implementation, so complement parity alone misses the defect. An independent Brownian absorbing-density method-of-images calculation gives no-touch 0.9981587590142639 and touch 0.00019875572704133946.

Two truncation mistakes in _fast_double_no_touch_pricer contribute:

  1. Stopping when one series term is small is not a tail bound. At zero log drift the even coefficients vanish while later odd terms can remain material. A midpoint spot also makes even sine factors vanish.
  2. The stated damping bound requires n >= Z/(pi*sigma) * sqrt(2*log(1/eps)/T). The current expression is half that threshold.

Across 480 fixed parameter scenarios (two prices each), oracle failures are 360 original, 48 after removing only the early stop, 0 after both corrections, and 360 after restoring the original source. The release reproduces the original rows. Probability-range failures are 72 / 24 / 0. All 48 nonzero-drift controls and all 120 previously passing scenarios remain within the same normalized tolerance 2e-10; they are not byte-identical. All 230 original source files are preserved.

The independent oracle uses 60-decimal method-of-images arithmetic, with an image-tail check recorded in the attachment. No clipping or tolerance relaxation is used. The existing 50-term minimum and 2000-term cap remain, so the candidate does not guarantee convergence for all inputs. Full upstream suite, Monte Carlo, Greeks, performance and production impact were not measured.

The attached packet contains the candidate patch, real API probe, raw original/intermediate/candidate/restored/release results and provenance. Its scripts retain local source paths and require adapting to a checkout; it is not a standalone build distribution. SHA-256: cb52bb4189635aada44413d2222e7b4c38fa07fbf8ddfadc976d8862d9a30cdd. Bounded duplicate search refreshed today; no exact match identified.

I would be glad to prepare a focused PR and discuss a suitable convergence contract. Xamit Kadirbekov / GERO, kadyrbekovhamit@gmail.com. AI-assisted preparation; claims are tied to the retained executed evidence.

financepy-double-no-touch-triage-maintainer-evidence.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions