Exemple #1
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(enabled = true) public void log_normal_atm()
        public virtual void log_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.0000;
            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_SPARSE, MULTICURVE, betaSurface, shiftSurface);

            SabrParametersSwaptionVolatilities calibratedAtm = SABR_CALIBRATION.calibrateAlphaWithAtm(NAME_SABR, calibratedSmile, MULTICURVE, ATM_LOGNORMAL_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  = calibratedAtm.price(time, tenor, PutCall.CALL, parRate, parRate, volBlack);
                    double        priceBlack     = BlackFormulaRepository.price(parRate, parRate, time, DATA_LOGNORMAL_ATM_SIMPLE[looptenor + loopexpiry * nbTenor], true);
                    assertEquals(priceComputed, priceBlack, TOLERANCE_PRICE_CALIBRATION_ROOT);
                }
            }
        }
Exemple #2
0
        private void presentValueSensitivityRawDataParallelSensitivity(SabrParametersSwaptionVolatilities sabrCalibrated, TenorRawOptionData dataRaw)
        {
            PointSensitivities             points = LEG_PRICER.presentValueSensitivityModelParamsSabr(FLOOR_LEG, MULTICURVE, sabrCalibrated).build();
            CurrencyParameterSensitivities sabrParametersSurfaceSensitivities = sabrCalibrated.parameterSensitivity(points);
            CurrencyParameterSensitivity   parallelSensitivitiesSurface       = RDSC.parallelSensitivity(sabrParametersSurfaceSensitivities, sabrCalibrated);
            DoubleArray sensitivityArray  = parallelSensitivitiesSurface.Sensitivity;
            double      fdShift           = 1.0E-6;
            int         surfacePointIndex = 0;

            for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
            {
                for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
                {
                    Tenor tenor = TENORS.get(looptenor);
                    Pair <DoubleArray, DoubleArray> ds = dataRaw.getData(tenor).availableSmileAtExpiry(EXPIRIES.get(loopexpiry));
                    if (!ds.First.Empty)
                    {
                        double[] pv = new double[2];   // pv with shift up and down
                        for (int loopsign = 0; loopsign < 2; loopsign++)
                        {
                            TenorRawOptionData dataShifted = SabrSwaptionCalibratorSmileTestUtils.rawDataShiftSmile(TENORS, EXPIRIES, ValueType.SIMPLE_MONEYNESS, MONEYNESS, ValueType.NORMAL_VOLATILITY, DATA_ARRAY_FULL, looptenor, loopexpiry, (2 * loopsign - 1) * fdShift);
                            SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, BETA_SURFACE, SHIFT_SABR_SURFACE);
                            pv[loopsign] = LEG_PRICER.presentValue(FLOOR_LEG, MULTICURVE, calibratedShifted).Amount;
                        }
                        double sensitivityFd = (pv[1] - pv[0]) / (2 * fdShift);   // FD sensitivity computation
                        SabrSwaptionCalibratorSmileTestUtils.checkAcceptable(sensitivityFd, sensitivityArray.get(surfacePointIndex), 0.10, "Tenor/Expiry: " + TENORS.get(looptenor) + " / " + EXPIRIES.get(loopexpiry));
                        surfacePointIndex++;
                    }
                }
            }
        }
        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);
                        }
                    }
                }
            }
        }
Exemple #4
0
        public virtual void coverage()
        {
            SabrParametersSwaptionVolatilities test1 = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            coverImmutableBean(test1);
            SabrParametersSwaptionVolatilities test2 = SabrParametersSwaptionVolatilities.of(NAME2, SwaptionSabrRateVolatilityDataSet.SWAP_CONVENTION_EUR, DATE_TIME.plusDays(1), SwaptionSabrRateVolatilityDataSet.SABR_PARAM_USD);

            coverBeanEquals(test1, test2);
        }
Exemple #5
0
        public virtual void test_of()
        {
            SabrParametersSwaptionVolatilities test = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            assertEquals(test.Convention, CONV);
            assertEquals(test.DayCount, ACT_ACT_ISDA);
            assertEquals(test.Parameters, PARAM);
            assertEquals(test.ValuationDateTime, DATE_TIME);
        }
