예제 #1
0
        // node sensitivity function
        private System.Func <DoubleArray, DoubleMatrix> createJacobianFunction(SabrIborCapletFloorletVolatilityCalibrationDefinition sabrDefinition, RatesProvider ratesProvider, SabrParametersIborCapletFloorletVolatilities volatilities, IList <ResolvedIborCapFloorLeg> capList, IList <double> priceList, Currency currency)
        {
            int            nCaps      = capList.Count;
            SabrParameters sabrParams = volatilities.Parameters;
            CurveName      alphaName  = sabrParams.AlphaCurve.Name;
            CurveName      betaName   = sabrParams.BetaCurve.Name;
            CurveName      rhoName    = sabrParams.RhoCurve.Name;
            CurveName      nuName     = sabrParams.NuCurve.Name;

            System.Func <DoubleArray, DoubleMatrix> jacobianFunction = (DoubleArray x) =>
            {
                SabrParametersIborCapletFloorletVolatilities volsNew = updateParameters(sabrDefinition, volatilities, x);
                double[][] jacobian = new double[nCaps][];
                for (int i = 0; i < nCaps; ++i)
                {
                    PointSensitivities             point = sabrPricer.presentValueSensitivityModelParamsSabr(capList[i], ratesProvider, volsNew).build();
                    CurrencyParameterSensitivities sensi = volsNew.parameterSensitivity(point);
                    double      targetPriceInv           = 1d / priceList[i];
                    DoubleArray sensitivities            = sensi.getSensitivity(alphaName, currency).Sensitivity;
                    if (sabrDefinition.BetaCurve.Present)
                    { // beta fixed
                        sensitivities = sensitivities.concat(sensi.getSensitivity(rhoName, currency).Sensitivity);
                    }
                    else
                    { // rho fixed
                        sensitivities = sensitivities.concat(sensi.getSensitivity(betaName, currency).Sensitivity);
                    }
                    jacobian[i] = sensitivities.concat(sensi.getSensitivity(nuName, currency).Sensitivity).multipliedBy(targetPriceInv).toArray();
                }
                return(DoubleMatrix.ofUnsafe(jacobian));
            };
            return(jacobianFunction);
        }
        public virtual void test_parameterSensitivity()
        {
            double alphaSensi = 2.24, betaSensi = 3.45, rhoSensi = -2.12, nuSensi = -0.56, shiftSensi = 2.5;
            SabrParametersIborCapletFloorletVolatilities prov = SabrParametersIborCapletFloorletVolatilities.of(NAME, EUR_EURIBOR_3M, DATE_TIME, PARAM);

            for (int i = 0; i < NB_TEST; i++)
            {
                double                         expiryTime             = prov.relativeTime(TEST_OPTION_EXPIRY[i]);
                PointSensitivities             point                  = PointSensitivities.of(IborCapletFloorletSabrSensitivity.of(NAME, expiryTime, ALPHA, EUR, alphaSensi), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime, BETA, EUR, betaSensi), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime, RHO, EUR, rhoSensi), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime, NU, EUR, nuSensi), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime, SHIFT, EUR, shiftSensi));
                CurrencyParameterSensitivities sensiComputed          = prov.parameterSensitivity(point);
                UnitParameterSensitivity       alphaSensitivities     = prov.Parameters.AlphaCurve.yValueParameterSensitivity(expiryTime);
                UnitParameterSensitivity       betaSensitivities      = prov.Parameters.BetaCurve.yValueParameterSensitivity(expiryTime);
                UnitParameterSensitivity       rhoSensitivities       = prov.Parameters.RhoCurve.yValueParameterSensitivity(expiryTime);
                UnitParameterSensitivity       nuSensitivities        = prov.Parameters.NuCurve.yValueParameterSensitivity(expiryTime);
                UnitParameterSensitivity       shiftSensitivities     = prov.Parameters.ShiftCurve.yValueParameterSensitivity(expiryTime);
                CurrencyParameterSensitivity   alphaSensiObj          = sensiComputed.getSensitivity(IborCapletFloorletSabrRateVolatilityDataSet.META_ALPHA.CurveName, EUR);
                CurrencyParameterSensitivity   betaSensiObj           = sensiComputed.getSensitivity(IborCapletFloorletSabrRateVolatilityDataSet.META_BETA.CurveName, EUR);
                CurrencyParameterSensitivity   rhoSensiObj            = sensiComputed.getSensitivity(IborCapletFloorletSabrRateVolatilityDataSet.META_RHO.CurveName, EUR);
                CurrencyParameterSensitivity   nuSensiObj             = sensiComputed.getSensitivity(IborCapletFloorletSabrRateVolatilityDataSet.META_NU.CurveName, EUR);
                CurrencyParameterSensitivity   shiftSensiObj          = sensiComputed.getSensitivity(IborCapletFloorletSabrRateVolatilityDataSet.META_SHIFT.CurveName, EUR);
                DoubleArray                    alphaNodeSensiComputed = alphaSensiObj.Sensitivity;
                DoubleArray                    betaNodeSensiComputed  = betaSensiObj.Sensitivity;
                DoubleArray                    rhoNodeSensiComputed   = rhoSensiObj.Sensitivity;
                DoubleArray                    nuNodeSensiComputed    = nuSensiObj.Sensitivity;
                DoubleArray                    shiftNodeSensiComputed = shiftSensiObj.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());
                assertEquals(shiftSensitivities.Sensitivity.size(), shiftNodeSensiComputed.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);
                }
                for (int k = 0; k < shiftNodeSensiComputed.size(); ++k)
                {
                    assertEquals(shiftNodeSensiComputed.get(k), shiftSensitivities.Sensitivity.get(k) * shiftSensi, TOLERANCE_VOL);
                }
            }
        }
        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 };
            SabrParametersIborCapletFloorletVolatilities prov = SabrParametersIborCapletFloorletVolatilities.of(NAME, EUR_EURIBOR_3M, 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(IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, ALPHA, EUR, points1[0]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, BETA, EUR, points1[1]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, RHO, EUR, points1[2]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, NU, EUR, points1[3]));
                PointSensitivities             sensi2   = PointSensitivities.of(IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, ALPHA, EUR, points2[0]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, BETA, EUR, points2[1]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, RHO, EUR, points2[2]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime0, NU, EUR, points2[3]));
                PointSensitivities             sensi3   = PointSensitivities.of(IborCapletFloorletSabrSensitivity.of(NAME, expiryTime3, ALPHA, EUR, points3[0]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime3, BETA, EUR, points3[1]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime3, RHO, EUR, points3[2]), IborCapletFloorletSabrSensitivity.of(NAME, expiryTime3, NU, EUR, 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.AlphaCurve.Name, EUR).Sensitivity.toArray(), expected.getSensitivity(PARAM.AlphaCurve.Name, EUR).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.BetaCurve.Name, EUR).Sensitivity.toArray(), expected.getSensitivity(PARAM.BetaCurve.Name, EUR).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.RhoCurve.Name, EUR).Sensitivity.toArray(), expected.getSensitivity(PARAM.RhoCurve.Name, EUR).Sensitivity.toArray(), TOLERANCE_VOL);
                DoubleArrayMath.fuzzyEquals(computed.getSensitivity(PARAM.NuCurve.Name, EUR).Sensitivity.toArray(), expected.getSensitivity(PARAM.NuCurve.Name, EUR).Sensitivity.toArray(), TOLERANCE_VOL);
            }
        }
