Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Caps and Floors

Instruments

let cap = MakeCapFloor::default()
    .with_identifier("USD_SOFR_CAP_2Y".to_string())
    .with_start_date(rd)
    .with_maturity_date(rd + Period::from_str("2Y")?)
    .with_notional(10_000_000.0)
    .with_strike(0.045)
    .with_cap_floor_type(CapFloorType::Cap)
    .with_currency(Currency::USD)
    .with_market_index(MarketIndex::SOFR)
    .with_frequency(Frequency::Quarterly)       // default
    .build()?;
let trade = CapFloorTrade::new(cap, rd, 10_000_000.0, Side::LongReceive);

Required: notional, start_date, maturity_date, strike, currency, market_index, identifier, cap_floor_type. Defaults: side LongReceive, frequency Quarterly. CapFloorType::{Cap, Floor}; a single period is a CapletFloorlet (CapletFloorletType::{Caplet, Floorlet}) with trade CapletFloorletTrade::new(..).

Black-76 pricers

ClosedFormBlackCapletPricer::new() and ClosedFormBlackCapPricer::new() handle Request::Value and Request::Sensitivities. For each caplet with fixing \(T\), accrual \([T,S]\), \(\tau=S-T\):

\[ F = \frac{1}{\tau}\left(\frac{P(T)}{P(S)}-1\right),\qquad \text{Caplet} = N\,\tau\,Pd(S)\,[F\,\Phi(d_1) - K\,\Phi(d_2)],\quad d{1,2}=\frac{\ln(F/K)\pm\tfrac12\sigma^2 T}{\sigma\sqrt T}. \]

  • The forward comes from the curve of market_index; the discount factor from the discount policy (dual-curve when a SingleCurveCSADiscountPolicy is set).
  • The strike is a Strike (Absolute, Atm, Relative) resolved against \(F\).
  • \(\sigma\) is read from the VolatilitySurfaceElement for market_index at (fixing_date, strike) through volatility_from_date; VolatilityType::Normal surfaces switch to the Bachelier formula.
  • A cap is the sum of its caplets; floors use the put formula.

Market data requested: the discount curve(s) and the volatility surface of the index. Sensitivities are labelled with the OIS quotes and the CapletFloorlet_* quotes that define the surface.

Hull-White pricers

ClosedFormHullWhiteCapletPricer::new(alpha, sigma) and ClosedFormHullWhiteCapPricer::new(alpha, sigma) price the same trades without a surface, using the one-factor Hull-White model with constant \(\sigma\):

\[ \text{Caplet} = N\,(1+\tau K)\;\text{BondPut}\bigl(T, S, X\bigr),\qquad X=\frac{1}{1+\tau K}, \]

where the zero-coupon bond option uses the volatility

\[ \sigma_P = \sigma\,B(T,S)\sqrt{\frac{1-e^{-2\alpha T}}{2\alpha}},\qquad B(t,T)=\frac{1-e^{-\alpha(T-t)}}{\alpha}. \]

They are useful to cross-check a calibrated model (HullWhite::calibrate_with_configuration, see Hull-White) against the Black surface it was fitted to.

Sensitivities

Both pricer families run the reverse sweep from the option value; results.sensitivities() therefore contains curve pillars (OIS_USD_SOFR_*) and, for Black pricers, one row per volatility quote (CapletFloorlet_USD_SOFR_3M_1Y_Absolute_0.045_Straddle_Black), i.e. a vega ladder on the quoted grid.