/** * Obtains an instance from a SABR volatility function provider and a swap pricer. * <p> * The swap pricer is used to compute the forward rate required for calibration. * * @param sabrVolatilityFormula the SABR implied volatility formula * @param swapPricer the swap pricer * @param refData the reference data * @return the calibrator */ public static SabrSwaptionCalibrator of( SabrVolatilityFormula sabrVolatilityFormula, DiscountingSwapProductPricer swapPricer, ReferenceData refData) { return new SabrSwaptionCalibrator(sabrVolatilityFormula, swapPricer, refData); }
ArgChecker.isTrue(nbStrikes == blackVolatilitiesInput.size(), "size of strikes must be the same as size of volatilities"); LocalDate calibrationDate = calibrationDateTime.toLocalDate(); LocalDate exerciseDate = expirationDate(bda, calibrationDate, periodToExpiry); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); DoubleArray errors = DoubleArray.filled(nbStrikes, 1e-4); DoubleArray strikes = strikesShifted(forward, 0.0, strikesLike, strikeType); Pair<DoubleArray, DoubleArray> volAndDerivatives = blackVolatilitiesShiftedFromBlackVolatilitiesShifted( forward, shiftOutput, timeToExpiry, strikes, blackVolatilitiesInput, shiftInput); DoubleArray blackVolatilitiesTransformed = volAndDerivatives.getFirst(); DoubleArray strikesShifted = strikesShifted(forward, shiftOutput, strikesLike, strikeType); SabrModelFitter fitter = new SabrModelFitter( forward + shiftOutput,
ArgChecker.isTrue(nbStrikes == normalVolatilities.size(), "size of strikes must be the same as size of prices"); LocalDate calibrationDate = calibrationDateTime.toLocalDate(); LocalDate exerciseDate = expirationDate(bda, calibrationDate, periodToExpiry); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); DoubleArray errors = DoubleArray.filled(nbStrikes, 1e-4); DoubleArray strikes = strikesShifted(forward, 0.0, strikesLike, strikeType); Pair<DoubleArray, DoubleArray> volAndDerivatives = blackVolatilitiesShiftedFromNormalVolatilities( forward, shiftOutput, timeToExpiry, strikes, normalVolatilities); DoubleArray blackVolatilitiesTransformed = volAndDerivatives.getFirst(); DoubleArray strikesShifted = strikesShifted(forward, shiftOutput, strikesLike, strikeType); SabrModelFitter fitter = new SabrModelFitter( forward + shiftOutput,
private Pair<Double, Double> calibrationAtm( double forward, double shift, double beta, double rho, double nu, BusinessDayAdjustment bda, ZonedDateTime calibrationDateTime, DayCount dayCount, Period expiry, double volatility, ValueType volatilityType) { double alphaStart = volatility / Math.pow(forward + shift, beta); DoubleArray startParameters = DoubleArray.of(alphaStart, beta, rho, nu); Pair<Double, Double> r = null; if (volatilityType.equals(ValueType.NORMAL_VOLATILITY)) { r = calibrateAtmShiftedFromNormalVolatilities( bda, calibrationDateTime, dayCount, expiry, forward, volatility, startParameters, shift); } else { if (volatilityType.equals(ValueType.BLACK_VOLATILITY)) { r = calibrateAtmShiftedFromBlackVolatilities( bda, calibrationDateTime, dayCount, expiry, forward, volatility, 0.0, startParameters, shift); } else { throw new IllegalArgumentException("Data type not supported"); } } return r; }
Pair<LeastSquareResultsWithTransform, DoubleArray> r = null; if (rawData.getDataType().equals(ValueType.NORMAL_VOLATILITY)) { r = calibrateLsShiftedFromNormalVolatilities(bda, calibrationDateTime, dayCount, expiry, forward, strike, rawData.getStrikeType(), data, startParameters, fixed, shift); } else { if (rawData.getDataType().equals(ValueType.PRICE)) { r = calibrateLsShiftedFromPrices(bda, calibrationDateTime, dayCount, expiry, forward, strike, rawData.getStrikeType(), data, startParameters, fixed, shift); } else { if (rawData.getDataType().equals(ValueType.BLACK_VOLATILITY)) { r = calibrateLsShiftedFromBlackVolatilities(bda, calibrationDateTime, dayCount, expiry, forward, strike, rawData.getStrikeType(), data, rawData.getShift().orElse(0d), startParameters, fixed, shift);
new SabrSwaptionCalibrator( SabrVolatilityFormula.hagan(), DiscountingSwapProductPricer.DEFAULT, ReferenceData.standard()); return calibrateWithFixedBetaAndShift( definition, calibrationDateTime, continue; LocalDate exerciseDate = expirationDate(bda, calibrationDate, expiries.get(loopexpiry)); LocalDate effectiveDate = convention.calculateSpotDateFromTradeDate(exerciseDate, refData); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); try { Pair<SabrFormulaData, DoubleMatrix> calibrationResult = calibration(forward, shift, beta, fixed, bda, calibrationDateTime, dayCount, availableSmile.getFirst(), availableSmile.getSecond(), expiries.get(loopexpiry), tenorData); sabrPoint = calibrationResult.getFirst();
TENORS, EXPIRIES, ValueType.SIMPLE_MONEYNESS, MONEYNESS, ValueType.NORMAL_VOLATILITY, DATA_ARRAY_FULL, looptenor, loopexpiry, (2 * loopsign - 1) * fdShift); SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, BETA_SURFACE, SHIFT_SABR_SURFACE); pv[loopsign] = LEG_PRICER.presentValue(FLOOR_LEG, MULTICURVE, calibratedShifted).getAmount();
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibratedSmile = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SPARSE, MULTICURVE, betaSurface, shiftSurface); SabrParametersSwaptionVolatilities calibratedAtm = SABR_CALIBRATION.calibrateAlphaWithAtm(NAME_SABR, calibratedSmile, MULTICURVE, ATM_LOGNORMAL_SIMPLE, TENORS_SIMPLE, EXPIRIES_SIMPLE_2, INTERPOLATOR_2D); int nbExp = EXPIRIES_SIMPLE_2.size();
ArgChecker.isTrue(nbStrikes == prices.size(), "size of strikes must be the same as size of prices"); LocalDate calibrationDate = calibrationDateTime.toLocalDate(); LocalDate exerciseDate = expirationDate(bda, calibrationDate, periodToExpiry); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); DoubleArray errors = DoubleArray.filled(nbStrikes, 1e-4); DoubleArray strikes = strikesShifted(forward, 0.0, strikesLike, strikeType); Pair<DoubleArray, DoubleArray> volAndDerivatives = blackVolatilitiesShiftedFromPrices( forward, shiftOutput, timeToExpiry, strikes, prices); DoubleArray blackVolatilitiesTransformed = volAndDerivatives.getFirst(); DoubleArray strikesShifted = strikesShifted(forward, shiftOutput, strikesLike, strikeType); SabrModelFitter fitter = new SabrModelFitter( forward + shiftOutput,
LocalDate exerciseDate = expirationDate(bda, calibrationDate, periodToExpiry); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); Pair<DoubleArray, DoubleArray> volAndDerivatives = blackVolatilitiesShiftedFromBlackVolatilitiesShifted( forward, shiftOutput, timeToExpiry, DoubleArray.of(forward), DoubleArray.of(blackVolatility), shiftInput); DoubleArray blackVolatilitiesTransformed = volAndDerivatives.getFirst();
LocalDate exerciseDate = expirationDate(bda, calibrationDate, periodToExpiry); double timeToExpiry = dayCount.relativeYearFraction(calibrationDate, exerciseDate); Pair<DoubleArray, DoubleArray> volAndDerivatives = blackVolatilitiesShiftedFromNormalVolatilities( forward, shiftOutput, timeToExpiry, DoubleArray.of(forward), DoubleArray.of(normalVolatility)); DoubleArray blackVolatilitiesTransformed = volAndDerivatives.getFirst();
private void checkCalibrationNormal( DoubleArray moneyness, DoubleArray normalVol, DoubleArray startParameters, BitSet fixed, double shift, double tolerance) { Pair<LeastSquareResultsWithTransform, DoubleArray> rComputed = SABR_CALIBRATION .calibrateLsShiftedFromNormalVolatilities(BDA, CALIBRATION_TIME, ACT_365F, EXPIRY_PERIOD, FORWARD, moneyness, ValueType.SIMPLE_MONEYNESS, normalVol, startParameters, fixed, shift); SabrFormulaData sabrComputed = SabrFormulaData.of(rComputed.getFirst().getModelParameters().toArrayUnsafe()); for (int i = 0; i < moneyness.size(); i++) { double ivComputed = SABR_FORMULA.volatility( FORWARD + shift, FORWARD + moneyness.get(i) + shift, TIME_EXPIRY, sabrComputed.getAlpha(), sabrComputed.getBeta(), sabrComputed.getRho(), sabrComputed.getNu()); double priceComputed = BlackFormulaRepository.price(FORWARD + shift, FORWARD + moneyness.get(i) + shift, TIME_EXPIRY, ivComputed, true); double priceNormal = NormalFormulaRepository.price(FORWARD, FORWARD + moneyness.get(i), TIME_EXPIRY, normalVol.get(i), PutCall.CALL); assertEquals(priceComputed, priceNormal, tolerance); } }
private void checkCalibrationBlack( DoubleArray moneyness, DoubleArray blackVol, DoubleArray startParameters, BitSet fixed, double shift, double tolerance) { Pair<LeastSquareResultsWithTransform, DoubleArray> rComputed = SABR_CALIBRATION .calibrateLsShiftedFromBlackVolatilities(BDA, CALIBRATION_TIME, ACT_365F, EXPIRY_PERIOD, FORWARD, moneyness, ValueType.SIMPLE_MONEYNESS, blackVol, 0.0, startParameters, fixed, shift); SabrFormulaData sabrComputed = SabrFormulaData.of(rComputed.getFirst().getModelParameters().toArrayUnsafe()); for (int i = 0; i < moneyness.size(); i++) { double ivComputed = SABR_FORMULA.volatility( FORWARD + shift, FORWARD + moneyness.get(i) + shift, TIME_EXPIRY, sabrComputed.getAlpha(), sabrComputed.getBeta(), sabrComputed.getRho(), sabrComputed.getNu()); double priceComputed = BlackFormulaRepository.price(FORWARD + shift, FORWARD + moneyness.get(i) + shift, TIME_EXPIRY, ivComputed, true); double priceBlack = BlackFormulaRepository.price(FORWARD, FORWARD + moneyness.get(i), TIME_EXPIRY, blackVol.get(i), true); assertEquals(priceComputed, priceBlack, tolerance); // System.out.println("Black: " + priceComputed + " / " + priceBlack); } }
.calibrateLsShiftedFromPrices(BDA, CALIBRATION_TIME, ACT_365F, EXPIRY_PERIOD, FORWARD, moneyness, ValueType.SIMPLE_MONEYNESS, DoubleArray.ofUnsafe(prices), startParameters, fixed, shift); SabrFormulaData sabrComputed = SabrFormulaData.of(rComputed.getFirst().getModelParameters().toArrayUnsafe());
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SPARSE, MULTICURVE, betaSurface, shiftSurface); double fdShift = 1.0E-5; .rawDataShiftPoint(TENORS, EXPIRIES, ValueType.SIMPLE_MONEYNESS, MONEYNESS, ValueType.BLACK_VOLATILITY, DATA_LOGNORMAL, looptenor, loopexpiry, loopmoney, (2 * loopsign - 1) * fdShift); SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, betaSurface, shiftSurface); alphaShifted[loopsign] = calibratedShifted.getParameters().getAlphaSurface().zValue(time, tenorYears);
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibratedSmile = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SIMPLE, MULTICURVE, betaSurface, shiftSurface); SabrParametersSwaptionVolatilities calibratedAtm = SABR_CALIBRATION.calibrateAlphaWithAtm(NAME_SABR, calibratedSmile, MULTICURVE, ATM_NORMAL_SIMPLE, TENORS_SIMPLE, EXPIRIES_SIMPLE_2, INTERPOLATOR_2D); int nbExp = EXPIRIES_SIMPLE_2.size();
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SIMPLE, MULTICURVE, betaSurface, shiftSurface); double fdShift = 1.0E-5; loopmoney, (2 * loopsign - 1) * fdShift); SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, betaSurface, shiftSurface); alphaShifted[loopsign] = calibratedShifted.getParameters().getAlphaSurface().zValue(time, tenorYear);
/** * Obtains an instance from a SABR volatility function provider and a swap pricer. * <p> * The swap pricer is used to compute the forward rate required for calibration. * * @param sabrVolatilityFormula the SABR implied volatility formula * @param swapPricer the swap pricer * @return the calibrator */ public static SabrSwaptionCalibrator of( SabrVolatilityFormula sabrVolatilityFormula, DiscountingSwapProductPricer swapPricer) { return new SabrSwaptionCalibrator(sabrVolatilityFormula, swapPricer, ReferenceData.standard()); }
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SPARSE, MULTICURVE, betaSurface, shiftSurface);
.withMetadata(DefaultSurfaceMetadata.builder() .xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).surfaceName("Shift").build()); SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift( DEFINITION, CALIBRATION_TIME, DATA_SIMPLE, MULTICURVE, betaSurface, shiftSurface);