private const double TOLERANCE_PRICE_CALIBRATION_LS = 5.0E-4; // Calibration Least Square; result not exact //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void normal_cube() public virtual void normal_cube() { double beta = 0.50; Surface betaSurface = ConstantSurface.of("Beta", beta).withMetadata(DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build()); double shift = 0.0300; Surface shiftSurface = ConstantSurface.of("Shift", shift).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); for (int looptenor = 0; looptenor < TENORS.size(); looptenor++) { double tenor = TENORS.get(looptenor).get(ChronoUnit.YEARS); for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++) { LocalDate expiry = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(EXPIRIES.get(loopexpiry)), REF_DATA); LocalDate effectiveDate = EUR_FIXED_1Y_EURIBOR_6M.calculateSpotDateFromTradeDate(expiry, REF_DATA); LocalDate endDate = effectiveDate.plus(TENORS.get(looptenor)); SwapTrade swap = EUR_FIXED_1Y_EURIBOR_6M.toTrade(CALIBRATION_DATE, effectiveDate, endDate, BuySell.BUY, 1.0, 0.0); double parRate = SWAP_PRICER.parRate(swap.resolve(REF_DATA).Product, MULTICURVE); ZonedDateTime expiryDateTime = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin")); double time = calibrated.relativeTime(expiryDateTime); for (int loopmoney = 0; loopmoney < MONEYNESS.size(); loopmoney++) { if (!double.IsNaN(DATA_ARRAY_SPARSE[looptenor][loopexpiry][loopmoney])) { double strike = parRate + MONEYNESS.get(loopmoney); double volBlack = calibrated.volatility(expiryDateTime, tenor, strike, parRate); double priceComputed = BlackFormulaRepository.price(parRate + shift, parRate + MONEYNESS.get(loopmoney) + shift, time, volBlack, true); double priceNormal = NormalFormulaRepository.price(parRate, parRate + MONEYNESS.get(loopmoney), time, DATA_ARRAY_SPARSE[looptenor][loopexpiry][loopmoney], PutCall.CALL); assertEquals(priceComputed, priceNormal, TOLERANCE_PRICE_CALIBRATION_LS); } } } } }
public virtual void test_price_formula() { double sampleVol = 0.2; for (int i = 0; i < NB_TEST; i++) { double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); for (int j = 0; j < NB_TEST; j++) { foreach (PutCall putCall in new PutCall[] { PutCall.CALL, PutCall.PUT }) { double price = VOLS.price(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double delta = VOLS.priceDelta(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double gamma = VOLS.priceGamma(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double theta = VOLS.priceTheta(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double vega = VOLS.priceVega(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); assertEquals(price, NormalFormulaRepository.price(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall)); assertEquals(delta, NormalFormulaRepository.delta(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall)); assertEquals(gamma, NormalFormulaRepository.gamma(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall)); assertEquals(theta, NormalFormulaRepository.theta(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall)); assertEquals(vega, NormalFormulaRepository.vega(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall)); } } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unused") @Test public void normal_atm() public virtual void normal_atm() { double beta = 0.50; Surface betaSurface = ConstantSurface.of("Beta", beta).withMetadata(DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build()); double shift = 0.0300; Surface shiftSurface = ConstantSurface.of("Shift", shift).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(); int nbTenor = TENORS_SIMPLE.size(); for (int loopexpiry = 0; loopexpiry < nbExp; loopexpiry++) { for (int looptenor = 0; looptenor < nbTenor; looptenor++) { double tenor = TENORS_SIMPLE.get(looptenor).get(ChronoUnit.YEARS); LocalDate expiry = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(EXPIRIES_SIMPLE_2.get(loopexpiry)), REF_DATA); LocalDate effectiveDate = EUR_FIXED_1Y_EURIBOR_6M.calculateSpotDateFromTradeDate(expiry, REF_DATA); LocalDate endDate = effectiveDate.plus(TENORS_SIMPLE.get(looptenor)); SwapTrade swap = EUR_FIXED_1Y_EURIBOR_6M.toTrade(CALIBRATION_DATE, effectiveDate, endDate, BuySell.BUY, 1.0, 0.0); double parRate = SWAP_PRICER.parRate(swap.resolve(REF_DATA).Product, MULTICURVE); ZonedDateTime expiryDateTime = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin")); double time = calibratedAtm.relativeTime(expiryDateTime); double volBlack = calibratedAtm.volatility(expiryDateTime, tenor, parRate, parRate); double priceComputed = BlackFormulaRepository.price(parRate + shift, parRate + shift, time, volBlack, true); double priceNormal = NormalFormulaRepository.price(parRate, parRate, time, DATA_NORMAL_ATM_SIMPLE[looptenor + loopexpiry * nbTenor], PutCall.CALL); assertEquals(priceComputed, priceNormal, TOLERANCE_PRICE_CALIBRATION_ROOT); } } }
private void checkCalibrationNormal(DoubleArray moneyness, DoubleArray normalVol, DoubleArray startParameters, BitArray @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.First.ModelParameters.toArrayUnsafe()); for (int i = 0; i < moneyness.size(); i++) { double ivComputed = SABR_FORMULA.volatility(FORWARD + shift, FORWARD + moneyness.get(i) + shift, TIME_EXPIRY, sabrComputed.Alpha, sabrComputed.Beta, sabrComputed.Rho, sabrComputed.Nu); 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); } }
//------------------------------------------------------------------------- public double price(double expiry, PutCall putCall, double strike, double forward, double volatility) { return(NormalFormulaRepository.price(forward, strike, expiry, volatility, putCall)); }