Пример #1
0
        public virtual void recovery_test_normal_shift_fixedRho()
        {
            double      shift   = 0.02;
            DoubleArray initial = DoubleArray.of(0.05, 0.35, 0.0, 0.9);
            SabrIborCapletFloorletVolatilityCalibrationDefinition definition = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedRho(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, shift, ALPHA_KNOTS, BETA_RHO_KNOTS, NU_KNOTS, initial, DOUBLE_QUADRATIC, FLAT, FLAT, HAGAN);
            ImmutableList <Period> maturities = createNormalEquivMaturities();
            DoubleArray            strikes    = createNormalEquivStrikes();
            DoubleMatrix           volData    = createFullNormalEquivDataMatrix();
            DoubleMatrix           error      = DoubleMatrix.filled(volData.rowCount(), volData.columnCount(), 1.0e-3);
            RawOptionData          data       = RawOptionData.of(maturities, strikes, ValueType.STRIKE, volData, error, ValueType.NORMAL_VOLATILITY);
            IborCapletFloorletVolatilityCalibrationResult res     = CALIBRATOR.calibrate(definition, CALIBRATION_TIME, data, RATES_PROVIDER);
            SabrIborCapletFloorletVolatilities            resVols = (SabrIborCapletFloorletVolatilities)res.Volatilities;

            for (int i = 0; i < strikes.size(); ++i)
            {
                Pair <IList <ResolvedIborCapFloorLeg>, IList <double> > capsAndVols = getCapsNormalEquivVols(i);
                IList <ResolvedIborCapFloorLeg> caps = capsAndVols.First;
                IList <double> vols  = capsAndVols.Second;
                int            nCaps = caps.Count;
                for (int j = 0; j < nCaps; ++j)
                {
                    ConstantSurface volSurface = ConstantSurface.of(Surfaces.normalVolatilityByExpiryStrike("test", ACT_ACT_ISDA), vols[j]);
                    NormalIborCapletFloorletExpiryStrikeVolatilities constVol = NormalIborCapletFloorletExpiryStrikeVolatilities.of(USD_LIBOR_3M, CALIBRATION_TIME, volSurface);
                    double priceOrg   = LEG_PRICER_NORMAL.presentValue(caps[j], RATES_PROVIDER, constVol).Amount;
                    double priceCalib = LEG_PRICER_SABR.presentValue(caps[j], RATES_PROVIDER, resVols).Amount;
                    assertEquals(priceOrg, priceCalib, Math.Max(priceOrg, 1d) * TOL * 5d);
                }
            }
        }