Exemple #6
0
        public virtual void test_calc()
        {
            SabrParametersSwaptionVolatilities test = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            assertEquals(test.alpha(1d, 2d), PARAM.alpha(1d, 2d));
            assertEquals(test.beta(1d, 2d), PARAM.beta(1d, 2d));
            assertEquals(test.rho(1d, 2d), PARAM.rho(1d, 2d));
            assertEquals(test.nu(1d, 2d), PARAM.nu(1d, 2d));
            assertEquals(test.shift(1d, 2d), PARAM.shift(1d, 2d));
        }
Exemple #7
0
        public virtual void test_findData()
        {
            SabrParametersSwaptionVolatilities test = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            assertEquals(test.findData(PARAM.AlphaSurface.Name), PARAM.AlphaSurface);
            assertEquals(test.findData(PARAM.BetaSurface.Name), PARAM.BetaSurface);
            assertEquals(test.findData(PARAM.RhoSurface.Name), PARAM.RhoSurface);
            assertEquals(test.findData(PARAM.NuSurface.Name), PARAM.NuSurface);
            assertEquals(test.findData(PARAM.ShiftSurface.Name), PARAM.ShiftSurface);
            assertEquals(test.findData(SurfaceName.of("Rubbish")), null);
        }
Exemple #8
0
        public virtual void test_relativeTime()
        {
            SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);
            double test1 = prov.relativeTime(DATE_TIME);

            assertEquals(test1, 0d);
            double test2 = prov.relativeTime(DATE_TIME.plusYears(2));
            double test3 = prov.relativeTime(DATE_TIME.minusYears(2));

            assertEquals(test2, -test3, 1e-2);
        }
Exemple #9
0
        public virtual void test_volatility()
        {
            SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            for (int i = 0; i < NB_TEST; i++)
            {
                for (int j = 0; j < NB_STRIKE; ++j)
                {
                    double expiryTime  = prov.relativeTime(TEST_OPTION_EXPIRY[i]);
                    double volExpected = PARAM.volatility(expiryTime, TEST_TENOR[i], TEST_STRIKE[j], TEST_FORWARD);
                    double volComputed = prov.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE[j], TEST_FORWARD);
                    assertEquals(volComputed, volExpected, TOLERANCE_VOL);
                }
            }
        }
Exemple #10
0
        public virtual void test_tenor()
        {
            SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);
            double test1 = prov.tenor(DATE, DATE);

            assertEquals(test1, 0d);
            double test2 = prov.tenor(DATE, DATE.plusYears(2));
            double test3 = prov.tenor(DATE, DATE.minusYears(2));

            assertEquals(test2, -test3);
            double test4 = prov.tenor(DATE, LocalDate.of(2019, 2, 2));
            double test5 = prov.tenor(DATE, LocalDate.of(2018, 12, 31));

            assertEquals(test4, 5d);
            assertEquals(test5, 5d);
        }
