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); }
//------------------------------------------------------------------------- public virtual void test_combinedWith() { OvernightRateSensitivity base1 = OvernightRateSensitivity.of(GBP_SONIA_OBSERVATION, 32d); OvernightRateSensitivity base2 = OvernightRateSensitivity.of(OvernightIndexObservation.of(GBP_SONIA, date(2015, 10, 27), REF_DATA), 22d); MutablePointSensitivities expected = new MutablePointSensitivities(); expected.add(base1).add(base2); PointSensitivityBuilder test = base1.combinedWith(base2); assertEquals(test, expected); }
public virtual void test_periodRatePointSensitivity_onholidaybeforepublication() { LocalDate lastFixingDate = LocalDate.of(2017, 6, 30); LocalDate gbdBeforeValDate = LocalDate.of(2017, 7, 3); LocalDate gbdAfterValDate = LocalDate.of(2017, 7, 5); double fixingValue = 0.0010; InterpolatedNodalCurve curve = InterpolatedNodalCurve.of(METADATA, DoubleArray.of(-1.0d, 10.0d), DoubleArray.of(0.01, 0.02), INTERPOLATOR); ZeroRateDiscountFactors df = ZeroRateDiscountFactors.of(USD, LocalDate.of(2017, 7, 4), curve); LocalDateDoubleTimeSeries series = LocalDateDoubleTimeSeries.builder().put(lastFixingDate, fixingValue).build(); DiscountOvernightIndexRates test = DiscountOvernightIndexRates.of(USD_FED_FUND, df, series); OvernightIndexObservation obs = OvernightIndexObservation.of(USD_FED_FUND, gbdBeforeValDate, REF_DATA); OvernightRateSensitivity expected = OvernightRateSensitivity.ofPeriod(obs, gbdAfterValDate, USD, 1d); assertEquals(test.periodRatePointSensitivity(obs, gbdAfterValDate), expected); }
//------------------------------------------------------------------------- public virtual void test_convertedTo() { LocalDate fixingDate = DATE; LocalDate endDate = date(2015, 10, 27); double sensi = 32d; OvernightRateSensitivity @base = OvernightRateSensitivity.ofPeriod(OvernightIndexObservation.of(GBP_SONIA, fixingDate, REF_DATA), endDate, GBP, sensi); double rate = 1.5d; FxMatrix matrix = FxMatrix.of(CurrencyPair.of(GBP, USD), rate); OvernightRateSensitivity test1 = (OvernightRateSensitivity)@base.convertedTo(USD, matrix); OvernightRateSensitivity expected = OvernightRateSensitivity.ofPeriod(OvernightIndexObservation.of(GBP_SONIA, fixingDate, REF_DATA), endDate, USD, rate * sensi); assertEquals(test1, expected); OvernightRateSensitivity test2 = (OvernightRateSensitivity)@base.convertedTo(GBP, matrix); assertEquals(test2, @base); }
public virtual PointSensitivityBuilder rateSensitivity(OvernightAveragedDailyRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { OvernightIndex index = computation.Index; OvernightIndexRates rates = provider.overnightIndexRates(index); LocalDate lastFixingDate = computation.EndDate; PointSensitivityBuilder pointSensitivityBuilder = PointSensitivityBuilder.none(); int numberOfDays = 0; LocalDate currentFixingDate = computation.StartDate; while (!currentFixingDate.isAfter(lastFixingDate)) { LocalDate referenceFixingDate = computation.FixingCalendar.previousOrSame(currentFixingDate); OvernightIndexObservation indexObs = computation.observeOn(referenceFixingDate); PointSensitivityBuilder forwardRateSensitivity = rates.ratePointSensitivity(indexObs); pointSensitivityBuilder = pointSensitivityBuilder.combinedWith(forwardRateSensitivity); numberOfDays++; currentFixingDate = currentFixingDate.plusDays(1); } return(pointSensitivityBuilder.multipliedBy(1d / numberOfDays)); }
//------------------------------------------------------------------------- public virtual double rate(OvernightAveragedDailyRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { OvernightIndex index = computation.Index; OvernightIndexRates rates = provider.overnightIndexRates(index); LocalDate lastFixingDate = computation.EndDate; double interestSum = 0d; int numberOfDays = 0; LocalDate currentFixingDate = computation.StartDate; while (!currentFixingDate.isAfter(lastFixingDate)) { LocalDate referenceFixingDate = computation.FixingCalendar.previousOrSame(currentFixingDate); OvernightIndexObservation indexObs = computation.observeOn(referenceFixingDate); double forwardRate = rates.rate(indexObs); interestSum += forwardRate; numberOfDays++; currentFixingDate = currentFixingDate.plusDays(1); } return(interestSum / numberOfDays); }
//------------------------------------------------------------------------- public virtual double rate(OvernightAveragedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { OvernightIndex index = computation.Index; OvernightIndexRates rates = provider.overnightIndexRates(index); LocalDate lastNonCutoffFixing = computation.EndDate; int cutoffOffset = computation.RateCutOffDays > 1 ? computation.RateCutOffDays : 1; double accumulatedInterest = 0.0d; double accrualFactorTotal = 0.0d; // Cut-off period. Starting from the end as the cutoff period is defined as a lag from the end. // When the fixing period end-date is not a good business day in the index calendar, // the last fixing end date will be after the fixing end-date. double cutoffAccrualFactor = 0.0; OvernightIndexObservation lastIndexObs = null; // cutoffOffset >= 1, so loop always runs at least once for (int i = 0; i < cutoffOffset; i++) { lastNonCutoffFixing = computation.FixingCalendar.previous(lastNonCutoffFixing); lastIndexObs = computation.observeOn(lastNonCutoffFixing); accrualFactorTotal += lastIndexObs.YearFraction; cutoffAccrualFactor += lastIndexObs.YearFraction; } double forwardRateCutOff = rates.rate(lastIndexObs); accumulatedInterest += cutoffAccrualFactor * forwardRateCutOff; LocalDate currentFixingNonCutoff = computation.StartDate; while (currentFixingNonCutoff.isBefore(lastNonCutoffFixing)) { // All dates involved in the period are computed. Potentially slow. // The fixing periods are added as long as their start date is (strictly) before the no cutoff period end-date. OvernightIndexObservation indexObs = computation.observeOn(currentFixingNonCutoff); double forwardRate = rates.rate(indexObs); accrualFactorTotal += indexObs.YearFraction; accumulatedInterest += indexObs.YearFraction * forwardRate; currentFixingNonCutoff = computation.FixingCalendar.next(currentFixingNonCutoff); } // final rate return(accumulatedInterest / accrualFactorTotal); }
public virtual void test_observeOn() { OvernightCompoundedRateComputation test = OvernightCompoundedRateComputation.of(USD_FED_FUND, date(2016, 2, 24), date(2016, 3, 24), REF_DATA); assertEquals(test.observeOn(date(2016, 2, 24)), OvernightIndexObservation.of(USD_FED_FUND, date(2016, 2, 24), REF_DATA)); }