public virtual void negativeRates() { double shift = 0.05; Surface surface = ConstantSurface.of("shfit", shift); SabrInterestRateParameters @params = SabrInterestRateParameters.of(ALPHA_SURFACE, BETA_SURFACE, RHO_SURFACE, NU_SURFACE, surface, FORMULA); double expiry = 2.0; double tenor = 3.0; assertEquals(@params.alpha(expiry, tenor), ALPHA_SURFACE.zValue(expiry, tenor)); assertEquals(@params.beta(expiry, tenor), BETA_SURFACE.zValue(expiry, tenor)); assertEquals(@params.rho(expiry, tenor), RHO_SURFACE.zValue(expiry, tenor)); assertEquals(@params.nu(expiry, tenor), NU_SURFACE.zValue(expiry, tenor)); double strike = -0.02; double forward = 0.015; double alpha = ALPHA_SURFACE.zValue(expiry, tenor); double beta = BETA_SURFACE.zValue(expiry, tenor); double rho = RHO_SURFACE.zValue(expiry, tenor); double nu = NU_SURFACE.zValue(expiry, tenor); assertEquals(@params.volatility(expiry, tenor, strike, forward), FORMULA.volatility(forward + shift, strike + shift, expiry, alpha, beta, rho, nu)); double[] adjCmp = @params.volatilityAdjoint(expiry, tenor, strike, forward).Derivatives.toArray(); double[] adjExp = FORMULA.volatilityAdjoint(forward + shift, strike + shift, expiry, alpha, beta, rho, nu).Derivatives.toArray(); for (int i = 0; i < 4; ++i) { assertEquals(adjCmp[i], adjExp[i]); } }
public virtual void flatVolTest() { double tol = 2.0e-2; double constantVol = 0.15; ConstantSurface impliedVolSurface = ConstantSurface.of("impliedVol", constantVol); System.Func <double, double> zeroRate = (double?x) => { return(0.05d); }; System.Func <double, double> zeroRate1 = (double?x) => { return(0.02d); }; ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(45, 1d, INTERP_TIMESQ_LINEAR); InterpolatedNodalSurface localVolSurface = calc.localVolatilityFromImpliedVolatility(impliedVolSurface, 100d, zeroRate, zeroRate1); assertEquals(localVolSurface.ZValues.Where(d => !DoubleMath.fuzzyEquals(d, constantVol, tol)).Count(), 0); }
public virtual void flatVolPriceTest() { double tol = 2.0e-2; double constantVol = 0.15; double spot = 100d; double maxTime = 1d; int nSteps = 9; ConstantSurface impliedVolSurface = ConstantSurface.of("impliedVol", constantVol); System.Func <double, double> zeroRate = (double?x) => { return(0d); }; System.Func <DoublesPair, ValueDerivatives> func = (DoublesPair x) => { double price = BlackFormulaRepository.price(spot, x.Second, x.First, constantVol, true); return(ValueDerivatives.of(price, DoubleArray.EMPTY)); }; DeformedSurface priceSurface = DeformedSurface.of(DefaultSurfaceMetadata.of("price"), impliedVolSurface, func); ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(nSteps, maxTime, INTERP_TIMESQ_LINEAR); InterpolatedNodalSurface localVolSurface = calc.localVolatilityFromPrice(priceSurface, spot, zeroRate, zeroRate); assertEquals(localVolSurface.ZValues.Where(d => !DoubleMath.fuzzyEquals(d, constantVol, tol)).Count(), 0); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivity() { PointSensitivityBuilder pointCaplet = PRICER.presentValueSensitivityRatesStickyModel(CAPLET_LONG, RATES, VOLS); CurrencyParameterSensitivities computedCaplet = RATES.parameterSensitivity(pointCaplet.build()); PointSensitivityBuilder pointFloorlet = PRICER.presentValueSensitivityRatesStickyModel(FLOORLET_SHORT, RATES, VOLS); CurrencyParameterSensitivities computedFloorlet = RATES.parameterSensitivity(pointFloorlet.build()); CurrencyParameterSensitivities expectedCaplet = FD_CAL.sensitivity(RATES, p => PRICER_BASE.presentValue(CAPLET_LONG, p, VOLS)); CurrencyParameterSensitivities expectedFloorlet = FD_CAL.sensitivity(RATES, p => PRICER_BASE.presentValue(FLOORLET_SHORT, p, VOLS)); assertTrue(computedCaplet.equalWithTolerance(expectedCaplet, EPS_FD * NOTIONAL * 50d)); assertTrue(computedFloorlet.equalWithTolerance(expectedFloorlet, EPS_FD * NOTIONAL * 50d)); // consistency with shifted Black PointSensitivityBuilder pointCapletBase = PRICER.presentValueSensitivityRates(CAPLET_LONG, RATES, VOLS); PointSensitivityBuilder pointFloorletBase = PRICER.presentValueSensitivityRates(FLOORLET_SHORT, RATES, VOLS); double forward = RATES.iborIndexRates(EUR_EURIBOR_3M).rate(RATE_COMP.Observation); double expiry = VOLS.relativeTime(CAPLET_LONG.FixingDateTime); double volatility = VOLS.volatility(expiry, STRIKE, forward); ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities vols = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(EUR_EURIBOR_3M, VALUATION, ConstantSurface.of("constVol", volatility).withMetadata(Surfaces.blackVolatilityByExpiryStrike("costVol", DayCounts.ACT_ACT_ISDA)), IborCapletFloorletSabrRateVolatilityDataSet.CURVE_CONST_SHIFT); PointSensitivityBuilder pointCapletExp = PRICER_BASE.presentValueSensitivityRates(CAPLET_LONG, RATES, vols); PointSensitivityBuilder pointFloorletExp = PRICER_BASE.presentValueSensitivityRates(FLOORLET_SHORT, RATES, vols); assertEquals(pointCapletBase, pointCapletExp); assertEquals(pointFloorletBase, pointFloorletExp); }
//------------------------------------------------------------------------- public virtual void test_presentValue_formula() { CurrencyAmount computedCaplet = PRICER.presentValue(CAPLET_LONG, RATES, VOLS); CurrencyAmount computedFloorlet = PRICER.presentValue(FLOORLET_SHORT, RATES, VOLS); double forward = RATES.iborIndexRates(EUR_EURIBOR_3M).rate(RATE_COMP.Observation); double expiry = VOLS.relativeTime(CAPLET_LONG.FixingDateTime); double volatility = VOLS.volatility(expiry, STRIKE, forward); double df = RATES.discountFactor(EUR, CAPLET_LONG.PaymentDate); double expectedCaplet = NOTIONAL * df * CAPLET_LONG.YearFraction * BlackFormulaRepository.price(forward + SHIFT, STRIKE + SHIFT, expiry, volatility, CALL.Call); double expectedFloorlet = -NOTIONAL *df *FLOORLET_SHORT.YearFraction *BlackFormulaRepository.price(forward + SHIFT, STRIKE + SHIFT, expiry, volatility, PUT.Call); assertEquals(computedCaplet.Currency, EUR); assertEquals(computedCaplet.Amount, expectedCaplet, NOTIONAL * TOL); assertEquals(computedFloorlet.Currency, EUR); assertEquals(computedFloorlet.Amount, expectedFloorlet, NOTIONAL * TOL); // consistency with shifted Black ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities vols = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(EUR_EURIBOR_3M, VALUATION, ConstantSurface.of("constVol", volatility).withMetadata(Surfaces.blackVolatilityByExpiryStrike("costVol", DayCounts.ACT_ACT_ISDA)), IborCapletFloorletSabrRateVolatilityDataSet.CURVE_CONST_SHIFT); CurrencyAmount computedCapletBlack = PRICER_BASE.presentValue(CAPLET_LONG, RATES, vols); CurrencyAmount computedFloorletBlack = PRICER_BASE.presentValue(FLOORLET_SHORT, RATES, vols); assertEquals(computedCaplet.Amount, computedCapletBlack.Amount, NOTIONAL * TOL); assertEquals(computedFloorlet.Amount, computedFloorletBlack.Amount, NOTIONAL * TOL); }