Exemple #11
0
        public virtual void test_parameterSensitivity()
        {
            double alphaSensi = 2.24, betaSensi = 3.45, rhoSensi = -2.12, nuSensi = -0.56;
            SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);

            for (int i = 0; i < NB_TEST; i++)
            {
                double                         expiryTime             = prov.relativeTime(TEST_OPTION_EXPIRY[i]);
                PointSensitivities             point                  = PointSensitivities.of(SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], ALPHA, USD, alphaSensi), SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], BETA, USD, betaSensi), SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], RHO, USD, rhoSensi), SwaptionSabrSensitivity.of(NAME, expiryTime, TEST_TENOR[i], NU, USD, nuSensi));
                CurrencyParameterSensitivities sensiComputed          = prov.parameterSensitivity(point);
                UnitParameterSensitivity       alphaSensitivities     = prov.Parameters.AlphaSurface.zValueParameterSensitivity(expiryTime, TEST_TENOR[i]);
                UnitParameterSensitivity       betaSensitivities      = prov.Parameters.BetaSurface.zValueParameterSensitivity(expiryTime, TEST_TENOR[i]);
                UnitParameterSensitivity       rhoSensitivities       = prov.Parameters.RhoSurface.zValueParameterSensitivity(expiryTime, TEST_TENOR[i]);
                UnitParameterSensitivity       nuSensitivities        = prov.Parameters.NuSurface.zValueParameterSensitivity(expiryTime, TEST_TENOR[i]);
                CurrencyParameterSensitivity   alphaSensiObj          = sensiComputed.getSensitivity(SwaptionSabrRateVolatilityDataSet.META_ALPHA.SurfaceName, USD);
                CurrencyParameterSensitivity   betaSensiObj           = sensiComputed.getSensitivity(SwaptionSabrRateVolatilityDataSet.META_BETA_USD.SurfaceName, USD);
                CurrencyParameterSensitivity   rhoSensiObj            = sensiComputed.getSensitivity(SwaptionSabrRateVolatilityDataSet.META_RHO.SurfaceName, USD);
                CurrencyParameterSensitivity   nuSensiObj             = sensiComputed.getSensitivity(SwaptionSabrRateVolatilityDataSet.META_NU.SurfaceName, USD);
                DoubleArray                    alphaNodeSensiComputed = alphaSensiObj.Sensitivity;
                DoubleArray                    betaNodeSensiComputed  = betaSensiObj.Sensitivity;
                DoubleArray                    rhoNodeSensiComputed   = rhoSensiObj.Sensitivity;
                DoubleArray                    nuNodeSensiComputed    = nuSensiObj.Sensitivity;
                assertEquals(alphaSensitivities.Sensitivity.size(), alphaNodeSensiComputed.size());
                assertEquals(betaSensitivities.Sensitivity.size(), betaNodeSensiComputed.size());
                assertEquals(rhoSensitivities.Sensitivity.size(), rhoNodeSensiComputed.size());
                assertEquals(nuSensitivities.Sensitivity.size(), nuNodeSensiComputed.size());
                for (int k = 0; k < alphaNodeSensiComputed.size(); ++k)
                {
                    assertEquals(alphaNodeSensiComputed.get(k), alphaSensitivities.Sensitivity.get(k) * alphaSensi, TOLERANCE_VOL);
                }
                for (int k = 0; k < betaNodeSensiComputed.size(); ++k)
                {
                    assertEquals(betaNodeSensiComputed.get(k), betaSensitivities.Sensitivity.get(k) * betaSensi, TOLERANCE_VOL);
                }
                for (int k = 0; k < rhoNodeSensiComputed.size(); ++k)
                {
                    assertEquals(rhoNodeSensiComputed.get(k), rhoSensitivities.Sensitivity.get(k) * rhoSensi, TOLERANCE_VOL);
                }
                for (int k = 0; k < nuNodeSensiComputed.size(); ++k)
                {
                    assertEquals(nuNodeSensiComputed.get(k), nuSensitivities.Sensitivity.get(k) * nuSensi, TOLERANCE_VOL);
                }
            }
        }
Exemple #12
0
        public virtual void test_pointShifts()
        {
            SabrParametersSwaptionVolatilities @base = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);
            PointShiftsBuilder builder = PointShifts.builder(ShiftType.ABSOLUTE);

            for (int i = 0; i < @base.ParameterCount; ++i)
            {
                builder.addShift(0, @base.getParameterMetadata(i).Identifier, 0.1d * (i + 1d));
                builder.addShift(1, @base.getParameterMetadata(i).Identifier, 10d * (i + 1d));
            }
            PointShifts shifts = builder.build();
            MarketDataBox <ParameterizedData>  resBox    = shifts.applyTo(MarketDataBox.ofSingleValue(@base), REF_DATA);
            SabrParametersSwaptionVolatilities computed0 = (SabrParametersSwaptionVolatilities)resBox.getValue(0);
            SabrParametersSwaptionVolatilities computed1 = (SabrParametersSwaptionVolatilities)resBox.getValue(1);

            for (int i = 0; i < @base.ParameterCount; ++i)
            {
                assertEquals(computed0.getParameter(i), @base.getParameter(i) + 0.1d * (i + 1d));
                assertEquals(computed1.getParameter(i), @base.getParameter(i) + 10d * (i + 1d));
            }
        }
