@Test(enabled = false) /** * Test the present value vs a external system. "enabled = false" for the standard testing: the * external system is using a TimeCalculator with ACT/365. */ public void presentValueExternal() { G2ppPiecewiseConstantParameters parametersCst = G2ppTestsDataSet.createG2ppCstParameters(); final YieldAndDiscountCurve curve5 = new YieldCurve(ConstantDoublesCurve.from(0.05)); final YieldCurveBundle curves = new YieldCurveBundle(); curves.setCurve(FUNDING_CURVE_NAME, curve5); curves.setCurve(FORWARD_CURVE_NAME, curve5); G2ppPiecewiseConstantDataBundle bundleCst = new G2ppPiecewiseConstantDataBundle(parametersCst, curves); CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, bundleCst); double pvExternal = 6885626.28245924; // ! TimeCalculator with ACT/365 assertEquals( "Swaption physical - G2++ - present value - external system", pvExternal, pv.getAmount(), 1E-2); }
/** Tests related to the pricing of physical delivery swaption in G2++ model. */ public class SwaptionPhysicalFixedIborG2ppMethodTest { // Swaption 5Yx5Y private static final Currency CUR = Currency.USD; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IS_EOM = true; private static final int SETTLEMENT_DAYS = 2; private static final Period IBOR_TENOR = Period.ofMonths(3); private static final DayCount IBOR_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final IborIndex IBOR_INDEX = new IborIndex( CUR, IBOR_TENOR, SETTLEMENT_DAYS, CALENDAR, IBOR_DAY_COUNT, BUSINESS_DAY, IS_EOM); private static final int SWAP_TENOR_YEAR = 5; private static final Period SWAP_TENOR = Period.ofYears(SWAP_TENOR_YEAR); private static final Period FIXED_PAYMENT_PERIOD = Period.ofMonths(6); private static final DayCount FIXED_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("30/360"); private static final CMSIndex CMS_INDEX = new CMSIndex(FIXED_PAYMENT_PERIOD, FIXED_DAY_COUNT, IBOR_INDEX, SWAP_TENOR); private static final ZonedDateTime EXPIRY_DATE = DateUtils.getUTCDate(2016, 7, 7); private static final ZonedDateTime SETTLEMENT_DATE = ScheduleCalculator.getAdjustedDate(EXPIRY_DATE, CALENDAR, SETTLEMENT_DAYS); private static final double NOTIONAL = 100000000; // 100m private static final double RATE = 0.0325; private static final boolean FIXED_IS_PAYER = true; private static final SwapFixedIborDefinition SWAP_PAYER_DEFINITION = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, FIXED_IS_PAYER); private static final SwapFixedIborDefinition SWAP_RECEIVER_DEFINITION = SwapFixedIborDefinition.from(SETTLEMENT_DATE, CMS_INDEX, NOTIONAL, RATE, !FIXED_IS_PAYER); private static final boolean IS_LONG = true; private static final SwaptionPhysicalFixedIborDefinition SWAPTION_PAYER_LONG_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_PAYER_DEFINITION, IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_RECEIVER_LONG_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_RECEIVER_DEFINITION, IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_PAYER_SHORT_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_PAYER_DEFINITION, !IS_LONG); private static final SwaptionPhysicalFixedIborDefinition SWAPTION_RECEIVER_SHORT_DEFINITION = SwaptionPhysicalFixedIborDefinition.from(EXPIRY_DATE, SWAP_RECEIVER_DEFINITION, !IS_LONG); // to derivatives private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 7, 7); private static final String FUNDING_CURVE_NAME = "Funding"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES_NAME = {FUNDING_CURVE_NAME, FORWARD_CURVE_NAME}; private static final YieldCurveBundle CURVES = TestsDataSets.createCurves1(); private static final FixedCouponSwap<Coupon> SWAP_RECEIVER = SWAP_RECEIVER_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_PAYER_LONG = SWAPTION_PAYER_LONG_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_RECEIVER_LONG = SWAPTION_RECEIVER_LONG_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_PAYER_SHORT = SWAPTION_PAYER_SHORT_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); private static final SwaptionPhysicalFixedIbor SWAPTION_RECEIVER_SHORT = SWAPTION_RECEIVER_SHORT_DEFINITION.toDerivative(REFERENCE_DATE, CURVES_NAME); // Calculator private static final SwaptionPhysicalFixedIborG2ppApproximationMethod METHOD_G2PP_APPROXIMATION = new SwaptionPhysicalFixedIborG2ppApproximationMethod(); private static final SwaptionPhysicalFixedIborG2ppNumericalIntegrationMethod METHOD_G2PP_NI = new SwaptionPhysicalFixedIborG2ppNumericalIntegrationMethod(); private static final G2ppPiecewiseConstantParameters PARAMETERS_G2PP = G2ppTestsDataSet.createG2ppParameters(); private static final G2ppPiecewiseConstantDataBundle BUNDLE_G2PP = new G2ppPiecewiseConstantDataBundle(PARAMETERS_G2PP, CURVES); private static final PresentValueCalculator PVC = PresentValueCalculator.getInstance(); @Test(enabled = false) /** * Test the present value vs a external system. "enabled = false" for the standard testing: the * external system is using a TimeCalculator with ACT/365. */ public void presentValueExternal() { G2ppPiecewiseConstantParameters parametersCst = G2ppTestsDataSet.createG2ppCstParameters(); final YieldAndDiscountCurve curve5 = new YieldCurve(ConstantDoublesCurve.from(0.05)); final YieldCurveBundle curves = new YieldCurveBundle(); curves.setCurve(FUNDING_CURVE_NAME, curve5); curves.setCurve(FORWARD_CURVE_NAME, curve5); G2ppPiecewiseConstantDataBundle bundleCst = new G2ppPiecewiseConstantDataBundle(parametersCst, curves); CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, bundleCst); double pvExternal = 6885626.28245924; // ! TimeCalculator with ACT/365 assertEquals( "Swaption physical - G2++ - present value - external system", pvExternal, pv.getAmount(), 1E-2); } @Test(enabled = true) /** Test the present value vs a hard-coded value. */ public void presentValue() { CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); double pvExpected = 4893110.87; assertEquals( "Swaption physical - G2++ - present value - hard coded value", pvExpected, pv.getAmount(), 1E-2); } @Test /** Tests long/short parity. */ public void longShortParity() { CurrencyAmount pvPayerLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvPayerLong.getAmount(), -pvPayerShort.getAmount(), 1E-2); CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvReceiverShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvReceiverLong.getAmount(), -pvReceiverShort.getAmount(), 1E-2); } @Test /** Tests payer/receiver/swap parity. */ public void payerReceiverParity() { CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); double pvSwap = PVC.visit(SWAP_RECEIVER, CURVES); assertEquals( "Swaption physical - G2++ - present value - payer/receiver/swap parity", pvReceiverLong.getAmount() + pvPayerShort.getAmount(), pvSwap, 1E-2); } @Test /** Test the present value by approximation vs by numerical integration. */ public void approximationNumericalIntegration() { CurrencyAmount pvApproximation = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvNI = METHOD_G2PP_NI.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - approximation vs Numerical integration", pvApproximation.getAmount(), pvNI.getAmount(), 2.0E+3); } @Test(enabled = false) /** Tests of performance. "enabled = false" for the standard testing. */ public void performance() { long startTime, endTime; final int nbTest = 100; CurrencyAmount pvPayerLongApproximation = CurrencyAmount.of(CUR, 0.0); CurrencyAmount pvPayerLongNI = CurrencyAmount.of(CUR, 0.0); startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongApproximation = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " pv swaption G2++ approximation method: " + (endTime - startTime) + " ms"); // Performance note: G2++ price: 24-Aug-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 175 ms for // 10000 swaptions. startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongNI = METHOD_G2PP_NI.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " pv swaption G2++ numerical integration method: " + (endTime - startTime) + " ms"); // Performance note: G2++ price: 24-Aug-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 1075 ms for // 100 swaptions. System.out.println("G2++ approximation - present value: " + pvPayerLongApproximation); System.out.println("G2++ numerical integration - present value: " + pvPayerLongNI); } }