Пример #2
0
        public virtual void recovery_test_flat()
        {
            DoubleArray initial = DoubleArray.of(0.4, 0.95, 0.5, 0.05);
            SabrIborCapletFloorletVolatilityCalibrationDefinition definition = SabrIborCapletFloorletVolatilityCalibrationDefinition.ofFixedBeta(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, ALPHA_KNOTS, BETA_RHO_KNOTS, NU_KNOTS, initial, LINEAR, FLAT, FLAT, HAGAN);
            DoubleArray   strikes = createBlackStrikes();
            RawOptionData data    = RawOptionData.of(createBlackMaturities(), strikes, ValueType.STRIKE, createFullFlatBlackDataMatrix(), ValueType.BLACK_VOLATILITY);
            IborCapletFloorletVolatilityCalibrationResult res    = CALIBRATOR.calibrate(definition, CALIBRATION_TIME, data, RATES_PROVIDER);
            SabrIborCapletFloorletVolatilities            resVol = (SabrIborCapletFloorletVolatilities)res.Volatilities;

            for (int i = 0; i < NUM_BLACK_STRIKES; ++i)
            {
                Pair <IList <ResolvedIborCapFloorLeg>, IList <double> > capsAndVols = getCapsFlatBlackVols(i);
                IList <ResolvedIborCapFloorLeg> caps = capsAndVols.First;
                IList <double> vols  = capsAndVols.Second;
                int            nCaps = caps.Count;
                for (int j = 0; j < nCaps; ++j)
                {
                    ConstantSurface volSurface = ConstantSurface.of(Surfaces.blackVolatilityByExpiryStrike("test", ACT_ACT_ISDA), vols[j]);
                    BlackIborCapletFloorletExpiryStrikeVolatilities constVol = BlackIborCapletFloorletExpiryStrikeVolatilities.of(USD_LIBOR_3M, CALIBRATION_TIME, volSurface);
                    double priceOrg   = LEG_PRICER_BLACK.presentValue(caps[j], RATES_PROVIDER, constVol).Amount;
                    double priceCalib = LEG_PRICER_SABR.presentValue(caps[j], RATES_PROVIDER, resVol).Amount;
                    assertEquals(priceOrg, priceCalib, Math.Max(priceOrg, 1d) * TOL);
                }
            }
        }
 /// <summary>
 /// Calculates the present value sensitivity to the SABR model parameters of the Ibor cap/floor.
 /// <para>
 /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
 ///
 /// </para>
 /// </summary>
 /// <param name="capFloorLeg">  the Ibor cap/floor </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="volatilities"> the volatilities </param>
 /// <returns> the point sensitivity to the SABR model parameters </returns>
 public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(ResolvedIborCapFloorLeg capFloorLeg, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
 {
     validate(ratesProvider, volatilities);
     return(capFloorLeg.CapletFloorletPeriods.Select(period => periodPricer.presentValueSensitivityModelParamsSabr(period, ratesProvider, volatilities)).Aggregate((c1, c2) => c1.combinedWith(c2)).get());
 }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the present value volatility sensitivity of the Ibor cap/floor product.
 /// <para>
 /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
 ///
 /// </para>
 /// </summary>
 /// <param name="capFloor">  the Ibor cap/floor product </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="volatilities">  the volatilities </param>
 /// <returns> the present value sensitivity </returns>
 public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(ResolvedIborCapFloor capFloor, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
 {
     return(capFloorLegPricer.presentValueSensitivityModelParamsSabr(capFloor.CapFloorLeg, ratesProvider, volatilities));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value rates sensitivity of the Ibor cap/floor product.
        /// <para>
        /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the
        /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential
        /// re-calibration of the model parameters to the raw market data.
        ///
        /// </para>
        /// </summary>
        /// <param name="capFloor">  the Ibor cap/floor product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value sensitivity </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyModel(ResolvedIborCapFloor capFloor, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            PointSensitivityBuilder pvSensiCapFloorLeg = capFloorLegPricer.presentValueSensitivityRatesStickyModel(capFloor.CapFloorLeg, ratesProvider, volatilities);

            if (!capFloor.PayLeg.Present)
            {
                return(pvSensiCapFloorLeg);
            }
            PointSensitivityBuilder pvSensiPayLeg = PayLegPricer.presentValueSensitivity(capFloor.PayLeg.get(), ratesProvider);

            return(pvSensiCapFloorLeg.combinedWith(pvSensiPayLeg));
        }
Пример #6
0
 /// <summary>
 /// Calculates the present value volatility sensitivity of the Ibor cap/floor trade.
 /// <para>
 /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the Ibor cap/floor trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="volatilities">  the volatilities </param>
 /// <returns> the present value sensitivity </returns>
 public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(ResolvedIborCapFloorTrade trade, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
 {
     return(productPricer.presentValueSensitivityModelParamsSabr(trade.Product, ratesProvider, volatilities));
 }
Пример #7
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value rates sensitivity of the Ibor cap/floor trade.
        /// <para>
        /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the
        /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential
        /// re-calibration of the model parameters to the raw market data.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the Ibor cap/floor trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value sensitivity </returns>
        public virtual PointSensitivities presentValueSensitivityRatesStickyModel(ResolvedIborCapFloorTrade trade, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            PointSensitivityBuilder pvSensiProduct = productPricer.presentValueSensitivityRatesStickyModel(trade.Product, ratesProvider, volatilities);

            if (!trade.Premium.Present)
            {
                return(pvSensiProduct.build());
            }
            PointSensitivityBuilder pvSensiPremium = PaymentPricer.presentValueSensitivity(trade.Premium.get(), ratesProvider);

            return(pvSensiProduct.combinedWith(pvSensiPremium).build());
        }
Пример #8
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the Ibor caplet/floorlet to the rate curves.
        /// <para>
        /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the
        /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential
        /// re-calibration of the model parameters to the raw market data.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyModel(IborCapletFloorletPeriod period, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            Currency currency = period.Currency;

            if (ratesProvider.ValuationDate.isAfter(period.PaymentDate))
            {
                return(PointSensitivityBuilder.none());
            }
            double  expiry    = volatilities.relativeTime(period.FixingDateTime);
            PutCall putCall   = period.PutCall;
            double  strike    = period.Strike;
            double  indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            PointSensitivityBuilder dfSensi = ratesProvider.discountFactors(currency).zeroRatePointSensitivity(period.PaymentDate);
            double factor = period.Notional * period.YearFraction;

            if (expiry < 0d)
            {     // option expired already, but not yet paid
                double sign   = putCall.Call ? 1d : -1d;
                double payoff = Math.Max(sign * (indexRate - strike), 0d);
                return(dfSensi.multipliedBy(payoff * factor));
            }
            ValueDerivatives        volatilityAdj       = volatilities.volatilityAdjoint(expiry, strike, indexRate);
            PointSensitivityBuilder indexRateSensiSensi = ratesProvider.iborIndexRates(period.Index).ratePointSensitivity(period.IborRate.Observation);
            double df       = ratesProvider.discountFactor(currency, period.PaymentDate);
            double fwdPv    = factor * volatilities.price(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            double fwdDelta = factor * volatilities.priceDelta(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            double fwdVega  = factor * volatilities.priceVega(expiry, putCall, strike, indexRate, volatilityAdj.Value);

            return(dfSensi.multipliedBy(fwdPv).combinedWith(indexRateSensiSensi.multipliedBy(fwdDelta * df + fwdVega * volatilityAdj.getDerivative(0) * df)));
        }
Пример #9
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to the SABR model parameters of the Ibor caplet/floorlet.
        /// <para>
        /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the Ibor caplet/floorlet period </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the SABR model parameters </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(IborCapletFloorletPeriod period, RatesProvider ratesProvider, SabrIborCapletFloorletVolatilities volatilities)
        {
            double expiry = volatilities.relativeTime(period.FixingDateTime);

            if (expiry < 0d)
            {     // option expired already
                return(PointSensitivityBuilder.none());
            }
            Currency         currency               = period.Currency;
            PutCall          putCall                = period.PutCall;
            double           strike                 = period.Strike;
            double           indexRate              = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation);
            double           factor                 = period.Notional * period.YearFraction;
            ValueDerivatives volatilityAdj          = volatilities.volatilityAdjoint(expiry, strike, indexRate);
            DoubleArray      derivative             = volatilityAdj.Derivatives;
            double           df                     = ratesProvider.discountFactor(currency, period.PaymentDate);
            double           vega                   = df * factor * volatilities.priceVega(expiry, putCall, strike, indexRate, volatilityAdj.Value);
            IborCapletFloorletVolatilitiesName name = volatilities.Name;

            return(PointSensitivityBuilder.of(IborCapletFloorletSabrSensitivity.of(name, expiry, ALPHA, currency, vega * derivative.get(2)), IborCapletFloorletSabrSensitivity.of(name, expiry, BETA, currency, vega * derivative.get(3)), IborCapletFloorletSabrSensitivity.of(name, expiry, RHO, currency, vega * derivative.get(4)), IborCapletFloorletSabrSensitivity.of(name, expiry, NU, currency, vega * derivative.get(5))));
        }