//------------------------------------------------------------------------- public virtual void test_presentValueSensitivity() { PointSensitivityBuilder pointCaplet = PRICER.presentValueSensitivityRatesStickyModel(CAPLET_LONG, RATES, VOLS); CurrencyParameterSensitivities computedCaplet = RATES.parameterSensitivity(pointCaplet.build()); PointSensitivityBuilder pointFloorlet = PRICER.presentValueSensitivityRatesStickyModel(FLOORLET_SHORT, RATES, VOLS); CurrencyParameterSensitivities computedFloorlet = RATES.parameterSensitivity(pointFloorlet.build()); CurrencyParameterSensitivities expectedCaplet = FD_CAL.sensitivity(RATES, p => PRICER_BASE.presentValue(CAPLET_LONG, p, VOLS)); CurrencyParameterSensitivities expectedFloorlet = FD_CAL.sensitivity(RATES, p => PRICER_BASE.presentValue(FLOORLET_SHORT, p, VOLS)); assertTrue(computedCaplet.equalWithTolerance(expectedCaplet, EPS_FD * NOTIONAL * 50d)); assertTrue(computedFloorlet.equalWithTolerance(expectedFloorlet, EPS_FD * NOTIONAL * 50d)); // consistency with shifted Black PointSensitivityBuilder pointCapletBase = PRICER.presentValueSensitivityRates(CAPLET_LONG, RATES, VOLS); PointSensitivityBuilder pointFloorletBase = PRICER.presentValueSensitivityRates(FLOORLET_SHORT, RATES, VOLS); double forward = RATES.iborIndexRates(EUR_EURIBOR_3M).rate(RATE_COMP.Observation); double expiry = VOLS.relativeTime(CAPLET_LONG.FixingDateTime); double volatility = VOLS.volatility(expiry, STRIKE, forward); ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities vols = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(EUR_EURIBOR_3M, VALUATION, ConstantSurface.of("constVol", volatility).withMetadata(Surfaces.blackVolatilityByExpiryStrike("costVol", DayCounts.ACT_ACT_ISDA)), IborCapletFloorletSabrRateVolatilityDataSet.CURVE_CONST_SHIFT); PointSensitivityBuilder pointCapletExp = PRICER_BASE.presentValueSensitivityRates(CAPLET_LONG, RATES, vols); PointSensitivityBuilder pointFloorletExp = PRICER_BASE.presentValueSensitivityRates(FLOORLET_SHORT, RATES, vols); assertEquals(pointCapletBase, pointCapletExp); assertEquals(pointFloorletBase, pointFloorletExp); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value rates sensitivity of the Ibor cap/floor leg. /// <para> /// The present value rates sensitivity of the leg is the sensitivity /// of the present value to the underlying curves. /// /// </para> /// </summary> /// <param name="capFloorLeg"> the Ibor cap/floor leg </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the present value curve sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivityRates(ResolvedIborCapFloorLeg capFloorLeg, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(ratesProvider, volatilities); return(capFloorLeg.CapletFloorletPeriods.Select(period => periodPricer.presentValueSensitivityRates(period, ratesProvider, volatilities)).Aggregate((p1, p2) => p1.combinedWith(p2)).get()); }