CouponIborAverageFixingDatesCompoundingDefinition extends CouponDefinition implements InstrumentDefinitionWithData<Payment, DoubleTimeSeries<ZonedDateTime>> { @Override public CouponIborAverageFixingDatesCompounding toDerivative(final ZonedDateTime date) { ArgumentChecker.notNull(date, "date"); final int nPeriods = getFixingDates().length; final int[] nDates = new int[nPeriods]; final LocalDate dayConversion = date.toLocalDate(); ArgumentChecker.isTrue(!dayConversion.isAfter(getPaymentDate().toLocalDate()), "date is after payment date"); ArgumentChecker.isTrue(!dayConversion.isAfter(getFixingDates()[0][0].toLocalDate()), "Do not have any fixing data but are asking for a derivative at " + date + " which is after fixing date " + getFixingDates()[0][0]); final double paymentTime = TimeCalculator.getTimeBetween(date, getPaymentDate()); final double[][] fixingTime = new double[nPeriods][]; final double[][] fixingPeriodStartTime = new double[nPeriods][]; final double[][] fixingPeriodEndTime = new double[nPeriods][]; for (int i = 0; i < nPeriods; ++i) { nDates[i] = getFixingDates()[i].length; fixingTime[i] = new double[nDates[i]]; fixingPeriodStartTime[i] = new double[nDates[i]]; fixingPeriodEndTime[i] = new double[nDates[i]]; for (int j = 0; j < nDates[i]; ++j) { fixingTime[i][j] = TimeCalculator.getTimeBetween(date, getFixingDates()[i][j]); fixingPeriodStartTime[i][j] = TimeCalculator.getTimeBetween(date, getFixingPeriodStartDates()[i][j]); fixingPeriodEndTime[i][j] = TimeCalculator.getTimeBetween(date, getFixingPeriodEndDates()[i][j]); } } return new CouponIborAverageFixingDatesCompounding(getCurrency(), paymentTime, getPaymentYearFraction(), getNotional(), getPaymentAccrualFactors(), getIndex(), fixingTime, getWeight(), fixingPeriodStartTime, fixingPeriodEndTime, getFixingPeriodAccrualFactor(), 0.0, 1.0); } CouponIborAverageFixingDatesCompoundingDefinition(final Currency currency, final ZonedDateTime paymentDate,
      final ZonedDateTime accrualStartDate, final ZonedDateTime accrualEndDate, final double paymentAccrualFactor,
      final double notional, final double[] paymentAccrualFactors, final IborIndex index, final ZonedDateTime[][] fixingDates,
      final double[][] weights, final Calendar iborCalendar);  CouponIborAverageFixingDatesCompoundingDefinition(final Currency currency, final ZonedDateTime paymentDate,
      final ZonedDateTime accrualStartDate, final ZonedDateTime accrualEndDate, final double paymentAccrualFactor,
      final double notional, final double[] paymentAccrualFactors, final IborIndex index, final ZonedDateTime[][] fixingDates,
      final double[][] weights, final ZonedDateTime[][] fixingPeriodStartDates, final ZonedDateTime[][] fixingPeriodEndDates,
      final double[][] fixingPeriodAccrualFactors); static CouponIborAverageFixingDatesCompoundingDefinition from(final Currency currency, final ZonedDateTime paymentDate,
      final ZonedDateTime accrualStartDate, final ZonedDateTime accrualEndDate, final double paymentAccrualFactor,
      final double notional, final double[] paymentAccrualFactors, final IborIndex index, final ZonedDateTime[][] fixingDates,
      final double[][] weights, final Calendar iborCalendar); static CouponIborAverageFixingDatesCompoundingDefinition from(final Currency currency, final ZonedDateTime paymentDate,
      final ZonedDateTime accrualStartDate, final ZonedDateTime accrualEndDate, final double paymentAccrualFactor,
      final double notional, final double[] paymentAccrualFactors, final IborIndex index, final ZonedDateTime[][] fixingDates,
      final double[][] weights, final ZonedDateTime[][] fixingPeriodStartDates, final ZonedDateTime[][] fixingPeriodEndDates,
      final double[][] fixingPeriodAccrualFactors); CouponIborAverageFixingDatesCompoundingDefinition withNotional(final double notional); @Override V accept(final InstrumentDefinitionVisitor<U, V> visitor, final U data); @Override V accept(final InstrumentDefinitionVisitor<?, V> visitor); IborIndex getIndex(); double[] getPaymentAccrualFactors(); double[][] getWeight(); ZonedDateTime[][] getFixingPeriodStartDates(); ZonedDateTime[][] getFixingPeriodEndDates(); ZonedDateTime[][] getFixingDates(); double[][] getFixingPeriodAccrualFactor(); @Override CouponIborAverageFixingDatesCompounding toDerivative(final ZonedDateTime date); @Override Coupon toDerivative(ZonedDateTime dateTime, DoubleTimeSeries<ZonedDateTime> indexFixingTimeSeries); @Override int hashCode(); @Override boolean equals(Object obj);  }