Exemple #13
0
        public virtual void test_parameterSensitivity_multi()
        {
            double[] points1 = new double[] { 2.24, 3.45, -2.12, -0.56 };
            double[] points2 = new double[] { -0.145, 1.01, -5.0, -11.0 };
            double[] points3 = new double[] { 1.3, -4.32, 2.1, -7.18 };
            SabrParametersSwaptionVolatilities prov = SabrParametersSwaptionVolatilities.of(NAME, CONV, DATE_TIME, PARAM);
            double expiryTime0 = prov.relativeTime(TEST_OPTION_EXPIRY[0]);
            double expiryTime3 = prov.relativeTime(TEST_OPTION_EXPIRY[3]);

            for (int i = 0; i < NB_TEST; i++)
            {
                PointSensitivities             sensi1   = PointSensitivities.of(SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], ALPHA, USD, points1[0]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], BETA, USD, points1[1]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], RHO, USD, points1[2]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], NU, USD, points1[3]));
                PointSensitivities             sensi2   = PointSensitivities.of(SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], ALPHA, USD, points2[0]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], BETA, USD, points2[1]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], RHO, USD, points2[2]), SwaptionSabrSensitivity.of(NAME, expiryTime0, TEST_TENOR[i], NU, USD, points2[3]));
                PointSensitivities             sensi3   = PointSensitivities.of(SwaptionSabrSensitivity.of(NAME, expiryTime3, TEST_TENOR[i], ALPHA, USD, points3[0]), SwaptionSabrSensitivity.of(NAME, expiryTime3, TEST_TENOR[i], BETA, USD, points3[1]), SwaptionSabrSensitivity.of(NAME, expiryTime3, TEST_TENOR[i], RHO, USD, points3[2]), SwaptionSabrSensitivity.of(NAME, expiryTime3, TEST_TENOR[i], NU, USD, points3[3]));
                PointSensitivities             sensis   = sensi1.combinedWith(sensi2).combinedWith(sensi3).normalized();
                CurrencyParameterSensitivities computed = prov.parameterSensitivity(sensis);
                CurrencyParameterSensitivities expected = prov.parameterSensitivity(sensi1).combinedWith(prov.parameterSensitivity(sensi2)).combinedWith(prov.parameterSensitivity(sensi3));
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.AlphaSurface.Name, USD).Sensitivity.toArray(), expected.getSensitivity(PARAM.AlphaSurface.Name, USD).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.BetaSurface.Name, USD).Sensitivity.toArray(), expected.getSensitivity(PARAM.BetaSurface.Name, USD).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.RhoSurface.Name, USD).Sensitivity.toArray(), expected.getSensitivity(PARAM.RhoSurface.Name, USD).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.NuSurface.Name, USD).Sensitivity.toArray(), expected.getSensitivity(PARAM.NuSurface.Name, USD).Sensitivity.toArray(), TOLERANCE_VOL);
            }
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Runs the calibration of SABR on swaptions and print on the console the present value, bucketed PV01 and
        /// the bucketed Vega of a 18M x 4Y swaption.
        /// </summary>
        /// <param name="args">  -s to use the spares data </param>
        public static void Main(string[] args)
        {
            long start, end;

            // Swaption description
            BuySell          payer            = BuySell.BUY;
            Period           expiry           = Period.ofMonths(18);
            double           notional         = 1_000_000;
            double           strike           = 0.0100;
            Tenor            tenor            = Tenor.TENOR_4Y;
            LocalDate        expiryDate       = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(expiry), REF_DATA);
            SwapTrade        underlying       = EUR_FIXED_1Y_EURIBOR_6M.createTrade(expiryDate, tenor, payer, notional, strike, REF_DATA);
            Swaption         swaption         = Swaption.builder().expiryDate(AdjustableDate.of(expiryDate)).expiryTime(LocalTime.of(11, 0x0)).expiryZone(ZoneId.of("Europe/Berlin")).underlying(underlying.Product).longShort(LongShort.LONG).swaptionSettlement(PhysicalSwaptionSettlement.DEFAULT).build();
            ResolvedSwaption resolvedSwaption = swaption.resolve(REF_DATA);

            // select data
            TenorRawOptionData data = DATA_FULL;

            if (args.Length > 0)
            {
                if (args[0].Equals("-s"))
                {
                    data = DATA_SPARSE;
                }
            }

            start = DateTimeHelper.CurrentUnixTimeMillis();
            // Curve calibration
            RatesProvider multicurve = CALIBRATOR.calibrate(CONFIGS, MARKET_QUOTES, REF_DATA);

            end = DateTimeHelper.CurrentUnixTimeMillis();
            Console.WriteLine("Curve calibration time: " + (end - start) + " ms.");

            // SABR calibration
            start = DateTimeHelper.CurrentUnixTimeMillis();
            double          beta                    = 0.50;
            SurfaceMetadata betaMetadata            = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build();
            Surface         betaSurface             = ConstantSurface.of(betaMetadata, beta);
            double          shift                   = 0.0300;
            Surface         shiftSurface            = ConstantSurface.of("SABR-Shift", shift);
            SabrParametersSwaptionVolatilities sabr = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, data, multicurve, betaSurface, shiftSurface);

            end = DateTimeHelper.CurrentUnixTimeMillis();
            Console.WriteLine("SABR calibration time: " + (end - start) + " ms.");

            // Price and risk
            Console.WriteLine("Risk measures: ");
            start = DateTimeHelper.CurrentUnixTimeMillis();
            CurrencyAmount pv = SWAPTION_PRICER.presentValue(resolvedSwaption, multicurve, sabr);

            Console.WriteLine("  |-> PV: " + pv.ToString());

            PointSensitivities             deltaPts      = SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(resolvedSwaption, multicurve, sabr).build();
            CurrencyParameterSensitivities deltaBucketed = multicurve.parameterSensitivity(deltaPts);

            Console.WriteLine("  |-> Delta bucketed: " + deltaBucketed.ToString());

            PointSensitivities vegaPts = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(resolvedSwaption, multicurve, sabr).build();

            Console.WriteLine("  |-> Vega point: " + vegaPts.ToString());

            CurrencyParameterSensitivities vegaBucketed = sabr.parameterSensitivity(vegaPts);

            for (int i = 0; i < vegaBucketed.size(); i++)
            {
                Console.WriteLine("  |-> Vega bucketed: " + vegaBucketed.Sensitivities.get(i));
            }

            end = DateTimeHelper.CurrentUnixTimeMillis();
            Console.WriteLine("PV and risk time: " + (end - start) + " ms.");
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Runs the calibration of swaptions and print the calibrated smile results on the console.
        /// </summary>
        /// <param name="args">  -s to use the sparse data, i.e. a cube with missing data points </param>
        public static void Main(string[] args)
        {
            // select data
            TenorRawOptionData data = DATA_FULL;

            if (args.Length > 0)
            {
                if (args[0].Equals("-s"))
                {
                    data = DATA_SPARSE;
                }
            }
            Console.WriteLine("Start calibration");
            double          beta         = 0.50;
            SurfaceMetadata betaMetadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build();
            Surface         betaSurface  = ConstantSurface.of(betaMetadata, beta);
            double          shift        = 0.0300;
            Surface         shiftSurface = ConstantSurface.of("Shift", shift);
            SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, data, MULTICURVE, betaSurface, shiftSurface);

            Console.WriteLine("End calibration");
            /* Graph calibration */
            int    nbStrikesGraph = 50;
            double moneyMin       = -0.0250;
            double moneyMax       = +0.0300;

            double[] moneyGraph = new double[nbStrikesGraph + 1];
            for (int i = 0; i < nbStrikesGraph + 1; i++)
            {
                moneyGraph[i] = moneyMin + i * (moneyMax - moneyMin) / nbStrikesGraph;
            }
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] strikesGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] strikesGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] volLNGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] volLNGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] volNGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] volNGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] parRate = new double[NB_TENORS][NB_EXPIRIES];
            double[][] parRate = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES);
            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);
                    parRate[looptenor][loopexpiry] = 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 i = 0; i < nbStrikesGraph + 1; i++)
                    {
                        strikesGraph[looptenor][loopexpiry][i] = parRate[looptenor][loopexpiry] + moneyGraph[i];
                        volLNGraph[looptenor][loopexpiry][i]   = calibrated.volatility(expiryDateTime, tenor, strikesGraph[looptenor][loopexpiry][i], parRate[looptenor][loopexpiry]);
                        volNGraph[looptenor][loopexpiry][i]    = NormalFormulaRepository.impliedVolatilityFromBlackApproximated(parRate[looptenor][loopexpiry] + shift, strikesGraph[looptenor][loopexpiry][i] + shift, time, volLNGraph[looptenor][loopexpiry][i]);
                    }
                }
            }

            /* Graph export */
            string svn = "Moneyness";

            for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
            {
                for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
                {
                    svn = svn + ", Strike_" + EXPIRIES.get(loopexpiry).ToString() + "x" + TENORS.get(looptenor).ToString() + ", NormalVol_" + EXPIRIES.get(loopexpiry).ToString() + "x" + TENORS.get(looptenor).ToString();
                }
            }
            svn = svn + "\n";
            for (int i = 0; i < nbStrikesGraph + 1; i++)
            {
                svn = svn + moneyGraph[i];
                for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
                {
                    for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
                    {
                        svn = svn + ", " + strikesGraph[looptenor][loopexpiry][i];
                        svn = svn + ", " + volNGraph[looptenor][loopexpiry][i];
                    }
                }
                svn = svn + "\n";
            }
            Console.WriteLine(svn);
        }
        /// <summary>
        /// Obtains {@code SABRVolatilitySwaptionProvider} for specified valuation date.
        /// </summary>
        /// <param name="valuationDate">  the valuation date </param>
        /// <param name="shift">  nonzero shift if true, zero shift otherwise </param>
        /// <returns> the volatility provider </returns>
        public static SabrParametersSwaptionVolatilities getVolatilitiesEur(LocalDate valuationDate, bool shift)
        {
            ZonedDateTime dateTime = valuationDate.atStartOfDay(ZoneOffset.UTC);

            return(shift ? SabrParametersSwaptionVolatilities.of(NAME, SWAP_CONVENTION_EUR, dateTime, SABR_PARAM_SHIFT_EUR) : SabrParametersSwaptionVolatilities.of(NAME, SWAP_CONVENTION_EUR, dateTime, SABR_PARAM_EUR));
        }