예제 #4
0
        // node sensitivity function
        private System.Func <DoubleArray, DoubleMatrix> createJacobianFunction(RatesProvider ratesProvider, SabrParametersIborCapletFloorletVolatilities volatilities, ZonedDateTime prevExpiry, IList <ResolvedIborCapFloorLeg> capList, IList <double> priceList, Currency currency, int[] startIndex, int nExpiries, int timeIndex, int nCaplets, bool betaFixed)
        {
            Curve alphaCurve   = volatilities.Parameters.AlphaCurve;
            Curve betaCurve    = volatilities.Parameters.BetaCurve;
            Curve rhoCurve     = volatilities.Parameters.RhoCurve;
            Curve nuCurve      = volatilities.Parameters.NuCurve;
            int   currentStart = startIndex[timeIndex];

            System.Func <DoubleArray, DoubleMatrix> jacobianFunction = (DoubleArray x) =>
            {
                SabrParametersIborCapletFloorletVolatilities volsNew = updateParameters(volatilities, nExpiries, timeIndex, betaFixed, x);
//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[][] jacobian = new double[nCaplets][4];
                double[][] jacobian = RectangularArrays.ReturnRectangularDoubleArray(nCaplets, 4);
                for (int i = 0; i < nCaplets; ++i)
                {
                    PointSensitivities             point       = capList[currentStart + i].CapletFloorletPeriods.Where(p => p.FixingDateTime.isAfter(prevExpiry)).Select(p => sabrPeriodPricer.presentValueSensitivityModelParamsSabr(p, ratesProvider, volsNew)).Aggregate((c1, c2) => c1.combinedWith(c2)).get().build();
                    double                         targetPrice = priceList[currentStart + i];
                    CurrencyParameterSensitivities sensi       = volsNew.parameterSensitivity(point);
                    jacobian[i][0] = sensi.getSensitivity(alphaCurve.Name, currency).Sensitivity.get(timeIndex) / targetPrice;
                    if (betaFixed)
                    {
                        jacobian[i][1] = 0d;
                        jacobian[i][2] = sensi.getSensitivity(rhoCurve.Name, currency).Sensitivity.get(timeIndex) / targetPrice;
                    }
                    else
                    {
                        jacobian[i][1] = sensi.getSensitivity(betaCurve.Name, currency).Sensitivity.get(timeIndex) / targetPrice;
                        jacobian[i][2] = 0d;
                    }
                    jacobian[i][3] = sensi.getSensitivity(nuCurve.Name, currency).Sensitivity.get(timeIndex) / targetPrice;
                }
                return(DoubleMatrix.ofUnsafe(jacobian));
            };
            return(jacobianFunction);
        }