@Test public void toDerivativeEndOfPeriodTest() { final ZonedDateTime[] dates1 = new ZonedDateTime[NUM_PRDS * NUM_OBS]; final double[] rates1 = new double[NUM_PRDS * NUM_OBS]; Arrays.fill(rates1, 0.01); for (int i = 0; i < NUM_PRDS; ++i) { for (int j = 0; j < NUM_OBS; ++j) { dates1[NUM_OBS * i + j] = FIXING_DATES[i][j]; } } final DoubleTimeSeries<ZonedDateTime> fixingTS1 = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dates1, rates1); final ZonedDateTime refDate4 = FIXING_DATES[2][4]; final CouponIborAverageFixingDatesCompounding derivative4 = (CouponIborAverageFixingDatesCompounding) DFN1.toDerivative(refDate4, fixingTS1); checkOutputs(refDate4, DFN1, derivative4, 2 + 1, 0); double refAcc = 1.0; for (int i = 0; i < 3; ++i) { double rate = 0.0; for (int j = 0; j < NUM_OBS; ++j) { rate += WEIGHTS[i][j] * 0.01; } refAcc *= (1.0 + rate * ACCRUAL_FACTORS[i]); } assertEquals(refAcc, derivative4.getAmountAccrued(), 1.e-14); assertEquals(0., derivative4.getInvestmentFactor(), 1.e-14); }
@Test public void toDerivativeCoincideTest() { final ZonedDateTime[] dates1 = new ZonedDateTime[NUM_PRDS * NUM_OBS]; final double[] rates1 = new double[NUM_PRDS * NUM_OBS]; Arrays.fill(rates1, 0.01); for (int i = 0; i < NUM_PRDS; ++i) { for (int j = 0; j < NUM_OBS; ++j) { dates1[NUM_OBS * i + j] = FIXING_DATES[i][j]; } } final DoubleTimeSeries<ZonedDateTime> fixingTS1 = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dates1, rates1); final ZonedDateTime refDate5 = FIXING_DATES[1][2]; final CouponIborAverageFixingDatesCompounding derivative5 = (CouponIborAverageFixingDatesCompounding) DFN1.toDerivative(refDate5, fixingTS1); checkOutputs(refDate5, DFN1, derivative5, 1, 3); double refAcc = 1.0; for (int i = 0; i < 1; ++i) { double rate = 0.0; for (int j = 0; j < NUM_OBS; ++j) { rate += WEIGHTS[i][j] * 0.01; } refAcc *= (1.0 + rate * ACCRUAL_FACTORS[i]); } assertEquals(refAcc, derivative5.getAmountAccrued(), 1.e-14); double refRate = 0.0; for (int j = 0; j < 3; ++j) { refRate += WEIGHTS[1][j] * 0.01; } assertEquals(refRate, derivative5.getInvestmentFactor(), 1.e-14); }
@Test public void toDerivativeNullRateTest() { final ZonedDateTime[] dates1 = new ZonedDateTime[NUM_PRDS * NUM_OBS]; final double[] rates1 = new double[NUM_PRDS * NUM_OBS]; Arrays.fill(rates1, 0.01); for (int i = 0; i < NUM_PRDS; ++i) { for (int j = 0; j < NUM_OBS; ++j) { dates1[NUM_OBS * i + j] = FIXING_DATES[i][j]; } } dates1[7] = dates1[7].plusDays(1); final DoubleTimeSeries<ZonedDateTime> fixingTS1 = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dates1, rates1); final ZonedDateTime refDate5 = FIXING_DATES[1][2]; final CouponIborAverageFixingDatesCompounding derivative5 = (CouponIborAverageFixingDatesCompounding) DFN1.toDerivative(refDate5, fixingTS1); checkOutputs(refDate5, DFN1, derivative5, 1, 2); double refAcc = 1.0; for (int i = 0; i < 1; ++i) { double rate = 0.0; for (int j = 0; j < NUM_OBS; ++j) { rate += WEIGHTS[i][j] * 0.01; } refAcc *= (1.0 + rate * ACCRUAL_FACTORS[i]); } assertEquals(refAcc, derivative5.getAmountAccrued(), 1.e-14); double refRate = 0.0; for (int j = 0; j < 2; ++j) { refRate += WEIGHTS[1][j] * 0.01; } assertEquals(refRate, derivative5.getInvestmentFactor(), 1.e-14); }
@Test public void toDerivativeDifferentFixingSize() { int dim = 0; final int[] nDates = new int[NB_SUBPERIODS]; for (int i = 0; i < NB_SUBPERIODS; ++i) { nDates[i] = FIXING_DATES_3[i].length; dim += FIXING_DATES_3[i].length; } final ZonedDateTime[] dates1 = new ZonedDateTime[dim]; final double[] rates1 = new double[dim]; Arrays.fill(rates1, 0.01); int k = 0; for (int i = 0; i < NB_SUBPERIODS; ++i) { for (int j = 0; j < nDates[i]; ++j) { dates1[k] = FIXING_DATES_3[i][j]; ++k; } } dates1[nDates[0] + 1] = dates1[nDates[0] + 1].plusDays(1); final DoubleTimeSeries<ZonedDateTime> fixingTS1 = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dates1, rates1); final ZonedDateTime refDate = FIXING_DATES_3[1][1]; final CouponIborAverageFixingDatesCompounding deriv = (CouponIborAverageFixingDatesCompounding) DFN3.toDerivative(refDate, fixingTS1); checkOutputs(refDate, DFN3, deriv, 1, 1); double refAcc = 1.0; for (int i = 0; i < 1; ++i) { double rate = 0.0; for (int j = 0; j < nDates[i]; ++j) { rate += WEIGHTS_3[i][j] * 0.01; } refAcc *= (1.0 + rate * ACCRUAL_FACTORS_3[i]); } assertEquals(refAcc, deriv.getAmountAccrued(), 1.e-14); double refRate = 0.0; for (int j = 0; j < 1; ++j) { refRate += WEIGHTS_3[1][j] * 0.01; } assertEquals(refRate, deriv.getInvestmentFactor(), 1.e-14); }
@Test public void exceptionTest() { try { new CouponIborAverageFixingDatesCompoundingDefinition(Currency.GBP, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, WEIGHTS, CALENDAR); throw new RuntimeException(); } catch (final Exception e) { assertEquals("index currency different from payment currency", e.getMessage()); } try { new CouponIborAverageFixingDatesCompoundingDefinition(Currency.USD, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, WEIGHTS, EXP_START_DATES, EXP_END_DATES, FIX_ACC_FACTORS); throw new RuntimeException(); } catch (final Exception e) { assertEquals("index currency different from payment currency", e.getMessage()); } double[][] shortWeight = Arrays.copyOf(WEIGHTS, NUM_PRDS - 1); try { new CouponIborAverageFixingDatesCompoundingDefinition(CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, shortWeight, CALENDAR); throw new RuntimeException(); } catch (final Exception e) { assertEquals("weights length different from fixingDate length", e.getMessage()); } try { new CouponIborAverageFixingDatesCompoundingDefinition(CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, shortWeight, EXP_START_DATES, EXP_END_DATES, FIX_ACC_FACTORS); throw new RuntimeException(); } catch (final Exception e) { assertEquals("weights length different from fixingDate length", e.getMessage()); } double[][] smallWeight = new double[NUM_PRDS][]; for (int i = 0; i < NUM_PRDS; ++i) { smallWeight[i] = Arrays.copyOf(WEIGHTS[i], NUM_OBS - 1); } final ZonedDateTime[][] shortStartDates = Arrays.copyOf(EXP_START_DATES, NUM_PRDS - 1); try { new CouponIborAverageFixingDatesCompoundingDefinition(CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, WEIGHTS, shortStartDates, EXP_END_DATES, FIX_ACC_FACTORS); throw new RuntimeException(); } catch (final Exception e) { assertEquals("fixingPeriodStartDates length different from fixingDate length", e.getMessage()); } final ZonedDateTime[][] shortEndDates = Arrays.copyOf(EXP_END_DATES, NUM_PRDS - 1); try { new CouponIborAverageFixingDatesCompoundingDefinition(CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, WEIGHTS, EXP_START_DATES, shortEndDates, FIX_ACC_FACTORS); throw new RuntimeException(); } catch (final Exception e) { assertEquals("fixingPeriodEndDates length different from fixingDate length", e.getMessage()); } final double[][] shortAcc = Arrays.copyOf(FIX_ACC_FACTORS, NUM_PRDS - 1); try { new CouponIborAverageFixingDatesCompoundingDefinition(CUR, PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, ACCRUAL_FACTOR, NOTIONAL, ACCRUAL_FACTORS, INDEX, FIXING_DATES, WEIGHTS, EXP_START_DATES, EXP_END_DATES, shortAcc); throw new RuntimeException(); } catch (final Exception e) { assertEquals("fixingPeriodAccrualFactors length different from fixingDate length", e.getMessage()); } final ZonedDateTime[][] smallStartDates = new ZonedDateTime[NUM_PRDS][]; final ZonedDateTime[][] smallEndDates = new ZonedDateTime[NUM_PRDS][]; final double[][] smallAcc = new double[NUM_PRDS][]; for (int i = 0; i < NUM_PRDS; ++i) { smallStartDates[i] = Arrays.copyOf(EXP_START_DATES[i], NUM_OBS - 1); smallEndDates[i] = Arrays.copyOf(EXP_END_DATES[i], NUM_OBS - 1); smallAcc[i] = Arrays.copyOf(FIX_ACC_FACTORS[i], NUM_OBS - 1); } final ZonedDateTime afterPayment = PAYMENT_DATE.plusDays(1); try { DFN1.toDerivative(afterPayment); throw new RuntimeException(); } catch (final Exception e) { assertEquals("date is after payment date", e.getMessage()); } final ZonedDateTime afterFixing = FIXING_DATES[0][0].plusDays(1); try { DFN1.toDerivative(afterFixing); throw new RuntimeException(); } catch (final Exception e) { assertEquals("Do not have any fixing data but are asking for a derivative at " + afterFixing + " which is after fixing date " + FIXING_DATES[0][0], e.getMessage()); } }