@Override public PointSensitivityBuilder periodRatePointSensitivity( OvernightIndexObservation startDateObservation, LocalDate endDate) { LocalDate startDate = startDateObservation.getEffectiveDate(); ArgChecker.inOrderNotEqual(startDate, endDate, "startDate", "endDate"); return OvernightRateSensitivity.ofPeriod(startDateObservation, endDate, 1d); }
private static double approximatedInterest( OvernightIndexObservation observation, LocalDate endDate, OvernightIndexRates rates) { DayCount dayCount = observation.getIndex().getDayCount(); double remainingFixingAccrualFactor = dayCount.yearFraction(observation.getEffectiveDate(), endDate); double forwardRate = rates.periodRate(observation, endDate); return Math.log(1.0 + forwardRate * remainingFixingAccrualFactor); }
@Override public double rateIgnoringFixings(OvernightIndexObservation observation) { LocalDate effectiveDate = observation.getEffectiveDate(); LocalDate maturityDate = observation.getMaturityDate(); double accrualFactor = observation.getYearFraction(); return simplyCompoundForwardRate(effectiveDate, maturityDate, accrualFactor); }
@Override public double periodRate(OvernightIndexObservation startDateObservation, LocalDate endDate) { LocalDate effectiveDate = startDateObservation.getEffectiveDate(); ArgChecker.inOrderNotEqual(effectiveDate, endDate, "startDate", "endDate"); double accrualFactor = startDateObservation.getIndex().getDayCount().yearFraction(effectiveDate, endDate); return simplyCompoundForwardRate(effectiveDate, endDate, accrualFactor); }
private double futureCompositionFactor() { if (!nextFixing.isAfter(lastFixing)) { OvernightIndexObservation obs = computation.observeOn(nextFixing); LocalDate startDate = obs.getEffectiveDate(); LocalDate endDate = computation.getEndDate(); double accrualFactor = dayCount.yearFraction(startDate, endDate); double rate = rates.periodRate(obs, endDate); return 1.0d + accrualFactor * rate; } return 1.0d; }
private double compositionFactorNonCutoff() { if (!nextFixing.isAfter(lastFixingNonCutoff)) { OvernightIndexObservation obs = computation.observeOn(nextFixing); LocalDate startDate = obs.getEffectiveDate(); LocalDate endDate = computation.calculateMaturityFromFixing(lastFixingNonCutoff); double accrualFactor = dayCount.yearFraction(startDate, endDate); double rate = rates.periodRate(obs, endDate); return 1.0d + accrualFactor * rate; } return 1.0d; }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(OvernightIndexObservation beanToCopy) { this.index = beanToCopy.getIndex(); this.fixingDate = beanToCopy.getFixingDate(); this.publicationDate = beanToCopy.getPublicationDate(); this.effectiveDate = beanToCopy.getEffectiveDate(); this.maturityDate = beanToCopy.getMaturityDate(); this.yearFraction = beanToCopy.getYearFraction(); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 100346066: // index return ((OvernightIndexObservation) bean).getIndex(); case 1255202043: // fixingDate return ((OvernightIndexObservation) bean).getFixingDate(); case 1470566394: // publicationDate return ((OvernightIndexObservation) bean).getPublicationDate(); case -930389515: // effectiveDate return ((OvernightIndexObservation) bean).getEffectiveDate(); case -414641441: // maturityDate return ((OvernightIndexObservation) bean).getMaturityDate(); case -1731780257: // yearFraction return ((OvernightIndexObservation) bean).getYearFraction(); } return super.propertyGet(bean, propertyName, quiet); }
private static PointSensitivityBuilder approximatedInterestSensitivity( OvernightIndexObservation observation, LocalDate endDate, OvernightIndexRates rates) { DayCount dayCount = observation.getIndex().getDayCount(); double remainingFixingAccrualFactor = dayCount.yearFraction(observation.getEffectiveDate(), endDate); double forwardRate = rates.periodRate(observation, endDate); PointSensitivityBuilder forwardRateSensitivity = rates.periodRatePointSensitivity(observation, endDate); double rateExp = 1.0 + forwardRate * remainingFixingAccrualFactor; forwardRateSensitivity = forwardRateSensitivity.multipliedBy(remainingFixingAccrualFactor / rateExp); return forwardRateSensitivity; }
public void test_of() { OvernightIndexObservation test = OvernightIndexObservation.of(GBP_SONIA, FIXING_DATE, REF_DATA); assertEquals(test.getIndex(), GBP_SONIA); assertEquals(test.getFixingDate(), FIXING_DATE); assertEquals(test.getPublicationDate(), PUBLICATION_DATE); assertEquals(test.getEffectiveDate(), EFFECTIVE_DATE); assertEquals(test.getMaturityDate(), MATURITY_DATE); assertEquals(test.getCurrency(), GBP_SONIA.getCurrency()); assertEquals(test.toString(), "OvernightIndexObservation[GBP-SONIA on 2016-02-22]"); }
private PointSensitivityBuilder calculateRateSensitivity() { double factor = pastCompositionFactor() * valuationCompositionFactor() / accrualFactorTotal; if (!nextFixing.isAfter(lastFixing)) { OvernightIndexObservation obs = computation.observeOn(nextFixing); LocalDate startDate = obs.getEffectiveDate(); LocalDate endDate = computation.calculateMaturityFromFixing(lastFixing); double accrualFactor = dayCount.yearFraction(startDate, endDate); PointSensitivityBuilder rateSensitivity = rates.periodRatePointSensitivity(obs, endDate); return rateSensitivity.multipliedBy(factor * accrualFactor); } return PointSensitivityBuilder.none(); } }
/** 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. */ public void rateGbpNoCutOff() { OvernightIndexRates mockRates = mock(OvernightIndexRates.class); when(mockRates.getIndex()).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].getEffectiveDate(); LocalDate endDate = GBP_OBS[i].getMaturityDate(); double af = GBP_SONIA.getDayCount().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); }
/** * Test for the case where publication lag=0, effective offset=1 (CHF conventions) and no cutoff period. * The arithmetic average coupons are used mainly in USD. This test is more for completeness than a real case. */ public void rateChfNoCutOff() { OvernightIndexRates mockRates = mock(OvernightIndexRates.class); when(mockRates.getIndex()).thenReturn(CHF_TOIS); SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates); for (int i = 0; i < CHF_OBS.length; i++) { when(mockRates.rate(CHF_OBS[i])).thenReturn(FIXING_RATES[i]); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(CHF_TOIS, 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 0 to 4 (inclusive) for (int i = 0; i < indexLast; i++) { LocalDate startDate = CHF_OBS[i].getEffectiveDate(); LocalDate endDate = CHF_OBS[i].getMaturityDate(); double af = CHF_TOIS.getDayCount().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); }
public void test_rateIgnoringFixings_onValuation_fixing() { DiscountOvernightIndexRates test = DiscountOvernightIndexRates.of(GBP_SONIA, DFCURVE, SERIES); LocalDate startDate = GBP_SONIA_VAL.getEffectiveDate(); LocalDate endDate = GBP_SONIA_VAL.getMaturityDate(); double accrualFactor = GBP_SONIA_VAL.getYearFraction(); double expected = (DFCURVE.discountFactor(startDate) / DFCURVE.discountFactor(endDate) - 1) / accrualFactor; assertEquals(test.rateIgnoringFixings(GBP_SONIA_VAL), expected, 1e-8); }
private ObjDoublePair<PointSensitivityBuilder> compositionFactorAndSensitivityNonCutoff() { if (!nextFixing.isAfter(lastFixingNonCutoff)) { OvernightIndexObservation obs = computation.observeOn(nextFixing); LocalDate startDate = obs.getEffectiveDate(); LocalDate endDate = computation.calculateMaturityFromFixing(lastFixingNonCutoff); double accrualFactor = dayCount.yearFraction(startDate, endDate); double rate = rates.periodRate(obs, endDate); PointSensitivityBuilder rateSensitivity = rates.periodRatePointSensitivity(obs, endDate); rateSensitivity = rateSensitivity.multipliedBy(accrualFactor); return ObjDoublePair.of(rateSensitivity, 1.0d + accrualFactor * rate); } return ObjDoublePair.of(PointSensitivityBuilder.none(), 1.0d); }
public void test_rate_afterPublication() { DiscountOvernightIndexRates test = DiscountOvernightIndexRates.of(GBP_SONIA, DFCURVE, SERIES); LocalDate startDate = GBP_SONIA_AFTER.getEffectiveDate(); LocalDate endDate = GBP_SONIA_AFTER.getMaturityDate(); double accrualFactor = GBP_SONIA.getDayCount().yearFraction(startDate, endDate); double expected = (DFCURVE.discountFactor(startDate) / DFCURVE.discountFactor(endDate) - 1) / accrualFactor; assertEquals(test.rate(GBP_SONIA_AFTER), expected, 1e-8); }
public void test_rate_onPublication_noFixing() { DiscountOvernightIndexRates test = DiscountOvernightIndexRates.of(GBP_SONIA, DFCURVE, SERIES_EMPTY); LocalDate startDate = GBP_SONIA_VAL.getEffectiveDate(); LocalDate endDate = GBP_SONIA_VAL.getMaturityDate(); double accrualFactor = GBP_SONIA.getDayCount().yearFraction(startDate, endDate); double expected = (DFCURVE.discountFactor(startDate) / DFCURVE.discountFactor(endDate) - 1) / accrualFactor; assertEquals(test.rate(GBP_SONIA_VAL), expected, 1e-4); }
@Override public CurrencyParameterSensitivities parameterSensitivity(OvernightRateSensitivity pointSensitivity) { OvernightIndex index = pointSensitivity.getIndex(); LocalDate startDate = pointSensitivity.getObservation().getEffectiveDate(); LocalDate endDate = pointSensitivity.getEndDate(); double accrualFactor = index.getDayCount().yearFraction(startDate, endDate); double forwardBar = pointSensitivity.getSensitivity(); double dfForwardStart = discountFactors.discountFactor(startDate); double dfForwardEnd = discountFactors.discountFactor(endDate); double dfStartBar = forwardBar / (accrualFactor * dfForwardEnd); double dfEndBar = -forwardBar * dfForwardStart / (accrualFactor * dfForwardEnd * dfForwardEnd); ZeroRateSensitivity zrsStart = discountFactors.zeroRatePointSensitivity(startDate, pointSensitivity.getCurrency()); ZeroRateSensitivity zrsEnd = discountFactors.zeroRatePointSensitivity(endDate, pointSensitivity.getCurrency()); CurrencyParameterSensitivities psStart = discountFactors.parameterSensitivity(zrsStart).multipliedBy(dfStartBar); CurrencyParameterSensitivities psEnd = discountFactors.parameterSensitivity(zrsEnd).multipliedBy(dfEndBar); return psStart.combinedWith(psEnd); }