Skip to main content

coupon_bond_option_from

Function coupon_bond_option_from 

pub(crate) fn coupon_bond_option_from<R: Scalar>(
    params: &HullWhiteParameters<R>,
    curve: &dyn YieldCurve<R>,
    expiry: NaiveDate,
    start: NaiveDate,
    pay_dates: &[NaiveDate],
    coupons: &[R],
    strike: f64,
    kind: OptionKind,
) -> Result<R, CurveError>
Expand description

A European option, exercised at expiry, to exchange strike paid on start for the coupon bond Σ c_i paid on pay_dates — Jamshidian’s decomposition in mode R, with the strike leg forward-starting as a swaption’s is: the swap delivered at expiry starts a spot lag later.

At expiry the exchange is worth P(T,S)·(Σ c_i X_i − K) with X_i = P(T, t_i)/P(T, S), each X_i monotone in the short rate, so the option exercises on one side of the r* that solves Σ c_i X_i(r*) = K and is the sum of options on the forward bonds X_i struck at K_i = X_i(r*). Under the S-forward measure each X_i is lognormal with volatility σ_p(T, t_i) − σ_p(T, S), so each piece is the zero-bond formula with P(0, S) in place of P(0, T) — which it is exactly when S = T, the bond options running from the swap’s first reset.

r* is solved passively — on the projection — and the strikes enter as constants: by the envelope argument, the decomposition is exact at the solved r*, so its own derivative is not needed and a Newton recorded in the mode would only put statements on the tape for a term that is identically zero. A test pins that claim against a full bump.

coupons are per unit face and include the redemption on the last date; strike is in the same units. The coupons are in the mode — a swaption’s carry its basis spread, which reads the curve — and by the same envelope argument only the final sum needs them active.

§Errors

Whatever the curve reports; CurveError::Malformed for an empty or mismatched schedule, a start before the expiry or after the first payment, or a critical-rate solve that does not converge.