/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.impl.rate;
import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_ISDA;
import static com.opengamma.strata.basics.index.OvernightIndices.GBP_SONIA;
import static com.opengamma.strata.basics.index.OvernightIndices.USD_FED_FUND;
import static com.opengamma.strata.collect.TestHelper.assertThrows;
import static com.opengamma.strata.collect.TestHelper.date;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.time.LocalDate;
import java.util.Arrays;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.index.OvernightIndexObservation;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeriesBuilder;
import com.opengamma.strata.market.curve.Curve;
import com.opengamma.strata.market.curve.Curves;
import com.opengamma.strata.market.curve.InterpolatedNodalCurve;
import com.opengamma.strata.market.curve.interpolator.CurveInterpolator;
import com.opengamma.strata.market.curve.interpolator.CurveInterpolators;
import com.opengamma.strata.market.explain.ExplainKey;
import com.opengamma.strata.market.explain.ExplainMap;
import com.opengamma.strata.market.explain.ExplainMapBuilder;
import com.opengamma.strata.market.param.CurrencyParameterSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.PricingException;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.pricer.rate.OvernightIndexRates;
import com.opengamma.strata.pricer.rate.OvernightRateSensitivity;
import com.opengamma.strata.pricer.rate.SimpleRatesProvider;
import com.opengamma.strata.pricer.sensitivity.RatesFiniteDifferenceSensitivityCalculator;
import com.opengamma.strata.product.rate.OvernightAveragedRateComputation;
/**
* Test {@link ApproxForwardOvernightAveragedRateComputationFn}.
*/
@Test
public class ApproxForwardOvernightAveragedRateComputationFnTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate DUMMY_ACCRUAL_START_DATE = date(2015, 1, 1); // Accrual dates irrelevant for the rate
private static final LocalDate DUMMY_ACCRUAL_END_DATE = date(2015, 1, 1); // Accrual dates irrelevant for the rate
private static final LocalDate FIXING_START_DATE = date(2015, 1, 8);
private static final LocalDate FIXING_START_NEXT_DATE = date(2015, 1, 9);
private static final LocalDate FIXING_END_DATE = date(2015, 1, 15); // 1w only to decrease data
private static final LocalDate FIXING_FINAL_DATE = date(2015, 1, 14);
private static final LocalDate[] FIXING_DATES = new LocalDate[] {
date(2015, 1, 7),
date(2015, 1, 8),
date(2015, 1, 9),
date(2015, 1, 12),
date(2015, 1, 13),
date(2015, 1, 14),
date(2015, 1, 15)};
private static final OvernightIndexObservation[] USD_OBS = new OvernightIndexObservation[] {
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 7), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 8), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 9), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 12), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 13), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 14), REF_DATA),
OvernightIndexObservation.of(USD_FED_FUND, date(2015, 1, 15), REF_DATA)};
private static final OvernightIndexObservation[] GBP_OBS = new OvernightIndexObservation[] {
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 7), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 8), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 9), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 12), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 13), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 14), REF_DATA),
OvernightIndexObservation.of(GBP_SONIA, date(2015, 1, 15), REF_DATA)};
private static final double[] FIXING_RATES = {
0.0012, 0.0023, 0.0034,
0.0045, 0.0056, 0.0067, 0.0078};
private static final double[] FORWARD_RATES = {
0.0112, 0.0123, 0.0134,
0.0145, 0.0156, 0.0167, 0.0178};
private static final double TOLERANCE_RATE = 1.0E-10;
private static final double TOLERANCE_APPROX = 1.0E-6;
private static final double EPS_FD = 1.0E-7;
private static final ApproxForwardOvernightAveragedRateComputationFn OBS_FN_APPROX_FWD =
ApproxForwardOvernightAveragedRateComputationFn.DEFAULT;
private static final ForwardOvernightAveragedRateComputationFn OBS_FN_DET_FWD =
ForwardOvernightAveragedRateComputationFn.DEFAULT;
//-------------------------------------------------------------------------
/** Compare the rate estimated with approximation to the rate estimated by daily forward. */
public void comparisonApproxVNoApprox() {
LocalDate valuationDate = date(2015, 1, 5);
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
when(mockRates.getValuationDate()).thenReturn(valuationDate);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(valuationDate, mockRates);
for (int i = 0; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
double investmentFactor = 1.0;
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;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / totalAf;
when(mockRates.periodRate(USD_OBS[1], FIXING_END_DATE)).thenReturn(rateCmp);
double rateApprox = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
double rateDet = OBS_FN_DET_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateDet, rateApprox, TOLERANCE_APPROX);
// explain
ExplainMapBuilder builder = ExplainMap.builder();
double explainedRate = OBS_FN_APPROX_FWD.explainRate(
ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv, builder);
assertEquals(explainedRate, rateApprox, TOLERANCE_APPROX);
ExplainMap built = builder.build();
assertEquals(built.get(ExplainKey.OBSERVATIONS).isPresent(), false);
assertEquals(built.get(ExplainKey.COMBINED_RATE).get().doubleValue(), rateApprox, TOLERANCE_APPROX);
}
/** No cutoff period and the period entirely forward. Test the approximation part only. */
public void rateFedFundNoCutOffForward() { // publication=1, cutoff=0, effective offset=0, Forward
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
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(FORWARD_RATES[i]);
}
double investmentFactor = 1.0;
double totalAf = 0.0;
for (int i = 1; i < 6; i++) {
double af = USD_OBS[i].getYearFraction();
totalAf += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / totalAf;
when(mockRates.periodRate(USD_OBS[1], FIXING_END_DATE)).thenReturn(rateCmp);
double rateExpected = Math.log(1.0 + rateCmp * totalAf) / totalAf;
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation. No cutoff period and the period entirely forward. */
public void rateFedFundNoCutOffForwardSensitivity() { // publication=1, cutoff=0, effective offset=0, Forward
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
OvernightIndexRates mockRatesUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvUp = new SimpleRatesProvider(mockRatesUp);
OvernightIndexRates mockRatesDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvDw = new SimpleRatesProvider(mockRatesDw);
double investmentFactor = 1.0;
double totalAf = 0.0;
for (int i = 1; i < 6; i++) {
double af = USD_OBS[i].getYearFraction();
totalAf += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / totalAf;
when(mockRates.periodRate(USD_OBS[1], FIXING_END_DATE)).thenReturn(rateCmp);
when(mockRatesUp.periodRate(USD_OBS[1], FIXING_END_DATE)).thenReturn(
rateCmp + EPS_FD);
when(mockRatesDw.periodRate(USD_OBS[1], FIXING_END_DATE)).thenReturn(
rateCmp - EPS_FD);
PointSensitivityBuilder periodSensitivity =
OvernightRateSensitivity.ofPeriod(USD_OBS[1], FIXING_END_DATE, 1d);
when(mockRates.periodRatePointSensitivity(USD_OBS[1], FIXING_END_DATE))
.thenReturn(periodSensitivity);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw);
double sensitivityExpected = 0.5 * (rateUp - rateDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected =
OvernightRateSensitivity.ofPeriod(USD_OBS[1], FIXING_END_DATE, sensitivityExpected);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
/** Two days cutoff and the period is entirely forward. Test Approximation part plus cutoff specifics.*/
public void rateFedFund2CutOffForward() { // publication=1, cutoff=2, effective offset=0, Forward
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
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(FORWARD_RATES[i]);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = 1; i < 5; i++) {
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
OvernightIndexObservation obs =
OvernightIndexObservation.of(USD_FED_FUND, FIXING_START_DATE, REF_DATA);
when(mockRates.periodRate(obs, FIXING_FINAL_DATE)).thenReturn(rateCmp);
LocalDate fixingCutOff = FIXING_DATES[5];
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(fixingCutOff, REF_DATA);
double afCutOff = USD_FED_FUND.getDayCount().yearFraction(fixingCutOff, endDate);
double rateExpected = (Math.log(1.0 + rateCmp * afApprox) + FORWARD_RATES[4] * afCutOff) / (afApprox + afCutOff);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation.
* Two days cutoff and the period is entirely forward. Test Approximation part plus cutoff specifics.*/
public void rateFedFund2CutOffForwardSensitivity() { // publication=1, cutoff=2, effective offset=0, Forward
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
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];
OvernightIndexRates mockRatesPeriodUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodUp = new SimpleRatesProvider(mockRatesPeriodUp);
OvernightIndexRates mockRatesPeriodDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodDw = new SimpleRatesProvider(mockRatesPeriodDw);
for (int i = 0; i < nRates; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
PointSensitivityBuilder pointSensitivity = OvernightRateSensitivity.of(USD_OBS[i], 1d);
when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(pointSensitivity);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = 1; i < 5; i++) {
double af = USD_OBS[i].getYearFraction();
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(USD_OBS[1], FIXING_FINAL_DATE)).thenReturn(rateCmp);
PointSensitivityBuilder pointSensitivity = OvernightRateSensitivity.ofPeriod(USD_OBS[1], FIXING_FINAL_DATE, 1d);
when(mockRates.periodRatePointSensitivity(USD_OBS[1], FIXING_FINAL_DATE)).thenReturn(pointSensitivity);
setRatesProviders(
mockRatesUp, simpleProvUp, mockRatesDw, simpleProvDw,
mockRatesPeriodUp, simpleProvPeriodUp, mockRatesPeriodDw, simpleProvPeriodDw,
ro, USD_OBS, FIXING_START_DATE, FIXING_FINAL_DATE, rateCmp, null);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
PointSensitivityBuilder sensitivityBuilderExpected1 = PointSensitivityBuilder.none();
for (int i = 0; i < nRates; ++i) {
when(mockRatesUp[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]);
double res = 0.5 * (rateUp - rateDw) / EPS_FD;
sensitivityBuilderExpected1 = res == 0.0 ? sensitivityBuilderExpected1 : sensitivityBuilderExpected1
.combinedWith(OvernightRateSensitivity.of(USD_OBS[i], res));
}
double ratePeriodUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE,
DUMMY_ACCRUAL_END_DATE, simpleProvPeriodUp);
double ratePeriodDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE,
DUMMY_ACCRUAL_END_DATE, simpleProvPeriodDw);
double periodSensitivityExpected = 0.5 * (ratePeriodUp - ratePeriodDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected2 =
OvernightRateSensitivity.ofPeriod(
USD_OBS[1], FIXING_FINAL_DATE, periodSensitivityExpected);
PointSensitivityBuilder sensitivityBuilderExpected = sensitivityBuilderExpected1
.combinedWith(sensitivityBuilderExpected2);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
private void setRatesProviders(
OvernightIndexRates[] mockRatesUp,
SimpleRatesProvider[] simpleProvUp,
OvernightIndexRates[] mockRatesDw,
SimpleRatesProvider[] simpleProvDw,
OvernightIndexRates mockRatesPeriodUp,
SimpleRatesProvider simpleProvPeriodUp,
OvernightIndexRates mockRatesPeriodDw,
SimpleRatesProvider simpleProvPeriodDw,
OvernightAveragedRateComputation ro,
OvernightIndexObservation[] obsArray,
LocalDate periodStartDate,
LocalDate periodEndDate,
double rateCmp,
LocalDateDoubleTimeSeriesBuilder tsb) {
int nRates = FIXING_DATES.length;
double[][] ratesUp = new double[nRates][];
double[][] ratesDw = new double[nRates][];
for (int i = 0; i < nRates; ++i) {
mockRatesUp[i] = mock(OvernightIndexRates.class);
simpleProvUp[i] = new SimpleRatesProvider(mockRatesUp[i]);
mockRatesDw[i] = mock(OvernightIndexRates.class);
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++) {
when(mockRatesPeriodUp.rate(obsArray[i])).thenReturn(FORWARD_RATES[i]);
when(mockRatesPeriodDw.rate(obsArray[i])).thenReturn(FORWARD_RATES[i]);
when(mockRatesUp[i].periodRate(obsArray[1], FIXING_FINAL_DATE)).thenReturn(rateCmp);
when(mockRatesDw[i].periodRate(obsArray[1], FIXING_FINAL_DATE)).thenReturn(rateCmp);
for (int j = 0; j < nRates; ++j) {
when(mockRatesUp[j].rate(obsArray[i])).thenReturn(ratesUp[j][i]);
when(mockRatesDw[j].rate(obsArray[i])).thenReturn(ratesDw[j][i]);
}
}
OvernightIndexObservation indexObs = OvernightIndexObservation.of(obsArray[0].getIndex(), periodStartDate, REF_DATA);
when(mockRatesPeriodUp.periodRate(indexObs, periodEndDate)).thenReturn(rateCmp + EPS_FD);
when(mockRatesPeriodDw.periodRate(indexObs, periodEndDate)).thenReturn(rateCmp - EPS_FD);
if (tsb != null) {
when(mockRatesPeriodUp.getFixings()).thenReturn(tsb.build());
when(mockRatesPeriodDw.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < nRates; i++) {
when(mockRatesUp[i].getFixings()).thenReturn(tsb.build());
when(mockRatesDw[i].getFixings()).thenReturn(tsb.build());
}
}
}
/** Two days cutoff and one already fixed ON rate. Test the already fixed portion with only one fixed ON rate.*/
public void rateFedFund2CutOffValuation1() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing 1
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
for (int i = 0; i < 2; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < 2; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = 2; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
LocalDate fixingknown = FIXING_DATES[1];
LocalDate endDateKnown = USD_FED_FUND.calculateMaturityFromEffective(fixingknown, REF_DATA);
double afKnown = USD_FED_FUND.getDayCount().yearFraction(fixingknown, endDateKnown);
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = 2; i < 5; i++) {
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(
OvernightIndexObservation.of(USD_FED_FUND, FIXING_START_NEXT_DATE, REF_DATA), FIXING_FINAL_DATE))
.thenReturn(rateCmp);
LocalDate fixingCutOff = FIXING_DATES[5];
LocalDate endDateCutOff = USD_FED_FUND.calculateMaturityFromEffective(fixingCutOff, REF_DATA);
double afCutOff = USD_FED_FUND.getDayCount().yearFraction(fixingCutOff, endDateCutOff);
double rateExpected = (FIXING_RATES[1] * afKnown + Math.log(1.0 + rateCmp * afApprox) + FORWARD_RATES[4] * afCutOff)
/ (afKnown + afApprox + afCutOff);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation.
* Two days cutoff and one already fixed ON rate. Test the already fixed portion with only one fixed ON rate.*/
public void rateFedFund2CutOffValuation1Sensitivity() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing 1
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
for (int i = 0; i < 2; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
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];
OvernightIndexRates mockRatesPeriodUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodUp = new SimpleRatesProvider(mockRatesPeriodUp);
OvernightIndexRates mockRatesPeriodDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodDw = new SimpleRatesProvider(mockRatesPeriodDw);
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < 2; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(PointSensitivityBuilder.none());
}
for (int i = 2; i < nRates; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
LocalDate fixingStartDate = USD_FED_FUND.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = USD_FED_FUND.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
PointSensitivityBuilder pointSensitivity =
OvernightRateSensitivity.ofPeriod(USD_OBS[i], fixingEndDate, 1d);
when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(pointSensitivity);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = 2; i < 5; i++) {
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
OvernightIndexObservation obs = OvernightIndexObservation.of(USD_FED_FUND, FIXING_START_NEXT_DATE, REF_DATA);
when(mockRates.periodRate(obs, FIXING_FINAL_DATE)).thenReturn(rateCmp);
PointSensitivityBuilder periodSensitivity = OvernightRateSensitivity.ofPeriod(obs, FIXING_FINAL_DATE, 1d);
when(mockRates.periodRatePointSensitivity(obs, FIXING_FINAL_DATE)).thenReturn(periodSensitivity);
setRatesProviders(
mockRatesUp, simpleProvUp, mockRatesDw, simpleProvDw,
mockRatesPeriodUp, simpleProvPeriodUp, mockRatesPeriodDw, simpleProvPeriodDw,
ro, USD_OBS, FIXING_START_NEXT_DATE, FIXING_FINAL_DATE, rateCmp, tsb);
for (int i = 0; i < 2; i++) {
when(mockRatesPeriodUp.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesPeriodDw.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
for (int j = 0; j < nRates; ++j) {
when(mockRatesUp[j].rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesDw[j].rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
}
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
PointSensitivityBuilder sensitivityBuilderExpected1 = PointSensitivityBuilder.none();
for (int i = 0; i < nRates; ++i) {
when(mockRatesUp[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]);
double res = 0.5 * (rateUp - rateDw) / EPS_FD;
LocalDate fixingStartDate = USD_FED_FUND.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = USD_FED_FUND.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
sensitivityBuilderExpected1 = res == 0.0 ? sensitivityBuilderExpected1 : sensitivityBuilderExpected1
.combinedWith(OvernightRateSensitivity.ofPeriod(USD_OBS[i], fixingEndDate, res));
}
double ratePeriodUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodUp);
double ratePeriodDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodDw);
double periodSensitivityExpected = 0.5 * (ratePeriodUp - ratePeriodDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected2 =
OvernightRateSensitivity.ofPeriod(obs, FIXING_FINAL_DATE, periodSensitivityExpected);
PointSensitivityBuilder sensitivityBuilderExpected = sensitivityBuilderExpected1
.combinedWith(sensitivityBuilderExpected2);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
/** Two days cutoff and two already fixed ON rate. ON index is Fed Fund. */
public void rateFedFund2CutOffValuation2() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 12), date(2015, 1, 13)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = lastFixing; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
double afKnown = 0.0;
double accruedKnown = 0.0;
for (int i = 0; i < lastFixing - 1; i++) {
LocalDate fixingknown = FIXING_DATES[i + 1];
LocalDate endDateKnown = USD_FED_FUND.calculateMaturityFromEffective(fixingknown, REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(fixingknown, endDateKnown);
afKnown += af;
accruedKnown += FIXING_RATES[i + 1] * af;
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 5; i++) {
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(USD_OBS[lastFixing], FIXING_DATES[5])).thenReturn(rateCmp);
LocalDate fixingCutOff = FIXING_DATES[5];
LocalDate endDateCutOff = USD_FED_FUND.calculateMaturityFromEffective(fixingCutOff, REF_DATA);
double afCutOff = USD_FED_FUND.getDayCount().yearFraction(fixingCutOff, endDateCutOff);
double rateExpected = (accruedKnown + Math.log(1.0 + rateCmp * afApprox) + FORWARD_RATES[4] * afCutOff)
/ (afKnown + afApprox + afCutOff);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation.
* Two days cutoff and two already fixed ON rate. ON index is Fed Fund. */
public void rateFedFund2CutOffValuation2Sensitivity() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 12), date(2015, 1, 13)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
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];
OvernightIndexRates mockRatesPeriodUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodUp = new SimpleRatesProvider(mockRatesPeriodUp);
OvernightIndexRates mockRatesPeriodDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodDw = new SimpleRatesProvider(mockRatesPeriodDw);
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(
PointSensitivityBuilder.none());
}
for (int i = lastFixing; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
LocalDate fixingStartDate = USD_FED_FUND.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = USD_FED_FUND.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
PointSensitivityBuilder pointSensitivity = OvernightRateSensitivity.ofPeriod(USD_OBS[i], fixingEndDate, 1d);
when(mockRates.ratePointSensitivity(USD_OBS[i])).thenReturn(pointSensitivity);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 5; i++) {
LocalDate endDate = USD_FED_FUND.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(USD_OBS[lastFixing], FIXING_DATES[5])).thenReturn(rateCmp);
PointSensitivityBuilder periodSensitivity =
OvernightRateSensitivity.ofPeriod(USD_OBS[lastFixing], FIXING_DATES[5], 1d);
when(mockRates.periodRatePointSensitivity(USD_OBS[lastFixing], FIXING_DATES[5]))
.thenReturn(periodSensitivity);
setRatesProviders(
mockRatesUp, simpleProvUp, mockRatesDw, simpleProvDw,
mockRatesPeriodUp, simpleProvPeriodUp, mockRatesPeriodDw, simpleProvPeriodDw,
ro, USD_OBS, FIXING_DATES[lastFixing], FIXING_DATES[5], rateCmp, tsb);
when(mockRatesPeriodUp.getFixings()).thenReturn(tsb.build());
when(mockRatesPeriodDw.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRatesPeriodUp.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesPeriodDw.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
for (int j = 0; j < nRates; ++j) {
when(mockRatesUp[j].rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesDw[j].rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
}
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
PointSensitivityBuilder sensitivityBuilderExpected1 = PointSensitivityBuilder.none();
for (int i = 0; i < nRates; ++i) {
when(mockRatesUp[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]);
double res = 0.5 * (rateUp - rateDw) / EPS_FD;
LocalDate fixingStartDate = USD_FED_FUND.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = USD_FED_FUND.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
sensitivityBuilderExpected1 = res == 0.0 ? sensitivityBuilderExpected1 : sensitivityBuilderExpected1
.combinedWith(OvernightRateSensitivity.ofPeriod(USD_OBS[i], fixingEndDate, res));
}
double ratePeriodUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodUp);
double ratePeriodDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodDw);
double periodSensitivityExpected = 0.5 * (ratePeriodUp - ratePeriodDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected2 =
OvernightRateSensitivity.ofPeriod(USD_OBS[lastFixing], FIXING_DATES[5], periodSensitivityExpected);
PointSensitivityBuilder sensitivityBuilderExpected = sensitivityBuilderExpected1
.combinedWith(sensitivityBuilderExpected2);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
//-------------------------------------------------------------------------
/** Two days cutoff and two already fixed ON rate. ON index is SONIA. */
public void rateSonia2CutOffValuation2() {
// publication=0, cutoff=2, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(GBP_SONIA, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(GBP_SONIA);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = lastFixing; i < GBP_OBS.length; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
double afKnown = 0.0;
double accruedKnown = 0.0;
for (int i = 0; i < lastFixing - 1; i++) {
LocalDate fixingknown = FIXING_DATES[i + 1];
LocalDate endDateKnown = GBP_SONIA.calculateMaturityFromEffective(fixingknown, REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(fixingknown, endDateKnown);
afKnown += af;
accruedKnown += FIXING_RATES[i + 1] * af;
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 5; i++) {
LocalDate endDate = GBP_SONIA.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(GBP_OBS[lastFixing], FIXING_DATES[5])).thenReturn(rateCmp);
LocalDate fixingCutOff = FIXING_DATES[5];
LocalDate endDateCutOff = GBP_SONIA.calculateMaturityFromEffective(fixingCutOff, REF_DATA);
double afCutOff = GBP_SONIA.getDayCount().yearFraction(fixingCutOff, endDateCutOff);
double rateExpected = (accruedKnown + Math.log(1.0 + rateCmp * afApprox) + FORWARD_RATES[4] * afCutOff)
/ (afKnown + afApprox + afCutOff);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation.
* Two days cutoff and two already fixed ON rate. ON index is SONIA. */
public void rateSonia2CutOffValuation2Sensitivity() {
// publication=0, cutoff=2, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(GBP_SONIA, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(GBP_SONIA);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
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];
OvernightIndexRates mockRatesPeriodUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodUp = new SimpleRatesProvider(mockRatesPeriodUp);
OvernightIndexRates mockRatesPeriodDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodDw = new SimpleRatesProvider(mockRatesPeriodDw);
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(
PointSensitivityBuilder.none());
}
for (int i = lastFixing; i < GBP_OBS.length; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FORWARD_RATES[i]);
LocalDate fixingStartDate = GBP_SONIA.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = GBP_SONIA.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
PointSensitivityBuilder pointSensitivity = OvernightRateSensitivity.ofPeriod(GBP_OBS[i], fixingEndDate, 1d);
when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(pointSensitivity);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 5; i++) {
LocalDate endDate = GBP_SONIA.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(GBP_OBS[lastFixing], FIXING_DATES[5])).thenReturn(rateCmp);
PointSensitivityBuilder periodSensitivity = OvernightRateSensitivity.ofPeriod(GBP_OBS[lastFixing], FIXING_DATES[5], 1d);
when(mockRates.periodRatePointSensitivity(GBP_OBS[lastFixing], FIXING_DATES[5])).thenReturn(periodSensitivity);
setRatesProviders(
mockRatesUp, simpleProvUp, mockRatesDw, simpleProvDw,
mockRatesPeriodUp, simpleProvPeriodUp, mockRatesPeriodDw, simpleProvPeriodDw,
ro, GBP_OBS, FIXING_DATES[lastFixing], FIXING_DATES[5], rateCmp, tsb);
when(mockRatesPeriodUp.getFixings()).thenReturn(tsb.build());
when(mockRatesPeriodDw.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRatesPeriodUp.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesPeriodDw.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
for (int j = 0; j < nRates; ++j) {
when(mockRatesUp[j].rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesDw[j].rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
}
}
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
PointSensitivityBuilder sensitivityBuilderExpected1 = PointSensitivityBuilder.none();
for (int i = 0; i < nRates; ++i) {
when(mockRatesUp[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]);
double res = 0.5 * (rateUp - rateDw) / EPS_FD;
LocalDate fixingStartDate = GBP_SONIA.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = GBP_SONIA.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
sensitivityBuilderExpected1 = res == 0.0 ? sensitivityBuilderExpected1 : sensitivityBuilderExpected1
.combinedWith(OvernightRateSensitivity.ofPeriod(GBP_OBS[i], fixingEndDate, res));
}
double ratePeriodUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodUp);
double ratePeriodDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodDw);
double periodSensitivityExpected = 0.5 * (ratePeriodUp - ratePeriodDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected2 =
OvernightRateSensitivity.ofPeriod(GBP_OBS[lastFixing], FIXING_DATES[5], periodSensitivityExpected);
PointSensitivityBuilder sensitivityBuilderExpected = sensitivityBuilderExpected1
.combinedWith(sensitivityBuilderExpected2);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
/** No cutoff period and two already fixed ON rate. ON index is SONIA. */
public void rateSonia0CutOffValuation2() {
// publication=0, cutoff=0, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(GBP_SONIA, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(GBP_SONIA);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = lastFixing; i < GBP_OBS.length; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
double afKnown = 0.0;
double accruedKnown = 0.0;
for (int i = 0; i < lastFixing - 1; i++) {
LocalDate fixingknown = FIXING_DATES[i + 1];
LocalDate endDateKnown = GBP_SONIA.calculateMaturityFromEffective(fixingknown, REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(fixingknown, endDateKnown);
afKnown += af;
accruedKnown += FIXING_RATES[i + 1] * af;
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 6; i++) {
LocalDate endDate = GBP_SONIA.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(GBP_OBS[lastFixing], FIXING_DATES[6])).thenReturn(rateCmp);
double rateExpected = (accruedKnown + Math.log(1.0 + rateCmp * afApprox))
/ (afKnown + afApprox);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate sensitivity against FD approximation.
* No cutoff period and two already fixed ON rate. ON index is SONIA. */
public void rateSonia0CutOffValuation2Sensitivity() {
// publication=0, cutoff=0, effective offset=0, TS: Fixing 2
LocalDate[] valuationDate = {date(2015, 1, 9), date(2015, 1, 12)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(GBP_SONIA, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(GBP_SONIA);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 3;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
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];
OvernightIndexRates mockRatesPeriodUp = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodUp = new SimpleRatesProvider(mockRatesPeriodUp);
OvernightIndexRates mockRatesPeriodDw = mock(OvernightIndexRates.class);
SimpleRatesProvider simpleProvPeriodDw = new SimpleRatesProvider(mockRatesPeriodDw);
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(
PointSensitivityBuilder.none());
}
for (int i = lastFixing; i < GBP_OBS.length; i++) {
when(mockRates.rate(GBP_OBS[i])).thenReturn(FORWARD_RATES[i]);
LocalDate fixingStartDate = GBP_SONIA.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = GBP_SONIA.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
PointSensitivityBuilder pointSensitivity = OvernightRateSensitivity.ofPeriod(GBP_OBS[i], fixingEndDate, 1d);
when(mockRates.ratePointSensitivity(GBP_OBS[i])).thenReturn(pointSensitivity);
}
double investmentFactor = 1.0;
double afApprox = 0.0;
for (int i = lastFixing; i < 6; i++) {
LocalDate endDate = GBP_SONIA.calculateMaturityFromEffective(FIXING_DATES[i], REF_DATA);
double af = GBP_SONIA.getDayCount().yearFraction(FIXING_DATES[i], endDate);
afApprox += af;
investmentFactor *= 1.0d + af * FORWARD_RATES[i];
}
double rateCmp = (investmentFactor - 1.0d) / afApprox;
when(mockRates.periodRate(GBP_OBS[lastFixing], FIXING_DATES[6])).thenReturn(rateCmp);
PointSensitivityBuilder periodSensitivity = OvernightRateSensitivity.ofPeriod(GBP_OBS[lastFixing], FIXING_DATES[6], 1d);
when(mockRates.periodRatePointSensitivity(GBP_OBS[lastFixing], FIXING_DATES[6]))
.thenReturn(periodSensitivity);
setRatesProviders(
mockRatesUp, simpleProvUp, mockRatesDw, simpleProvDw,
mockRatesPeriodUp, simpleProvPeriodUp, mockRatesPeriodDw, simpleProvPeriodDw,
ro, GBP_OBS, FIXING_DATES[lastFixing], FIXING_DATES[6], rateCmp, tsb);
when(mockRatesPeriodUp.getFixings()).thenReturn(tsb.build());
when(mockRatesPeriodDw.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRatesPeriodUp.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesPeriodDw.rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
for (int j = 0; j < nRates; ++j) {
when(mockRatesUp[j].rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
when(mockRatesDw[j].rate(GBP_OBS[i])).thenReturn(FIXING_RATES[i]);
}
}
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodUp.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesPeriodDw.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderComputed = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
PointSensitivityBuilder sensitivityBuilderExpected1 = PointSensitivityBuilder.none();
for (int i = 0; i < nRates; ++i) {
when(mockRatesUp[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
when(mockRatesDw[i].getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvUp[i]);
double rateDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProvDw[i]);
double res = 0.5 * (rateUp - rateDw) / EPS_FD;
LocalDate fixingStartDate = GBP_SONIA.calculateEffectiveFromFixing(FIXING_DATES[i], REF_DATA);
LocalDate fixingEndDate = GBP_SONIA.calculateMaturityFromEffective(fixingStartDate, REF_DATA);
sensitivityBuilderExpected1 = res == 0.0 ? sensitivityBuilderExpected1 : sensitivityBuilderExpected1
.combinedWith(OvernightRateSensitivity.ofPeriod(GBP_OBS[i], fixingEndDate, res));
}
double ratePeriodUp = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodUp);
double ratePeriodDw = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE,
simpleProvPeriodDw);
double periodSensitivityExpected = 0.5 * (ratePeriodUp - ratePeriodDw) / EPS_FD;
PointSensitivityBuilder sensitivityBuilderExpected2 =
OvernightRateSensitivity.ofPeriod(GBP_OBS[lastFixing], FIXING_DATES[6], periodSensitivityExpected);
PointSensitivityBuilder sensitivityBuilderExpected = sensitivityBuilderExpected1
.combinedWith(sensitivityBuilderExpected2);
assertTrue(sensitivityBuilderComputed.build().normalized().equalWithTolerance(
sensitivityBuilderExpected.build().normalized(), EPS_FD));
}
}
//-------------------------------------------------------------------------
/** One past fixing missing. Checking the error thrown. */
public void rateFedFund2CutOffValuation2MissingFixing() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing 2
LocalDate valuationDate = date(2015, 1, 13);
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
when(mockRates.getValuationDate()).thenReturn(valuationDate);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(valuationDate, mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 2;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = lastFixing; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
assertThrows(
() -> OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv),
PricingException.class);
assertThrows(
() -> OBS_FN_APPROX_FWD.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv),
PricingException.class);
}
/** Two days cutoff, all ON rates already fixed. */
public void rateFedFund2CutOffValuationEnd() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing all
LocalDate[] valuationDate = {date(2015, 1, 15), date(2015, 1, 16)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 6;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int i = 0; i < lastFixing; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FIXING_RATES[i]);
}
for (int i = lastFixing; i < USD_OBS.length; i++) {
when(mockRates.rate(USD_OBS[i])).thenReturn(FORWARD_RATES[i]);
}
double afKnown = 0.0;
double accruedKnown = 0.0;
for (int i = 0; i < 4; i++) {
LocalDate fixingknown = FIXING_DATES[i + 1];
LocalDate endDateKnown = USD_FED_FUND.calculateMaturityFromEffective(fixingknown, REF_DATA);
double af = USD_FED_FUND.getDayCount().yearFraction(fixingknown, endDateKnown);
afKnown += af;
accruedKnown += FIXING_RATES[i + 1] * af;
}
LocalDate fixingCutOff = FIXING_DATES[5];
LocalDate endDateCutOff = USD_FED_FUND.calculateMaturityFromEffective(fixingCutOff, REF_DATA);
double afCutOff = USD_FED_FUND.getDayCount().yearFraction(fixingCutOff, endDateCutOff);
double rateExpected = (accruedKnown + FIXING_RATES[4] * afCutOff)
/ (afKnown + afCutOff);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
double rateComputed = OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(rateComputed, rateExpected, TOLERANCE_RATE);
}
}
/** Test rate Sensitivity. Two days cutoff, all ON rates already fixed. Thus none is expected*/
public void rateFedFund2CutOffValuationEndSensitivity() {
// publication=1, cutoff=2, effective offset=0, TS: Fixing all
LocalDate[] valuationDate = {date(2015, 1, 15), date(2015, 1, 16)};
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
OvernightIndexRates mockRates = mock(OvernightIndexRates.class);
when(mockRates.getIndex()).thenReturn(USD_FED_FUND);
SimpleRatesProvider simpleProv = new SimpleRatesProvider(mockRates);
LocalDateDoubleTimeSeriesBuilder tsb = LocalDateDoubleTimeSeries.builder();
int lastFixing = 6;
for (int i = 0; i < lastFixing; i++) {
tsb.put(FIXING_DATES[i], FIXING_RATES[i]);
}
when(mockRates.getFixings()).thenReturn(tsb.build());
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
when(mockRates.getValuationDate()).thenReturn(valuationDate[loopvaldate]);
PointSensitivityBuilder sensitivityBuilderExpected = OBS_FN_APPROX_FWD.rateSensitivity(ro,
DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, simpleProv);
assertEquals(sensitivityBuilderExpected, PointSensitivityBuilder.none());
}
}
//-------------------------------------------------------------------------
private static final CurveInterpolator INTERPOLATOR = CurveInterpolators.DOUBLE_QUADRATIC;
private static final LocalDateDoubleTimeSeries TIME_SERIES;
static {
LocalDateDoubleTimeSeriesBuilder builder = LocalDateDoubleTimeSeries.builder();
for (int i = 0; i < FIXING_DATES.length; i++) {
builder.put(FIXING_DATES[i], FIXING_RATES[i]);
}
TIME_SERIES = builder.build();
}
private static final RatesFiniteDifferenceSensitivityCalculator CAL_FD =
new RatesFiniteDifferenceSensitivityCalculator(EPS_FD);
/** Test curve parameter sensitivity with finite difference sensitivity calculator. No cutoff period*/
public void rateFedFundNoCutOffForwardParameterSensitivity() {
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
DoubleArray time_usd = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 5.0, 10.0);
DoubleArray rate_usd = DoubleArray.of(0.0100, 0.0110, 0.0115, 0.0130, 0.0135, 0.0135);
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 0, REF_DATA);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
Curve fedFundCurve = InterpolatedNodalCurve.of(
Curves.zeroRates("USD-Fed-Fund", ACT_ACT_ISDA), time_usd, rate_usd, INTERPOLATOR);
ImmutableRatesProvider prov = ImmutableRatesProvider.builder(valuationDate[loopvaldate])
.overnightIndexCurve(USD_FED_FUND, fedFundCurve, TIME_SERIES)
.build();
PointSensitivityBuilder sensitivityBuilderComputed =
OBS_FN_APPROX_FWD.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov);
CurrencyParameterSensitivities parameterSensitivityComputed =
prov.parameterSensitivity(sensitivityBuilderComputed.build());
CurrencyParameterSensitivities parameterSensitivityExpected =
CAL_FD.sensitivity(prov, (p) -> CurrencyAmount.of(USD_FED_FUND.getCurrency(),
OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, (p))));
assertTrue(parameterSensitivityComputed.equalWithTolerance(parameterSensitivityExpected, EPS_FD * 10.0));
}
}
/** Test curve parameter sensitivity with finite difference sensitivity calculator. Two days cutoff period*/
public void rateFedFund2CutOffForwardParameterSensitivity() {
LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)};
DoubleArray time_usd = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 5.0, 10.0);
DoubleArray rate_usd = DoubleArray.of(0.0100, 0.0110, 0.0115, 0.0130, 0.0135, 0.0135);
OvernightAveragedRateComputation ro =
OvernightAveragedRateComputation.of(USD_FED_FUND, FIXING_START_DATE, FIXING_END_DATE, 2, REF_DATA);
for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) {
Curve fedFundCurve = InterpolatedNodalCurve.of(
Curves.zeroRates("USD-Fed-Fund", ACT_ACT_ISDA), time_usd, rate_usd, INTERPOLATOR);
ImmutableRatesProvider prov = ImmutableRatesProvider.builder(valuationDate[loopvaldate])
.overnightIndexCurve(USD_FED_FUND, fedFundCurve, TIME_SERIES)
.build();
PointSensitivityBuilder sensitivityBuilderComputed =
OBS_FN_APPROX_FWD.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov);
CurrencyParameterSensitivities parameterSensitivityComputed =
prov.parameterSensitivity(sensitivityBuilderComputed.build());
CurrencyParameterSensitivities parameterSensitivityExpected =
CAL_FD.sensitivity(prov, (p) -> CurrencyAmount.of(USD_FED_FUND.getCurrency(),
OBS_FN_APPROX_FWD.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, (p))));
assertTrue(parameterSensitivityComputed.equalWithTolerance(parameterSensitivityExpected, EPS_FD * 10.0));
}
}
}