public virtual void test_rate() { SimpleRatesProvider prov = new SimpleRatesProvider(); LocalDateDoubleTimeSeries timeSeries = LocalDateDoubleTimeSeries.of(FIXING_DATE, RATE); IborIndexRates mockIbor = new TestingIborIndexRates(GBP_LIBOR_3M, FIXING_DATE, LocalDateDoubleTimeSeries.empty(), timeSeries); prov.IborRates = mockIbor; ForwardIborRateComputationFn obsFn = ForwardIborRateComputationFn.DEFAULT; assertEquals(obsFn.rate(GBP_LIBOR_3M_COMP, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov), RATE); // explain ExplainMapBuilder builder = ExplainMap.builder(); assertEquals(obsFn.explainRate(GBP_LIBOR_3M_COMP, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov, builder), RATE); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().size(), 1); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FIXING_DATE), FIXING_DATE); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.INDEX), GBP_LIBOR_3M); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.INDEX_VALUE), RATE); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FROM_FIXING_SERIES), true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FORWARD_RATE_START_DATE), FORWARD_START_DATE); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FORWARD_RATE_END_DATE), FORWARD_END_DATE); assertEquals(built.get(ExplainKey.COMBINED_RATE), RATE); }
public virtual void test_explainPresentValue_inPast() { RatesProvider prov = createProvider(VAL_DATE); ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PERIOD_PAST, prov, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "KnownAmountPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_PAST.PaymentDate); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_PAST.Currency); int daysBetween = (int)DAYS.between(DATE_1, DATE_2); assertEquals(explain.get(ExplainKey.START_DATE).get(), PERIOD_PAST.StartDate); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), PERIOD_PAST.UnadjustedStartDate); assertEquals(explain.get(ExplainKey.END_DATE).get(), PERIOD_PAST.EndDate); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), PERIOD_PAST.UnadjustedEndDate); assertEquals(explain.get(ExplainKey.DAYS).Value, (int?)daysBetween); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, PERIOD_PAST.Currency); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0, TOLERANCE_PV); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, PERIOD_PAST.Currency); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0 * DISCOUNT_FACTOR, TOLERANCE_PV); }
//------------------------------------------------------------------------- public virtual void test_rate() { ImmutableRatesProvider prov = createProvider(RATE_END, RATE_END_INTERP); InflationEndInterpolatedRateComputation ro = InflationEndInterpolatedRateComputation.of(GB_RPIX, START_INDEX_VALUE, REF_END_MONTH, WEIGHT); ForwardInflationEndInterpolatedRateComputationFn obsFn = ForwardInflationEndInterpolatedRateComputationFn.DEFAULT; // rate double rateExpected = (WEIGHT * RATE_END + (1.0 - WEIGHT) * RATE_END_INTERP) / START_INDEX_VALUE - 1; assertEquals(obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov), rateExpected, EPS); // explain ExplainMapBuilder builder = ExplainMap.builder(); assertEquals(obsFn.explainRate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov, builder), rateExpected, EPS); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().size(), 2); ExplainMap explain0 = built.get(ExplainKey.OBSERVATIONS).get().get(0); assertEquals(explain0.get(ExplainKey.FIXING_DATE), REF_END_MONTH.atEndOfMonth()); assertEquals(explain0.get(ExplainKey.INDEX), GB_RPIX); assertEquals(explain0.get(ExplainKey.INDEX_VALUE), RATE_END); assertEquals(explain0.get(ExplainKey.WEIGHT), WEIGHT); ExplainMap explain1 = built.get(ExplainKey.OBSERVATIONS).get().get(1); assertEquals(explain1.get(ExplainKey.FIXING_DATE), REF_END_MONTH_INTERP.atEndOfMonth()); assertEquals(explain1.get(ExplainKey.INDEX), GB_RPIX); assertEquals(explain1.get(ExplainKey.INDEX_VALUE), RATE_END_INTERP); assertEquals(explain1.get(ExplainKey.WEIGHT), (1d - WEIGHT)); assertEquals(built.get(ExplainKey.COMBINED_RATE).Value.doubleValue(), rateExpected, EPS); }
//------------------------------------------------------------------------- /// <summary> /// Explains the present value of the FRA product. /// <para> /// This returns explanatory information about the calculation. /// /// </para> /// </summary> /// <param name="fra"> the FRA product for which present value should be computed </param> /// <param name="provider"> the rates provider </param> /// <returns> the explanatory information </returns> public virtual ExplainMap explainPresentValue(ResolvedFra fra, RatesProvider provider) { ExplainMapBuilder builder = ExplainMap.builder(); Currency currency = fra.Currency; builder.put(ExplainKey.ENTRY_TYPE, "FRA"); builder.put(ExplainKey.PAYMENT_DATE, fra.PaymentDate); builder.put(ExplainKey.START_DATE, fra.StartDate); builder.put(ExplainKey.END_DATE, fra.EndDate); builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, fra.YearFraction); builder.put(ExplainKey.DAYS, (int)DAYS.between(fra.StartDate, fra.EndDate)); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.NOTIONAL, CurrencyAmount.of(currency, fra.Notional)); builder.put(ExplainKey.TRADE_NOTIONAL, CurrencyAmount.of(currency, fra.Notional)); if (fra.PaymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { double rate = rateComputationFn.explainRate(fra.FloatingRate, fra.StartDate, fra.EndDate, provider, builder); builder.put(ExplainKey.FIXED_RATE, fra.FixedRate); builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, fra.PaymentDate)); builder.put(ExplainKey.PAY_OFF_RATE, rate); builder.put(ExplainKey.UNIT_AMOUNT, unitAmount(fra, provider)); builder.put(ExplainKey.FORECAST_VALUE, forecastValue(fra, provider)); builder.put(ExplainKey.PRESENT_VALUE, presentValue(fra, provider)); } return(builder.build()); }
//------------------------------------------------------------------------- public virtual void test_rate() { ImmutableRatesProvider prov = createProvider(RATE_START, RATE_END); InflationMonthlyRateComputation ro = InflationMonthlyRateComputation.of(GB_RPIX, REFERENCE_START_MONTH, REFERENCE_END_MONTH); ForwardInflationMonthlyRateComputationFn obsFn = ForwardInflationMonthlyRateComputationFn.DEFAULT; double rateExpected = RATE_END / RATE_START - 1.0; assertEquals(obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov), rateExpected, EPS); // explain ExplainMapBuilder builder = ExplainMap.builder(); assertEquals(obsFn.explainRate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov, builder), rateExpected, EPS); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().size(), 2); ExplainMap explain0 = built.get(ExplainKey.OBSERVATIONS).get().get(0); assertEquals(explain0.get(ExplainKey.FIXING_DATE), REFERENCE_START_MONTH.atEndOfMonth()); assertEquals(explain0.get(ExplainKey.INDEX), GB_RPIX); assertEquals(explain0.get(ExplainKey.INDEX_VALUE), RATE_START); ExplainMap explain1 = built.get(ExplainKey.OBSERVATIONS).get().get(1); assertEquals(explain1.get(ExplainKey.FIXING_DATE), REFERENCE_END_MONTH.atEndOfMonth()); assertEquals(explain1.get(ExplainKey.INDEX), GB_RPIX); assertEquals(explain1.get(ExplainKey.INDEX_VALUE), RATE_END); assertEquals(built.get(ExplainKey.COMBINED_RATE).Value.doubleValue(), rateExpected, EPS); }
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); }
// common parts of explain private void explainBasics(FixedCouponBondPaymentPeriod period, ExplainMapBuilder builder, Currency currency, LocalDate paymentDate) { builder.put(ExplainKey.ENTRY_TYPE, "FixedCouponBondPaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.START_DATE, period.StartDate); builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate); builder.put(ExplainKey.END_DATE, period.EndDate); builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate); builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, period.YearFraction); builder.put(ExplainKey.DAYS, (int)DAYS.between(period.StartDate, period.EndDate)); }
//------------------------------------------------------------------------- public virtual void coverage() { DispatchingSwapPaymentPeriodPricer test = new DispatchingSwapPaymentPeriodPricer(MOCK_RATE, MOCK_KNOWN); SwapPaymentPeriod kapp = KnownAmountSwapPaymentPeriod.builder().payment(Payment.of(CurrencyAmount.of(GBP, 1000), date(2015, 8, 21))).startDate(date(2015, 5, 19)).endDate(date(2015, 8, 19)).build(); SwapPaymentPeriod mockPaymentPeriod = mock(typeof(SwapPaymentPeriod)); ignoreThrows(() => test.presentValue(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.presentValue(kapp, MOCK_PROV)); ignoreThrows(() => test.presentValue(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.forecastValue(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.forecastValue(kapp, MOCK_PROV)); ignoreThrows(() => test.forecastValue(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.pvbp(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.pvbp(kapp, MOCK_PROV)); ignoreThrows(() => test.pvbp(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.presentValueSensitivity(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.presentValueSensitivity(kapp, MOCK_PROV)); ignoreThrows(() => test.presentValueSensitivity(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.forecastValueSensitivity(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.forecastValueSensitivity(kapp, MOCK_PROV)); ignoreThrows(() => test.forecastValueSensitivity(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.pvbpSensitivity(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.pvbpSensitivity(kapp, MOCK_PROV)); ignoreThrows(() => test.pvbpSensitivity(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.accruedInterest(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.accruedInterest(kapp, MOCK_PROV)); ignoreThrows(() => test.accruedInterest(mockPaymentPeriod, MOCK_PROV)); ExplainMapBuilder explain = ExplainMap.builder(); ignoreThrows(() => test.explainPresentValue(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV, explain)); ignoreThrows(() => test.explainPresentValue(kapp, MOCK_PROV, explain)); ignoreThrows(() => test.explainPresentValue(mockPaymentPeriod, MOCK_PROV, explain)); ignoreThrows(() => test.currencyExposure(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.currencyExposure(kapp, MOCK_PROV)); ignoreThrows(() => test.currencyExposure(mockPaymentPeriod, MOCK_PROV)); ignoreThrows(() => test.currentCash(SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV)); ignoreThrows(() => test.currentCash(kapp, MOCK_PROV)); ignoreThrows(() => test.currentCash(mockPaymentPeriod, MOCK_PROV)); }
//------------------------------------------------------------------------- /// <summary> /// Explains the present value of a CMS leg. /// <para> /// This returns explanatory information about the calculation. /// /// </para> /// </summary> /// <param name="cmsLeg"> the CMS leg </param> /// <param name="provider"> the rates provider </param> /// <param name="volatilities"> the swaption volatilities </param> /// <returns> the explanatory information </returns> public virtual ExplainMap explainPresentValue(ResolvedCmsLeg cmsLeg, RatesProvider provider, SabrSwaptionVolatilities volatilities) { ExplainMapBuilder builder = ExplainMap.builder(); builder.put(ExplainKey.ENTRY_TYPE, "CmsLeg"); builder.put(ExplainKey.PAY_RECEIVE, cmsLeg.PayReceive); builder.put(ExplainKey.PAYMENT_CURRENCY, cmsLeg.Currency); builder.put(ExplainKey.START_DATE, cmsLeg.StartDate); builder.put(ExplainKey.END_DATE, cmsLeg.EndDate); builder.put(ExplainKey.INDEX, cmsLeg.Index); foreach (CmsPeriod period in cmsLeg.CmsPeriods) { builder.addListEntry(ExplainKey.PAYMENT_PERIODS, child => cmsPeriodPricer.explainPresentValue(period, provider, volatilities, child)); } builder.put(ExplainKey.PRESENT_VALUE, presentValue(cmsLeg, provider, volatilities)); return(builder.build()); }
public virtual void test_rate() { RatesProvider mockProv = mock(typeof(RatesProvider)); LocalDateDoubleTimeSeries timeSeries = LocalDateDoubleTimeSeries.of(FIXING_DATE, RATE3TS); IborIndexRates mockRates3M = new TestingIborIndexRates(GBP_LIBOR_3M, FIXING_DATE, LocalDateDoubleTimeSeries.empty(), timeSeries); IborIndexRates mockRates6M = new TestingIborIndexRates(GBP_LIBOR_6M, FIXING_DATE, LocalDateDoubleTimeSeries.of(FIXING_DATE, RATE6), LocalDateDoubleTimeSeries.empty()); when(mockProv.iborIndexRates(GBP_LIBOR_3M)).thenReturn(mockRates3M); when(mockProv.iborIndexRates(GBP_LIBOR_6M)).thenReturn(mockRates6M); IborInterpolatedRateComputation ro = IborInterpolatedRateComputation.of(GBP_LIBOR_3M, GBP_LIBOR_6M, FIXING_DATE, REF_DATA); ForwardIborInterpolatedRateComputationFn obs = 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); double rateExpected = (weight3M * RATE3TS + weight6M * RATE6); double rateComputed = obs.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProv); assertEquals(rateComputed, rateExpected, TOLERANCE_RATE); // explain ExplainMapBuilder builder = ExplainMap.builder(); assertEquals(obs.explainRate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, mockProv, builder), rateExpected, TOLERANCE_RATE); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().size(), 2); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FIXING_DATE), FIXING_DATE); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.INDEX), GBP_LIBOR_3M); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.INDEX_VALUE), RATE3TS); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.WEIGHT), weight3M); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(0).get(ExplainKey.FROM_FIXING_SERIES), true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(1).get(ExplainKey.FIXING_DATE), FIXING_DATE); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(1).get(ExplainKey.INDEX), GBP_LIBOR_6M); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(1).get(ExplainKey.INDEX_VALUE), RATE6); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(1).get(ExplainKey.WEIGHT), weight6M); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().get(1).get(ExplainKey.FROM_FIXING_SERIES), null); assertEquals(built.get(ExplainKey.COMBINED_RATE), rateExpected); }
public virtual void test_explainPresentValueWithZSpread_past() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValueWithZSpread(PERIOD_INTERP, IRP_AFTER_PAY, ICDF_AFTER_PAY, builder, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.PaymentDate); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.Currency); assertEquals(explain.get(ExplainKey.START_DATE).get(), START); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ); assertEquals(explain.get(ExplainKey.END_DATE).get(), END); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ); assertEquals(explain.get(ExplainKey.DAYS).Value.intValue(), (int)DAYS.between(START_UNADJ, END_UNADJ)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0d, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0d, NOTIONAL * TOL); }
//------------------------------------------------------------------------- public virtual void test_explainPresentValue() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.PaymentDate); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.Currency); assertEquals(explain.get(ExplainKey.START_DATE).get(), START); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ); assertEquals(explain.get(ExplainKey.END_DATE).get(), END); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ); assertEquals(explain.get(ExplainKey.DAYS).Value.intValue(), (int)DAYS.between(START_UNADJ, END_UNADJ)); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).Value, ICDF_BEFORE_START.discountFactor(END)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, PRICER.forecastValue(PERIOD_INTERP, IRP_BEFORE_START), NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, PRICER.presentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START), NOTIONAL * TOL); }
/// <summary> /// Explains the present value of the payment. /// <para> /// This returns explanatory information about the calculation. /// /// </para> /// </summary> /// <param name="payment"> the payment </param> /// <param name="provider"> the provider </param> /// <returns> the explanatory information </returns> public virtual ExplainMap explainPresentValue(Payment payment, BaseProvider provider) { Currency currency = payment.Currency; LocalDate paymentDate = payment.Date; ExplainMapBuilder builder = ExplainMap.builder(); builder.put(ExplainKey.ENTRY_TYPE, "Payment"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); if (paymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, forecastValue(payment, provider)); builder.put(ExplainKey.PRESENT_VALUE, presentValue(payment, provider)); } return(builder.build()); }
public virtual double explainRate(InflationInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { PriceIndexValues values = provider.priceIndexValues(computation.Index); double w1 = computation.Weight; double w2 = 1d - w1; builder.addListEntry(ExplainKey.OBSERVATIONS, child => child.put(ExplainKey.ENTRY_TYPE, "InflationObservation").put(ExplainKey.FIXING_DATE, computation.StartObservation.FixingMonth.atEndOfMonth()).put(ExplainKey.INDEX, computation.Index).put(ExplainKey.INDEX_VALUE, values.value(computation.StartObservation)).put(ExplainKey.WEIGHT, w1)); builder.addListEntry(ExplainKey.OBSERVATIONS, child => child.put(ExplainKey.ENTRY_TYPE, "InflationObservation").put(ExplainKey.FIXING_DATE, computation.StartSecondObservation.FixingMonth.atEndOfMonth()).put(ExplainKey.INDEX, computation.Index).put(ExplainKey.INDEX_VALUE, values.value(computation.StartSecondObservation)).put(ExplainKey.WEIGHT, w2)); builder.addListEntry(ExplainKey.OBSERVATIONS, child => child.put(ExplainKey.ENTRY_TYPE, "InflationObservation").put(ExplainKey.FIXING_DATE, computation.EndObservation.FixingMonth.atEndOfMonth()).put(ExplainKey.INDEX, computation.Index).put(ExplainKey.INDEX_VALUE, values.value(computation.EndObservation)).put(ExplainKey.WEIGHT, w1)); builder.addListEntry(ExplainKey.OBSERVATIONS, child => child.put(ExplainKey.ENTRY_TYPE, "InflationObservation").put(ExplainKey.FIXING_DATE, computation.EndSecondObservation.FixingMonth.atEndOfMonth()).put(ExplainKey.INDEX, computation.Index).put(ExplainKey.INDEX_VALUE, values.value(computation.EndSecondObservation)).put(ExplainKey.WEIGHT, w2)); double rate = this.rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
// explain PV for an accrual period, ignoring compounding private void explainPresentValue(RateAccrualPeriod accrualPeriod, DayCount dayCount, Currency currency, double notional, RatesProvider provider, ExplainMapBuilder builder) { double rawRate = rateComputationFn.explainRate(accrualPeriod.RateComputation, accrualPeriod.StartDate, accrualPeriod.EndDate, provider, builder); double payOffRate = rawRate * accrualPeriod.Gearing + accrualPeriod.Spread; double ua = unitNotionalAccrual(accrualPeriod, accrualPeriod.Spread, provider); // Note that the forecast value is not published since this is potentially misleading when // compounding is being applied, and when it isn't then it's the same as the forecast // value of the payment period. builder.put(ExplainKey.ENTRY_TYPE, "AccrualPeriod"); builder.put(ExplainKey.START_DATE, accrualPeriod.StartDate); builder.put(ExplainKey.UNADJUSTED_START_DATE, accrualPeriod.UnadjustedStartDate); builder.put(ExplainKey.END_DATE, accrualPeriod.EndDate); builder.put(ExplainKey.UNADJUSTED_END_DATE, accrualPeriod.UnadjustedEndDate); builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, accrualPeriod.YearFraction); builder.put(ExplainKey.ACCRUAL_DAYS, dayCount.days(accrualPeriod.StartDate, accrualPeriod.EndDate)); builder.put(ExplainKey.DAYS, (int)DAYS.between(accrualPeriod.StartDate, accrualPeriod.EndDate)); builder.put(ExplainKey.GEARING, accrualPeriod.Gearing); builder.put(ExplainKey.SPREAD, accrualPeriod.Spread); builder.put(ExplainKey.PAY_OFF_RATE, accrualPeriod.NegativeRateMethod.adjust(payOffRate)); builder.put(ExplainKey.UNIT_AMOUNT, ua); }
//------------------------------------------------------------------------- public virtual void explainPresentValue(RatePaymentPeriod paymentPeriod, RatesProvider provider, ExplainMapBuilder builder) { Currency currency = paymentPeriod.Currency; LocalDate paymentDate = paymentPeriod.PaymentDate; double fxRate = this.fxRate(paymentPeriod, provider); double notional = paymentPeriod.Notional * fxRate; builder.put(ExplainKey.ENTRY_TYPE, "RatePaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.NOTIONAL, CurrencyAmount.of(currency, notional)); builder.put(ExplainKey.TRADE_NOTIONAL, paymentPeriod.NotionalAmount); if (paymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { paymentPeriod.FxReset.ifPresent(fxReset => { builder.addListEntry(ExplainKey.OBSERVATIONS, child => { child.put(ExplainKey.ENTRY_TYPE, "FxObservation"); child.put(ExplainKey.INDEX, fxReset.Observation.Index); child.put(ExplainKey.FIXING_DATE, fxReset.Observation.FixingDate); child.put(ExplainKey.INDEX_VALUE, fxRate); }); }); foreach (RateAccrualPeriod accrualPeriod in paymentPeriod.AccrualPeriods) { builder.addListEntry(ExplainKey.ACCRUAL_PERIODS, child => explainPresentValue(accrualPeriod, paymentPeriod.DayCount, currency, notional, provider, child)); } builder.put(ExplainKey.COMPOUNDING, paymentPeriod.CompoundingMethod); builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(paymentPeriod, provider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(paymentPeriod, provider))); } }
public virtual double explainRate(OvernightAveragedDailyRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { double rate = this.rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
/// <summary> /// Explains the present value of a single payment period with z-spread. /// <para> /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="issuerDiscountFactors"> the discount factor 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="builder"> the builder to populate </param> public virtual void explainPresentValueWithZSpread(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, ExplainMapBuilder builder, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { Currency currency = period.Currency; LocalDate paymentDate = period.PaymentDate; builder.put(ExplainKey.ENTRY_TYPE, "CapitalIndexedBondPaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.START_DATE, period.StartDate); builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate); builder.put(ExplainKey.END_DATE, period.EndDate); builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate); builder.put(ExplainKey.DAYS, (int)DAYS.between(period.UnadjustedStartDate, period.UnadjustedEndDate)); if (paymentDate.isBefore(ratesProvider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, issuerDiscountFactors.discountFactor(paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, ratesProvider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValueWithZSpread(period, ratesProvider, issuerDiscountFactors, zSpread, compoundedRateType, periodsPerYear))); } }
//------------------------------------------------------------------------- public virtual void explainPresentValue(NotionalExchange @event, RatesProvider provider, ExplainMapBuilder builder) { Currency currency = @event.Currency; LocalDate paymentDate = @event.PaymentDate; builder.put(ExplainKey.ENTRY_TYPE, "NotionalExchange"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.TRADE_NOTIONAL, @event.PaymentAmount); if (paymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(@event, provider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(@event, provider))); } }
//------------------------------------------------------------------------- public virtual void explainPresentValue(FxResetNotionalExchange @event, RatesProvider provider, ExplainMapBuilder builder) { Currency currency = @event.Currency; LocalDate paymentDate = @event.PaymentDate; builder.put(ExplainKey.ENTRY_TYPE, "FxResetNotionalExchange"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.TRADE_NOTIONAL, @event.NotionalAmount); if (paymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.addListEntry(ExplainKey.OBSERVATIONS, child => { child.put(ExplainKey.ENTRY_TYPE, "FxObservation"); child.put(ExplainKey.INDEX, @event.Observation.Index); child.put(ExplainKey.FIXING_DATE, @event.Observation.FixingDate); child.put(ExplainKey.INDEX_VALUE, fxRate(@event, provider)); }); builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(@event, provider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(@event, provider))); } }
public virtual double explainRate(InflationEndMonthRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { PriceIndexValues values = provider.priceIndexValues(computation.Index); double indexEnd = values.value(computation.EndObservation); builder.addListEntry(ExplainKey.OBSERVATIONS, child => child.put(ExplainKey.ENTRY_TYPE, "InflationObservation").put(ExplainKey.FIXING_DATE, computation.EndObservation.FixingMonth.atEndOfMonth()).put(ExplainKey.INDEX, computation.Index).put(ExplainKey.INDEX_VALUE, indexEnd)); double rate = this.rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
//------------------------------------------------------------------------- public virtual void explainPresentValue(SwapPaymentPeriod paymentPeriod, RatesProvider provider, ExplainMapBuilder builder) { // dispatch by runtime type if (paymentPeriod is RatePaymentPeriod) { ratePaymentPeriodPricer.explainPresentValue((RatePaymentPeriod)paymentPeriod, provider, builder); } else if (paymentPeriod is KnownAmountSwapPaymentPeriod) { knownAmountPaymentPeriodPricer.explainPresentValue((KnownAmountSwapPaymentPeriod)paymentPeriod, provider, builder); } else { throw new System.ArgumentException("Unknown PaymentEvent type: " + paymentPeriod.GetType().Name); } }
public virtual double explainRate(IborAveragedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { IborIndexRates rates = provider.iborIndexRates(computation.Index); foreach (IborAveragedFixing fixing in computation.Fixings) { rates.explainRate(fixing.Observation, builder, child => child.put(ExplainKey.WEIGHT, fixing.Weight)); } double rate = this.rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
/// <summary> /// Explains the present value of a single fixed coupon payment period with z-spread. /// <para> /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor 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="builder"> the builder to populate </param> public virtual void explainPresentValueWithSpread(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors, ExplainMapBuilder builder, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { Currency currency = period.Currency; LocalDate paymentDate = period.PaymentDate; explainBasics(period, builder, currency, paymentDate); if (paymentDate.isBefore(discountFactors.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, discountFactors.DiscountFactors.discountFactorWithSpread(paymentDate, zSpread, compoundedRateType, periodsPerYear)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, discountFactors))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValueWithSpread(period, discountFactors, zSpread, compoundedRateType, periodsPerYear))); } }
public virtual double explainRate(RateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { // dispatch by runtime type if (computation is FixedRateComputation) { // inline code (performance) avoiding need for FixedRateComputationFn implementation double rate = ((FixedRateComputation)computation).Rate; builder.put(ExplainKey.FIXED_RATE, rate); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); } else if (computation is IborRateComputation) { return(iborRateComputationFn.explainRate((IborRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is IborInterpolatedRateComputation) { return(iborInterpolatedRateComputationFn.explainRate((IborInterpolatedRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is IborAveragedRateComputation) { return(iborAveragedRateComputationFn.explainRate((IborAveragedRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is OvernightAveragedRateComputation) { return(overnightAveragedRateComputationFn.explainRate((OvernightAveragedRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is OvernightCompoundedRateComputation) { return(overnightCompoundedRateComputationFn.explainRate((OvernightCompoundedRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is OvernightAveragedDailyRateComputation) { return(overnightAveragedDailyRateComputationFn.explainRate((OvernightAveragedDailyRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is InflationMonthlyRateComputation) { return(inflationMonthlyRateComputationFn.explainRate((InflationMonthlyRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is InflationInterpolatedRateComputation) { return(inflationInterpolatedRateComputationFn.explainRate((InflationInterpolatedRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is InflationEndMonthRateComputation) { return(inflationEndMonthRateComputationFn.explainRate((InflationEndMonthRateComputation)computation, startDate, endDate, provider, builder)); } else if (computation is InflationEndInterpolatedRateComputation) { return(inflationEndInterpolatedRateComputationFn.explainRate((InflationEndInterpolatedRateComputation)computation, startDate, endDate, provider, builder)); } else { throw new System.ArgumentException("Unknown Rate type: " + computation.GetType().Name); } }
public virtual double explainRate(IborRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { IborIndexRates rates = provider.iborIndexRates(computation.Index); double rate = rates.explainRate(computation.Observation, builder, child => { }); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
//------------------------------------------------------------------------- public virtual void explainPresentValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider, ExplainMapBuilder builder) { Currency currency = period.Currency; LocalDate paymentDate = period.PaymentDate; builder.put(ExplainKey.ENTRY_TYPE, "KnownAmountPaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.START_DATE, period.StartDate); builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate); builder.put(ExplainKey.END_DATE, period.EndDate); builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate); builder.put(ExplainKey.DAYS, (int)DAYS.between(period.StartDate, period.EndDate)); if (paymentDate.isBefore(provider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, provider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(period, provider))); } }
public virtual double explainRate(IborInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { IborIndexObservation obs1 = computation.ShortObservation; IborIndexObservation obs2 = computation.LongObservation; DoublesPair weights = this.weights(obs1, obs2, endDate); IborIndexRates rates1 = provider.iborIndexRates(obs1.Index); IborIndexRates rates2 = provider.iborIndexRates(obs2.Index); rates1.explainRate(obs1, builder, child => child.put(ExplainKey.WEIGHT, weights.First)); rates2.explainRate(obs2, builder, child => child.put(ExplainKey.WEIGHT, weights.Second)); double rate = this.rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return(rate); }
//------------------------------------------------------------------------- public virtual void explainPresentValue(SwapPaymentEvent paymentEvent, RatesProvider provider, ExplainMapBuilder builder) { // dispatch by runtime type if (paymentEvent is NotionalExchange) { notionalExchangePricer.explainPresentValue((NotionalExchange)paymentEvent, provider, builder); } else if (paymentEvent is FxResetNotionalExchange) { fxResetNotionalExchangePricer.explainPresentValue((FxResetNotionalExchange)paymentEvent, provider, builder); } else { throw new System.ArgumentException("Unknown PaymentEvent type: " + paymentEvent.GetType().Name); } }