示例#1
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++;
                    }
                }
            }
        }
示例#2
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);
            }
        }
示例#3
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);
                }
            }
        }
        //-------------------------------------------------------------------------
        /// <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.");
        }
        public virtual void regressionPvSurfaceSensi()
        {
            PointSensitivities pointComputed = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_LONG, RATE_PROVIDER, VOLS_REGRESSION).build();

            assertSensitivity(pointComputed, SabrParameterType.ALPHA, 6.5786313367554754E7, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.BETA, -1.2044275797229866E7, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.RHO, 266223.51118849067, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.NU, 400285.5505271345, REGRESSION_TOL);
            CurrencyParameterSensitivities sensiComputed = VOLS_REGRESSION.parameterSensitivity(pointComputed);

            double[][] alphaExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 6204.475194599179 },
                new double[] { 2.0, 5.0, 3.94631212984123E7 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 4136.961894403858 },
                new double[] { 2.0, 10.0, 2.631285063205345E7 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][] betaExp = new double[][]
            {
                new double[] { 0.0, 1.0, -0.0 },
                new double[] { 0.5, 1.0, -0.0 },
                new double[] { 1.0, 1.0, -0.0 },
                new double[] { 2.0, 1.0, -0.0 },
                new double[] { 5.0, 1.0, -0.0 },
                new double[] { 10.0, 1.0, -0.0 },
                new double[] { 0.0, 5.0, -0.0 },
                new double[] { 0.5, 5.0, -0.0 },
                new double[] { 1.0, 5.0, -1135.926404680998 },
                new double[] { 2.0, 5.0, -7224978.759366533 },
                new double[] { 5.0, 5.0, -0.0 },
                new double[] { 10.0, 5.0, -0.0 },
                new double[] { 0.0, 10.0, -0.0 },
                new double[] { 0.5, 10.0, -0.0 },
                new double[] { 1.0, 10.0, -757.402375482629 },
                new double[] { 2.0, 10.0, -4817403.70908317 },
                new double[] { 5.0, 10.0, -0.0 },
                new double[] { 10.0, 10.0, -0.0 }
            };
            double[][] rhoExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 25.10821912392996 },
                new double[] { 2.0, 5.0, 159699.03429338703 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 16.741423326578513 },
                new double[] { 2.0, 10.0, 106482.62725265314 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][] nuExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 37.751952372314484 },
                new double[] { 2.0, 5.0, 240118.59649585965 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 25.171893432592533 },
                new double[] { 2.0, 10.0, 160104.03018547 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][][]      exps     = new double[][][] { alphaExp, betaExp, rhoExp, nuExp };
            SurfaceMetadata[] metadata = new SurfaceMetadata[] { SwaptionSabrRateVolatilityDataSet.META_ALPHA, SwaptionSabrRateVolatilityDataSet.META_BETA_USD, SwaptionSabrRateVolatilityDataSet.META_RHO, SwaptionSabrRateVolatilityDataSet.META_NU };
            // x-y-value order does not match sorted order in surface, thus sort it
            CurrencyParameterSensitivities sensiExpected = CurrencyParameterSensitivities.empty();

            for (int i = 0; i < exps.Length; ++i)
            {
                int size = exps[i].Length;
                IDictionary <DoublesPair, double> sensiMap = new SortedDictionary <DoublesPair, double>();
                for (int j = 0; j < size; ++j)
                {
                    sensiMap[DoublesPair.of(exps[i][j][0], exps[i][j][1])] = exps[i][j][2];
                }
                IList <ParameterMetadata> paramMetadata = new List <ParameterMetadata>(size);
                IList <double>            sensi         = new List <double>();
                foreach (KeyValuePair <DoublesPair, double> entry in sensiMap.SetOfKeyValuePairs())
                {
                    paramMetadata.Add(SwaptionSurfaceExpiryTenorParameterMetadata.of(entry.Key.First, entry.Key.Second));
                    sensi.Add(entry.Value);
                }
                SurfaceMetadata surfaceMetadata = metadata[i].withParameterMetadata(paramMetadata);
                sensiExpected = sensiExpected.combinedWith(CurrencyParameterSensitivity.of(surfaceMetadata.SurfaceName, surfaceMetadata.ParameterMetadata.get(), USD, DoubleArray.copyOf(sensi)));
            }
            testSurfaceParameterSensitivities(sensiComputed, sensiExpected, REGRESSION_TOL * NOTIONAL);
        }
        public virtual void test_presentValueVega_SwaptionSensitivity()
        {
            SwaptionSensitivity vegaRec = SWAPTION_PRICER.presentValueSensitivityModelParamsVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS);

            assertEquals(VOLS.parameterSensitivity(vegaRec), CurrencyParameterSensitivities.empty());
        }