Esempio n. 1
0
        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);
        }