Quanto-adjusted dividend curve¶
QuantoTermStructure is an additive Rust-core yield curve. It combines five
live handles into a continuously compounded dividend zero yield:
[ q_Q(t)=q(t)+r_d(t)-r_f(t)+\rho\,\sigma_S(t,K)\,\sigma_{FX}(t,L). ]
| Input | Meaning |
|---|---|
| Dividend yield curve | Underlying asset dividend zero yield q |
| Domestic / foreign yield curves | Interest-rate differential r_d - r_f |
| Asset Black volatility curve | Volatility at fixed underlying strike K |
| FX Black volatility curve | Volatility at fixed FX ATM level L |
| Correlation | Fixed asset/FX correlation rho, in [-1, 1] |
The discount factor is exp(-q_Q(t) * t). This is a building block, not a
complete quanto option engine. The feature does not activate deferred finite-difference quanto paths, change existing engines, or add language bindings.
Construction and live inputs¶
Import QuantoTermStructure from libitofin::termstructures::yields.
new(dividend, domestic, foreign, asset_vol, strike, fx_vol, fx_atm, correlation)
returns QlResult<Self>. Existing YieldTermStructure methods expose discounts,
zero rates and forward rates; ZeroYieldStructure::zero_yield_impl exposes the
continuous zero-yield formula directly.
- All five handles are observed through the existing weak base relay.
- Quote moves, relinks and moving-curve evaluation-date notifications propagate.
- No inputs or calculated yields are cached.
- Dividend metadata is live: reference date, day counter, calendar and settlement days change when the dividend handle is relinked.
- Maximum date is the minimum of all five inputs' calendar maximum dates. Maximum time uses that date and the dividend curve's reference/day counter.
Query conventions preserved from QuantLib¶
All inputs receive the same numerical time, with internal extrapolation explicitly enabled for both time and volatility strike. Reference dates and day counters are not silently aligned or rebased. Differing clocks therefore retain QuantLib's numerical result, but a meaningful financial application must supply compatible conventions. The original source warns about common day counts.
Public range checks use the wrapper's own maximum date/time. Its extrapolation
flag starts disabled and does not inherit or synchronize input flags. Explicit
query extrapolation or enable_extrapolation() permits queries past its maximum;
it does not make negative/nonfinite times valid.
discount(0, ...)returns one without evaluating the five inputs, after the public range check. With extrapolation allowed this also works on empty links.zero_rate(0, ...)follows the existing yield-curve convention: it computes a discount at1e-4years, not the formula directly at zero.- Direct
zero_yield_impl(0)uses input zero rates at their1e-4convention, but requests Black volatilities at zero, matching native source behavior. - At extremely short positive times, zero rates recovered from a rounded
discount can lose precision through
log(discount) / time. Native fixtures test1e-8discounts, not a promised exact short-time analytic yield.
Checked Rust boundaries¶
The original scalar constructor is unchecked. This additive constructor rejects nonfinite strike/FX levels and nonfinite/out-of-range correlation. Finite zero or negative levels remain allowed because some volatility domains support them; the wrapper does not impose a new positive-strike domain.
Numerical queries reject missing links, nonfinite component zero rates, nonfinite/negative component Black volatilities, a nonfinite combined zero yield, and a nonpositive/nonfinite final discount. Component errors propagate even when a zero correlation would make a volatility irrelevant algebraically. Source-order arithmetic is preserved: intermediate overflow can reject an input whose result could be finite under symbolic rearrangement. No arbitrary-precision or catastrophic-cancellation guarantee is made.
Construction permits empty handles for later relinking. Empty dividend metadata
returns None/Err; any missing input gives the null maximum-date sentinel.
These are safe Rust fallbacks where native inspectors dereference empty handles.
Independent reference¶
Fixtures use the compiled QuantLib==1.43 QuantoTermStructure directly:
24 discounts and zero rates over nonflat curves, mixed reference dates/day counts,
correlation signs, out-of-domain asset strikes and extrapolated times. That wheel
is distinct from inspected source revision
9863b578af0caa4cecabf697196533e84a8308b6.
The generator and provenance are in
crates/libitofin/tests/fixtures/medium2_quanto_curve/.