Exemple #17
0
        /// <summary>
        /// Check that the sensitivities of parameters with respect to data is stored in the metadata.
        /// Compare the sensitivities to a finite difference approximation.
        /// This test is relatively slow as it calibrates the full surface multiple times.
        /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void log_normal_cube_sensitivity()
        public virtual void log_normal_cube_sensitivity()
        {
            double  beta         = 1.0;
            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.0000;
            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);
            double fdShift = 1.0E-5;

            SurfaceMetadata alphaMetadata = calibrated.Parameters.AlphaSurface.Metadata;
            Optional <IList <ParameterMetadata> > alphaParameterMetadataOption = alphaMetadata.ParameterMetadata;

            assertTrue(alphaParameterMetadataOption.Present);
            IList <ParameterMetadata>             alphaParameterMetadata     = alphaParameterMetadataOption.get();
            IList <DoubleArray>                   alphaJacobian              = calibrated.DataSensitivityAlpha.get();
            SurfaceMetadata                       rhoMetadata                = calibrated.Parameters.RhoSurface.Metadata;
            Optional <IList <ParameterMetadata> > rhoParameterMetadataOption = rhoMetadata.ParameterMetadata;

            assertTrue(rhoParameterMetadataOption.Present);
            IList <ParameterMetadata>             rhoParameterMetadata      = rhoParameterMetadataOption.get();
            IList <DoubleArray>                   rhoJacobian               = calibrated.DataSensitivityRho.get();
            SurfaceMetadata                       nuMetadata                = calibrated.Parameters.NuSurface.Metadata;
            Optional <IList <ParameterMetadata> > nuParameterMetadataOption = nuMetadata.ParameterMetadata;

            assertTrue(nuParameterMetadataOption.Present);
            IList <ParameterMetadata> nuParameterMetadata = nuParameterMetadataOption.get();
            IList <DoubleArray>       nuJacobian          = calibrated.DataSensitivityNu.get();

            int surfacePointIndex = 0;

            for (int loopexpiry = 0; loopexpiry < EXPIRIES.Count; loopexpiry++)
            {
                for (int looptenor = 0; looptenor < TENORS.Count; looptenor++)
                {
                    Tenor         tenor                = TENORS[looptenor];
                    double        tenorYears           = tenor.get(ChronoUnit.YEARS);
                    LocalDate     expiry               = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(EXPIRIES[loopexpiry]), REF_DATA);
                    ZonedDateTime expiryDateTime       = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin"));
                    double        time                 = calibrated.relativeTime(expiryDateTime);
                    Pair <DoubleArray, DoubleArray> ds = DATA_SPARSE.getData(tenor).availableSmileAtExpiry(EXPIRIES[loopexpiry]);
                    if (!ds.First.Empty)
                    {
                        int availableDataIndex = 0;

                        ParameterMetadata alphaPM = alphaParameterMetadata[surfacePointIndex];
                        assertTrue(alphaPM is SwaptionSurfaceExpiryTenorParameterMetadata);
                        SwaptionSurfaceExpiryTenorParameterMetadata pmAlphaSabr = (SwaptionSurfaceExpiryTenorParameterMetadata)alphaPM;
                        assertEquals(tenorYears, pmAlphaSabr.Tenor);
                        assertEquals(time, pmAlphaSabr.YearFraction, TOLERANCE_EXPIRY);
                        DoubleArray       alphaSensitivityToData = alphaJacobian[surfacePointIndex];
                        ParameterMetadata rhoPM = rhoParameterMetadata[surfacePointIndex];
                        assertTrue(rhoPM is SwaptionSurfaceExpiryTenorParameterMetadata);
                        SwaptionSurfaceExpiryTenorParameterMetadata pmRhoSabr = (SwaptionSurfaceExpiryTenorParameterMetadata)rhoPM;
                        assertEquals(tenorYears, pmRhoSabr.Tenor);
                        assertEquals(time, pmRhoSabr.YearFraction, TOLERANCE_EXPIRY);
                        DoubleArray       rhoSensitivityToData = rhoJacobian[surfacePointIndex];
                        ParameterMetadata nuPM = nuParameterMetadata[surfacePointIndex];
                        assertTrue(nuPM is SwaptionSurfaceExpiryTenorParameterMetadata);
                        SwaptionSurfaceExpiryTenorParameterMetadata pmNuSabr = (SwaptionSurfaceExpiryTenorParameterMetadata)nuPM;
                        assertEquals(tenorYears, pmNuSabr.Tenor);
                        assertEquals(time, pmNuSabr.YearFraction, TOLERANCE_EXPIRY);
                        DoubleArray nuSensitivityToData = nuJacobian[surfacePointIndex];

                        for (int loopmoney = 0; loopmoney < MONEYNESS.size(); loopmoney++)
                        {
                            if (!double.IsNaN(DATA_LOGNORMAL[looptenor][loopexpiry][loopmoney]))
                            {
                                double[] alphaShifted = new double[2];
                                double[] rhoShifted   = new double[2];
                                double[] nuShifted    = new double[2];
                                for (int loopsign = 0; loopsign < 2; loopsign++)
                                {
                                    TenorRawOptionData dataShifted = SabrSwaptionCalibratorSmileTestUtils.rawDataShiftPoint(TENORS, EXPIRIES, ValueType.SIMPLE_MONEYNESS, MONEYNESS, ValueType.BLACK_VOLATILITY, DATA_LOGNORMAL, looptenor, loopexpiry, loopmoney, (2 * loopsign - 1) * fdShift);
                                    SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, betaSurface, shiftSurface);
                                    alphaShifted[loopsign] = calibratedShifted.Parameters.AlphaSurface.zValue(time, tenorYears);
                                    rhoShifted[loopsign]   = calibratedShifted.Parameters.RhoSurface.zValue(time, tenorYears);
                                    nuShifted[loopsign]    = calibratedShifted.Parameters.NuSurface.zValue(time, tenorYears);
                                }
                                double alphaSensitivityComputed = alphaSensitivityToData.get(availableDataIndex);
                                double alphaSensitivityExpected = (alphaShifted[1] - alphaShifted[0]) / (2 * fdShift);
                                checkAcceptable(alphaSensitivityComputed, alphaSensitivityExpected, TOLERANCE_PARAM_SENSITIVITY, "Alpha: " + looptenor + " / " + loopexpiry + " / " + loopmoney);
                                double rhoSensitivityComputed = rhoSensitivityToData.get(availableDataIndex);
                                double rhoSensitivityExpected = (rhoShifted[1] - rhoShifted[0]) / (2 * fdShift);
                                checkAcceptable(rhoSensitivityComputed, rhoSensitivityExpected, TOLERANCE_PARAM_SENSITIVITY, "Rho: " + looptenor + " / " + loopexpiry + " / " + loopmoney);
                                double nuSensitivityComputed = nuSensitivityToData.get(availableDataIndex);
                                double nuSensitivityExpected = (nuShifted[1] - nuShifted[0]) / (2 * fdShift);
                                checkAcceptable(nuSensitivityComputed, nuSensitivityExpected, TOLERANCE_PARAM_SENSITIVITY, "Nu: " + looptenor + " / " + loopexpiry + " / " + loopmoney);
                                availableDataIndex++;
                            }
                        }
                        surfacePointIndex++;
                    }
                }
            }
        }
