public void test_of() { SabrParametersSwaptionVolatilities test = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM); assertEquals(test.getConvention(), CONV); assertEquals(test.getDayCount(), ACT_ACT_ISDA); assertEquals(test.getParameters(), PARAM); assertEquals(test.getValuationDateTime(), DATE_TIME); }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(SabrParametersSwaptionVolatilities beanToCopy) { this.name = beanToCopy.getName(); this.convention = beanToCopy.getConvention(); this.valuationDateTime = beanToCopy.getValuationDateTime(); this.parameters = beanToCopy.getParameters(); this.dataSensitivityAlpha = beanToCopy.dataSensitivityAlpha; this.dataSensitivityBeta = beanToCopy.dataSensitivityBeta; this.dataSensitivityRho = beanToCopy.dataSensitivityRho; this.dataSensitivityNu = beanToCopy.dataSensitivityNu; }
@Override public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities) { CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty(); for (PointSensitivity point : pointSensitivities.getSensitivities()) { if (point instanceof SwaptionSabrSensitivity) { SwaptionSabrSensitivity pt = (SwaptionSabrSensitivity) point; if (pt.getVolatilitiesName().equals(getName())) { sens = sens.combinedWith(parameterSensitivity(pt)); } } } return sens; }
private SabrParametersSwaptionVolatilities replaceSabrParameters( SabrInterestRateParameters sabrParams, SabrParametersSwaptionVolatilities orgVols) { return SabrParametersSwaptionVolatilities.of( SwaptionVolatilitiesName.of("Test-SABR"), orgVols.getConvention(), orgVols.getValuationDateTime(), sabrParams); }
SurfaceMetadata alphaMetadata = calibrated.getParameters().getAlphaSurface().getMetadata(); Optional<List<ParameterMetadata>> alphaParameterMetadataOption = alphaMetadata.getParameterMetadata(); assertTrue(alphaParameterMetadataOption.isPresent()); List<ParameterMetadata> alphaParameterMetadata = alphaParameterMetadataOption.get(); List<DoubleArray> alphaJacobian = calibrated.getDataSensitivityAlpha().get(); SurfaceMetadata rhoMetadata = calibrated.getParameters().getRhoSurface().getMetadata(); Optional<List<ParameterMetadata>> rhoParameterMetadataOption = rhoMetadata.getParameterMetadata(); assertTrue(rhoParameterMetadataOption.isPresent()); List<ParameterMetadata> rhoParameterMetadata = rhoParameterMetadataOption.get(); List<DoubleArray> rhoJacobian = calibrated.getDataSensitivityRho().get(); SurfaceMetadata nuMetadata = calibrated.getParameters().getNuSurface().getMetadata(); Optional<List<ParameterMetadata>> nuParameterMetadataOption = nuMetadata.getParameterMetadata(); assertTrue(nuParameterMetadataOption.isPresent()); List<ParameterMetadata> nuParameterMetadata = nuParameterMetadataOption.get(); List<DoubleArray> nuJacobian = calibrated.getDataSensitivityNu().get(); .adjust(CALIBRATION_DATE.plus(EXPIRIES.get(loopexpiry)), REF_DATA); ZonedDateTime expiryDateTime = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin")); double time = calibrated.relativeTime(expiryDateTime); Pair<DoubleArray, DoubleArray> ds = DATA_SPARSE.getData(tenor).availableSmileAtExpiry(EXPIRIES.get(loopexpiry)); if (!ds.getFirst().isEmpty()) { SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, betaSurface, shiftSurface); alphaShifted[loopsign] = calibratedShifted.getParameters().getAlphaSurface().zValue(time, tenorYears); rhoShifted[loopsign] = calibratedShifted.getParameters().getRhoSurface().zValue(time, tenorYears); nuShifted[loopsign] = calibratedShifted.getParameters().getNuSurface().zValue(time, tenorYears);
FixedIborSwapConvention convention = sabr.getConvention(); DayCount dayCount = sabr.getDayCount(); BusinessDayAdjustment bda = convention.getFloatingLeg().getStartDateBusinessDayAdjustment(); LocalDate calibrationDate = sabr.getValuationDate(); DoubleArray timeToExpiryArray = DoubleArray.EMPTY; DoubleArray timeTenorArray = DoubleArray.EMPTY; ValueType volatilityType = atmVolatilities.getVolatilityType(); double beta = sabr.getParameters().beta(timeToExpiry, timeTenor); double rho = sabr.getParameters().rho(timeToExpiry, timeTenor); double nu = sabr.getParameters().nu(timeToExpiry, timeTenor); double shift = sabr.getParameters().shift(timeToExpiry, timeTenor); Pair<Double, Double> calibrationResult = calibrationAtm(forward, shift, beta, rho, nu, bda, sabr.getValuationDateTime(), dayCount, expiries.get(loopexpiry), atmVolatility, volatilityType); timeToExpiryArray = timeToExpiryArray.concat(timeToExpiry); timeTenorArray = timeTenorArray.concat(timeTenor); .of(metadataAlpha, timeToExpiryArray, timeTenorArray, alphaArray, interpolator); SabrInterestRateParameters params = SabrInterestRateParameters.of( alphaSurface, sabr.getParameters().getBetaSurface(), sabr.getParameters().getRhoSurface(), sabr.getParameters().getNuSurface(), sabr.getParameters().getShiftSurface(), sabrVolatilityFormula); return SabrParametersSwaptionVolatilities.builder() .name(name) .convention(convention) .valuationDateTime(sabr.getValuationDateTime()) .parameters(params) .dataSensitivityAlpha(dataSensitivityAlpha).build();
Optional<ImmutableList<DoubleArray>> alphaInfo = volatilities.getDataSensitivityAlpha(); sensitivityToRawData.add(alphaInfo.orElse(null)); Optional<ImmutableList<DoubleArray>> betaInfo = volatilities.getDataSensitivityBeta(); sensitivityToRawData.add(betaInfo.orElse(null)); Optional<ImmutableList<DoubleArray>> rhoInfo = volatilities.getDataSensitivityRho(); sensitivityToRawData.add(rhoInfo.orElse(null)); Optional<ImmutableList<DoubleArray>> nuInfo = volatilities.getDataSensitivityNu(); sensitivityToRawData.add(nuInfo.orElse(null)); ArgChecker.isTrue(alphaInfo.isPresent() || betaInfo.isPresent() || rhoInfo.isPresent() || nuInfo.isPresent(), MarketDataName<?> name = s.getMarketDataName(); if (name instanceof SurfaceName) { if (volatilities.getParameters().getAlphaSurface().getName().equals(name) && alphaInfo.isPresent()) { updateSensitivity(s, sensitivityToRawData.get(0), sensitivityRawArray); metadataResult = s.getParameterMetadata(); if (volatilities.getParameters().getBetaSurface().getName().equals(name) && betaInfo.isPresent()) { updateSensitivity(s, sensitivityToRawData.get(1), sensitivityRawArray); metadataResult = s.getParameterMetadata(); if (volatilities.getParameters().getRhoSurface().getName().equals(name) && rhoInfo.isPresent()) { updateSensitivity(s, sensitivityToRawData.get(2), sensitivityRawArray); metadataResult = s.getParameterMetadata(); if (volatilities.getParameters().getNuSurface().getName().equals(name) && nuInfo.isPresent()) { updateSensitivity(s, sensitivityToRawData.get(3), sensitivityRawArray); metadataResult = s.getParameterMetadata();
public void test_presentValueSensitivityRatesStickyStrike() { SwaptionVolatilities volSabr = SwaptionSabrRateVolatilityDataSet.getVolatilitiesEur(VAL_DATE_TIME.toLocalDate(), false); double impliedVol = PRICER.impliedVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr); SurfaceMetadata blackMeta = Surfaces.blackVolatilityByExpiryTenor("CST", VOLS.getDayCount()); SwaptionVolatilities volCst = BlackSwaptionExpiryTenorVolatilities.of( VOLS.getConvention(), VOLS.getValuationDateTime(), ConstantSurface.of(blackMeta, impliedVol)); // To obtain a constant volatility surface which create a sticky strike sensitivity PointSensitivityBuilder pointRec = PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr); CurrencyParameterSensitivities computedRec = RATE_PROVIDER.parameterSensitivity(pointRec.build()); CurrencyParameterSensitivities expectedRec = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> PRICER.presentValue(SWAPTION_REC_LONG, (p), volCst)); assertTrue(computedRec.equalWithTolerance(expectedRec, NOTIONAL * FD_EPS * 300d)); PointSensitivityBuilder pointPay = PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_PAY_SHORT, RATE_PROVIDER, volSabr); CurrencyParameterSensitivities computedPay = RATE_PROVIDER.parameterSensitivity(pointPay.build()); CurrencyParameterSensitivities expectedPay = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> PRICER.presentValue(SWAPTION_PAY_SHORT, (p), volCst)); assertTrue(computedPay.equalWithTolerance(expectedPay, NOTIONAL * FD_EPS * 300d)); }
public void test_parameterSensitivity() { double alphaSensi = 2.24, betaSensi = 3.45, rhoSensi = -2.12, nuSensi = -0.56; SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM); for (int i = 0; i < NB_TEST; i++) { double expiryTime = prov.relativeTime(TEST_OPTION_EXPIRY[i]); PointSensitivities point = PointSensitivities.of( SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], ALPHA, USD, alphaSensi), SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], RHO, USD, rhoSensi), SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], NU, USD, nuSensi)); CurrencyParameterSensitivities sensiComputed = prov.parameterSensitivity(point); UnitParameterSensitivity alphaSensitivities = prov.getParameters().getAlphaSurface() .zValueParameterSensitivity(expiryTime, TEST_TENOR[i]); UnitParameterSensitivity betaSensitivities = prov.getParameters().getBetaSurface() .zValueParameterSensitivity(expiryTime, TEST_TENOR[i]); UnitParameterSensitivity rhoSensitivities = prov.getParameters().getRhoSurface() .zValueParameterSensitivity(expiryTime, TEST_TENOR[i]); UnitParameterSensitivity nuSensitivities = prov.getParameters().getNuSurface() .zValueParameterSensitivity(expiryTime, TEST_TENOR[i]); CurrencyParameterSensitivity alphaSensiObj = sensiComputed.getSensitivity(
public void test_presentValueSensitivityModelParamsSabr() { PointSensitivities sensiRec = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build(); PointSensitivities sensiPay = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build(); double forward = SWAP_PRICER.parRate(RSWAP_REC, RATE_PROVIDER); double pvbp = SWAP_PRICER.getLegPricer().pvbp(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), RATE_PROVIDER); double volatility = VOLS.volatility(SWAPTION_REC_LONG.getExpiry(), TENOR_YEAR, RATE, forward); double maturity = VOLS.relativeTime(SWAPTION_REC_LONG.getExpiry()); double[] volSensi = VOLS.getParameters() .volatilityAdjoint(maturity, TENOR_YEAR, RATE, forward).getDerivatives().toArray(); double vegaRec = pvbp * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, maturity, volatility); double vegaPay = -pvbp * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, maturity, volatility); assertSensitivity(sensiRec, SabrParameterType.ALPHA, vegaRec * volSensi[2], TOL); assertSensitivity(sensiRec, SabrParameterType.BETA, vegaRec * volSensi[3], TOL); assertSensitivity(sensiRec, SabrParameterType.RHO, vegaRec * volSensi[4], TOL); assertSensitivity(sensiRec, SabrParameterType.NU, vegaRec * volSensi[5], TOL); assertSensitivity(sensiPay, SabrParameterType.ALPHA, vegaPay * volSensi[2], TOL); assertSensitivity(sensiPay, SabrParameterType.BETA, vegaPay * volSensi[3], TOL); assertSensitivity(sensiPay, SabrParameterType.RHO, vegaPay * volSensi[4], TOL); assertSensitivity(sensiPay, SabrParameterType.NU, vegaPay * volSensi[5], TOL); }
public void test_presentValueVega_SwaptionSensitivity() { SwaptionSensitivity vegaRec = PRICER .presentValueSensitivityModelParamsVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS); assertEquals(VOLS.parameterSensitivity(vegaRec), CurrencyParameterSensitivities.empty()); }
double[] points2 = new double[] {-0.145, 1.01, -5.0, -11.0}; double[] points3 = new double[] {1.3, -4.32, 2.1, -7.18}; SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM); double expiryTime0 = prov.relativeTime(TEST_OPTION_EXPIRY[0]); double expiryTime3 = prov.relativeTime(TEST_OPTION_EXPIRY[3]); for (int i = 0; i < NB_TEST; i++) { PointSensitivities sensi1 = PointSensitivities.of( SwaptionSabrSensitivity.of(NAME, expiryTime3, TEST_TENOR[i], NU, USD, points3[3])); PointSensitivities sensis = sensi1.combinedWith(sensi2).combinedWith(sensi3).normalized(); CurrencyParameterSensitivities computed = prov.parameterSensitivity(sensis); CurrencyParameterSensitivities expected = prov.parameterSensitivity(sensi1) .combinedWith(prov.parameterSensitivity(sensi2)) .combinedWith(prov.parameterSensitivity(sensi3)); DoubleArrayMath.fuzzyEquals( computed.getSensitivity(PARAM.getAlphaSurface().getName(), USD).getSensitivity().toArray(),
PRICER.presentValueSensitivityModelParamsSabr(coupon, ratesProvider, volatilities).build(); CurrencyParameterSensitivities computedCoupon = volatilities.parameterSensitivity(pvPointCoupon); PointSensitivities pvCapPoint = PRICER.presentValueSensitivityModelParamsSabr(caplet, ratesProvider, volatilities).build(); CurrencyParameterSensitivities computedCap = volatilities.parameterSensitivity(pvCapPoint); PointSensitivities pvFloorPoint = PRICER.presentValueSensitivityModelParamsSabr(foorlet, ratesProvider, volatilities).build(); CurrencyParameterSensitivities computedFloor = volatilities.parameterSensitivity(pvFloorPoint); SabrInterestRateParameters sabr = volatilities.getParameters();
/** * Gets the day count used to calculate the expiry year fraction. * * @return the day count */ public DayCount getDayCount() { return getParameters().getDayCount(); }
private void assertSensitivity(PointSensitivities points, SabrParameterType type, double expected) { for (PointSensitivity point : points.getSensitivities()) { SwaptionSabrSensitivity sens = (SwaptionSabrSensitivity) point; assertEquals(sens.getCurrency(), EUR); assertEquals(sens.getVolatilitiesName(), VOLS.getName()); if (sens.getSensitivityType() == type) { assertEquals(sens.getSensitivity(), expected, NOTIONAL * TOL); return; } } fail("Did not find sensitivity: " + type + " in " + points); }
@Override public double relativeTime(ZonedDateTime dateTime) { ArgChecker.notNull(dateTime, "dateTime"); LocalDate valuationDate = valuationDateTime.toLocalDate(); LocalDate date = dateTime.toLocalDate(); return getDayCount().relativeYearFraction(valuationDate, date); }
@Override public SabrParametersSwaptionVolatilities build() { return new SabrParametersSwaptionVolatilities( name, convention, valuationDateTime, parameters, dataSensitivityAlpha, dataSensitivityBeta, dataSensitivityRho, dataSensitivityNu); }
SurfaceMetadata alphaMetadata = calibrated.getParameters().getAlphaSurface().getMetadata(); Optional<List<ParameterMetadata>> alphaParameterMetadataOption = alphaMetadata.getParameterMetadata(); assertTrue(alphaParameterMetadataOption.isPresent()); List<ParameterMetadata> alphaParameterMetadata = alphaParameterMetadataOption.get(); List<DoubleArray> alphaJacobian = calibrated.getDataSensitivityAlpha().get(); SurfaceMetadata rhoMetadata = calibrated.getParameters().getRhoSurface().getMetadata(); Optional<List<ParameterMetadata>> rhoParameterMetadataOption = rhoMetadata.getParameterMetadata(); assertTrue(rhoParameterMetadataOption.isPresent()); List<ParameterMetadata> rhoParameterMetadata = rhoParameterMetadataOption.get(); List<DoubleArray> rhoJacobian = calibrated.getDataSensitivityRho().get(); SurfaceMetadata nuMetadata = calibrated.getParameters().getNuSurface().getMetadata(); Optional<List<ParameterMetadata>> nuParameterMetadataOption = nuMetadata.getParameterMetadata(); assertTrue(nuParameterMetadataOption.isPresent()); List<ParameterMetadata> nuParameterMetadata = nuParameterMetadataOption.get(); List<DoubleArray> nuJacobian = calibrated.getDataSensitivityNu().get(); .adjust(CALIBRATION_DATE.plus(EXPIRIES_SIMPLE.get(loopexpiry)), REF_DATA); ZonedDateTime expiryDateTime = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin")); double time = calibrated.relativeTime(expiryDateTime); Pair<DoubleArray, DoubleArray> ds = DATA_SIMPLE.getData(tenor).availableSmileAtExpiry(EXPIRIES_SIMPLE.get(loopexpiry)); if (!ds.getFirst().isEmpty()) { SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, betaSurface, shiftSurface); alphaShifted[loopsign] = calibratedShifted.getParameters().getAlphaSurface().zValue(time, tenorYear); rhoShifted[loopsign] = calibratedShifted.getParameters().getRhoSurface().zValue(time, tenorYear); nuShifted[loopsign] = calibratedShifted.getParameters().getNuSurface().zValue(time, tenorYear);
public void test_presentValueSensitivityRatesStickyModel_stickyStrike() { SwaptionVolatilities volSabr = SwaptionSabrRateVolatilityDataSet.getVolatilitiesUsd(VAL_DATE, false); double impliedVol = SWAPTION_PRICER.impliedVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr); SurfaceMetadata blackMeta = Surfaces.blackVolatilityByExpiryTenor("CST", VOLS.getDayCount()); SwaptionVolatilities volCst = BlackSwaptionExpiryTenorVolatilities.of( VOLS.getConvention(), VOLS.getValuationDateTime(), ConstantSurface.of(blackMeta, impliedVol)); // To obtain a constant volatility surface which create a sticky strike sensitivity PointSensitivityBuilder pointRec = SWAPTION_PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr); CurrencyParameterSensitivities computedRec = RATE_PROVIDER.parameterSensitivity(pointRec.build()); CurrencyParameterSensitivities expectedRec = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> SWAPTION_PRICER.presentValue(SWAPTION_REC_LONG, (p), volCst)); assertTrue(computedRec.equalWithTolerance(expectedRec, NOTIONAL * FD_EPS * 100d)); PointSensitivityBuilder pointPay = SWAPTION_PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_PAY_SHORT, RATE_PROVIDER, volSabr); CurrencyParameterSensitivities computedPay = RATE_PROVIDER.parameterSensitivity(pointPay.build()); CurrencyParameterSensitivities expectedPay = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> SWAPTION_PRICER.presentValue(SWAPTION_PAY_SHORT, (p), volCst)); assertTrue(computedPay.equalWithTolerance(expectedPay, NOTIONAL * FD_EPS * 100d)); }
public void test_presentValueSensitivityModelParamsSabr() { PointSensitivities sensiRec = PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build(); PointSensitivities sensiPay = PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build(); double forward = PRICER_SWAP.parRate(RSWAP_REC, RATE_PROVIDER); double annuityCash = PRICER_SWAP.getLegPricer().annuityCash(RFIXED_LEG_REC, forward); double expiry = VOLS.relativeTime(MATURITY); double volatility = VOLS.volatility(SWAPTION_REC_LONG.getExpiry(), TENOR_YEAR, RATE, forward); double df = RATE_PROVIDER.discountFactor(EUR, SETTLE); double[] volSensi = VOLS.getParameters().volatilityAdjoint(expiry, TENOR_YEAR, RATE, forward).getDerivatives().toArray(); double vegaRec = df * annuityCash * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, expiry, volatility); double vegaPay = -df * annuityCash * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, expiry, volatility); assertSensitivity(sensiRec, SabrParameterType.ALPHA, vegaRec * volSensi[2]); assertSensitivity(sensiRec, SabrParameterType.BETA, vegaRec * volSensi[3]); assertSensitivity(sensiRec, SabrParameterType.RHO, vegaRec * volSensi[4]); assertSensitivity(sensiRec, SabrParameterType.NU, vegaRec * volSensi[5]); assertSensitivity(sensiPay, SabrParameterType.ALPHA, vegaPay * volSensi[2]); assertSensitivity(sensiPay, SabrParameterType.BETA, vegaPay * volSensi[3]); assertSensitivity(sensiPay, SabrParameterType.RHO, vegaPay * volSensi[4]); assertSensitivity(sensiPay, SabrParameterType.NU, vegaPay * volSensi[5]); }