public virtual void presentValueSensitivity_onFix_nots() { PointSensitivities pv = PRICER_CMS.presentValueSensitivity(COUPON, RATES_PROVIDER_ON_FIX).build(); double df = RATES_PROVIDER_ON_FIX.discountFactor(EUR, PAYMENT); ZeroRateSensitivity dfdr = RATES_PROVIDER_ON_FIX.discountFactors(EUR).zeroRatePointSensitivity(PAYMENT); double forward = PRICER_SWAP.parRate(COUPON.UnderlyingSwap, RATES_PROVIDER_ON_FIX); PointSensitivities forwarddr = PRICER_SWAP.parRateSensitivity(COUPON.UnderlyingSwap, RATES_PROVIDER_ON_FIX).build(); PointSensitivities expected = forwarddr.multipliedBy(df).combinedWith(dfdr.multipliedBy(forward).build()).multipliedBy(NOTIONAL * ACC_FACTOR); assertTrue(pv.equalWithTolerance(expected, TOLERANCE_DELTA)); }
public virtual void test_presentValueSensitivityRatesStickyModel_after() { PointSensitivityBuilder capComputed = PRICER.presentValueSensitivityRatesStickyModel(CAP, RATES_AFTER, VOLS_AFTER); PointSensitivityBuilder floorComputed = PRICER.presentValueSensitivityRatesStickyModel(FLOOR, RATES_AFTER, VOLS_AFTER); PointSensitivityBuilder capExpected = PointSensitivityBuilder.none(); IborCapletFloorletPeriod period = FLOOR.CapletFloorletPeriods.get(1); PointSensitivityBuilder floorExpected = RATES_AFTER.discountFactors(EUR).zeroRatePointSensitivity(period.PaymentDate).multipliedBy(-(STRIKE - OBS_INDEX_2) * NOTIONAL_VALUE * period.YearFraction); int nPeriods = CAP.CapletFloorletPeriods.size(); for (int i = 2; i < nPeriods; ++i) { capExpected = capExpected.combinedWith(PRICER_PERIOD.presentValueSensitivityRatesStickyModel(CAP.CapletFloorletPeriods.get(i), RATES_AFTER, VOLS_AFTER)); floorExpected = floorExpected.combinedWith(PRICER_PERIOD.presentValueSensitivityRatesStickyModel(FLOOR.CapletFloorletPeriods.get(i), RATES_AFTER, VOLS_AFTER)); } CurrencyParameterSensitivities capSensiComputed = RATES_AFTER.parameterSensitivity(capComputed.build()); CurrencyParameterSensitivities floorSensiComputed = RATES_AFTER.parameterSensitivity(floorComputed.build()); CurrencyParameterSensitivities capSensiExpected = RATES_AFTER.parameterSensitivity(capExpected.build()); CurrencyParameterSensitivities floorSensiExpected = RATES_AFTER.parameterSensitivity(floorExpected.build()); assertTrue(capSensiComputed.equalWithTolerance(capSensiExpected, NOTIONAL_VALUE * TOL)); assertTrue(floorSensiComputed.equalWithTolerance(floorSensiExpected, NOTIONAL_VALUE * TOL)); }
public virtual void test_recoverVolatility() { int nSteps = TREE_DATA.NumberOfSteps; double spot = TREE_DATA.Spot; double timeToExpiry = TREE_DATA.getTime(nSteps); double dfDom = RATE_PROVIDER.discountFactors(USD).discountFactor(timeToExpiry); double dfFor = RATE_PROVIDER.discountFactors(EUR).discountFactor(timeToExpiry); double forward = spot * dfFor / dfDom; for (int i = 0; i < 100; ++i) { double strike = spot * (0.8 + 0.004 * i); OptionFunction func = EuropeanVanillaOptionFunction.of(strike, timeToExpiry, PutCall.CALL, nSteps); double price = TREE.optionPrice(func, TREE_DATA); double impliedVol = BlackFormulaRepository.impliedVolatility(price / dfDom, forward, strike, timeToExpiry, true); double orgVol = VOLS.volatility(FX_PRODUCT.CurrencyPair, timeToExpiry, strike, forward); assertEquals(impliedVol, orgVol, orgVol * 0.1); // large tol double priceMrkt = TREE.optionPrice(func, TREE_DATA_MRKT); double impliedVolMrkt = BlackFormulaRepository.impliedVolatility(priceMrkt / dfDom, forward, strike, timeToExpiry, true); double orgVolMrkt = VOLS_MRKT.volatility(FX_PRODUCT.CurrencyPair, timeToExpiry, strike, forward); assertEquals(impliedVolMrkt, orgVolMrkt, orgVolMrkt * 0.1); // large tol } }
public virtual void presentValueSensitivity_afterFix() { PointSensitivities ptsCpn = PRICER_CMS.presentValueSensitivity(COUPON, RATES_PROVIDER_AFTER_FIX).build(); PointSensitivities ptsCapletOtm = PRICER_CMS.presentValueSensitivity(CAPLET, RATES_PROVIDER_AFTER_FIX).build(); PointSensitivities ptsCapletItm = PRICER_CMS.presentValueSensitivity(CAPLET_NEGATIVE, RATES_PROVIDER_AFTER_FIX).build(); PointSensitivities ptsFloorletItm = PRICER_CMS.presentValueSensitivity(FLOORLET, RATES_PROVIDER_AFTER_FIX).build(); PointSensitivities ptsFloorletOtm = PRICER_CMS.presentValueSensitivity(FLOORLET_NEGATIVE, RATES_PROVIDER_AFTER_FIX).build(); double factor = NOTIONAL * COUPON.YearFraction; ZeroRateSensitivity pts = RATES_PROVIDER_AFTER_FIX.discountFactors(EUR).zeroRatePointSensitivity(PAYMENT); assertTrue(ptsCpn.equalWithTolerance(pts.build().multipliedBy(factor * OBS_INDEX), TOLERANCE_DELTA)); assertTrue(ptsCapletOtm.equalWithTolerance(pts.build().multipliedBy(0d), TOLERANCE_DELTA)); assertTrue(ptsCapletItm.equalWithTolerance(pts.build().multipliedBy(factor * (OBS_INDEX - STRIKE_NEGATIVE)), TOLERANCE_DELTA)); assertTrue(ptsFloorletItm.equalWithTolerance(pts.build().multipliedBy(factor * (STRIKE - OBS_INDEX)), TOLERANCE_DELTA)); assertTrue(ptsFloorletOtm.equalWithTolerance(pts.build().multipliedBy(0d), TOLERANCE_DELTA)); }
//------------------------------------------------------------------------- public virtual void test_putCallParity() { double df = RATES_PROVIDER.discountFactor(USD, PAY); PointSensitivityBuilder dfSensi = RATES_PROVIDER.discountFactors(USD).zeroRatePointSensitivity(PAY); for (int i = 0; i < NB_STRIKES; ++i) { CurrencyAmount pvCall = PRICER.presentValue(CALLS[i], RATES_PROVIDER, VOLS); PointSensitivityBuilder pvSensiCall = PRICER.presentValueSensitivityRatesStickyStrike(CALLS[i], RATES_PROVIDER, VOLS); PointSensitivityBuilder pvSensiVolCall = PRICER.presentValueSensitivityModelParamsVolatility(CALLS[i], RATES_PROVIDER, VOLS); CurrencyAmount pvPut = PRICER.presentValue(PUTS[i], RATES_PROVIDER, VOLS); PointSensitivityBuilder pvSensiPut = PRICER.presentValueSensitivityRatesStickyStrike(PUTS[i], RATES_PROVIDER, VOLS); PointSensitivityBuilder pvSensiVolPut = PRICER.presentValueSensitivityModelParamsVolatility(PUTS[i], RATES_PROVIDER, VOLS); double forward = FX_PRICER.forwardFxRate(UNDERLYING[i], RATES_PROVIDER).fxRate(CURRENCY_PAIR); PointSensitivityBuilder forwardSensi = FX_PRICER.forwardFxRatePointSensitivity(UNDERLYING[i], RATES_PROVIDER); double strike = CALLS[i].Strike; assertEquals(pvCall.Amount + pvPut.Amount, df * (forward - strike) * NOTIONAL, TOL * NOTIONAL); assertTrue(pvSensiCall.combinedWith(pvSensiPut).build().normalized().equalWithTolerance(dfSensi.multipliedBy((forward - strike) * NOTIONAL).combinedWith(forwardSensi.multipliedBy(df * NOTIONAL)).build().normalized(), NOTIONAL * TOL)); DoubleArray sensiVol = VOLS.parameterSensitivity(pvSensiVolCall.combinedWith(pvSensiVolPut).build()).Sensitivities.get(0).Sensitivity; assertTrue(DoubleArrayMath.fuzzyEquals(sensiVol.toArray(), new double[sensiVol.size()], NOTIONAL * TOL)); } }