private double approximatedForwardAccumulation() { int nbPeriodNotCutOff = nbPeriods - cutoffOffset + 1; if (fixedPeriod < nbPeriodNotCutOff) { LocalDate endDateApprox = observations.get(nbPeriodNotCutOff - 1).getMaturityDate(); return approximatedInterest(observations.get(fixedPeriod), endDateApprox, rates); } return 0.0d; }
private PointSensitivityBuilder approximatedForwardAccumulationSensitivity() { int nbPeriodNotCutOff = nbPeriods - cutoffOffset + 1; if (fixedPeriod < nbPeriodNotCutOff) { LocalDate endDateApprox = observations.get(nbPeriodNotCutOff - 1).getMaturityDate(); return approximatedInterestSensitivity(observations.get(fixedPeriod), endDateApprox, rates); } return PointSensitivityBuilder.none(); }
/** * Obtains an instance from the observation and sensitivity value, * specifying the currency of the value. * <p> * The end date will be the maturity date of the observation. * * @param observation the rate observation, including the fixing date * @param sensitivityCurrency the currency of the sensitivity * @param sensitivity the value of the sensitivity * @return the point sensitivity object */ public static OvernightRateSensitivity of( OvernightIndexObservation observation, Currency sensitivityCurrency, double sensitivity) { return new OvernightRateSensitivity(observation, observation.getMaturityDate(), sensitivityCurrency, sensitivity); }
@Override public double rateIgnoringFixings(OvernightIndexObservation observation) { LocalDate effectiveDate = observation.getEffectiveDate(); LocalDate maturityDate = observation.getMaturityDate(); double accrualFactor = observation.getYearFraction(); return simplyCompoundForwardRate(effectiveDate, maturityDate, accrualFactor); }
/** * 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); }
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]"); }
/** Test for the case where publication lag=1, effective offset=0 (USD conventions) and cutoff=2 (FedFund swaps). */ public void rateFedFund() { OvernightIndexRates mockRates = mock(OvernightIndexRates.class); when(mockRates.getIndex()).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].getMaturityDate(); double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate); accrualFactorTotal += af; accruedRate += FIXING_RATES[i] * af; } // CutOff LocalDate endDate = USD_OBS[indexLast].getMaturityDate(); double af = USD_FED_FUND.getDayCount().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); }
public void test_withCurrency() { OvernightRateSensitivity base = OvernightRateSensitivity.of(GBP_SONIA_OBSERVATION, 32d); assertSame(base.withCurrency(GBP), base); LocalDate mat = GBP_SONIA_OBSERVATION.getMaturityDate(); OvernightRateSensitivity expected = OvernightRateSensitivity.ofPeriod(GBP_SONIA_OBSERVATION, mat, USD, 32d); OvernightRateSensitivity test = base.withCurrency(USD); assertEquals(test, expected); }
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].getMaturityDate(); double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate); accrualFactorTotal += af;
/** 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 against FD approximation for the case where publication lag=1, effective offset=0 (USD conventions) and * no cutoff period. Note that all the rates are bumped here, i.e., all the rates are treated as forward rates.*/ public void rateFedFundNoCutOffSensitivity() { OvernightIndexRates mockRates = mock(OvernightIndexRates.class); when(mockRates.getIndex()).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]); LocalDate fixingEndDate = USD_OBS[i].getMaturityDate(); OvernightRateSensitivity sensitivity = OvernightRateSensitivity.ofPeriod(USD_OBS[i], fixingEndDate, USD_FED_FUND.getCurrency(), 1d); when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(sensitivity); } OvernightAveragedRateComputation ro = OvernightAveragedRateComputation.of(USD_FED_FUND, 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, USD_FED_FUND, USD_OBS); assertEquals(sensitivityComputed.getSensitivities().size(), sensitivityExpected.length); for (int i = 0; i < sensitivityExpected.length; ++i) { assertEquals(sensitivityComputed.getSensitivities().get(i).getSensitivity(), sensitivityExpected[i], EPS_FD); } }
/** * 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); }
double totalAf = 0.0; for (int i = 1; i < 6; i++) { LocalDate endDate = USD_OBS[i].getMaturityDate(); double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate); totalAf += af;
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); }
private double rateForward(OvernightAveragedRateComputation computation, OvernightIndexRates rates) { OvernightIndex index = computation.getIndex(); HolidayCalendar calendar = computation.getFixingCalendar(); LocalDate startFixingDate = computation.getStartDate(); LocalDate endFixingDateP1 = computation.getEndDate(); LocalDate endFixingDate = calendar.previous(endFixingDateP1); LocalDate onRateEndDate = computation.calculateMaturityFromFixing(endFixingDate); LocalDate onRateStartDate = computation.calculateEffectiveFromFixing(startFixingDate); LocalDate onRateNoCutOffEndDate = onRateEndDate; int cutoffOffset = computation.getRateCutOffDays() > 1 ? computation.getRateCutOffDays() : 1; double accumulatedInterest = 0.0d; double accrualFactorTotal = index.getDayCount().yearFraction(onRateStartDate, onRateEndDate); if (cutoffOffset > 1) { // Cut-off period LocalDate currentFixingDate = endFixingDate; OvernightIndexObservation lastIndexObs = null; double cutOffAccrualFactorTotal = 0d; for (int i = 1; i < cutoffOffset; i++) { currentFixingDate = calendar.previous(currentFixingDate); lastIndexObs = computation.observeOn(currentFixingDate); onRateNoCutOffEndDate = lastIndexObs.getMaturityDate(); cutOffAccrualFactorTotal += lastIndexObs.getYearFraction(); } double forwardRateCutOff = rates.rate(lastIndexObs); accumulatedInterest += cutOffAccrualFactorTotal * forwardRateCutOff; } // Approximated part accumulatedInterest += approximatedInterest(computation.observeOn(onRateStartDate), onRateNoCutOffEndDate, rates); // final rate return accumulatedInterest / accrualFactorTotal; }