public virtual void test_explainPresentValue_paymentDateInPast() { SimpleRatesProvider prov = createProvider(FX_RESET_NOTIONAL_EXCHANGE_REC_USD); prov.ValuationDate = VAL_DATE.plusYears(1); DiscountingFxResetNotionalExchangePricer test = new DiscountingFxResetNotionalExchangePricer(); ExplainMapBuilder builder = ExplainMap.builder(); test.explainPresentValue(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov, builder); ExplainMap explain = builder.build(); Currency paymentCurrency = FX_RESET_NOTIONAL_EXCHANGE_REC_USD.Currency; Currency notionalCurrency = FX_RESET_NOTIONAL_EXCHANGE_REC_USD.ReferenceCurrency; double notional = FX_RESET_NOTIONAL_EXCHANGE_REC_USD.Notional; assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FxResetNotionalExchange"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), FX_RESET_NOTIONAL_EXCHANGE_REC_USD.PaymentDate); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), paymentCurrency); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Currency, notionalCurrency); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Amount, notional, TOLERANCE); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, paymentCurrency); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0d, TOLERANCE); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, paymentCurrency); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0d * DISCOUNT_FACTOR, TOLERANCE); }
/// <summary> /// Test present value sensitivity for AFMA FRA discounting method. /// </summary> public virtual void test_presentValueSensitivity_AFMA() { RateComputationFn<RateComputation> mockObs = mock(typeof(RateComputationFn)); DiscountFactors mockDf = mock(typeof(DiscountFactors)); SimpleRatesProvider simpleProv = new SimpleRatesProvider(VAL_DATE, mockDf); ResolvedFra fraExp = RFRA_AFMA; double forwardRate = 0.05; double discountRate = 0.025; double paymentTime = 0.3; double discountFactor = Math.Exp(-discountRate * paymentTime); LocalDate fixingDate = FRA_AFMA.StartDate; IborIndexObservation obs = IborIndexObservation.of(FRA.Index, fixingDate, REF_DATA); PointSensitivityBuilder sens = IborRateSensitivity.of(obs, 1d); when(mockDf.discountFactor(fraExp.PaymentDate)).thenReturn(discountFactor); when(mockDf.zeroRatePointSensitivity(fraExp.PaymentDate)).thenReturn(ZeroRateSensitivity.of(fraExp.Currency, paymentTime, -discountFactor * paymentTime)); when(mockObs.rateSensitivity(fraExp.FloatingRate, fraExp.StartDate, fraExp.EndDate, simpleProv)).thenReturn(sens); when(mockObs.rate(fraExp.FloatingRate, FRA_AFMA.StartDate, FRA_AFMA.EndDate, simpleProv)).thenReturn(forwardRate); DiscountingFraProductPricer test = new DiscountingFraProductPricer(mockObs); PointSensitivities sensitivity = test.presentValueSensitivity(fraExp, simpleProv); double eps = 1.e-7; double fdDscSense = dscSensitivity(RFRA_AFMA, forwardRate, discountFactor, paymentTime, eps); double fdSense = presentValueFwdSensitivity(RFRA_AFMA, forwardRate, discountFactor, eps); ImmutableList<PointSensitivity> sensitivities = sensitivity.Sensitivities; assertEquals(sensitivities.size(), 2); IborRateSensitivity sensitivity0 = (IborRateSensitivity) sensitivities.get(0); assertEquals(sensitivity0.Index, FRA_AFMA.Index); assertEquals(sensitivity0.Observation.FixingDate, fixingDate); assertEquals(sensitivity0.Sensitivity, fdSense, FRA_AFMA.Notional * eps); ZeroRateSensitivity sensitivity1 = (ZeroRateSensitivity) sensitivities.get(1); assertEquals(sensitivity1.Currency, FRA_AFMA.Currency); assertEquals(sensitivity1.YearFraction, paymentTime); assertEquals(sensitivity1.Sensitivity, fdDscSense, FRA_AFMA.Notional * eps); }
public virtual void test_explainPresentValue_paymentDateInPast() { SimpleRatesProvider prov = createProvider(NOTIONAL_EXCHANGE_REC_GBP); prov.ValuationDate = VAL_DATE.plusYears(1); DiscountingNotionalExchangePricer test = DiscountingNotionalExchangePricer.DEFAULT; ExplainMapBuilder builder = ExplainMap.builder(); test.explainPresentValue(NOTIONAL_EXCHANGE_REC_GBP, prov, builder); ExplainMap explain = builder.build(); Currency currency = NOTIONAL_EXCHANGE_REC_GBP.Currency; CurrencyAmount notional = NOTIONAL_EXCHANGE_REC_GBP.PaymentAmount; assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "NotionalExchange"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), NOTIONAL_EXCHANGE_REC_GBP.PaymentDate); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), currency); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Currency, currency); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Amount, notional.Amount, TOLERANCE); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, currency); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0d, TOLERANCE); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, currency); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0d * DISCOUNT_FACTOR, TOLERANCE); }
public virtual void test_rateSensitivity() { IborIndexRates mockIbor = mock(typeof(IborIndexRates)); SimpleRatesProvider prov = new SimpleRatesProvider(); prov.IborRates = mockIbor; IList <IborAveragedFixing> fixings = new List <IborAveragedFixing>(); double totalWeight = 0.0d; for (int i = 0; i < OBSERVATIONS.Length; i++) { IborIndexObservation obs = OBSERVATIONS[i]; IborAveragedFixing fixing = IborAveragedFixing.builder().observation(obs).weight(WEIGHTS[i]).build(); fixings.Add(fixing); totalWeight += WEIGHTS[i]; when(mockIbor.ratePointSensitivity(obs)).thenReturn(SENSITIVITIES[i]); } PointSensitivities expected = PointSensitivities.of(ImmutableList.of(IborRateSensitivity.of(OBSERVATIONS[0], WEIGHTS[0] / totalWeight), IborRateSensitivity.of(OBSERVATIONS[1], WEIGHTS[1] / totalWeight), IborRateSensitivity.of(OBSERVATIONS[2], WEIGHTS[2] / totalWeight), IborRateSensitivity.of(OBSERVATIONS[3], WEIGHTS[3] / totalWeight))); IborAveragedRateComputation ro = IborAveragedRateComputation.of(fixings); ForwardIborAveragedRateComputationFn obsFn = ForwardIborAveragedRateComputationFn.DEFAULT; PointSensitivityBuilder test = obsFn.rateSensitivity(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov); assertEquals(test.build(), expected); }
/// <summary> /// Test for the case where publication lag=0, effective offset=0 (GBP conventions) and no cutoff period. /// The arithmetic average coupons are used mainly in USD. This test is more for completeness than a real case. /// </summary> public virtual void rateGbpNoCutOffSensitivity() { OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates)); when(mockRates.Index).thenReturn(GBP_SONIA); SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates); for (int i = 0; i < GBP_OBS.Length; i++) { when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]); OvernightRateSensitivity sensitivity = OvernightRateSensitivity.of(GBP_OBS[i], GBP_SONIA.Currency, 1d); when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(sensitivity); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(GBP_SONIA, START_DATE, END_DATE, 0, REF_DATA); ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; PointSensitivityBuilder sensitivityBuilderComputed = obsFn.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv); PointSensitivities sensitivityComputed = sensitivityBuilderComputed.build().normalized(); double?[] sensitivityExpected = computedSensitivityFD(ro, GBP_SONIA, GBP_OBS); assertEquals(sensitivityComputed.Sensitivities.size(), sensitivityExpected.Length); for (int i = 0; i < sensitivityExpected.Length; ++i) { assertEquals(sensitivityComputed.Sensitivities.get(i).Sensitivity, sensitivityExpected[i], EPS_FD); } }
/// <summary> /// Test for the case where publication lag=0, effective offset=0 (GBP conventions) and no cutoff period. /// The arithmetic average coupons are used mainly in USD. This test is more for completeness than a real case. /// </summary> public virtual void rateGbpNoCutOff() { OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates)); when(mockRates.Index).thenReturn(GBP_SONIA); SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates); for (int i = 0; i < GBP_OBS.Length; i++) { when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(GBP_SONIA, START_DATE, END_DATE, 0, REF_DATA); ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; double accrualFactorTotal = 0.0d; double accruedRate = 0.0d; int indexLast = 5; // Fixing in the observation period are from 1 to 5 (inclusive) for (int i = 1; i <= indexLast; i++) { LocalDate startDate = GBP_OBS[i].EffectiveDate; LocalDate endDate = GBP_OBS[i].MaturityDate; double af = GBP_SONIA.DayCount.yearFraction(startDate, endDate); accrualFactorTotal += af; accruedRate += FIXING_RATES[i] * af; } double rateExpected = accruedRate / accrualFactorTotal; double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv); assertEquals(rateExpected, rateComputed, TOLERANCE_RATE); }
/// <summary> /// Test for the case where publication lag=1, effective offset=0 (USD conventions) and cutoff=2 (FedFund swaps). </summary> public virtual void rateFedFund() { OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates)); when(mockRates.Index).thenReturn(USD_FED_FUND); SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates); for (int i = 0; i < USD_OBS.Length; i++) { when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(USD_FED_FUND, START_DATE, END_DATE, 2, REF_DATA); ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; double accrualFactorTotal = 0.0d; double accruedRate = 0.0d; int indexLast = 5; // Fixing in the observation period are from 1 to 5 (inclusive), but last is modified by cut-off for (int i = 1; i <= indexLast - 1; i++) { LocalDate endDate = USD_OBS[i].MaturityDate; double af = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[i], endDate); accrualFactorTotal += af; accruedRate += FIXING_RATES[i] * af; } // CutOff LocalDate endDate = USD_OBS[indexLast].MaturityDate; double af = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[indexLast], endDate); accrualFactorTotal += af; accruedRate += FIXING_RATES[indexLast - 1] * af; double rateExpected = accruedRate / accrualFactorTotal; double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv); assertEquals(rateExpected, rateComputed, TOLERANCE_RATE); }
/// <summary> /// Test FRA paying in the past. /// </summary> public virtual void test_forecastValue_inPast() { SimpleRatesProvider prov = createProvider(RFRA.toBuilder().paymentDate(VAL_DATE.minusDays(1)).build()); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(RFRA.toBuilder().paymentDate(VAL_DATE.minusDays(1)).build(), prov); assertEquals(computed.Amount, 0d, TOLERANCE); }
//------------------------------------------------------------------------- // creates a simple provider private SimpleRatesProvider createProvider(ResolvedFra fraExp) { DiscountFactors mockDf = SimpleDiscountFactors.of(GBP, VAL_DATE, ConstantCurve.of(Curves.discountFactors("DSC", DAY_COUNT), DISCOUNT_FACTOR)); LocalDateDoubleTimeSeries timeSeries = LocalDateDoubleTimeSeries.of(VAL_DATE, FORWARD_RATE); IborIndexRates mockIbor = SimpleIborIndexRates.of(GBP_LIBOR_3M, VAL_DATE, ConstantCurve.of(Curves.forwardRates("L3M", DAY_COUNT), FORWARD_RATE), timeSeries); SimpleRatesProvider prov = new SimpleRatesProvider(VAL_DATE, mockDf); prov.IborRates = mockIbor; return prov; }
/// <summary> /// Test FRA paying in the past. /// </summary> public virtual void test_presentValue_inPast() { ResolvedFra fra = RFRA.toBuilder().paymentDate(VAL_DATE.minusDays(1)).build(); SimpleRatesProvider prov = createProvider(fra); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.presentValue(fra, prov); assertEquals(computed.Amount, 0d, TOLERANCE); }
/// <summary> /// Test present value for ISDA FRA Discounting method. /// </summary> public virtual void test_presentValue_AFMA() { SimpleRatesProvider prov = createProvider(RFRA_AFMA); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount pvComputed = test.presentValue(RFRA_AFMA, prov); CurrencyAmount pvExpected = test.forecastValue(RFRA_AFMA, prov).multipliedBy(DISCOUNT_FACTOR); assertEquals(pvComputed.Amount, pvExpected.Amount, TOLERANCE); }
public virtual void test_forecastValue() { SimpleRatesProvider prov = createProvider(NOTIONAL_EXCHANGE_REC_GBP); DiscountingNotionalExchangePricer test = DiscountingNotionalExchangePricer.DEFAULT; double calculated = test.forecastValue(NOTIONAL_EXCHANGE_REC_GBP, prov); assertEquals(calculated, NOTIONAL_EXCHANGE_REC_GBP.PaymentAmount.Amount, 0d); }
//------------------------------------------------------------------------- public virtual void test_forecastValue() { SimpleRatesProvider prov = createProvider(FX_RESET_NOTIONAL_EXCHANGE_REC_USD); DiscountingFxResetNotionalExchangePricer test = new DiscountingFxResetNotionalExchangePricer(); double calculated = test.forecastValue(FX_RESET_NOTIONAL_EXCHANGE_REC_USD, prov); assertEquals(calculated, FX_RESET_NOTIONAL_EXCHANGE_REC_USD.Notional * FX_RATE, 0d); }
/// <summary> /// Test par spread for AFMA FRA Discounting method. /// </summary> public virtual void test_parSpread_AFMA() { ResolvedFra fraExp = RFRA_AFMA; SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; double parSpread = test.parSpread(fraExp, prov); ResolvedFra fra = createNewFra(FRA_AFMA, FRA_AFMA.FixedRate + parSpread); CurrencyAmount pv = test.presentValue(fra, prov); assertEquals(pv.Amount, 0.0, TOLERANCE); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivity() { SimpleRatesProvider prov = createProvider(NOTIONAL_EXCHANGE_REC_GBP); DiscountingNotionalExchangePricer test = DiscountingNotionalExchangePricer.DEFAULT; PointSensitivities senseComputed = test.presentValueSensitivity(NOTIONAL_EXCHANGE_REC_GBP, prov).build(); double eps = 1.0e-7; PointSensitivities senseExpected = PointSensitivities.of(dscSensitivityFD(prov, NOTIONAL_EXCHANGE_REC_GBP, eps)); assertTrue(senseComputed.equalWithTolerance(senseExpected, NOTIONAL_EXCHANGE_REC_GBP.PaymentAmount.Amount * eps)); }
/// <summary> /// Test par rate for NONE FRA Discounting method. /// </summary> public virtual void test_parRate_NONE() { ResolvedFra fraExp = RFRA_NONE; SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; double parRate = test.parRate(fraExp, prov); assertEquals(parRate, FORWARD_RATE); ResolvedFra fra = createNewFra(FRA_NONE, parRate); CurrencyAmount pv = test.presentValue(fra, prov); assertEquals(pv.Amount, 0.0, TOLERANCE); }
/// <summary> /// Test forecast value for NONE FRA Discounting method. /// </summary> public virtual void test_forecastValue_NONE() { SimpleRatesProvider prov = createProvider(RFRA_NONE); double fixedRate = FRA_NONE.FixedRate; double yearFraction = RFRA_NONE.YearFraction; double notional = RFRA_NONE.Notional; double expected = notional * yearFraction * (FORWARD_RATE - fixedRate); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(RFRA_NONE, prov); assertEquals(computed.Amount, expected, TOLERANCE); }
/// <summary> /// Test forecast value for AFMA FRA Discounting method. /// </summary> public virtual void test_forecastValue_AFMA() { SimpleRatesProvider prov = createProvider(RFRA_AFMA); double fixedRate = FRA_AFMA.FixedRate; double yearFraction = RFRA_AFMA.YearFraction; double notional = RFRA_AFMA.Notional; double expected = -notional * (1.0 / (1.0 + yearFraction * FORWARD_RATE) - 1.0 / (1.0 + yearFraction * fixedRate)); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(RFRA_AFMA, prov); assertEquals(computed.Amount, expected, TOLERANCE); }
//------------------------------------------------------------------------- /// <summary> /// Test present value for ISDA FRA Discounting method. /// </summary> public virtual void test_presentValue_ISDA() { SimpleRatesProvider prov = createProvider(RFRA); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount pvComputed = test.presentValue(RFRA, prov); CurrencyAmount pvExpected = test.forecastValue(RFRA, prov).multipliedBy(DISCOUNT_FACTOR); assertEquals(pvComputed.Amount, pvExpected.Amount, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.presentValue(RFRA_TRADE, prov), test.presentValue(RFRA, prov)); }
public virtual void test_rateSensitivity_finiteDifference() { IborIndexRates mockIbor = mock(typeof(IborIndexRates)); SimpleRatesProvider prov = new SimpleRatesProvider(); prov.IborRates = mockIbor; double eps = 1.0e-7; int nDates = OBSERVATIONS.Length; IList <IborAveragedFixing> fixings = new List <IborAveragedFixing>(); for (int i = 0; i < nDates; i++) { IborIndexObservation obs = OBSERVATIONS[i]; IborAveragedFixing fixing = IborAveragedFixing.builder().observation(obs).weight(WEIGHTS[i]).build(); fixings.Add(fixing); when(mockIbor.ratePointSensitivity(obs)).thenReturn(SENSITIVITIES[i]); } IborAveragedRateComputation ro = IborAveragedRateComputation.of(fixings); ForwardIborAveragedRateComputationFn obsFn = ForwardIborAveragedRateComputationFn.DEFAULT; PointSensitivityBuilder test = obsFn.rateSensitivity(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov); for (int i = 0; i < nDates; ++i) { IborIndexRates mockIborUp = mock(typeof(IborIndexRates)); SimpleRatesProvider provUp = new SimpleRatesProvider(); provUp.IborRates = mockIborUp; IborIndexRates mockIborDw = mock(typeof(IborIndexRates)); SimpleRatesProvider provDw = new SimpleRatesProvider(); provDw.IborRates = mockIborDw; for (int j = 0; j < nDates; ++j) { if (i == j) { when(mockIborUp.rate(OBSERVATIONS[j])).thenReturn(FIXING_VALUES[j] + eps); when(mockIborDw.rate(OBSERVATIONS[j])).thenReturn(FIXING_VALUES[j] - eps); } else { when(mockIborUp.rate(OBSERVATIONS[j])).thenReturn(FIXING_VALUES[j]); when(mockIborDw.rate(OBSERVATIONS[j])).thenReturn(FIXING_VALUES[j]); } } double rateUp = obsFn.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, provUp); double rateDw = obsFn.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, provDw); double resExpected = 0.5 * (rateUp - rateDw) / eps; assertEquals(test.build().Sensitivities.get(i).Sensitivity, resExpected, eps); } }
public virtual void test_rate() { LocalDate fixingDate = OBSERVATIONS[0].FixingDate; LocalDateDoubleTimeSeries timeSeries = LocalDateDoubleTimeSeries.of(fixingDate, FIXING_VALUES[0]); LocalDateDoubleTimeSeries rates = LocalDateDoubleTimeSeries.builder().put(OBSERVATIONS[1].FixingDate, FIXING_VALUES[1]).put(OBSERVATIONS[2].FixingDate, FIXING_VALUES[2]).put(OBSERVATIONS[3].FixingDate, FIXING_VALUES[3]).build(); IborIndexRates mockIbor = new TestingIborIndexRates(GBP_LIBOR_3M, fixingDate, rates, timeSeries); SimpleRatesProvider prov = new SimpleRatesProvider(fixingDate); prov.IborRates = mockIbor; IList <IborAveragedFixing> fixings = new List <IborAveragedFixing>(); double totalWeightedRate = 0.0d; double totalWeight = 0.0d; for (int i = 0; i < OBSERVATIONS.Length; i++) { IborIndexObservation obs = OBSERVATIONS[i]; IborAveragedFixing fixing = IborAveragedFixing.builder().observation(obs).weight(WEIGHTS[i]).build(); fixings.Add(fixing); totalWeightedRate += FIXING_VALUES[i] * WEIGHTS[i]; totalWeight += WEIGHTS[i]; } double rateExpected = totalWeightedRate / totalWeight; IborAveragedRateComputation ro = IborAveragedRateComputation.of(fixings); ForwardIborAveragedRateComputationFn obsFn = ForwardIborAveragedRateComputationFn.DEFAULT; double rateComputed = obsFn.rate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov); assertEquals(rateComputed, rateExpected, TOLERANCE_RATE); // explain ExplainMapBuilder builder = ExplainMap.builder(); assertEquals(obsFn.explainRate(ro, ACCRUAL_START_DATE, ACCRUAL_END_DATE, prov, builder), rateExpected, TOLERANCE_RATE); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, true); assertEquals(built.get(ExplainKey.OBSERVATIONS).get().size(), OBSERVATIONS.Length); for (int i = 0; i < 4; i++) { ExplainMap childMap = built.get(ExplainKey.OBSERVATIONS).get().get(i); assertEquals(childMap.get(ExplainKey.FIXING_DATE), (OBSERVATIONS[i].FixingDate)); assertEquals(childMap.get(ExplainKey.INDEX), GBP_LIBOR_3M); assertEquals(childMap.get(ExplainKey.INDEX_VALUE), FIXING_VALUES[i]); assertEquals(childMap.get(ExplainKey.WEIGHT), WEIGHTS[i]); assertEquals(childMap.get(ExplainKey.FROM_FIXING_SERIES), i == 0 ? true : null); } assertEquals(built.get(ExplainKey.COMBINED_RATE), rateExpected); }
/// <summary> /// Test par spread for ISDA FRA Discounting method. /// </summary> public virtual void test_parSpread_ISDA() { ResolvedFra fraExp = RFRA; SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; double parSpread = test.parSpread(fraExp, prov); ResolvedFra fra = createNewFra(FRA, FRA.FixedRate + parSpread); CurrencyAmount pv = test.presentValue(fra, prov); assertEquals(pv.Amount, 0.0, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.parSpread(RFRA_TRADE, prov), test.parSpread(RFRA, prov)); }
/// <summary> /// Test forecast value sensitivity for AFMA FRA discounting method. /// </summary> public virtual void test_forecastValueSensitivity_AFMA() { SimpleRatesProvider prov = createProvider(RFRA_AFMA); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; PointSensitivities sensitivity = test.forecastValueSensitivity(RFRA_AFMA, prov); double eps = 1.e-7; double fdSense = forecastValueFwdSensitivity(RFRA_AFMA, FORWARD_RATE, eps); ImmutableList<PointSensitivity> sensitivities = sensitivity.Sensitivities; assertEquals(sensitivities.size(), 1); IborRateSensitivity sensitivity0 = (IborRateSensitivity) sensitivities.get(0); assertEquals(sensitivity0.Index, FRA_AFMA.Index); assertEquals(sensitivity0.Observation.FixingDate, FRA_AFMA.StartDate); assertEquals(sensitivity0.Sensitivity, fdSense, FRA_AFMA.Notional * eps); }
private double?[] computedSensitivityFD(OvernightAveragedRateComputation ro, OvernightIndex index, OvernightIndexObservation[] indexObs) { int nRates = FIXING_DATES.Length; OvernightIndexRates[] mockRatesUp = new OvernightIndexRates[nRates]; SimpleRatesProvider[] simpleProvUp = new SimpleRatesProvider[nRates]; OvernightIndexRates[] mockRatesDw = new OvernightIndexRates[nRates]; SimpleRatesProvider[] simpleProvDw = new SimpleRatesProvider[nRates]; double[][] ratesUp = new double[nRates][]; double[][] ratesDw = new double[nRates][]; for (int i = 0; i < nRates; ++i) { mockRatesUp[i] = mock(typeof(OvernightIndexRates)); simpleProvUp[i] = new SimpleRatesProvider(mockRatesUp[i]); mockRatesDw[i] = mock(typeof(OvernightIndexRates)); simpleProvDw[i] = new SimpleRatesProvider(mockRatesDw[i]); ratesUp[i] = Arrays.copyOf(FIXING_RATES, nRates); ratesDw[i] = Arrays.copyOf(FIXING_RATES, nRates); ratesUp[i][i] += EPS_FD; ratesDw[i][i] -= EPS_FD; } for (int i = 0; i < nRates; i++) { for (int j = 0; j < nRates; ++j) { when(mockRatesUp[j].rate(indexObs[i])).thenReturn(ratesUp[j][i]); when(mockRatesDw[j].rate(indexObs[i])).thenReturn(ratesDw[j][i]); } } ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; IList <double> sensitivityExpected = new List <double>(); for (int i = 0; i < nRates; ++i) { double rateUp = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]); double rateDw = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]); double res = 0.5 * (rateUp - rateDw) / EPS_FD; if (Math.Abs(res) > 1.0e-14) { sensitivityExpected.Add(res); } } int size = sensitivityExpected.Count; double?[] result = new double?[size]; return(sensitivityExpected.toArray(result)); }
//------------------------------------------------------------------------- // creates a simple provider private SimpleRatesProvider createProvider(NotionalExchange ne) { LocalDate paymentDate = ne.PaymentDate; double paymentTime = DAY_COUNT.relativeYearFraction(VAL_DATE, paymentDate); Currency currency = ne.Currency; DiscountFactors mockDf = mock(typeof(DiscountFactors)); when(mockDf.discountFactor(paymentDate)).thenReturn(DISCOUNT_FACTOR); ZeroRateSensitivity sens = ZeroRateSensitivity.of(currency, paymentTime, -DISCOUNT_FACTOR * paymentTime); when(mockDf.zeroRatePointSensitivity(paymentDate)).thenReturn(sens); SimpleRatesProvider prov = new SimpleRatesProvider(VAL_DATE, mockDf); prov.DayCount = DAY_COUNT; return(prov); }
/// <summary> /// Test forecast value for ISDA FRA Discounting method. /// </summary> public virtual void test_forecastValue_ISDA() { SimpleRatesProvider prov = createProvider(RFRA); double fixedRate = FRA.FixedRate; double yearFraction = RFRA.YearFraction; double notional = RFRA.Notional; double expected = notional * yearFraction * (FORWARD_RATE - fixedRate) / (1.0 + yearFraction * FORWARD_RATE); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(RFRA, prov); assertEquals(computed.Amount, expected, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.forecastValue(RFRA_TRADE, prov), test.forecastValue(RFRA, prov)); }
//------------------------------------------------------------------------- /// <summary> /// Test explain. /// </summary> public virtual void test_explainPresentValue_ISDA() { ResolvedFra fraExp = RFRA; SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount fvExpected = test.forecastValue(fraExp, prov); CurrencyAmount pvExpected = test.presentValue(fraExp, prov); ExplainMap explain = test.explainPresentValue(fraExp, prov); Currency currency = fraExp.Currency; int daysBetween = (int) DAYS.between(fraExp.StartDate, fraExp.EndDate); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FRA"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), fraExp.PaymentDate); assertEquals(explain.get(ExplainKey.START_DATE).get(), fraExp.StartDate); assertEquals(explain.get(ExplainKey.END_DATE).get(), fraExp.EndDate); assertEquals(explain.get(ExplainKey.ACCRUAL_YEAR_FRACTION).Value, fraExp.YearFraction); assertEquals(explain.get(ExplainKey.DAYS).Value, (int?)(int) daysBetween); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), currency); assertEquals(explain.get(ExplainKey.NOTIONAL).get().Amount, fraExp.Notional, TOLERANCE); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Amount, fraExp.Notional, TOLERANCE); assertEquals(explain.get(ExplainKey.OBSERVATIONS).get().size(), 1); ExplainMap explainObs = explain.get(ExplainKey.OBSERVATIONS).get().get(0); IborRateComputation floatingRate = (IborRateComputation) fraExp.FloatingRate; assertEquals(explainObs.get(ExplainKey.INDEX).get(), floatingRate.Index); assertEquals(explainObs.get(ExplainKey.FIXING_DATE).get(), floatingRate.FixingDate); assertEquals(explainObs.get(ExplainKey.INDEX_VALUE).Value, FORWARD_RATE, TOLERANCE); assertEquals(explainObs.get(ExplainKey.FROM_FIXING_SERIES).HasValue, false); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).Value, DISCOUNT_FACTOR, TOLERANCE); assertEquals(explain.get(ExplainKey.FIXED_RATE).Value, fraExp.FixedRate, TOLERANCE); assertEquals(explain.get(ExplainKey.PAY_OFF_RATE).Value, FORWARD_RATE, TOLERANCE); assertEquals(explain.get(ExplainKey.COMBINED_RATE).Value, FORWARD_RATE, TOLERANCE); assertEquals(explain.get(ExplainKey.UNIT_AMOUNT).Value, fvExpected.Amount / fraExp.Notional, TOLERANCE); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, currency); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, fvExpected.Amount, TOLERANCE); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, currency); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, pvExpected.Amount, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.explainPresentValue(RFRA_TRADE, prov), test.explainPresentValue(RFRA, prov)); }
//------------------------------------------------------------------------- /// <summary> /// Test for the case where publication lag=1, effective offset=0 (USD conventions) and no cutoff period. </summary> public virtual void rateFedFundNoCutOff() { OvernightIndexRates mockRates = mock(typeof(OvernightIndexRates)); when(mockRates.Index).thenReturn(USD_FED_FUND); SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates); for (int i = 0; i < USD_OBS.Length; i++) { when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(USD_FED_FUND, START_DATE, END_DATE, 0, REF_DATA); // Accrual dates = fixing dates ForwardOvernightAveragedRateComputationFn obsFn = ForwardOvernightAveragedRateComputationFn.DEFAULT; double accrualFactorTotal = 0.0d; double accruedRate = 0.0d; int indexLast = 5; // Fixing in the observation period are from 1 to 5 (inclusive) for (int i = 1; i <= indexLast; i++) { LocalDate endDate = USD_OBS[i].MaturityDate; double af = USD_FED_FUND.DayCount.yearFraction(FIXING_DATES[i], endDate); accrualFactorTotal += af; accruedRate += FIXING_RATES[i] * af; } double rateExpected = accruedRate / accrualFactorTotal; double rateComputed = obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv); assertEquals(rateExpected, rateComputed, TOLERANCE_RATE); // explain ExplainMapBuilder builder = ExplainMap.builder(); double explainedRate = obsFn.explainRate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv, builder); assertEquals(explainedRate, rateExpected, TOLERANCE_RATE); ExplainMap built = builder.build(); assertEquals(built.get(ExplainKey.OBSERVATIONS).Present, false); assertEquals(built.get(ExplainKey.COMBINED_RATE).Value.doubleValue(), rateExpected, TOLERANCE_RATE); }
//------------------------------------------------------------------------- // creates a simple provider private SimpleRatesProvider createProvider(FxResetNotionalExchange ne) { LocalDate paymentDate = ne.PaymentDate; double paymentTime = ACT_360.relativeYearFraction(VAL_DATE, paymentDate); Currency currency = ne.Currency; DiscountFactors mockDf = mock(typeof(DiscountFactors)); when(mockDf.discountFactor(paymentDate)).thenReturn(DISCOUNT_FACTOR); ZeroRateSensitivity sens = ZeroRateSensitivity.of(currency, paymentTime, -DISCOUNT_FACTOR * paymentTime); when(mockDf.zeroRatePointSensitivity(paymentDate)).thenReturn(sens); FxIndexRates mockFxRates = mock(typeof(FxIndexRates)); when(mockFxRates.rate(ne.Observation, ne.ReferenceCurrency)).thenReturn(FX_RATE); SimpleRatesProvider prov = new SimpleRatesProvider(VAL_DATE); prov.DiscountFactors = mockDf; prov.FxIndexRates = mockFxRates; prov.DayCount = ACT_360; return(prov); }
//------------------------------------------------------------------------- /// <summary> /// Test cash flow for ISDA FRA Discounting method. /// </summary> public virtual void test_cashFlows_ISDA() { ResolvedFra fraExp = RFRA; SimpleRatesProvider prov = createProvider(fraExp); double fixedRate = FRA.FixedRate; double yearFraction = fraExp.YearFraction; double notional = fraExp.Notional; double expected = notional * yearFraction * (FORWARD_RATE - fixedRate) / (1.0 + yearFraction * FORWARD_RATE); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CashFlows computed = test.cashFlows(fraExp, prov); assertEquals(computed.getCashFlows().size(), 1); assertEquals(computed.getCashFlows().size(), 1); assertEquals(computed.getCashFlows().get(0).PaymentDate, fraExp.PaymentDate); assertEquals(computed.getCashFlows().get(0).ForecastValue.Currency, fraExp.Currency); assertEquals(computed.getCashFlows().get(0).ForecastValue.Amount, expected, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.cashFlows(RFRA_TRADE, prov), test.cashFlows(fraExp, prov)); }