/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate; import static org.testng.AssertJUnit.assertEquals; import java.util.ArrayList; import java.util.List; import org.testng.annotations.Test; import org.threeten.bp.Period; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponFixedDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponIborDefinition; import com.opengamma.analytics.financial.instrument.index.GeneratorAttributeIR; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedIbor; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedIborMaster; import com.opengamma.analytics.financial.instrument.index.IborIndex; import com.opengamma.analytics.financial.instrument.payment.CouponFixedDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponIborDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapFixedIborDefinition; import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity; import com.opengamma.analytics.financial.interestrate.annuity.derivative.AnnuityCouponFixed; import com.opengamma.analytics.financial.interestrate.datasets.StandardDataSetsMulticurveUSD; import com.opengamma.analytics.financial.interestrate.payments.derivative.Coupon; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap; import com.opengamma.analytics.financial.interestrate.swap.derivative.SwapFixedCoupon; import com.opengamma.analytics.financial.interestrate.swap.provider.SwapFixedCouponDiscountingMethod; import com.opengamma.analytics.financial.provider.calculator.discounting.ParRateDiscountingCalculator; import com.opengamma.analytics.financial.provider.calculator.discounting.PresentValueDiscountingCalculator; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.financial.convention.daycount.DayCount; import com.opengamma.timeseries.precise.zdt.ImmutableZonedDateTimeDoubleTimeSeries; import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries; import com.opengamma.util.money.Currency; import com.opengamma.util.test.TestGroup; import com.opengamma.util.time.DateUtils; import com.opengamma.util.tuple.Pair; /** * */ @Test(groups = TestGroup.UNIT) public class SwapCleanDiscountingCalculatorTest { private static final ZonedDateTime[] VALUATION_DATE_SET = new ZonedDateTime[] {DateUtils.getUTCDate(2014, 1, 22), DateUtils.getUTCDate(2014, 4, 22) }; private static final Calendar NYC = StandardDataSetsMulticurveUSD.calendarArray()[0]; private static final GeneratorSwapFixedIborMaster GENERATOR_SWAP_FIXED_IBOR_MASTER = GeneratorSwapFixedIborMaster .getInstance(); private static final GeneratorSwapFixedIbor USD6MLIBOR3M = GENERATOR_SWAP_FIXED_IBOR_MASTER.getGenerator( "USD6MLIBOR3M", NYC); private static final double NOTIONAL = 100000000; //100 m private static final ZonedDateTimeDoubleTimeSeries TS_USDLIBOR3M = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2013, 12, 10), DateUtils.getUTCDate(2013, 12, 12), DateUtils.getUTCDate(2014, 3, 10) }, new double[] {0.0024185, 0.0024285, 0.0025175, }); private static final ZonedDateTimeDoubleTimeSeries[] TS_ARRAY_USDLIBOR3M = new ZonedDateTimeDoubleTimeSeries[] {TS_USDLIBOR3M }; /* Instrument description: Swap Fixed vs Libor3M already started */ private static final ZonedDateTime TRADE_DATE_3M_S = DateUtils.getUTCDate(2013, 9, 10); private static final Period TENOR_SWAP_3M_S = Period.ofYears(7); private static final double FIXED_RATE_3M_S = 0.0150; private static final GeneratorAttributeIR ATTRIBUTE_3M_S = new GeneratorAttributeIR(TENOR_SWAP_3M_S); // Fixed payer private static final SwapFixedIborDefinition SWAP_FIXED_3M_PAY_DEFINITION = USD6MLIBOR3M.generateInstrument(TRADE_DATE_3M_S, FIXED_RATE_3M_S, NOTIONAL, ATTRIBUTE_3M_S); // Fixed receiver private static final SwapFixedIborDefinition SWAP_FIXED_3M_REC_DEFINITION_ = USD6MLIBOR3M.generateInstrument(TRADE_DATE_3M_S, FIXED_RATE_3M_S, NOTIONAL, ATTRIBUTE_3M_S, false); private static final MulticurveProviderDiscount[] MULTICURVE_SET; static { Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_OIS_PAIR = StandardDataSetsMulticurveUSD.getCurvesUSDOisL1L3L6(); MulticurveProviderDiscount MULTICURVE_OIS = MULTICURVE_OIS_PAIR.getFirst(); Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_FF_PAIR = StandardDataSetsMulticurveUSD.getCurvesUSDOisFFL1L3L6(); MulticurveProviderDiscount MULTICURVE_FFS = MULTICURVE_FF_PAIR.getFirst(); MULTICURVE_SET = new MulticurveProviderDiscount[] {MULTICURVE_OIS, MULTICURVE_FFS }; } private static final PresentValueDiscountingCalculator PVDC = PresentValueDiscountingCalculator.getInstance(); private static final ParRateDiscountingCalculator PRDC = ParRateDiscountingCalculator.getInstance(); private static final SwapFixedCouponDiscountingMethod METHOD_SWAP = SwapFixedCouponDiscountingMethod.getInstance(); private static final SwapCleanDiscountingCalculator CPRC = new SwapCleanDiscountingCalculator(); private static final double TOL = 1.0e-12; /** * Example test */ @Test public void E2ETest() { ZonedDateTime valuationDate = VALUATION_DATE_SET[0]; // 2014, 1, 22 MulticurveProviderDiscount multicurve = MULTICURVE_SET[0]; // MULTICURVE_OIS // Calendar and DayCount should be taken from GeneratorSwapFixedIbor double parRate = CPRC.parRate(SWAP_FIXED_3M_PAY_DEFINITION, USD6MLIBOR3M.getFixedLegDayCount(), USD6MLIBOR3M .getIborIndex().getDayCount(), USD6MLIBOR3M.getCalendar(), valuationDate, TS_USDLIBOR3M, multicurve); assertRelative("consistencyTest", 0.021442847215148938, parRate, TOL); multicurve = MULTICURVE_SET[1]; // MULTICURVE_FFS // Calendar and DayCount should be taken from GeneratorSwapFixedIbor parRate = CPRC.parRate(SWAP_FIXED_3M_PAY_DEFINITION, USD6MLIBOR3M.getFixedLegDayCount(), USD6MLIBOR3M .getIborIndex().getDayCount(), USD6MLIBOR3M.getCalendar(), valuationDate, TS_USDLIBOR3M, multicurve); assertRelative("consistencyTest", 0.0208613981377012, parRate, TOL); } /** * Test consistency between accrued interest and par rate */ @Test public void consistencyTest() { SwapFixedIborDefinition[] swapSet = new SwapFixedIborDefinition[] {SWAP_FIXED_3M_PAY_DEFINITION, SWAP_FIXED_3M_REC_DEFINITION_ }; int n = swapSet.length; for (ZonedDateTime valuationDate : VALUATION_DATE_SET) { for (MulticurveProviderDiscount multicurve : MULTICURVE_SET) { double[] accruedInterest = new double[n]; double[] parRate = new double[n]; for (int i = 0; i < n; ++i) { SwapFixedIborDefinition swapDefinition = swapSet[i]; /* Compute "clean" par rate manually */ AnnuityCouponIborDefinition floatingLeg = (AnnuityCouponIborDefinition) swapDefinition .getSecondLeg(); IborIndex index = floatingLeg.getIborIndex(); DayCount dayCountFloating = index.getDayCount(); Calendar calendarFloating = swapDefinition.getFirstLeg().getCalendar(); CouponIborDefinition[] paymentsFloating = floatingLeg.getPayments(); final List<CouponIborDefinition> listFloating = new ArrayList<>(); for (final CouponIborDefinition payment : paymentsFloating) { if (!payment.getPaymentDate().isBefore(valuationDate)) { listFloating.add(payment); } } AnnuityCouponIborDefinition trimedFloatingLeg = new AnnuityCouponIborDefinition( listFloating.toArray(new CouponIborDefinition[listFloating.size()]), index, calendarFloating); Annuity<? extends Coupon> floatingLegDerivative = trimedFloatingLeg .toDerivative(valuationDate, TS_USDLIBOR3M); double accruedYearFractionFloating = dayCountFloating.getDayCountFraction(trimedFloatingLeg.getNthPayment(0) .getAccrualStartDate(), valuationDate, calendarFloating); double dirtyFloatingPV = floatingLegDerivative.accept(PVDC, multicurve).getAmount( floatingLegDerivative.getCurrency()) * Math.signum(floatingLegDerivative.getNthPayment(0).getNotional()); CouponFixed firstCoupon = (CouponFixed) floatingLegDerivative.getNthPayment(0); double accruedInterestFloating = firstCoupon.getFixedRate() * accruedYearFractionFloating * Math.abs(firstCoupon.getNotional()); double cleanFloatingPV = dirtyFloatingPV - accruedInterestFloating; AnnuityCouponFixedDefinition fixedLeg = (AnnuityCouponFixedDefinition) swapDefinition.getFirstLeg(); DayCount dayCountFixed = USD6MLIBOR3M.getFixedLegDayCount(); Calendar calendarFixed = USD6MLIBOR3M.getCalendar(); CouponFixedDefinition[] paymentsFixed = fixedLeg.getPayments(); final List<CouponFixedDefinition> listFixed = new ArrayList<>(); for (final CouponFixedDefinition payment : paymentsFixed) { if (!payment.getPaymentDate().isBefore(valuationDate)) { listFixed.add(payment); } } AnnuityCouponFixedDefinition trimedFixedLeg = new AnnuityCouponFixedDefinition( listFixed.toArray(new CouponFixedDefinition[listFixed.size()]), calendarFixed); double accruedYearFractionFixed = dayCountFixed.getDayCountFraction(trimedFixedLeg.getNthPayment(0) .getAccrualStartDate(), valuationDate, calendarFixed); AnnuityCouponFixed fixedLegDerivative = trimedFixedLeg.toDerivative(valuationDate); SwapFixedCoupon<?> fixedCouponSwap = new SwapFixedCoupon<>(fixedLegDerivative, floatingLegDerivative); double dirtyAnnuity = METHOD_SWAP.presentValueBasisPoint(fixedCouponSwap, multicurve); double accruedFixed = accruedYearFractionFixed * Math.abs(trimedFixedLeg.getNthPayment(0).getNotional()); double cleanAnnuity = dirtyAnnuity - accruedFixed; double refParRate = cleanFloatingPV / cleanAnnuity; parRate[i] = CPRC.parRate(swapDefinition, USD6MLIBOR3M.getFixedLegDayCount(), USD6MLIBOR3M .getIborIndex().getDayCount(), USD6MLIBOR3M.getCalendar(), valuationDate, TS_USDLIBOR3M, multicurve); assertRelative("consistencyTest", refParRate, parRate[i], TOL); /* Check the par rate produces zero clean PV */ SwapFixedIborDefinition swapWithParRateDfn = USD6MLIBOR3M.generateInstrument(TRADE_DATE_3M_S, parRate[i], NOTIONAL, ATTRIBUTE_3M_S); Swap<? extends Payment, ? extends Payment> swapWithParRate = swapWithParRateDfn.toDerivative(valuationDate, TS_ARRAY_USDLIBOR3M); double accruedInterestPar = CPRC.accruedInterest(swapWithParRateDfn, USD6MLIBOR3M.getFixedLegDayCount(), USD6MLIBOR3M.getIborIndex().getDayCount(), USD6MLIBOR3M.getCalendar(), valuationDate, TS_USDLIBOR3M, multicurve).getAmount(Currency.USD); double dirtyPV = swapWithParRate.accept(PVDC, multicurve).getAmount(Currency.USD); assertRelative("consistencyTest", 0.0, dirtyPV - accruedInterestPar, Math.abs(dirtyPV) * TOL); accruedInterest[i] = CPRC.accruedInterest(swapDefinition, USD6MLIBOR3M.getFixedLegDayCount(), USD6MLIBOR3M .getIborIndex().getDayCount(), USD6MLIBOR3M.getCalendar(), valuationDate, TS_USDLIBOR3M, multicurve) .getAmount(Currency.USD); } assertRelative("consistencyTest", parRate[0], parRate[1], TOL); assertRelative("consistencyTest", accruedInterest[0], -accruedInterest[1], TOL); } } } /** * first coupon is not yet paid, but second coupon period started */ @Test public void paidAfterPeriodEndTest() { MulticurveProviderDiscount multicurve = MULTICURVE_SET[0]; ZonedDateTime valuationDate = DateUtils.getUTCDate(2014, 3, 17); ZonedDateTimeDoubleTimeSeries timeSeries = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 12), DateUtils.getUTCDate(2013, 12, 12), DateUtils.getUTCDate(2014, 3, 13) }, new double[] {0.0024185, 0.0025285, 0.0024175, }); ZonedDateTimeDoubleTimeSeries[] timeSeriesArray = new ZonedDateTimeDoubleTimeSeries[] {timeSeries }; Currency usd = Currency.USD; /* Ibor leg */ ZonedDateTime[] paymentDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 12, 16), DateUtils.getUTCDate(2014, 3, 17), DateUtils.getUTCDate(2014, 6, 16), DateUtils.getUTCDate(2014, 9, 16) }; ZonedDateTime[] accStartDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 16), DateUtils.getUTCDate(2013, 12, 16), DateUtils.getUTCDate(2014, 3, 16), DateUtils.getUTCDate(2014, 6, 16) }; ZonedDateTime[] accEndDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 12, 16), DateUtils.getUTCDate(2014, 3, 16), DateUtils.getUTCDate(2014, 6, 16), DateUtils.getUTCDate(2014, 9, 16) }; ZonedDateTime[] FixingDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 12), DateUtils.getUTCDate(2013, 12, 12), DateUtils.getUTCDate(2014, 3, 13), DateUtils.getUTCDate(2014, 6, 12) }; int nPaymentsIbor = paymentDatesIbor.length; IborIndex index = USD6MLIBOR3M.getIborIndex(); // USDLIBOR3M Calendar calendar = USD6MLIBOR3M.getCalendar(); DayCount dcIbor = index.getDayCount(); CouponIborDefinition[] ibor = new CouponIborDefinition[nPaymentsIbor]; for (int i = 0; i < nPaymentsIbor; ++i) { double paymentYearFraction = dcIbor.getDayCountFraction(accStartDatesIbor[i], accEndDatesIbor[i], NYC); ibor[i] = new CouponIborDefinition(usd, paymentDatesIbor[i], accStartDatesIbor[i], accEndDatesIbor[i], paymentYearFraction, -NOTIONAL, FixingDatesIbor[i], index, NYC); } AnnuityCouponIborDefinition iborLeg = new AnnuityCouponIborDefinition(ibor, index, calendar); /* Fixed leg */ ZonedDateTime[] paymentDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2014, 3, 17), DateUtils.getUTCDate(2014, 9, 16) }; ZonedDateTime[] accStartDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 16), DateUtils.getUTCDate(2014, 3, 16) }; ZonedDateTime[] accEndDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2014, 3, 16), DateUtils.getUTCDate(2014, 9, 16) }; int nPaymentsFixed = paymentDatesFixed.length; CouponFixedDefinition[] fixed = new CouponFixedDefinition[nPaymentsFixed]; DayCount dcFixed = USD6MLIBOR3M.getFixedLegDayCount(); for (int i = 0; i < nPaymentsFixed; ++i) { double paymentYearFraction = dcFixed.getDayCountFraction(accStartDatesFixed[i], accEndDatesFixed[i], calendar); fixed[i] = new CouponFixedDefinition(usd, paymentDatesFixed[i], accStartDatesFixed[i], accEndDatesFixed[i], paymentYearFraction, NOTIONAL, FIXED_RATE_3M_S); } AnnuityCouponFixedDefinition fixedLeg = new AnnuityCouponFixedDefinition(fixed, calendar); /* Swap */ SwapFixedIborDefinition swapDefinition = new SwapFixedIborDefinition(fixedLeg, iborLeg); SwapFixedCoupon<Coupon> fixedCouponSwap = swapDefinition.toDerivative(valuationDate, timeSeriesArray); /* Result */ double parRate = CPRC.parRate(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, timeSeries, multicurve); double accruedInterest = CPRC.accruedInterest(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, timeSeries, multicurve).getAmount(usd); /* Compute accrued amounts manually */ int pIbor = 1; double accYFIbor = dcIbor.getDayCountFraction(accStartDatesIbor[pIbor], valuationDate, calendar); double indexRate = timeSeries.getValue(ibor[pIbor].getFixingDate()); double notionalIbor = ibor[pIbor].getNotional(); double accIbor = accYFIbor * indexRate * notionalIbor; ++pIbor; accYFIbor = dcIbor.getDayCountFraction(accStartDatesIbor[pIbor], valuationDate, calendar); indexRate = timeSeries.getValue(ibor[pIbor].getFixingDate()); notionalIbor = ibor[pIbor].getNotional(); accIbor += accYFIbor * indexRate * notionalIbor; int pFixed = 0; double accYFFixed = dcFixed.getDayCountFraction(accStartDatesFixed[pFixed], valuationDate, calendar); double notionalFixed = fixed[pFixed].getNotional(); double accFixed = accYFFixed * notionalFixed; ++pFixed; accYFFixed = dcFixed.getDayCountFraction(accStartDatesFixed[pFixed], valuationDate, calendar); notionalFixed = fixed[pFixed].getNotional(); accFixed += accYFFixed * notionalFixed; double refAccInterest = accIbor + FIXED_RATE_3M_S * accFixed; assertRelative("paidAfterPeriodEndTest", refAccInterest, accruedInterest, TOL); double pvIborLeg = iborLeg.toDerivative(valuationDate, timeSeries).accept(PVDC, multicurve).getAmount(usd); double annuity = METHOD_SWAP.presentValueBasisPoint(fixedCouponSwap, multicurve); double refParRate = Math.abs((pvIborLeg - accIbor) / (annuity - accFixed)); assertRelative("paidAfterPeriodEndTest", refParRate, parRate, TOL); } /** * valuation date is equal to payment date */ @Test public void paymentDateTest() { ZonedDateTime valuationDate = DateUtils.getUTCDate(2014, 3, 12); // before start date for (SwapFixedIborDefinition swapDefinition : new SwapFixedIborDefinition[] {SWAP_FIXED_3M_PAY_DEFINITION, SWAP_FIXED_3M_REC_DEFINITION_ }) { SwapFixedCoupon<Coupon> fixedCouponSwap = swapDefinition.toDerivative(valuationDate, TS_ARRAY_USDLIBOR3M); MulticurveProviderDiscount multicurve = MULTICURVE_SET[1]; Calendar calendar = USD6MLIBOR3M.getCalendar(); DayCount dcIbor = USD6MLIBOR3M.getIborIndex().getDayCount(); DayCount dcFixed = USD6MLIBOR3M.getFixedLegDayCount(); double parRate = CPRC.parRate(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, TS_USDLIBOR3M, multicurve); double accruedInterest = CPRC.accruedInterest(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, TS_USDLIBOR3M, multicurve).getAmount(Currency.USD); double pvFirstLibor = fixedCouponSwap.getSecondLeg().getNthPayment(0).accept(PVDC, multicurve) .getAmount(Currency.USD); double pvFirstFixed = fixedCouponSwap.getFirstLeg().getNthPayment(0).accept(PVDC, multicurve) .getAmount(Currency.USD); double pvLibor = fixedCouponSwap.getSecondLeg().accept(PVDC, multicurve).getAmount(Currency.USD); double pvFixed = fixedCouponSwap.getFirstLeg().accept(PVDC, multicurve).getAmount(Currency.USD); double refAccruedInterest = pvFirstLibor + pvFirstFixed; double refParRate = Math.abs((pvLibor - pvFirstLibor) * FIXED_RATE_3M_S / (pvFixed - pvFirstFixed)); assertRelative("notAccruedTest", refParRate, parRate, TOL); assertRelative("notAccruedTest", refAccruedInterest, accruedInterest, TOL); } } /** * No accrued for a newly issued swap */ @Test public void notAccruedTest() { ZonedDateTime valuationDate = DateUtils.getUTCDate(2013, 8, 10); // before start date for (SwapFixedIborDefinition swapDefinition : new SwapFixedIborDefinition[] {SWAP_FIXED_3M_PAY_DEFINITION, SWAP_FIXED_3M_REC_DEFINITION_ }) { SwapFixedCoupon<Coupon> fixedCouponSwap = swapDefinition.toDerivative(valuationDate, TS_ARRAY_USDLIBOR3M); MulticurveProviderDiscount multicurve = MULTICURVE_SET[1]; Calendar calendar = USD6MLIBOR3M.getCalendar(); DayCount dcIbor = USD6MLIBOR3M.getIborIndex().getDayCount(); DayCount dcFixed = USD6MLIBOR3M.getFixedLegDayCount(); double parRate = CPRC.parRate(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, TS_USDLIBOR3M, multicurve); double accruedInterest = CPRC.accruedInterest(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, TS_USDLIBOR3M, multicurve).getAmount(Currency.USD); double refParRate = fixedCouponSwap.accept(PRDC, multicurve); assertRelative("notAccruedTest", refParRate, parRate, TOL); assertRelative("notAccruedTest", 0.0, accruedInterest, TOL); } } /** * With 30/360 accrued days are 0 between 30th and 31st */ @Test public void afterStartNotAccruedTest() { MulticurveProviderDiscount multicurve = MULTICURVE_SET[0]; ZonedDateTime valuationDate = DateUtils.getUTCDate(2013, 12, 31); ZonedDateTimeDoubleTimeSeries timeSeries = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2013, 6, 26), DateUtils.getUTCDate(2013, 9, 26), DateUtils.getUTCDate(2013, 12, 26) }, new double[] {0.0024185, 0.0025285, 0.0024175, }); ZonedDateTimeDoubleTimeSeries[] timeSeriesArray = new ZonedDateTimeDoubleTimeSeries[] {timeSeries }; Currency usd = Currency.USD; /* Ibor leg */ ZonedDateTime[] paymentDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 30), DateUtils.getUTCDate(2013, 12, 30), DateUtils.getUTCDate(2014, 3, 31), DateUtils.getUTCDate(2014, 6, 30) }; ZonedDateTime[] accStartDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 6, 30), DateUtils.getUTCDate(2013, 9, 30), DateUtils.getUTCDate(2013, 12, 30), DateUtils.getUTCDate(2014, 3, 30) }; ZonedDateTime[] accEndDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 9, 30), DateUtils.getUTCDate(2013, 12, 30), DateUtils.getUTCDate(2014, 3, 30), DateUtils.getUTCDate(2014, 6, 30) }; ZonedDateTime[] FixingDatesIbor = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 6, 26), DateUtils.getUTCDate(2013, 9, 26), DateUtils.getUTCDate(2013, 12, 26), DateUtils.getUTCDate(2014, 3, 26) }; int nPaymentsIbor = paymentDatesIbor.length; IborIndex index = USD6MLIBOR3M.getIborIndex(); // USDLIBOR3M Calendar calendar = USD6MLIBOR3M.getCalendar(); // modified s.t.30U/360 is used for both legs DayCount dcIbor = USD6MLIBOR3M.getFixedLegDayCount(); CouponIborDefinition[] ibor = new CouponIborDefinition[nPaymentsIbor]; for (int i = 0; i < nPaymentsIbor; ++i) { double paymentYearFraction = dcIbor.getDayCountFraction(accStartDatesIbor[i], accEndDatesIbor[i], NYC); ibor[i] = new CouponIborDefinition(usd, paymentDatesIbor[i], accStartDatesIbor[i], accEndDatesIbor[i], paymentYearFraction, -NOTIONAL, FixingDatesIbor[i], index, NYC); } AnnuityCouponIborDefinition iborLeg = new AnnuityCouponIborDefinition(ibor, index, calendar); /* Fixed leg */ ZonedDateTime[] paymentDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 12, 30), DateUtils.getUTCDate(2014, 6, 30) }; ZonedDateTime[] accStartDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 6, 30), DateUtils.getUTCDate(2013, 12, 30) }; ZonedDateTime[] accEndDatesFixed = new ZonedDateTime[] {DateUtils.getUTCDate(2013, 12, 30), DateUtils.getUTCDate(2014, 6, 30) }; int nPaymentsFixed = paymentDatesFixed.length; CouponFixedDefinition[] fixed = new CouponFixedDefinition[nPaymentsFixed]; DayCount dcFixed = USD6MLIBOR3M.getFixedLegDayCount(); for (int i = 0; i < nPaymentsFixed; ++i) { double paymentYearFraction = dcFixed.getDayCountFraction(accStartDatesFixed[i], accEndDatesFixed[i], calendar); fixed[i] = new CouponFixedDefinition(usd, paymentDatesFixed[i], accStartDatesFixed[i], accEndDatesFixed[i], paymentYearFraction, NOTIONAL, FIXED_RATE_3M_S); } AnnuityCouponFixedDefinition fixedLeg = new AnnuityCouponFixedDefinition(fixed, calendar); /* Swap */ SwapFixedIborDefinition swapDefinition = new SwapFixedIborDefinition(fixedLeg, iborLeg); SwapFixedCoupon<Coupon> fixedCouponSwap = swapDefinition.toDerivative(valuationDate, timeSeriesArray); double parRate = CPRC.parRate(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, timeSeries, multicurve); double accruedInterest = CPRC.accruedInterest(swapDefinition, dcFixed, dcIbor, calendar, valuationDate, timeSeries, multicurve).getAmount(usd); double refParRate = fixedCouponSwap.accept(PRDC, multicurve); assertRelative("afterStartNotAccruedTest", refParRate, parRate, TOL); assertRelative("afterStartNotAccruedTest", 0.0, accruedInterest, TOL); } private void assertRelative(String message, double expected, double obtained, double relativeTol) { double ref = Math.max(Math.abs(expected), 1.0); assertEquals(message, expected, obtained, ref * relativeTol); } }