public virtual void test_rateSensitivity() { RatesProvider mockProv = mock(typeof(RatesProvider)); IborIndexRates mockRates3M = mock(typeof(IborIndexRates)); IborIndexRates mockRates6M = mock(typeof(IborIndexRates)); when(mockProv.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRates3M); when(mockProv.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRates6M); when(mockRates3M.ratePointSensitivity(GBP_LIBOR_3M_OBS)).thenReturn(SENSITIVITY3); when(mockRates6M.ratePointSensitivity(GBP_LIBOR_6M_OBS)).thenReturn(SENSITIVITY6); IborInterpolatedRateComputation ro = IborInterpolatedRateComputation.of(GBP_LIBOR_3M, GBP_LIBOR_6M, FIXING_DATE, REF_DATA); ForwardIborInterpolatedRateComputationFn obsFn = ForwardIborInterpolatedRateComputationFn.DEFAULT; LocalDate fixingEndDate3M = GBP_LIBOR_3M_OBS.MaturityDate; LocalDate fixingEndDate6M = GBP_LIBOR_6M_OBS.MaturityDate; double days3M = fixingEndDate3M.toEpochDay() - FIXING_DATE.toEpochDay(); //nb days in 3M fixing period double days6M = fixingEndDate6M.toEpochDay() - FIXING_DATE.toEpochDay(); //nb days in 6M fixing period double daysCpn = ACCRUAL_END_DATE.toEpochDay() - FIXING_DATE.toEpochDay(); double weight3M = (days6M - daysCpn) / (days6M - days3M); double weight6M = (daysCpn - days3M) / (days6M - days3M); IborRateSensitivity sens3 = IborRateSensitivity.of(GBP_LIBOR_3M_OBS, weight3M); IborRateSensitivity sens6 = IborRateSensitivity.of(GBP_LIBOR_6M_OBS, weight6M); PointSensitivities expected = PointSensitivities.of(ImmutableList.of(sens3, sens6)); PointSensitivityBuilder test = obsFn.rateSensitivity(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProv); assertEquals(test.build(), expected); }
public virtual void test_before() { LocalDate startDate = date(2018, 2, 1); LocalDate endDate = date(2018, 2, 28); OvernightAveragedDailyRateComputation cmp = OvernightAveragedDailyRateComputation.of(USD_FED_FUND, startDate, endDate, REF_DATA); ImmutableRatesProvider rates = getRatesProvider(date(2018, 1, 24)); double computedRate = FUNCTION.rate(cmp, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, rates); PointSensitivityBuilder sensiComputed = FUNCTION.rateSensitivity(cmp, startDate, endDate, rates); ExplainMapBuilder builder = ExplainMap.builder(); double explainRate = FUNCTION.explainRate(cmp, startDate, endDate, rates, builder); double expectedRate = 0d; PointSensitivityBuilder sensiExpected = PointSensitivityBuilder.none(); LocalDate date = startDate; while (!date.isAfter(endDate)) { OvernightIndexObservation obs = OvernightIndexObservation.of(USD_FED_FUND, date, REF_DATA); double rate = rates.overnightIndexRates(USD_FED_FUND).rate(obs); PointSensitivityBuilder rateSensi = rates.overnightIndexRates(USD_FED_FUND).ratePointSensitivity(obs); LocalDate nextDate = cmp.FixingCalendar.next(date); long days = DAYS.between(date, nextDate); expectedRate += rate * days; sensiExpected = sensiComputed.combinedWith(rateSensi.multipliedBy(days)); date = nextDate; } double nDays = 28d; expectedRate /= nDays; sensiExpected = sensiExpected.multipliedBy(1d / nDays); assertEquals(computedRate, expectedRate, TOL); assertTrue(sensiComputed.build().equalWithTolerance(sensiExpected.build(), TOL)); assertEquals(explainRate, computedRate, TOL); assertEquals(builder.build().get(ExplainKey.COMBINED_RATE).Value, expectedRate, TOL); }
//------------------------------------------------------------------------- // the sensitivity of the product plus settlement private PointSensitivityBuilder presentValueSensitivityFromProductPresentValueSensitivity(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, PointSensitivityBuilder productPresnetValueSensitivity) { PointSensitivityBuilder sensiProduct = productPresnetValueSensitivity.multipliedBy(trade.Quantity); PointSensitivityBuilder sensiPayment = presentValueSensitivitySettlement(trade, ratesProvider, discountingProvider); return(sensiProduct.combinedWith(sensiPayment)); }
//------------------------------------------------------------------------- public virtual void test_ratePointSensitivity_fixing() { ForwardFxIndexRates test = ForwardFxIndexRates.of(GBP_USD_WM, FWD_RATES, SERIES); assertEquals(test.ratePointSensitivity(OBS_BEFORE, GBP), PointSensitivityBuilder.none()); assertEquals(test.ratePointSensitivity(OBS_VAL, GBP), PointSensitivityBuilder.none()); }
//------------------------------------------------------------------------- public virtual void test_ratePointSensitivity_fixing() { DiscountOvernightIndexRates test = DiscountOvernightIndexRates.of(GBP_SONIA, DFCURVE, SERIES); assertEquals(test.ratePointSensitivity(GBP_SONIA_BEFORE), PointSensitivityBuilder.none()); assertEquals(test.ratePointSensitivity(GBP_SONIA_VAL), PointSensitivityBuilder.none()); }
public virtual void test_forwardFxRatePointSensitivity() { PointSensitivityBuilder computed = PRICER.forwardFxRatePointSensitivity(FWD, PROVIDER); FxForwardSensitivity expected = FxForwardSensitivity.of(CurrencyPair.of(USD, KRW), USD, FWD.PaymentDate, 1d); assertEquals(computed, expected); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity to the SABR model parameters of the swaption product. /// <para> /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu. /// /// </para> /// </summary> /// <param name="swaption"> the swaption product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="swaptionVolatilities"> the volatilities </param> /// <returns> the point sensitivity to the SABR model parameters </returns> public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities) { validate(swaption, ratesProvider, swaptionVolatilities); double expiry = swaptionVolatilities.relativeTime(swaption.Expiry); ResolvedSwap underlying = swaption.Underlying; ResolvedSwapLeg fixedLeg = this.fixedLeg(underlying); double tenor = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate); double shift = swaptionVolatilities.shift(expiry, tenor); double strike = calculateStrike(fixedLeg); if (expiry < 0d) { // Option has expired already return(PointSensitivityBuilder.none()); } double forward = SwapPricer.parRate(underlying, ratesProvider); double volatility = swaptionVolatilities.volatility(expiry, tenor, strike, forward); double numeraire = calculateNumeraire(swaption, fixedLeg, forward, ratesProvider); DoubleArray derivative = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward).Derivatives; double vega = numeraire * swaption.LongShort.sign() * BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility); // sensitivities Currency ccy = fixedLeg.Currency; SwaptionVolatilitiesName name = swaptionVolatilities.Name; return(PointSensitivityBuilder.of(SwaptionSabrSensitivity.of(name, expiry, tenor, ALPHA, ccy, vega * derivative.get(2)), SwaptionSabrSensitivity.of(name, expiry, tenor, BETA, ccy, vega * derivative.get(3)), SwaptionSabrSensitivity.of(name, expiry, tenor, RHO, ccy, vega * derivative.get(4)), SwaptionSabrSensitivity.of(name, expiry, tenor, NU, ccy, vega * derivative.get(5)))); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the swaption product to the rate curves. /// <para> /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential /// re-calibration of the model parameters to the raw market data. /// /// </para> /// </summary> /// <param name="swaption"> the swaption product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="swaptionVolatilities"> the volatilities </param> /// <returns> the point sensitivity to the rate curves </returns> public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyModel(ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities) { validate(swaption, ratesProvider, swaptionVolatilities); ZonedDateTime expiryDateTime = swaption.Expiry; double expiry = swaptionVolatilities.relativeTime(expiryDateTime); ResolvedSwap underlying = swaption.Underlying; ResolvedSwapLeg fixedLeg = this.fixedLeg(underlying); if (expiry < 0d) { // Option has expired already return(PointSensitivityBuilder.none()); } double forward = SwapPricer.parRate(underlying, ratesProvider); ValueDerivatives annuityDerivative = SwapPricer.LegPricer.annuityCashDerivative(fixedLeg, forward); double annuityCash = annuityDerivative.Value; double annuityCashDr = annuityDerivative.getDerivative(0); LocalDate settlementDate = ((CashSwaptionSettlement)swaption.SwaptionSettlement).SettlementDate; double discountSettle = ratesProvider.discountFactor(fixedLeg.Currency, settlementDate); double strike = calculateStrike(fixedLeg); double tenor = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate); double shift = swaptionVolatilities.shift(expiry, tenor); ValueDerivatives volatilityAdj = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward); bool isCall = fixedLeg.PayReceive.Pay; double shiftedForward = forward + shift; double shiftedStrike = strike + shift; double price = BlackFormulaRepository.price(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value, isCall); double delta = BlackFormulaRepository.delta(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value, isCall); double vega = BlackFormulaRepository.vega(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value); PointSensitivityBuilder forwardSensi = SwapPricer.parRateSensitivity(underlying, ratesProvider); PointSensitivityBuilder discountSettleSensi = ratesProvider.discountFactors(fixedLeg.Currency).zeroRatePointSensitivity(settlementDate); double sign = swaption.LongShort.sign(); return(forwardSensi.multipliedBy(sign * discountSettle * (annuityCash * (delta + vega * volatilityAdj.getDerivative(0)) + annuityCashDr * price)).combinedWith(discountSettleSensi.multipliedBy(sign * annuityCash * price))); }
private PointSensitivityBuilder presentValueSensitivityFromProductPresentValueSensitivity(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, PointSensitivityBuilder productPresnetValueSensitivity) { PointSensitivityBuilder sensiProduct = productPresnetValueSensitivity.multipliedBy(trade.Quantity); PointSensitivityBuilder sensiPayment = presentValueSensitivityPayment(trade, provider); return(sensiProduct.combinedWith(sensiPayment)); }
/// <summary> /// Calculates the present value sensitivity of the fixed coupon bond trade with z-spread. /// <para> /// The present value sensitivity of the trade is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value curve sensitivity of the trade </returns> public virtual PointSensitivities presentValueSensitivityWithZSpread(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { LocalDate settlementDate = this.settlementDate(trade, provider.ValuationDate); PointSensitivityBuilder sensiProduct = productPricer.presentValueSensitivityWithZSpread(trade.Product, provider, zSpread, compoundedRateType, periodsPerYear, settlementDate); return(presentValueSensitivityFromProductPresentValueSensitivity(trade, provider, sensiProduct).build()); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the fixed coupon bond trade. /// <para> /// The present value sensitivity of the trade is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <returns> the present value curve sensitivity of the trade </returns> public virtual PointSensitivities presentValueSensitivity(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider) { LocalDate settlementDate = this.settlementDate(trade, provider.ValuationDate); PointSensitivityBuilder sensiProduct = productPricer.presentValueSensitivity(trade.Product, provider, settlementDate); return(presentValueSensitivityFromProductPresentValueSensitivity(trade, provider, sensiProduct).build()); }
/// <summary> /// Calculates the forward exchange rate point sensitivity. /// <para> /// The returned value is based on the direction of the FX product. /// /// </para> /// </summary> /// <param name="fx"> the product </param> /// <param name="provider"> the rates provider </param> /// <returns> the point sensitivity </returns> public virtual PointSensitivityBuilder forwardFxRatePointSensitivity(ResolvedFxSingle fx, RatesProvider provider) { FxForwardRates fxForwardRates = provider.fxForwardRates(fx.CurrencyPair); PointSensitivityBuilder forwardFxRatePointSensitivity = fxForwardRates.ratePointSensitivity(fx.ReceiveCurrencyAmount.Currency, fx.PaymentDate); return(forwardFxRatePointSensitivity); }
//------------------------------------------------------------------------- public virtual void test_ratePointSensitivity_fixing() { DiscountIborIndexRates test = DiscountIborIndexRates.of(GBP_LIBOR_3M, DFCURVE, SERIES); assertEquals(test.ratePointSensitivity(GBP_LIBOR_3M_BEFORE), PointSensitivityBuilder.none()); assertEquals(test.ratePointSensitivity(GBP_LIBOR_3M_VAL), PointSensitivityBuilder.none()); }
/// <summary> /// Calculates the price sensitivity of the bond future product with z-spread. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates /// of the issuer discounting curve. /// </para> /// <para> /// Note that the price sensitivity should be no currency. /// /// </para> /// </summary> /// <param name="future"> the future </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodPerYear"> the number of periods per year </param> /// <returns> the price curve sensitivity of the product </returns> public PointSensitivities priceSensitivityWithZSpread(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { ImmutableList <ResolvedFixedCouponBond> basket = future.DeliveryBasket; int size = basket.size(); double[] priceBonds = new double[size]; int indexCTD = 0; double priceMin = 2d; for (int i = 0; i < size; i++) { ResolvedFixedCouponBond bond = basket.get(i); double dirtyPrice = bondPricer.dirtyPriceFromCurvesWithZSpread(bond, discountingProvider, zSpread, compoundedRateType, periodPerYear, future.LastDeliveryDate); priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.LastDeliveryDate, dirtyPrice) / future.ConversionFactors.get(i); if (priceBonds[i] < priceMin) { priceMin = priceBonds[i]; indexCTD = i; } } ResolvedFixedCouponBond bond = basket.get(indexCTD); PointSensitivityBuilder pointSensi = bondPricer.dirtyPriceSensitivityWithZspread(bond, discountingProvider, zSpread, compoundedRateType, periodPerYear, future.LastDeliveryDate); return(pointSensi.multipliedBy(1d / future.ConversionFactors.get(indexCTD)).build()); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity to the SABR model parameters of the swaption trade. /// <para> /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu. /// /// </para> /// </summary> /// <param name="trade"> the swaption trade </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="swaptionVolatilities"> the volatilities </param> /// <returns> the point sensitivity to the SABR model parameters </returns> public virtual PointSensitivities presentValueSensitivityModelParamsSabr(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities) { ResolvedSwaption product = trade.Product; PointSensitivityBuilder pointSens = isCash(product) ? cashParYieldPricer.presentValueSensitivityModelParamsSabr(product, ratesProvider, swaptionVolatilities) : physicalPricer.presentValueSensitivityModelParamsSabr(product, ratesProvider, swaptionVolatilities); return(pointSens.build()); }
/// <summary> /// Calculates the present value sensitivity of the settlement of the bond trade from the real clean price /// with z-spread. /// <para> /// The present value sensitivity of the settlement is the sensitivity of the present value to /// the underlying curves. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="refData"> the reference data used to calculate the settlement date </param> /// <param name="discountingProvider"> the discount factors provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <param name="cleanRealPrice"> the clean real price </param> /// <returns> the present value sensitivity of the settlement </returns> public virtual PointSensitivities presentValueSensitivityFromCleanPriceWithZSpread(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.ValuationDate; ResolvedCapitalIndexedBond bond = trade.Product; LocalDate standardSettlementDate = bond.calculateSettlementDateFromValuation(valuationDate, refData); LocalDate tradeSettlementDate = settlementDate(trade, valuationDate); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(bond, discountingProvider); double df = repoDf.discountFactor(standardSettlementDate); PointSensitivityBuilder dfSensi = repoDf.zeroRatePointSensitivity(standardSettlementDate); PointSensitivityBuilder pvSensiStandard = forecastValueSensitivityStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice).multipliedBy(df).combinedWith(dfSensi.multipliedBy(forecastValueStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice).Amount)); if (standardSettlementDate.isEqual(tradeSettlementDate)) { return(presentValueSensitivityFromProductPresentValueSensitivity(trade, ratesProvider, discountingProvider, pvSensiStandard).build()); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingCapitalIndexedBondProductPricer.issuerCurveDf(bond, discountingProvider); PointSensitivityBuilder pvSensiDiff = PointSensitivityBuilder.none(); if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCouponWithZSpread(bond, ratesProvider, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear).multipliedBy(-1d)); } else { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCouponWithZSpread(bond, ratesProvider, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear)); } return(presentValueSensitivityFromProductPresentValueSensitivity(trade, ratesProvider, discountingProvider, pvSensiStandard.combinedWith(pvSensiDiff)).build()); }
//------------------------------------------------------------------------- public virtual void test_valuePointSensitivity_fixing() { SimplePriceIndexValues test = SimplePriceIndexValues.of(US_CPI_U, VAL_DATE, CURVE_NOFIX, USCPI_TS); PriceIndexObservation obs = PriceIndexObservation.of(US_CPI_U, VAL_MONTH.minusMonths(3)); assertEquals(test.valuePointSensitivity(obs), PointSensitivityBuilder.none()); }
//------------------------------------------------------------------------- public virtual void test_rateSensitivity() { ImmutableRatesProvider prov = createProvider(RATE_START, RATE_START_INTERP, RATE_END, RATE_END_INTERP); ImmutableRatesProvider provSrtUp = createProvider(RATE_START + EPS_FD, RATE_START_INTERP, RATE_END, RATE_END_INTERP); ImmutableRatesProvider provSrtDw = createProvider(RATE_START - EPS_FD, RATE_START_INTERP, RATE_END, RATE_END_INTERP); ImmutableRatesProvider provSrtIntUp = createProvider(RATE_START, RATE_START_INTERP + EPS_FD, RATE_END, RATE_END_INTERP); ImmutableRatesProvider provSrtIntDw = createProvider(RATE_START, RATE_START_INTERP - EPS_FD, RATE_END, RATE_END_INTERP); ImmutableRatesProvider provEndUp = createProvider(RATE_START, RATE_START_INTERP, RATE_END + EPS_FD, RATE_END_INTERP); ImmutableRatesProvider provEndDw = createProvider(RATE_START, RATE_START_INTERP, RATE_END - EPS_FD, RATE_END_INTERP); ImmutableRatesProvider provEndIntUp = createProvider(RATE_START, RATE_START_INTERP, RATE_END, RATE_END_INTERP + EPS_FD); ImmutableRatesProvider provEndIntDw = createProvider(RATE_START, RATE_START_INTERP, RATE_END, RATE_END_INTERP - EPS_FD); InflationInterpolatedRateComputation ro = InflationInterpolatedRateComputation.of(GB_RPIX, REF_START_MONTH, REF_END_MONTH, WEIGHT); ForwardInflationInterpolatedRateComputationFn obsFn = ForwardInflationInterpolatedRateComputationFn.DEFAULT; double rateSrtUp = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provSrtUp); double rateSrtDw = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provSrtDw); double rateSrtIntUp = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provSrtIntUp); double rateSrtIntDw = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provSrtIntDw); double rateEndUp = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provEndUp); double rateEndDw = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provEndDw); double rateEndIntUp = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provEndIntUp); double rateEndIntDw = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, provEndIntDw); PointSensitivityBuilder sensSrt = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPIX, REF_START_MONTH), 0.5 * (rateSrtUp - rateSrtDw) / EPS_FD); PointSensitivityBuilder sensSrtInt = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPIX, REF_START_MONTH_INTERP), 0.5 * (rateSrtIntUp - rateSrtIntDw) / EPS_FD); PointSensitivityBuilder sensEnd = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPIX, REF_END_MONTH), 0.5 * (rateEndUp - rateEndDw) / EPS_FD); PointSensitivityBuilder sensEndInt = InflationRateSensitivity.of(PriceIndexObservation.of(GB_RPIX, REF_END_MONTH_INTERP), 0.5 * (rateEndIntUp - rateEndIntDw) / EPS_FD); PointSensitivityBuilder sensiExpected = sensSrt.combinedWith(sensSrtInt).combinedWith(sensEnd).combinedWith(sensEndInt); PointSensitivityBuilder sensiComputed = obsFn.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov); assertTrue(sensiComputed.build().normalized().equalWithTolerance(sensiExpected.build().normalized(), EPS_FD)); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivity() { for (int i = 0; i < NB_STRIKES; ++i) { ResolvedFxVanillaOption option = CALLS[i]; PointSensitivityBuilder point = PRICER.presentValueSensitivityRatesStickyStrike(option, RATES_PROVIDER, VOLS); CurrencyParameterSensitivities sensiComputed = RATES_PROVIDER.parameterSensitivity(point.build()); double timeToExpiry = VOLS.relativeTime(EXPIRY); double forwardRate = FX_PRICER.forwardFxRate(UNDERLYING[i], RATES_PROVIDER).fxRate(CURRENCY_PAIR); double strikeRate = option.Strike; SmileDeltaParameters smileAtTime = VOLS.Smile.smileForExpiry(timeToExpiry); double[] vols = smileAtTime.Volatility.toArray(); double df = RATES_PROVIDER.discountFactor(USD, PAY); CurrencyParameterSensitivities sensiExpected = FD_CAL.sensitivity(RATES_PROVIDER, p => PRICER.presentValue(option, p, VOLS)); CurrencyParameterSensitivities sensiRes = FD_CAL.sensitivity(RATES_PROVIDER, (ImmutableRatesProvider p) => { double fwd = FX_PRICER.forwardFxRate(option.Underlying, p).fxRate(CURRENCY_PAIR); double[] strs = smileAtTime.strike(fwd).toArray(); double[] wghts = weights(fwd, strikeRate, strs, timeToExpiry, vols[1]); double res = 0d; for (int j = 0; j < 3; ++j) { res += wghts[j] * (BlackFormulaRepository.price(forwardRate, strs[j], timeToExpiry, vols[j], true) - BlackFormulaRepository.price(forwardRate, strs[j], timeToExpiry, vols[1], true)); } return(CurrencyAmount.of(USD, -res * df * NOTIONAL)); }); assertTrue(sensiComputed.equalWithTolerance(sensiExpected.combinedWith(sensiRes), FD_EPS * NOTIONAL * 10d)); } }
public virtual PointSensitivityBuilder forecastValueSensitivity(RatePaymentPeriod period, RatesProvider provider) { // historic payments have zero sensi if (period.PaymentDate.isBefore(provider.ValuationDate)) { return(PointSensitivityBuilder.none()); } PointSensitivityBuilder sensiFx = fxRateSensitivity(period, provider); double accrual = accrualWithNotional(period, period.Notional, provider); sensiFx = sensiFx.multipliedBy(accrual); PointSensitivityBuilder sensiAccrual = PointSensitivityBuilder.none(); if (period.CompoundingApplicable) { sensiAccrual = accrueCompoundedSensitivity(period, provider); } else { sensiAccrual = unitNotionalSensitivityNoCompounding(period, provider); } double notional = period.Notional * fxRate(period, provider); sensiAccrual = sensiAccrual.multipliedBy(notional); return(sensiFx.combinedWith(sensiAccrual)); }
//------------------------------------------------------------------------- public virtual void test_cashFlowEquivalentAndSensitivity() { ResolvedSwap swap = ResolvedSwap.of(IBOR_LEG, FIXED_LEG); ImmutableMap <Payment, PointSensitivityBuilder> computedFull = CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivitySwap(swap, PROVIDER); ImmutableList <Payment> keyComputedFull = computedFull.Keys.asList(); ImmutableList <PointSensitivityBuilder> valueComputedFull = computedFull.values().asList(); ImmutableMap <Payment, PointSensitivityBuilder> computedIborLeg = CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityIborLeg(IBOR_LEG, PROVIDER); ImmutableMap <Payment, PointSensitivityBuilder> computedFixedLeg = CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityFixedLeg(FIXED_LEG, PROVIDER); assertEquals(computedFixedLeg.Keys.asList(), keyComputedFull.subList(0, 2)); assertEquals(computedIborLeg.Keys.asList(), keyComputedFull.subList(2, 6)); assertEquals(computedFixedLeg.values().asList(), valueComputedFull.subList(0, 2)); assertEquals(computedIborLeg.values().asList(), valueComputedFull.subList(2, 6)); double eps = 1.0e-7; RatesFiniteDifferenceSensitivityCalculator calc = new RatesFiniteDifferenceSensitivityCalculator(eps); int size = keyComputedFull.size(); for (int i = 0; i < size; ++i) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int index = i; int index = i; CurrencyParameterSensitivities expected = calc.sensitivity(PROVIDER, p => ((NotionalExchange)CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, p).PaymentEvents.get(index)).PaymentAmount); SwapPaymentEvent @event = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, PROVIDER).PaymentEvents.get(index); PointSensitivityBuilder point = computedFull.get(((NotionalExchange)@event).Payment); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point.build()); assertTrue(computed.equalWithTolerance(expected, eps * NOTIONAL)); } }
public virtual PointSensitivityBuilder rateSensitivity(InflationEndInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { PriceIndexValues values = provider.priceIndexValues(computation.Index); PointSensitivityBuilder sensi = endSensitivity(computation, values); return(sensi.multipliedBy(1d / computation.StartIndexValue)); }
public virtual void test_rateSensitivity_finiteDifference() { double eps = 1.0e-7; RatesProvider mockProv = mock(typeof(RatesProvider)); IborIndexRates mockRates3M = mock(typeof(IborIndexRates)); IborIndexRates mockRates6M = mock(typeof(IborIndexRates)); when(mockProv.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRates3M); when(mockProv.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRates6M); when(mockRates3M.rate(GBP_LIBOR_3M_OBS)).thenReturn(RATE3); when(mockRates6M.rate(GBP_LIBOR_6M_OBS)).thenReturn(RATE6); when(mockRates3M.ratePointSensitivity(GBP_LIBOR_3M_OBS)).thenReturn(SENSITIVITY3); when(mockRates6M.ratePointSensitivity(GBP_LIBOR_6M_OBS)).thenReturn(SENSITIVITY6); IborInterpolatedRateComputation ro = IborInterpolatedRateComputation.of(GBP_LIBOR_3M, GBP_LIBOR_6M, FIXING_DATE, REF_DATA); ForwardIborInterpolatedRateComputationFn obs = ForwardIborInterpolatedRateComputationFn.DEFAULT; PointSensitivityBuilder test = obs.rateSensitivity(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProv); IborIndexRates mockRatesUp3M = mock(typeof(IborIndexRates)); when(mockRatesUp3M.rate(GBP_LIBOR_3M_OBS)).thenReturn(RATE3 + eps); IborIndexRates mockRatesDw3M = mock(typeof(IborIndexRates)); when(mockRatesDw3M.rate(GBP_LIBOR_3M_OBS)).thenReturn(RATE3 - eps); IborIndexRates mockRatesUp6M = mock(typeof(IborIndexRates)); when(mockRatesUp6M.rate(GBP_LIBOR_6M_OBS)).thenReturn(RATE6 + eps); IborIndexRates mockRatesDw6M = mock(typeof(IborIndexRates)); when(mockRatesDw6M.rate(GBP_LIBOR_6M_OBS)).thenReturn(RATE6 - eps); RatesProvider mockProvUp3M = mock(typeof(RatesProvider)); when(mockProvUp3M.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRatesUp3M); when(mockProvUp3M.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRates6M); RatesProvider mockProvDw3M = mock(typeof(RatesProvider)); when(mockProvDw3M.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRatesDw3M); when(mockProvDw3M.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRates6M); RatesProvider mockProvUp6M = mock(typeof(RatesProvider)); when(mockProvUp6M.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRates3M); when(mockProvUp6M.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRatesUp6M); RatesProvider mockProvDw6M = mock(typeof(RatesProvider)); when(mockProvDw6M.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRates3M); when(mockProvDw6M.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRatesDw6M); double rateUp3M = obs.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProvUp3M); double rateDw3M = obs.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProvDw3M); double senseExpected3M = 0.5 * (rateUp3M - rateDw3M) / eps; double rateUp6M = obs.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProvUp6M); double rateDw6M = obs.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProvDw6M); double senseExpected6M = 0.5 * (rateUp6M - rateDw6M) / eps; assertEquals(test.build().Sensitivities.get(0).Sensitivity, senseExpected3M, eps); assertEquals(test.build().Sensitivities.get(1).Sensitivity, senseExpected6M, eps); }
/// <summary> /// Calculates the present value sensitivity of the bond trade with z-spread. /// <para> /// The present value sensitivity of the trade is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="discountingProvider"> the discount factors provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value sensitivity of the bond trade </returns> public virtual PointSensitivities presentValueSensitivityWithZSpread(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = this.settlementDate(trade, ratesProvider.ValuationDate); PointSensitivityBuilder productSensi = productPricer.presentValueSensitivityWithZSpread(trade.Product, ratesProvider, discountingProvider, settlementDate, zSpread, compoundedRateType, periodsPerYear); return(presentValueSensitivityFromProductPresentValueSensitivity(trade, ratesProvider, discountingProvider, productSensi).build()); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the bond trade. /// <para> /// The present value sensitivity of the trade is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="discountingProvider"> the discount factors provider </param> /// <returns> the present value sensitivity of the bond trade </returns> public virtual PointSensitivities presentValueSensitivity(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = this.settlementDate(trade, ratesProvider.ValuationDate); PointSensitivityBuilder productSensi = productPricer.presentValueSensitivity(trade.Product, ratesProvider, discountingProvider, settlementDate); return(presentValueSensitivityFromProductPresentValueSensitivity(trade, ratesProvider, discountingProvider, productSensi).build()); }
public virtual void test_combinedWith_mutable() { FxForwardSensitivity @base = FxForwardSensitivity.of(CURRENCY_PAIR, GBP, REFERENCE_DATE, SENSITIVITY); MutablePointSensitivities expected = new MutablePointSensitivities(); expected.add(@base); PointSensitivityBuilder test = @base.combinedWith(new MutablePointSensitivities()); assertEquals(test, expected); }
// interpolate the observations at the end private PointSensitivityBuilder endSensitivity(InflationInterpolatedRateComputation computation, PriceIndexValues values) { double weight = computation.Weight; PointSensitivityBuilder sensi1 = values.valuePointSensitivity(computation.EndObservation).multipliedBy(weight); PointSensitivityBuilder sensi2 = values.valuePointSensitivity(computation.EndSecondObservation).multipliedBy(1d - weight); return(sensi1.combinedWith(sensi2)); }
public virtual void test_presentValueSensitivityVolatility_afterFix() { PointSensitivityBuilder computedCaplet = PRICER.presentValueSensitivityModelParamsVolatility(CAPLET_LONG, RATES_AFTER_FIX, VOLS_AFTER_FIX); PointSensitivityBuilder computedFloorlet = PRICER.presentValueSensitivityModelParamsVolatility(FLOORLET_SHORT, RATES_AFTER_FIX, VOLS_AFTER_FIX); assertEquals(computedCaplet, PointSensitivityBuilder.none()); assertEquals(computedFloorlet, PointSensitivityBuilder.none()); }
public virtual void test_presentValueSensitivity_afterPay() { PointSensitivityBuilder computedCaplet = PRICER.presentValueSensitivityRates(CAPLET_LONG, RATES_AFTER_PAY, VOLS_AFTER_PAY); PointSensitivityBuilder computedFloorlet = PRICER.presentValueSensitivityRates(FLOORLET_SHORT, RATES_AFTER_PAY, VOLS_AFTER_PAY); assertEquals(computedCaplet, PointSensitivityBuilder.none()); assertEquals(computedFloorlet, PointSensitivityBuilder.none()); }
/// <summary> /// Compute the present value curve sensitivity of the payment. /// <para> /// The present value sensitivity of the payment is the sensitivity of the /// present value to the discount factor curve. /// There is no sensitivity if the payment date is before the valuation date. /// </para> /// <para> /// The specified discount factors should be for the payment currency, however this is not validated. /// /// </para> /// </summary> /// <param name="payment"> the payment </param> /// <param name="discountFactors"> the discount factors to price against </param> /// <returns> the point sensitivity of the present value </returns> public virtual PointSensitivityBuilder presentValueSensitivity(Payment payment, DiscountFactors discountFactors) { if (discountFactors.ValuationDate.isAfter(payment.Date)) { return(PointSensitivityBuilder.none()); } return(discountFactors.zeroRatePointSensitivity(payment.Date).multipliedBy(payment.Amount)); }