Exemple #18
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the raw data sensitivities from SABR parameter sensitivity.
        /// <para>
        /// The SABR parameter sensitivities to data are stored in some optional data in the
        /// <seealso cref="SabrParametersSwaptionVolatilities"/>.
        /// The sensitivities to the SABR parameters passed in should be compatible with the SABR parameters in term of data order.
        /// </para>
        /// <para>
        /// Only the sensitivity to the SABR parameters for which there is a data sensitivity are taken into account.
        /// At least one of the four parameter must have such sensitivities.
        ///
        /// </para>
        /// </summary>
        /// <param name="paramSensitivities">  the curve SABR parameter sensitivities </param>
        /// <param name="volatilities">  the SABR parameters, including the data sensitivity metadata </param>
        /// <returns> the raw data sensitivities </returns>
        public virtual CurrencyParameterSensitivity parallelSensitivity(CurrencyParameterSensitivities paramSensitivities, SabrParametersSwaptionVolatilities volatilities)
        {
            IList <IList <DoubleArray> >            sensitivityToRawData = new List <IList <DoubleArray> >(4);
            Optional <ImmutableList <DoubleArray> > alphaInfo            = volatilities.DataSensitivityAlpha;

            sensitivityToRawData.Add(alphaInfo.orElse(null));
            Optional <ImmutableList <DoubleArray> > betaInfo = volatilities.DataSensitivityBeta;

            sensitivityToRawData.Add(betaInfo.orElse(null));
            Optional <ImmutableList <DoubleArray> > rhoInfo = volatilities.DataSensitivityRho;

            sensitivityToRawData.Add(rhoInfo.orElse(null));
            Optional <ImmutableList <DoubleArray> > nuInfo = volatilities.DataSensitivityNu;

            sensitivityToRawData.Add(nuInfo.orElse(null));
            ArgChecker.isTrue(alphaInfo.Present || betaInfo.Present || rhoInfo.Present || nuInfo.Present, "at least one sensitivity to raw data must be available");
            checkCurrency(paramSensitivities);
            int nbSurfaceNode = sensitivityToRawData[0].Count;

            double[] sensitivityRawArray = new double[nbSurfaceNode];
            Currency ccy = null;
            IList <ParameterMetadata> metadataResult = null;

            foreach (CurrencyParameterSensitivity s in paramSensitivities.Sensitivities)
            {
                ccy = s.Currency;
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: com.opengamma.strata.data.MarketDataName<?> name = s.getMarketDataName();
                MarketDataName <object> name = s.MarketDataName;
                if (name is SurfaceName)
                {
                    if (volatilities.Parameters.AlphaSurface.Name.Equals(name) && alphaInfo.Present)
                    {
                        updateSensitivity(s, sensitivityToRawData[0], sensitivityRawArray);
                        metadataResult = s.ParameterMetadata;
                    }
                    if (volatilities.Parameters.BetaSurface.Name.Equals(name) && betaInfo.Present)
                    {
                        updateSensitivity(s, sensitivityToRawData[1], sensitivityRawArray);
                        metadataResult = s.ParameterMetadata;
                    }
                    if (volatilities.Parameters.RhoSurface.Name.Equals(name) && rhoInfo.Present)
                    {
                        updateSensitivity(s, sensitivityToRawData[2], sensitivityRawArray);
                        metadataResult = s.ParameterMetadata;
                    }
                    if (volatilities.Parameters.NuSurface.Name.Equals(name) && nuInfo.Present)
                    {
                        updateSensitivity(s, sensitivityToRawData[3], sensitivityRawArray);
                        metadataResult = s.ParameterMetadata;
                    }
                }
            }
            DoubleArray sensitivityRaw = DoubleArray.ofUnsafe(sensitivityRawArray);

            return(CurrencyParameterSensitivity.of(SurfaceName.of("RawDataParallelSensitivity"), metadataResult, ccy, sensitivityRaw));
        }