/// <summary> /// Calculates the present value sensitivity of the product. /// <para> /// The present value sensitivity of the product is the sensitivity of present value to the underlying curves. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="refData"> the reference data </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivity(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { if (isExpired(cdsIndex, ratesProvider)) { return(PointSensitivityBuilder.none()); } ResolvedCds cds = cdsIndex.toSingleNameCds(); LocalDate stepinDate = cds.StepinDateOffset.adjust(ratesProvider.ValuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = underlyingPricer.recoveryRate(cds, ratesProvider); Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider); double signedNotional = cds.BuySell.normalize(cds.Notional); PointSensitivityBuilder protectionLegSensi = underlyingPricer.protectionLegSensitivity(cds, rates.First, rates.Second, referenceDate, effectiveStartDate, recoveryRate); protectionLegSensi = protectionLegSensi.multipliedBy(signedNotional * rates.Third); PointSensitivityBuilder riskyAnnuitySensi = underlyingPricer.riskyAnnuitySensitivity(cds, rates.First, rates.Second, referenceDate, stepinDate, effectiveStartDate); riskyAnnuitySensi = riskyAnnuitySensi.multipliedBy(-cds.FixedRate * signedNotional * rates.Third); return(protectionLegSensi.combinedWith(riskyAnnuitySensi)); }