/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.capletstripping; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import java.util.Arrays; 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.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.index.IndexIborMaster; import com.opengamma.analytics.financial.instrument.payment.CapFloorIborDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponIborDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapDefinition; import com.opengamma.analytics.financial.interestrate.datasets.StandardDataSetsMulticurveUSD; import com.opengamma.analytics.financial.interestrate.payments.derivative.CapFloorIbor; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIbor; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborInArrearsSmileModelReplicationMethod; import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.BenaimDodgsonKainthExtrapolationFunctionProvider; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.InterpolatedSmileFunction; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.ShiftedLogNormalExtrapolationFunctionProvider; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.SmileExtrapolationFunctionSABRProvider; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.SmileInterpolatorSABRWithExtrapolation; import com.opengamma.analytics.financial.provider.calculator.discounting.PresentValueDiscountingCalculator; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.MulticurveProviderDiscountDataSets; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity; import com.opengamma.analytics.financial.schedule.ScheduleCalculator; import com.opengamma.analytics.financial.util.AssertSensitivityObjects; import com.opengamma.analytics.math.function.DoublesVectorFunctionProvider; import com.opengamma.analytics.math.function.InterpolatedVectorFunctionProvider; import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolator; import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory; import com.opengamma.analytics.math.interpolation.GridInterpolator2D; import com.opengamma.analytics.math.interpolation.Interpolator1D; import com.opengamma.analytics.math.interpolation.Interpolator1DFactory; import com.opengamma.analytics.math.interpolation.TransformedInterpolator1D; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.analytics.math.minimization.DoubleRangeLimitTransform; import com.opengamma.analytics.math.minimization.ParameterLimitsTransform; import com.opengamma.analytics.math.minimization.ParameterLimitsTransform.LimitType; import com.opengamma.analytics.math.minimization.SingleRangeLimitTransform; import com.opengamma.analytics.math.surface.InterpolatedDoublesSurface; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.util.money.Currency; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.test.TestGroup; import com.opengamma.util.time.DateUtils; import com.opengamma.util.tuple.DoublesPair; import com.opengamma.util.tuple.Pair; /** * Demo for in arrears end-to-end, where we ultimately wish to price an in-arrears caplet/floorlets. This proceeds as follows: * <ul> * <li>We take a set of market quoted cap/floor values (on the relevant index), and infer the (Black) volatilities of the * underlying caplet/floorlets (aka caplet stripping).</li> * <li>This (possible via some interpolation) gives use caplet volatilities (smile) at the expiry of the in-arrears * caplet/floorlet.</li> * <li>This smile is fitted with a smile interpolator, and extrapolated beyond the range of (market) strikes, using a * smile extrapolator.</li> * <li>Using a static replication augment, the in-arrears price is computed by integration of the price of standard * caplet/floorlets out to a strike of infinity (in practice some large cut-off), where * the price is determined from the smile extrapolation.</li> * </ul> */ @Test(groups = TestGroup.UNIT) public class CouponInArrearsCalculationTest { private static final MulticurveProviderDiscount CURVES = CapletStrippingSetup.getYieldCurves(); private static final IndexIborMaster MASTER_IBOR_INDEX = IndexIborMaster.getInstance(); private static final IborIndex USDLIBOR3M = MASTER_IBOR_INDEX.getIndex(IndexIborMaster.USDLIBOR3M); private static final Currency USD = USDLIBOR3M.getCurrency(); private static final Calendar CALENDAR = MulticurveProviderDiscountDataSets.getUSDCalendar(); // Dates private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2013, 6, 7); private static final ZonedDateTime START_ACCRUAL_DATE = ScheduleCalculator.getAdjustedDate(REFERENCE_DATE, Period.ofYears(9), USDLIBOR3M, CALENDAR); private static final ZonedDateTime END_ACCRUAL_DATE = ScheduleCalculator.getAdjustedDate(START_ACCRUAL_DATE, USDLIBOR3M, CALENDAR); private static final double ACCRUAL_FACTOR = USDLIBOR3M.getDayCount().getDayCountFraction(START_ACCRUAL_DATE, END_ACCRUAL_DATE, CALENDAR); private static final ZonedDateTime FIXING_DATE = ScheduleCalculator.getAdjustedDate(END_ACCRUAL_DATE, -USDLIBOR3M.getSpotLag(), CALENDAR); private static final double NOTIONAL = 100000000; // 100m private static final double STRIKE = 0.01; private static final boolean IS_CAP = true; // Definition description: In arrears private static final CapFloorIborDefinition CAP_IA_LONG_DEFINITION = new CapFloorIborDefinition(USD, FIXING_DATE, START_ACCRUAL_DATE, END_ACCRUAL_DATE, ACCRUAL_FACTOR, NOTIONAL, FIXING_DATE, USDLIBOR3M, STRIKE, IS_CAP, CALENDAR); private static final CapFloorIborDefinition FLOOR_IA_SHORT_DEFINITION = new CapFloorIborDefinition(USD, FIXING_DATE, START_ACCRUAL_DATE, END_ACCRUAL_DATE, ACCRUAL_FACTOR, -NOTIONAL, FIXING_DATE, USDLIBOR3M, STRIKE, !IS_CAP, CALENDAR); private static final CouponIborDefinition COUPON_IBOR_IA_DEFINITION = new CouponIborDefinition(USD, FIXING_DATE, START_ACCRUAL_DATE, END_ACCRUAL_DATE, ACCRUAL_FACTOR, NOTIONAL, FIXING_DATE, USDLIBOR3M, CALENDAR); // To derivative private static final CapFloorIbor CAPLET_LONG = (CapFloorIbor) CAP_IA_LONG_DEFINITION.toDerivative(REFERENCE_DATE); private static final CapFloorIbor FLOORLET_SHORT = (CapFloorIbor) FLOOR_IA_SHORT_DEFINITION .toDerivative(REFERENCE_DATE); private static final CouponIbor COUPON_IBOR = (CouponIbor) COUPON_IBOR_IA_DEFINITION.toDerivative(REFERENCE_DATE); // Knots chosen to realize "smooth" term structure private static final double[] ALPHA_KNOTS = new double[] {1, 2, 3, 5, 7, 10 }; private static final double[] BETA_KNOTS = new double[] {1 }; private static final double[] RHO_KNOTS = new double[] {1, 3, 7 }; private static final double[] NU_KNOTS = new double[] {1, 2, 3, 5, 7, 10 }; private static final Interpolator1D BASE_INTERPOLATOR; private static final ParameterLimitsTransform ALPHA_TRANSFORM; private static final ParameterLimitsTransform BETA_TRANSFORM; private static final ParameterLimitsTransform RHO_TRANSFORM; private static final ParameterLimitsTransform NU_TRANSFORM; private static final DoubleMatrix1D SABR_START; private static final DoublesVectorFunctionProvider[] s_providers; static { BASE_INTERPOLATOR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.DOUBLE_QUADRATIC, Interpolator1DFactory.LINEAR_EXTRAPOLATOR); ALPHA_TRANSFORM = new SingleRangeLimitTransform(0.0, LimitType.GREATER_THAN); BETA_TRANSFORM = new DoubleRangeLimitTransform(0.1, 1); RHO_TRANSFORM = new DoubleRangeLimitTransform(-1, 1); NU_TRANSFORM = new SingleRangeLimitTransform(0.0, LimitType.GREATER_THAN); int nAlphaKnots = ALPHA_KNOTS.length; int nBetaKnots = BETA_KNOTS.length; int nRhoKnots = RHO_KNOTS.length; int nNuKnots = NU_KNOTS.length; SABR_START = new DoubleMatrix1D(nAlphaKnots + +nBetaKnots + nRhoKnots + nNuKnots); double[] temp = new double[nAlphaKnots]; Arrays.fill(temp, ALPHA_TRANSFORM.transform(0.2)); System.arraycopy(temp, 0, SABR_START.getData(), 0, nAlphaKnots); temp = new double[nBetaKnots]; Arrays.fill(temp, BETA_TRANSFORM.transform(0.7)); System.arraycopy(temp, 0, SABR_START.getData(), nAlphaKnots, nBetaKnots); temp = new double[nRhoKnots]; Arrays.fill(temp, RHO_TRANSFORM.transform(-0.2)); System.arraycopy(temp, 0, SABR_START.getData(), nAlphaKnots + nBetaKnots, nRhoKnots); temp = new double[nNuKnots]; Arrays.fill(temp, NU_TRANSFORM.transform(0.5)); System.arraycopy(temp, 0, SABR_START.getData(), nAlphaKnots + nBetaKnots + nRhoKnots, nNuKnots); InterpolatedVectorFunctionProvider alphaPro = new InterpolatedVectorFunctionProvider(new TransformedInterpolator1D(BASE_INTERPOLATOR, ALPHA_TRANSFORM), ALPHA_KNOTS); InterpolatedVectorFunctionProvider betaPro = new InterpolatedVectorFunctionProvider(new TransformedInterpolator1D(CombinedInterpolatorExtrapolatorFactory.getInterpolator( Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR), BETA_TRANSFORM), BETA_KNOTS); InterpolatedVectorFunctionProvider rhoPro = new InterpolatedVectorFunctionProvider(new TransformedInterpolator1D(BASE_INTERPOLATOR, RHO_TRANSFORM), RHO_KNOTS); InterpolatedVectorFunctionProvider nuPro = new InterpolatedVectorFunctionProvider(new TransformedInterpolator1D(BASE_INTERPOLATOR, NU_TRANSFORM), NU_KNOTS); s_providers = new DoublesVectorFunctionProvider[] {alphaPro, betaPro, rhoPro, nuPro }; } /* * Swap examples */ private static final Calendar NYC = StandardDataSetsMulticurveUSD.calendarArray()[0]; private static final GeneratorSwapFixedIborMaster GENERATOR_SWAP_FIXED_IBOR_MASTER = GeneratorSwapFixedIborMaster .getInstance(); private static final GeneratorSwapFixedIbor USD6MLIBOR1M = GENERATOR_SWAP_FIXED_IBOR_MASTER.getGenerator( "USD6MLIBOR1M", NYC); private static final ZonedDateTime TRADE_DATE_1M = DateUtils.getUTCDate(2014, 9, 10); private static final double FIXED_RATE_1M = 0.0125; private static final Period TENOR_SWAP_1M = Period.ofYears(2); private static final GeneratorAttributeIR ATTRIBUTE_1M = new GeneratorAttributeIR(TENOR_SWAP_1M); private static final ZonedDateTime VALUATION_DATE = DateUtils.getUTCDate(2014, 1, 22); private static final SwapDefinition SWAP_FIXED_1M_DEFINITION = USD6MLIBOR1M.generateInstrument(TRADE_DATE_1M, FIXED_RATE_1M, NOTIONAL, ATTRIBUTE_1M); private static final Swap<? extends Payment, ? extends Payment> SWAP_FIXED_1M = SWAP_FIXED_1M_DEFINITION .toDerivative(VALUATION_DATE); private static final Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_OIS_PAIR = StandardDataSetsMulticurveUSD.getCurvesUSDOisL1L3L6(); private static final MulticurveProviderDiscount MULTICURVE_OIS = MULTICURVE_OIS_PAIR.getFirst(); private static final CurveBuildingBlockBundle BLOCK_OIS = MULTICURVE_OIS_PAIR.getSecond(); private static final GeneratorSwapFixedIbor USD6MLIBOR3M = GENERATOR_SWAP_FIXED_IBOR_MASTER.getGenerator( "USD6MLIBOR3M", NYC); private static final ZonedDateTime TRADE_DATE_3M = DateUtils.getUTCDate(2014, 9, 10); private static final Period TENOR_SWAP_3M = Period.ofYears(7); private static final double FIXED_RATE_3M = 0.0150; private static final GeneratorAttributeIR ATTRIBUTE_3M = new GeneratorAttributeIR(TENOR_SWAP_3M); private static final SwapDefinition SWAP_FIXED_3M_DEFINITION = USD6MLIBOR3M.generateInstrument(TRADE_DATE_3M, FIXED_RATE_3M, NOTIONAL, ATTRIBUTE_3M); private static final Swap<? extends Payment, ? extends Payment> SWAP_FIXED_3M = SWAP_FIXED_3M_DEFINITION .toDerivative(VALUATION_DATE); private static final Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_FF_PAIR = StandardDataSetsMulticurveUSD.getCurvesUSDOisFFL1L3L6(); private static final MulticurveProviderDiscount MULTICURVE_FFS = MULTICURVE_FF_PAIR.getFirst(); private static final CurveBuildingBlockBundle BLOCK_FFS = MULTICURVE_FF_PAIR.getSecond(); /** * Minimal consistency test for subsequent demos */ @Test public void consistencyCapCouponTest() { List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, CURVES); double lambda = 1.0; double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); double stdPv = cal.simpleCapletPrice(CAPLET_LONG) * CAPLET_LONG.getNotional(); ShiftedLogNormalExtrapolationFunctionProvider provider = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(CAPLET_LONG, sabrExtrap).getAmount(USD); assertTrue(stdPv < pv); //IBOR SmileInterpolatorSABRWithExtrapolation sabrExtrap1 = new SmileInterpolatorSABRWithExtrapolation(provider); double pvIbor = cal.presentValue(COUPON_IBOR, sabrExtrap1).getAmount(USD); // underlying computation CapletStrippingResult result = stripper.solve(capVols, MarketDataType.VOL, errors, guess); DoublesPair[] expStrikes = result.getPricer().getExpiryStrikeArray(); DoubleMatrix1D vols = result.getCapletVols(); CombinedInterpolatorExtrapolator interpolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator( Interpolator1DFactory.LINEAR, Interpolator1DFactory.LINEAR_EXTRAPOLATOR); GridInterpolator2D interpolator2D = new GridInterpolator2D(interpolator, interpolator); InterpolatedDoublesSurface volSurface = new InterpolatedDoublesSurface(expStrikes, vols.getData(), interpolator2D); double expiry = COUPON_IBOR.getFixingTime(); double[] sampleStrikes = result.getPricer().getStrikes(); int nStrikes = sampleStrikes.length; double[] sampleVols = new double[nStrikes]; for (int i = 0; i < nStrikes; i++) { sampleVols[i] = volSurface.getZValue(expiry, sampleStrikes[i]); } double forward = CURVES.getSimplyCompoundForwardRate(COUPON_IBOR.getIndex(), COUPON_IBOR.getFixingPeriodStartTime(), COUPON_IBOR.getFixingPeriodEndTime(), COUPON_IBOR.getFixingAccrualFactor()); // reconstruct smile interpolation -- next random tends to result in different SBAR parameters SmileInterpolatorSABRWithExtrapolation interp = new SmileInterpolatorSABRWithExtrapolation(provider); InterpolatedSmileFunction smileFunction = new InterpolatedSmileFunction(interp, forward, sampleStrikes, expiry, sampleVols); CouponIborInArrearsSmileModelReplicationMethod inArrearsCal = new CouponIborInArrearsSmileModelReplicationMethod( smileFunction); double pvIborRe = inArrearsCal.presentValue(COUPON_IBOR, CURVES).getAmount(USD); assertEquals(pvIborRe, pvIbor, pvIborRe * 1.e-12); } /** * BDK can not be used if forward is outside strike range */ @Test public void consistencySwapTest() { List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, MULTICURVE_OIS); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol /* * lambda = 0.01 */ double lambda = 0.01; CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, MULTICURVE_OIS); PresentValueDiscountingCalculator pvdc = PresentValueDiscountingCalculator.getInstance(); double mu = 2.25; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount firstPV = SWAP_FIXED_1M.getFirstLeg().accept(pvdc, MULTICURVE_OIS); MultipleCurrencyAmount secondPV = cal.presentValue((CouponIbor) SWAP_FIXED_1M.getSecondLeg().getNthPayment(0), sabrExtrapQuiet); for (int j = 1; j < SWAP_FIXED_1M.getSecondLeg().getNumberOfPayments(); j++) { secondPV = secondPV.plus(cal.presentValue((CouponIbor) SWAP_FIXED_1M.getSecondLeg().getNthPayment(j), sabrExtrapQuiet)); } MultipleCurrencyAmount ref = firstPV.plus(secondPV); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet1 = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount res1 = cal.presentValue(SWAP_FIXED_1M, sabrExtrapQuiet1); Swap<? extends Payment, ? extends Payment> swap = new Swap<>( SWAP_FIXED_1M.getSecondLeg(), SWAP_FIXED_1M.getFirstLeg()); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet2 = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount res2 = cal.presentValue(swap, sabrExtrapQuiet2); assertEquals(ref.getAmount(USD), res1.getAmount(USD), Math.abs(ref.getAmount(USD)) * 1.0e-12); assertEquals(ref.getAmount(USD), res2.getAmount(USD), Math.abs(ref.getAmount(USD)) * 1.0e-12); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet3 = new SmileInterpolatorSABRWithExtrapolation(provider); double parRate = cal.parRate(SWAP_FIXED_1M, sabrExtrapQuiet3); double firstPVMod = firstPV.getAmount(USD) * parRate / 0.0125; assertTrue(Math.abs((secondPV.getAmount(USD) + firstPVMod)) < Math.abs(ref.getAmount(USD)) * 1.e-10); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet4 = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyParameterSensitivity sense = cal.presentValueCurveSensitivity(SWAP_FIXED_1M, BLOCK_OIS, sabrExtrapQuiet4).multipliedBy(oneBP); assertEquals(sense.getAllNamesCurrency().iterator().next().getSecond(), USD); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet5 = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyParameterSensitivity sense1 = cal.presentValueCurveSensitivity(swap, BLOCK_OIS, sabrExtrapQuiet5).multipliedBy(oneBP); AssertSensitivityObjects.assertEquals("two identical swaps", sense, sense1, 1.0e-10); } /** * BDK can not be used if forward is outside strike range */ @Test(description = "demo test", enabled = false) public void SwapFixed1MExampleTest() { boolean printPm = false; System.out.println("***Global Direct stripper***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, MULTICURVE_OIS); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol double[] pvExp = new double[] {-999256.6452057632, -999612.9915298112, -999719.000398742, -999767.3095724229, -999796.3194925257, -999816.7613261989, -999832.1593903063, -999844.8322095645, -999855.1842177836, -999864.2914286759, -999872.796355135, -999300.6017961318, -999638.3711596527, -999738.9160627383, -999784.9565502962, -999812.6365483969, -999832.0825131405, -999847.0944008618, -999859.0744759005, -999869.2581859969, -999877.6731890535, -999885.2848242149 }; int pos = 0; /* * lambda = 0.02 */ System.out.println("<<lambda = 0.02>>"); double lambda = 0.02; // this is chosen to give a chi2/DoF of around 1 CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, MULTICURVE_OIS); if (printPm == true) { System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); } for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount pv = cal.presentValue(SWAP_FIXED_1M, sabrExtrapQuiet); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet1 = new SmileInterpolatorSABRWithExtrapolation(provider); Double parRate = cal.parRate(SWAP_FIXED_1M, sabrExtrapQuiet1); System.out.println("mu: " + mu + ", pv: " + pv + ", parRate: " + parRate); assertEquals(pvExp[pos], pv.getAmount(USD), Math.abs(pvExp[pos]) * 1.0e-10); pos++; SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet2 = new SmileInterpolatorSABRWithExtrapolation(provider); System.out.println(cal.presentValueCurveSensitivity(SWAP_FIXED_1M, BLOCK_OIS, sabrExtrapQuiet2).multipliedBy( oneBP)); } System.out.println(); /* * lambda = 1.0 */ System.out.println("<<lambda = 1.0>>"); double lambdaLarge = 1.0; CapletStripperDirect stripperLarge = new CapletStripperDirect(pricer, lambdaLarge); CouponInArrearsCalculation calLarge = new CouponInArrearsCalculation(stripperLarge, caps, capVols, MarketDataType.VOL, errors, guess, MULTICURVE_OIS); if (printPm == true) { System.out.println("Chi2: " + calLarge.getChiSq()); System.out.println("Time for stripping :" + calLarge.getTime() + "s"); System.out.println(); } for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount pv = calLarge.presentValue(SWAP_FIXED_1M, sabrExtrapQuiet); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet1 = new SmileInterpolatorSABRWithExtrapolation(provider); Double parRate = calLarge.parRate(SWAP_FIXED_1M, sabrExtrapQuiet1); System.out.println("mu: " + mu + ", pv: " + pv + ", parRate: " + parRate); assertEquals(pvExp[pos], pv.getAmount(USD), Math.abs(pvExp[pos]) * 1.0e-10); pos++; SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet2 = new SmileInterpolatorSABRWithExtrapolation(provider); System.out.println(calLarge.presentValueCurveSensitivity(SWAP_FIXED_1M, BLOCK_OIS, sabrExtrapQuiet2) .multipliedBy(oneBP)); } System.out.println(); } /** * BDK can not be used if forward is outside strike range */ @Test(description = "demo test", enabled = false) public void SwapFixed3MFFSExampleTest() { boolean printPm = false; System.out.println("***Global Direct stripper***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, MULTICURVE_OIS); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol double[] pvExp = new double[] {6520434.641867844, 6398669.449687583, 6362290.156999622, 6346915.570986342, 6338521.628707422, 6333136.846634999, 6329318.698859148, 6326428.057337409, 6324137.781339593, 6322263.637458503, 6320684.844994415, 6485449.284607982, 6386210.883078229, 6356269.952578809, 6343375.078376908, 6336185.403058179, 6331484.482977858, 6328101.927802069, 6325505.240991287, 6323426.590608101, 6321706.978522498, 6320251.668892078 }; int pos = 0; /* * lambda = 0.02 */ System.out.println("<<lambda = 0.02>>"); double lambda = 0.02; // this is chosen to give a chi2/DoF of around 1 CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, MULTICURVE_FFS); if (printPm == true) { System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); } for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount pv = cal.presentValue(SWAP_FIXED_3M, sabrExtrapQuiet); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet1 = new SmileInterpolatorSABRWithExtrapolation(provider); Double parRate = cal.parRate(SWAP_FIXED_3M, sabrExtrapQuiet1); System.out.println("mu: " + mu + ", pv: " + pv + ", parRate: " + parRate); assertEquals(pvExp[pos], pv.getAmount(USD), Math.abs(pvExp[pos]) * 1.0e-10); pos++; SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet2 = new SmileInterpolatorSABRWithExtrapolation(provider); System.out.println(cal.presentValueCurveSensitivity(SWAP_FIXED_3M, BLOCK_FFS, sabrExtrapQuiet2).multipliedBy( oneBP)); } System.out.println(); /* * lambda = 1.0 */ System.out.println("<<lambda = 1.0>>"); double lambdaLarge = 1.0; CapletStripperDirect stripperLarge = new CapletStripperDirect(pricer, lambdaLarge); CouponInArrearsCalculation calLarge = new CouponInArrearsCalculation(stripperLarge, caps, capVols, MarketDataType.VOL, errors, guess, MULTICURVE_FFS); if (printPm == true) { System.out.println("Chi2: " + calLarge.getChiSq()); System.out.println("Time for stripping :" + calLarge.getTime() + "s"); System.out.println(); } for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(provider); MultipleCurrencyAmount pv = calLarge.presentValue(SWAP_FIXED_3M, sabrExtrapQuiet); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet1 = new SmileInterpolatorSABRWithExtrapolation(provider); Double parRate = calLarge.parRate(SWAP_FIXED_3M, sabrExtrapQuiet1); System.out.println("mu: " + mu + ", pv: " + pv + ", parRate: " + parRate); assertEquals(pvExp[pos], pv.getAmount(USD), Math.abs(pvExp[pos]) * 1.0e-10); pos++; SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet2 = new SmileInterpolatorSABRWithExtrapolation(provider); System.out.println(calLarge.presentValueCurveSensitivity(SWAP_FIXED_3M, BLOCK_FFS, sabrExtrapQuiet2) .multipliedBy( oneBP)); } System.out.println(); } /** * Use CapletStripperDirect as the caplet stripper, then model the smile with a SABR interpolator and * Benaim-Dodgson-Kainth extrapolation */ @Test(description = "demo test", enabled = false) public void capletStrippingDirectBDKTest() { System.out.println("***Global Direct stripper with local SABR + Benaim-Dodgson-Kainth***"); System.out.println(); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); // ATMs are not consistent absolute strike caps, thus excluded // List<CapFloor> caps = CapletStrippingSetup.getAllCaps(); // double[] capVols = CapletStrippingSetup.getAllCapVols(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, CURVES); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol /* * lambda = 0.03 */ System.out.println("<<lambda = 0.03>>"); double lambda = 0.03; // this is chosen to give a chi2/DoF of around 1 CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); } System.out.println(); // increase lambda to get a smoother (but less we fitting) caplet vol surface. Ultimately, the choice of lambda has // less effect than the choice of mu /* * lambda = 1.0 */ System.out.println("<<lambda = 1.0>>"); lambda = 1.0; stripper = new CapletStripperDirect(pricer, lambda); cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider( mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); } System.out.println("\n"); } /** * Use CapletStripperSABR as the caplet stripper, then model the smile with a SABR interpolator and * Benaim-Dodgson-Kainth extrapolation. * <p> * Note, even though a full SABR term structure surface is formed in the caplet stripping stage, this information is thrown away, and new SABR fits (as part of the SABR interpolation) are made. */ @Test(description = "demo test", enabled = false) public void capletStrippingSABRBDKTest() { System.out.println("***Interpolated SABR parameter stripper with local SABR + Benaim-Dodgson-Kainth***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); // List<CapFloor> caps = CapletStrippingSetup.getAllCaps(); // double[] capVols = CapletStrippingSetup.getAllCapVols(); double oneBP = 1e-4; int nCaps = caps.size(); MultiCapFloorPricer pricer = new MultiCapFloorPricer(caps, CURVES); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); // 1bps CapletStripper stripper = new CapletStripperSABRModel(pricer, s_providers); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, SABR_START, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; BenaimDodgsonKainthExtrapolationFunctionProvider provider = new BenaimDodgsonKainthExtrapolationFunctionProvider(mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); } System.out.println("\n"); } /** * Global Direct stripper with local SABR + shifted lognormal */ @Test(description = "demo test", enabled = false) public void capletStrippingDirectSLNTest() { System.out.println("***Global Direct stripper with local SABR + shifted lognormal***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); // List<CapFloor> caps = CapletStrippingSetup.getAllCaps(); // double[] capVols = CapletStrippingSetup.getAllCapVols(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, CURVES); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol /* * lambda = 0.03 */ System.out.println("<<lambda = 0.03>>"); double lambda = 0.03; // this is chosen to give a chi2/DoF of around 1 CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); ShiftedLogNormalExtrapolationFunctionProvider provider = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Quiet): " + pv); provider = new ShiftedLogNormalExtrapolationFunctionProvider("Flat"); sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); } System.out.println(); /* * lambda = 1.0 */ System.out.println("<<lambda = 1.0>>"); lambda = 1.0; stripper = new CapletStripperDirect(pricer, lambda); cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); ShiftedLogNormalExtrapolationFunctionProvider provider = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Quiet): " + pv); provider = new ShiftedLogNormalExtrapolationFunctionProvider("Flat"); sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); } System.out.println("\n"); } /** * Interpolated SABR parameter stripper with local SABR + shifted lognormal */ @Test(description = "demo test", enabled = false) public void capletStrippingSABRSLNTest() { System.out.println("***Interpolated SABR parameter stripper with local SABR + shifted lognormal***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); // List<CapFloor> caps = CapletStrippingSetup.getAllCaps(); // double[] capVols = CapletStrippingSetup.getAllCapVols(); MultiCapFloorPricer pricer = new MultiCapFloorPricer(caps, CURVES); double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); // 1bps CapletStripper stripper = new CapletStripperSABRModel(pricer, s_providers); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, SABR_START, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); for (CapFloorIbor caplet : new CapFloorIbor[] {CAPLET_LONG, FLOORLET_SHORT }) { System.out.println("isCap: " + caplet.isCap()); System.out.println("non corrected price: " + cal.simpleCapletPrice(caplet) * caplet.getNotional()); ShiftedLogNormalExtrapolationFunctionProvider provider = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Quiet): " + pv); provider = new ShiftedLogNormalExtrapolationFunctionProvider("Flat"); sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); pv = cal.presentValue(caplet, sabrExtrap).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); } System.out.println("\n"); } /** * All cases for COUPON_IBOR with direct stripping */ @Test(description = "demo test", enabled = false) public void couponIborDirectAllTest() { System.out.println("***Global Direct stripper***"); CouponIbor couponIbor = COUPON_IBOR; List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(caps, CURVES); // Setting up errors and guess values double oneBP = 1e-4; int nCaps = caps.size(); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); double avVol = 0.0; for (int i = 0; i < nCaps; i++) { avVol += capVols[i]; } avVol /= nCaps; DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), avVol); // set the initial guess equal to the average cap vol /* * lambda = 0.03 */ System.out.println("<<lambda = 0.03>>"); double lambda = 0.03; // this is chosen to give a chi2/DoF of around 1 CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); /* * lambda = 1.0 */ System.out.println("<<lambda = 1.0>>"); double lambdaLarge = 1.0; CapletStripperDirect stripperLarge = new CapletStripperDirect(pricer, lambdaLarge); CouponInArrearsCalculation calLarge = new CouponInArrearsCalculation(stripperLarge, caps, capVols, MarketDataType.VOL, errors, guess, CURVES); System.out.println("Chi2: " + calLarge.getChiSq()); System.out.println("Time for stripping :" + calLarge.getTime() + "s"); System.out.println(); SmileExtrapolationFunctionSABRProvider provider; System.out.println("*With local SABR + BDK*"); System.out.println("<<lambda = 0.03>>"); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; provider = new BenaimDodgsonKainthExtrapolationFunctionProvider(mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(couponIbor, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); System.out.println("<<lambda = 1.0>>"); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; provider = new BenaimDodgsonKainthExtrapolationFunctionProvider(mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = calLarge.presentValue(couponIbor, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); System.out.println("*With local SABR + shifted lognormal*"); System.out.println("<<lambda = 0.03>>"); ShiftedLogNormalExtrapolationFunctionProvider providerQuiet = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrapQuiet = new SmileInterpolatorSABRWithExtrapolation(providerQuiet); double pv = cal.presentValue(couponIbor, sabrExtrapQuiet).getAmount(USD); System.out.println("pv(Quiet): " + pv); ShiftedLogNormalExtrapolationFunctionProvider providerFlat = new ShiftedLogNormalExtrapolationFunctionProvider( "Flat"); SmileInterpolatorSABRWithExtrapolation sabrExtrapFlat = new SmileInterpolatorSABRWithExtrapolation(providerFlat); pv = cal.presentValue(couponIbor, sabrExtrapFlat).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); System.out.println("<<lambda = 1.0>>"); pv = calLarge.presentValue(couponIbor, sabrExtrapQuiet).getAmount(USD); System.out.println("pv(Quiet): " + pv); pv = calLarge.presentValue(couponIbor, sabrExtrapFlat).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); } /** * All cases for COUPON_IBOR with interpolated SABR parameter strpping */ @Test(description = "demo test", enabled = false) public void couponIborSABRParameterAllTest() { CouponIbor couponIbor = COUPON_IBOR; System.out.println("***Interpolated SABR parameter stripper***"); List<CapFloor> caps = CapletStrippingSetup.getAllCapsExATM(); double[] capVols = CapletStrippingSetup.getAllCapVolsExATM(); // List<CapFloor> caps = CapletStrippingSetup.getAllCaps(); // double[] capVols = CapletStrippingSetup.getAllCapVols(); double oneBP = 1e-4; int nCaps = caps.size(); MultiCapFloorPricer pricer = new MultiCapFloorPricer(caps, CURVES); double[] errors = new double[nCaps]; Arrays.fill(errors, oneBP); // 1bps CapletStripper stripper = new CapletStripperSABRModel(pricer, s_providers); CouponInArrearsCalculation cal = new CouponInArrearsCalculation(stripper, caps, capVols, MarketDataType.VOL, errors, SABR_START, CURVES); System.out.println("Chi2: " + cal.getChiSq()); System.out.println("Time for stripping :" + cal.getTime() + "s"); System.out.println(); SmileExtrapolationFunctionSABRProvider provider; System.out.println("*With local SABR + BDK*"); for (int i = 0; i < 11; i++) { double mu = 1.0 + 0.25 * i; provider = new BenaimDodgsonKainthExtrapolationFunctionProvider(mu, mu); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(couponIbor, sabrExtrap).getAmount(USD); System.out.println("mu: " + mu + ", pv: " + pv); } System.out.println(); System.out.println("*With local SABR + shifted lognormal*"); provider = new ShiftedLogNormalExtrapolationFunctionProvider( "Quiet"); SmileInterpolatorSABRWithExtrapolation sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); double pv = cal.presentValue(couponIbor, sabrExtrap).getAmount(USD); System.out.println("pv(Quiet): " + pv); provider = new ShiftedLogNormalExtrapolationFunctionProvider("Flat"); sabrExtrap = new SmileInterpolatorSABRWithExtrapolation(provider); pv = cal.presentValue(couponIbor, sabrExtrap).getAmount(USD); System.out.println("pv(Flat): " + pv); System.out.println(); } }