Exemplo n.º 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);
        }
Exemplo n.º 2
0
        public virtual void parSpreadSensitivity()
        {
            // March
            PointSensitivities             pointMar = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_MAR, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiMar = LED_PROVIDER.parameterSensitivity(pointMar);

            double[] sensiIssuerMar = new double[] { -4.795692708445902E-6, -2.0781215861310126E-5, -7.730767169573405E-5, -1.6071777740512183E-4, -2.3044416935116369E-4, -3.333307694739688E-4, -4.263036155523118E-4, -5.685365085703306E-4, -0.10407934097674876, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoMar   = new double[] { 0.0, 0.0, 0.0, 0.0, 0.001370140084809201, 3.3554451056551886E-4, 0.0, 0.0 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerMar, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoMar, TOL));
            // June
            PointSensitivities             pointJun = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_JUN, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiJun = LED_PROVIDER.parameterSensitivity(pointJun);

            double[] sensiIssuerJun = new double[] { -1.1453989553600325E-5, -2.348926498286566E-5, -1.0106640809190963E-4, -1.9509367993719023E-4, -3.132622179286758E-4, -4.395002117284386E-4, -5.572262990208806E-4, -7.858225833901946E-4, -0.07087170775675304, -0.03539736978075175, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoJun   = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.003012223890022257, 0.0024215917547237764, 0.0 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerJun, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoJun, TOL));
            // September
            PointSensitivities             pointSep = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_SEP, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiSep = LED_PROVIDER.parameterSensitivity(pointSep);

            double[] sensiIssuerSep = new double[] { -6.287268294968501E-6, -2.7244672992830814E-5, -1.0135221390528455E-4, -2.1070486533414349E-4, -3.021178394458564E-4, -4.370046427203812E-4, -5.588942763935072E-4, -7.453650144370277E-4, -0.03687605192905092, -0.07313888023068209, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoSep   = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.007209056180693214, 0.0020653493968426154 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerSep, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoSep, TOL));
        }
Exemplo n.º 3
0
        public virtual void presentValueSensitivity()
        {
            // March
            PointSensitivities             pointMar = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_MAR, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiMar = LED_PROVIDER.parameterSensitivity(pointMar);

            double[] sensiIssuerMar = new double[] { -4.795692708445902, -20.78121586131013, -77.30767169573404, -160.71777740512184, -230.44416935116368, -333.3307694739688, -426.3036155523117, -568.5365085703306, -104079.34097674876, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoMar   = new double[] { 0.0, 0.0, 0.0, 0.0, 1370.1400848092012, 335.54451056551886, 0.0, 0.0 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerMar, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoMar, TOL));
            // June
            PointSensitivities             pointJun = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_JUN, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiJun = LED_PROVIDER.parameterSensitivity(pointJun);

            double[] sensiIssuerJun = new double[] { -11.453989553600326, -23.489264982865656, -101.06640809190962, -195.09367993719025, -313.2622179286758, -439.5002117284386, -557.2262990208807, -785.8225833901945, -70871.70775675304, -35397.369780751746, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoJun   = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 3012.223890022257, 2421.5917547237764, 0.0 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerJun, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoJun, TOL));
            // September
            PointSensitivities             pointSep = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_SEP, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT);
            CurrencyParameterSensitivities sensiSep = LED_PROVIDER.parameterSensitivity(pointSep);

            double[] sensiIssuerSep = new double[] { -6.287268294968501, -27.244672992830814, -101.35221390528456, -210.7048653341435, -302.1178394458564, -437.0046427203812, -558.8942763935072, -745.3650144370276, -36876.05192905092, -73138.88023068209, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 };
            double[] sensiRepoSep   = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7209.056180693215, 2065.3493968426155 };
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerSep, TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoSep, TOL));
        }
Exemplo n.º 4
0
        public virtual void regression_curveSensitivity()
        {
            PointSensitivities             point    = PRICER.presentValueSensitivityRates(SWAPTION_PAY_LONG, RATE_PROVIDER, HW_PROVIDER).build();
            CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point);

            double[] dscExp = new double[] { 0.0, 0.0, 0.0, 0.0, -1.4127023229222856E7, -1.744958350376594E7 };
            double[] fwdExp = new double[] { 0.0, 0.0, 0.0, 0.0, -2.0295973516660026E8, 4.12336887967829E8 };
            assertTrue(DoubleArrayMath.fuzzyEquals(computed.getSensitivity(HullWhiteIborFutureDataSet.DSC_NAME, EUR).Sensitivity.toArray(), dscExp, NOTIONAL * TOL));
            assertTrue(DoubleArrayMath.fuzzyEquals(computed.getSensitivity(HullWhiteIborFutureDataSet.FWD6_NAME, EUR).Sensitivity.toArray(), fwdExp, NOTIONAL * TOL));
        }
        private void calibration_market_quote_sensitivity_check(System.Func <ImmutableMarketData, RatesProvider> calibrator, double shift)
        {
            double notional = 100_000_000.0;
            double fx       = 1.1111;
            double fxPts    = 0.0012;
            ResolvedFxSwapTrade            trade  = EUR_USD.createTrade(VAL_DATE, Period.ofWeeks(6), Period.ofMonths(5), BuySell.BUY, notional, fx, fxPts, REF_DATA).resolve(REF_DATA);
            RatesProvider                  result = CALIBRATOR.calibrate(CURVE_GROUP_CONFIG, ALL_QUOTES, REF_DATA);
            PointSensitivities             pts    = FX_PRICER.presentValueSensitivity(trade.Product, result);
            CurrencyParameterSensitivities ps     = result.parameterSensitivity(pts);
            CurrencyParameterSensitivities mqs    = MQC.sensitivity(ps, result);
            double pvUsd = FX_PRICER.presentValue(trade.Product, result).getAmount(USD).Amount;
            double pvEur = FX_PRICER.presentValue(trade.Product, result).getAmount(EUR).Amount;

            double[] mqsUsd1Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < USD_DSC_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i]))] = USD_DSC_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = FX_PRICER.presentValue(trade.Product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsUsd1Computed[i], (pvS - pvUsd) / shift, TOLERANCE_PV_DELTA);
            }
            double[] mqsUsd2Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, EUR).Sensitivity.toArray();
            for (int i = 0; i < USD_DSC_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i]))] = USD_DSC_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = FX_PRICER.presentValue(trade.Product, rpShifted).getAmount(EUR).Amount;
                assertEquals(mqsUsd2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA);
            }
            double[] mqsEur1Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < EUR_DSC_NB_NODES; i++)
            {
                assertEquals(mqsEur1Computed[i], 0.0, TOLERANCE_PV_DELTA);
            }
            double[] mqsEur2Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, EUR).Sensitivity.toArray();
            for (int i = 0; i < EUR_DSC_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, EUR_DSC_ID_VALUE[i]))] = EUR_DSC_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = FX_PRICER.presentValue(trade.Product, rpShifted).getAmount(EUR).Amount;
                assertEquals(mqsEur2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA, "Node " + i);
            }
        }
Exemplo n.º 6
0
        private void calibration_market_quote_sensitivity_check(System.Func <MarketData, RatesProvider> calibrator, double shift)
        {
            double                         notional = 100_000_000.0;
            double                         spread   = 0.0050;
            SwapTrade                      trade    = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.createTrade(VAL_DATE, Period.ofMonths(8), Tenor.TENOR_7Y, BuySell.BUY, notional, spread, REF_DATA);
            RatesProvider                  result   = calibrator(ALL_QUOTES);
            ResolvedSwap                   product  = trade.Product.resolve(REF_DATA);
            PointSensitivityBuilder        pts      = SWAP_PRICER.presentValueSensitivity(product, result);
            CurrencyParameterSensitivities ps       = result.parameterSensitivity(pts.build());
            CurrencyParameterSensitivities mqs      = MQC.sensitivity(ps, result);
            double                         pv0      = SWAP_PRICER.presentValue(product, result).getAmount(USD).Amount;

            double[] mqsDscComputed = mqs.getSensitivity(DSCON_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < DSC_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, DSC_ID_VALUE[i]))] = DSC_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsDscComputed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "DSC - node " + i);
            }
            double[] mqsFwd3Computed = mqs.getSensitivity(FWD3_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < FWD3_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, FWD3_ID_VALUE[i]))] = FWD3_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsFwd3Computed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "FWD3 - node " + i);
            }
            double[] mqsFwd6Computed = mqs.getSensitivity(FWD6_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < FWD6_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, FWD6_ID_VALUE[i]))] = FWD6_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsFwd6Computed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "FWD6 - node " + i);
            }
        }
        public virtual void check_equivalent_notional()
        {
            ImmutableRatesProvider multicurve = CALIBRATOR.calibrate(GROUP_DEFINITION_PV_SENSI, MARKET_QUOTES, REF_DATA);
            // Create notional equivalent for a basis trade
            ResolvedSwapTrade              trade = ThreeLegBasisSwapConventions.EUR_FIXED_1Y_EURIBOR_3M_EURIBOR_6M.createTrade(VALUATION_DATE, Period.ofMonths(7), Tenor.TENOR_6Y, BuySell.SELL, 1_000_000, 0.03, REF_DATA).resolve(REF_DATA);
            PointSensitivities             pts   = PRICER_SWAP_TRADE.presentValueSensitivity(trade, multicurve);
            CurrencyParameterSensitivities ps    = multicurve.parameterSensitivity(pts);
            CurrencyParameterSensitivities mqs   = MQSC.sensitivity(ps, multicurve);
            CurrencyParameterSensitivities notionalEquivalent = NEC.notionalEquivalent(mqs, multicurve);

            // Check metadata are same as market quote sensitivities.
            foreach (CurrencyParameterSensitivity sensi in mqs.Sensitivities)
            {
                assertEquals(notionalEquivalent.getSensitivity(sensi.MarketDataName, sensi.Currency).ParameterMetadata, sensi.ParameterMetadata);
            }
            // Check sensitivity: trade sensitivity = sum(notional equivalent sensitivities)
            int totalNbParameters = 0;
            IDictionary <CurveName, IList <ResolvedTrade> > equivalentTrades = new Dictionary <CurveName, IList <ResolvedTrade> >();
            ImmutableList <CurveDefinition> curveGroups = GROUP_DEFINITION.CurveDefinitions;

            ImmutableList.Builder <CurveParameterSize> builder = ImmutableList.builder();
            foreach (CurveDefinition entry in curveGroups)
            {
                totalNbParameters += entry.ParameterCount;
                DoubleArray notionalCurve       = notionalEquivalent.getSensitivity(entry.Name, Currency.EUR).Sensitivity;
                ImmutableList <CurveNode> nodes = entry.Nodes;
                IList <ResolvedTrade>     resolvedTradesCurve = new List <ResolvedTrade>();
                for (int i = 0; i < nodes.size(); i++)
                {
                    resolvedTradesCurve.Add(nodes.get(i).resolvedTrade(notionalCurve.get(i), MARKET_QUOTES, REF_DATA));
                }
                equivalentTrades[entry.Name] = resolvedTradesCurve;
                builder.add(entry.toCurveParameterSize());
            }
            ImmutableList <CurveParameterSize> order = builder.build();    // order of the curves
            DoubleArray totalSensitivity             = DoubleArray.filled(totalNbParameters);

            foreach (KeyValuePair <CurveName, IList <ResolvedTrade> > entry in equivalentTrades.SetOfKeyValuePairs())
            {
                foreach (ResolvedTrade t in entry.Value)
                {
                    totalSensitivity = totalSensitivity.plus(PV_MEASURES.derivative(t, multicurve, order));
                }
            }
            DoubleArray instrumentSensi = PV_MEASURES.derivative(trade, multicurve, order);

            assertTrue(totalSensitivity.equalWithTolerance(instrumentSensi, TOLERANCE_PV_DELTA));
        }
Exemplo n.º 8
0
	  public virtual void test_volatility_sensitivity()
	  {
		double eps = 1.0e-6;
		int nData = TIME.size();
		for (int i = 0; i < NB_TEST; i++)
		{
		  double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]);
		  SwaptionSensitivity point = SwaptionSensitivity.of(VOLS.Name, expiryTime, TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD, GBP, TEST_SENSITIVITY[i]);
		  CurrencyParameterSensitivities sensActual = VOLS.parameterSensitivity(point);
		  DoubleArray computed = sensActual.getSensitivity(SURFACE.Name, GBP).Sensitivity;
		  for (int j = 0; j < nData; j++)
		  {
			DoubleArray volDataUp = VOL.with(j, VOL.get(j) + eps);
			DoubleArray volDataDw = VOL.with(j, VOL.get(j) - eps);
			InterpolatedNodalSurface paramUp = InterpolatedNodalSurface.of(METADATA, TIME, TENOR, volDataUp, INTERPOLATOR_2D);
			InterpolatedNodalSurface paramDw = InterpolatedNodalSurface.of(METADATA, TIME, TENOR, volDataDw, INTERPOLATOR_2D);
			BlackSwaptionExpiryTenorVolatilities provUp = BlackSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE_TIME, paramUp);
			BlackSwaptionExpiryTenorVolatilities provDw = BlackSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE_TIME, paramDw);
			double volUp = provUp.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD);
			double volDw = provDw.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD);
			double fd = 0.5 * (volUp - volDw) / eps;
			assertEquals(computed.get(j), fd * TEST_SENSITIVITY[i], eps);
		  }
		}
	  }
        public virtual void test_builder_mixCurrency()
        {
            CurveName          curveName = CurveName.of("WEIRD");
            CurveSensitivities test      = CurveSensitivities.builder(PortfolioItemInfo.empty()).add(ZERO_RATE_DELTA, curveName, GBP, TENOR_MD_1Y, 1).add(ZERO_RATE_DELTA, curveName, USD, TENOR_MD_1Y, 2).build();

            assertEquals(test.Info, PortfolioItemInfo.empty());
            assertEquals(test.TypedSensitivities.size(), 1);
            CurrencyParameterSensitivities sens = test.getTypedSensitivity(ZERO_RATE_DELTA);

            assertEquals(sens.Sensitivities.size(), 2);
            CurrencyParameterSensitivity sensGbp = sens.getSensitivity(curveName, GBP);

            assertEquals(sensGbp.Sensitivity, DoubleArray.of(1));
            assertEquals(sensGbp.getParameterMetadata(0), TENOR_MD_1Y);
            CurrencyParameterSensitivity sensUsd = sens.getSensitivity(curveName, USD);

            assertEquals(sensUsd.Sensitivity, DoubleArray.of(2));
            assertEquals(sensUsd.getParameterMetadata(0), TENOR_MD_1Y);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void sensitivity_legalEntity_Simple()
        public virtual void sensitivity_legalEntity_Simple()
        {
            CurrencyParameterSensitivities sensiComputed = FD_CALCULATOR.sensitivity(LegalEntityDiscountingProviderDataSets.ISSUER_REPO_SIMPLE, this.fn);
            DoubleArray timeIssuer = LegalEntityDiscountingProviderDataSets.ISSUER_TIME_USD;
            DoubleArray timesRepo  = LegalEntityDiscountingProviderDataSets.REPO_TIME_USD;

            assertEquals(sensiComputed.size(), 2);
            DoubleArray sensiIssuer = sensiComputed.getSensitivity(LegalEntityDiscountingProviderDataSets.META_SIMPLE_ISSUER_USD.CurveName, USD).Sensitivity;

            assertEquals(sensiIssuer.size(), timeIssuer.size());
            for (int i = 0; i < timeIssuer.size(); i++)
            {
                assertEquals(timeIssuer.get(i), sensiIssuer.get(i), TOLERANCE_DELTA);
            }
            DoubleArray sensiRepo = sensiComputed.getSensitivity(LegalEntityDiscountingProviderDataSets.META_SIMPLE_REPO_USD.CurveName, USD).Sensitivity;

            assertEquals(sensiRepo.size(), timesRepo.size());
            for (int i = 0; i < timesRepo.size(); i++)
            {
                assertEquals(timesRepo.get(i), sensiRepo.get(i), TOLERANCE_DELTA);
            }
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void sensitivity_multi_curve()
        public virtual void sensitivity_multi_curve()
        {
            CurrencyParameterSensitivities sensiComputed = FD_CALCULATOR.sensitivity(RatesProviderDataSets.MULTI_CPI_USD, this.fn);
            DoubleArray times1 = RatesProviderDataSets.TIMES_1;
            DoubleArray times2 = RatesProviderDataSets.TIMES_2;
            DoubleArray times3 = RatesProviderDataSets.TIMES_3;
            DoubleArray times4 = RatesProviderDataSets.TIMES_4;

            assertEquals(sensiComputed.size(), 4);
            DoubleArray s1 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD).Sensitivity;

            assertEquals(s1.size(), times1.size());
            for (int i = 0; i < times1.size(); i++)
            {
                assertEquals(times1.get(i) * 2.0d, s1.get(i), TOLERANCE_DELTA);
            }
            DoubleArray s2 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity;

            assertEquals(s2.size(), times2.size());
            for (int i = 0; i < times2.size(); i++)
            {
                assertEquals(times2.get(i), s2.get(i), TOLERANCE_DELTA);
            }
            DoubleArray s3 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity;

            assertEquals(s3.size(), times3.size());
            for (int i = 0; i < times3.size(); i++)
            {
                assertEquals(times3.get(i), s3.get(i), TOLERANCE_DELTA);
            }
            DoubleArray s4 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD).Sensitivity;

            assertEquals(s4.size(), times4.size());
            for (int i = 0; i < times4.size(); i++)
            {
                assertEquals(times4.get(i), s4.get(i), TOLERANCE_DELTA);
            }
        }
Exemplo n.º 12
0
        public virtual void pvCurveSensiRegression()
        {
            PointSensitivityBuilder        point    = PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS);
            CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point.build());

            computed.getSensitivity(DSC_NAME, EUR).Sensitivity;
            DoubleArray dscSensi = DoubleArray.of(0.0, 0.0, 0.0, -7143525.908886078, -1749520.4110068753, -719115.4683096837);     // 2.x
            DoubleArray fwdSensi = DoubleArray.of(0d, 0d, 0d, 1.7943318714062232E8, -3.4987983718159467E8, -2.6516758066404995E8); // 2.x
            CurrencyParameterSensitivity   dsc      = DSC_CURVE.createParameterSensitivity(EUR, dscSensi);
            CurrencyParameterSensitivity   fwd      = FWD6_CURVE.createParameterSensitivity(EUR, fwdSensi);
            CurrencyParameterSensitivities expected = CurrencyParameterSensitivities.of(ImmutableList.of(dsc, fwd));

            assertTrue(computed.equalWithTolerance(expected, NOTIONAL * TOL));
        }
        private CrossGammaParameterSensitivity computeGammaForCurve(CurveName curveName, Curve curve, Currency sensitivityCurrency, System.Func <Curve, ImmutableLegalEntityDiscountingProvider> ratesProviderFn, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyParameterSensitivities> sensitivitiesFn)
        {
            System.Func <DoubleArray, DoubleArray> function = (DoubleArray t) =>
            {
                Curve newCurve = curve.withPerturbation((i, v, m) => t.get(i));
                ImmutableLegalEntityDiscountingProvider newRates   = ratesProviderFn(newCurve);
                CurrencyParameterSensitivities          sensiMulti = sensitivitiesFn(newRates);
                return(sensiMulti.getSensitivity(curveName, sensitivityCurrency).Sensitivity);
            };
            int          nParams = curve.ParameterCount;
            DoubleMatrix sensi   = fd.differentiate(function).apply(DoubleArray.of(nParams, n => curve.getParameter(n)));
            IList <ParameterMetadata> metadata = IntStream.range(0, nParams).mapToObj(i => curve.getParameterMetadata(i)).collect(toImmutableList());

            return(CrossGammaParameterSensitivity.of(curveName, metadata, sensitivityCurrency, sensi));
        }
Exemplo n.º 14
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);
        }
        // computes the sensitivity of baseDeltaSingle to Curve
        internal CrossGammaParameterSensitivity computeGammaForCurve(CurrencyParameterSensitivity baseDeltaSingle, Curve curve, System.Func <Curve, ImmutableRatesProvider> ratesProviderFn, System.Func <ImmutableRatesProvider, CurrencyParameterSensitivities> sensitivitiesFn)
        {
            System.Func <DoubleArray, DoubleArray> function = (DoubleArray t) =>
            {
                Curve newCurve = replaceParameters(curve, t);
                ImmutableRatesProvider         newRates   = ratesProviderFn(newCurve);
                CurrencyParameterSensitivities sensiMulti = sensitivitiesFn(newRates);
                return(sensiMulti.getSensitivity(baseDeltaSingle.MarketDataName, baseDeltaSingle.Currency).Sensitivity);
            };
            int          nParams = curve.ParameterCount;
            DoubleMatrix sensi   = fd.differentiate(function).apply(DoubleArray.of(nParams, n => curve.getParameter(n)));
            IList <ParameterMetadata> metadata = IntStream.range(0, nParams).mapToObj(i => curve.getParameterMetadata(i)).collect(toImmutableList());

            return(CrossGammaParameterSensitivity.of(baseDeltaSingle.MarketDataName, baseDeltaSingle.ParameterMetadata, curve.Name, metadata, baseDeltaSingle.Currency, sensi));
        }
        public virtual void test_builder_tenors()
        {
            CurveName curveName = CurveName.of("GBP");
            CurrencyParameterSensitivity sens1Y = CurrencyParameterSensitivity.of(curveName, ImmutableList.of(TENOR_MD_1Y), GBP, DoubleArray.of(3));
            CurveSensitivities           test   = CurveSensitivities.builder(PortfolioItemInfo.empty()).add(ZERO_RATE_DELTA, curveName, GBP, TENOR_MD_1M, 4).add(ZERO_RATE_DELTA, curveName, GBP, TENOR_MD_1W, 1).add(ZERO_RATE_DELTA, curveName, GBP, TENOR_MD_1Y, 2).add(ZERO_RATE_DELTA, curveName, GBP, TENOR_MD_1W, 2).add(ZERO_RATE_DELTA, sens1Y).build();

            assertEquals(test.Info, PortfolioItemInfo.empty());
            assertEquals(test.TypedSensitivities.size(), 1);
            CurrencyParameterSensitivities sens = test.getTypedSensitivity(ZERO_RATE_DELTA);

            assertEquals(sens.Sensitivities.size(), 1);
            CurrencyParameterSensitivity singleSens = sens.getSensitivity(curveName, GBP);

            assertEquals(singleSens.Sensitivity, DoubleArray.of(3, 4, 5));
            assertEquals(singleSens.getParameterMetadata(0), TENOR_MD_1W);
            assertEquals(singleSens.getParameterMetadata(1), TENOR_MD_1M);
            assertEquals(singleSens.getParameterMetadata(2), TENOR_MD_1Y);
        }
        //-------------------------------------------------------------------------
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void sensitivity_credit_isda()
        public virtual void sensitivity_credit_isda()
        {
            LocalDate                         valuationDate = LocalDate.of(2014, 1, 3);
            CreditRatesProvider               rates         = CreditRatesProviderDataSets.createCreditRatesProvider(valuationDate);
            CurrencyParameterSensitivities    sensiComputed = FD_CALCULATOR.sensitivity(rates, this.creditFunction);
            IList <IsdaCreditDiscountFactors> curves        = CreditRatesProviderDataSets.getAllDiscountFactors(valuationDate);

            assertEquals(sensiComputed.size(), curves.Count);
            foreach (IsdaCreditDiscountFactors curve in curves)
            {
                DoubleArray time = curve.ParameterKeys;
                DoubleArray sensiValueComputed = sensiComputed.getSensitivity(curve.Curve.Name, USD).Sensitivity;
                assertEquals(sensiValueComputed.size(), time.size());
                for (int i = 0; i < time.size(); i++)
                {
                    assertEquals(time.get(i), sensiValueComputed.get(i), TOLERANCE_DELTA);
                }
            }
        }
        public virtual void test_volatility_sensitivity()
        {
            double eps   = 1.0e-6;
            int    nData = TIME.size();

            for (int i = 0; i < NB_TEST; i++)
            {
                double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]);
                SwaptionSensitivity            point      = SwaptionSensitivity.of(VOLS.Name, expiryTime, TEST_TENOR, TEST_STRIKE[i], TEST_FORWARD, GBP, TEST_SENSITIVITY[i]);
                CurrencyParameterSensitivities sensActual = VOLS.parameterSensitivity(point);
                CurrencyParameterSensitivity   sensi      = sensActual.getSensitivity(SURFACE.Name, GBP);
                DoubleArray computed = sensi.Sensitivity;

                IDictionary <DoublesPair, double> map = new Dictionary <DoublesPair, double>();
                for (int j = 0; j < nData; ++j)
                {
                    DoubleArray volDataUp            = VOL.subArray(0, nData).with(j, VOL.get(j) + eps);
                    DoubleArray volDataDw            = VOL.subArray(0, nData).with(j, VOL.get(j) - eps);
                    InterpolatedNodalSurface paramUp = InterpolatedNodalSurface.of(METADATA, TIME, STRIKE, volDataUp, INTERPOLATOR_2D);
                    InterpolatedNodalSurface paramDw = InterpolatedNodalSurface.of(METADATA, TIME, STRIKE, volDataDw, INTERPOLATOR_2D);
                    NormalSwaptionExpiryStrikeVolatilities provUp = NormalSwaptionExpiryStrikeVolatilities.of(CONVENTION, VAL_DATE_TIME, paramUp);
                    NormalSwaptionExpiryStrikeVolatilities provDw = NormalSwaptionExpiryStrikeVolatilities.of(CONVENTION, VAL_DATE_TIME, paramDw);
                    double volUp = provUp.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR, TEST_STRIKE[i], TEST_FORWARD);
                    double volDw = provDw.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR, TEST_STRIKE[i], TEST_FORWARD);
                    double fd    = 0.5 * (volUp - volDw) / eps;
                    map[DoublesPair.of(TIME.get(j), STRIKE.get(j))] = fd;
                }
                IList <ParameterMetadata> list = sensi.ParameterMetadata;
                assertEquals(computed.size(), nData);
                for (int j = 0; j < list.Count; ++j)
                {
                    SwaptionSurfaceExpiryStrikeParameterMetadata metadata = (SwaptionSurfaceExpiryStrikeParameterMetadata)list[i];
                    double expected = map[DoublesPair.of(metadata.YearFraction, metadata.Strike)];
                    assertEquals(computed.get(i), expected, eps);
                }
            }
        }
 private double[] getStandardQuoteForm(ResolvedCdsTrade calibrationCds, CdsQuote marketQuote, LocalDate valuationDate, CreditDiscountFactors discountFactors, RecoveryRates recoveryRates, bool computeJacobian, ReferenceData refData)
 {
     double[] res = new double[3];
     res[2] = 1d;
     if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.PAR_SPREAD))
     {
         res[0] = marketQuote.QuotedValue;
     }
     else if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.QUOTED_SPREAD))
     {
         double     qSpread                 = marketQuote.QuotedValue;
         CurveName  curveName               = CurveName.of("quoteConvertCurve");
         NodalCurve tempCreditCurve         = calibrate(ImmutableList.of(calibrationCds), DoubleArray.of(qSpread), DoubleArray.of(0d), curveName, valuationDate, discountFactors, recoveryRates, refData);
         Currency   currency                = calibrationCds.Product.Currency;
         StandardId legalEntityId           = calibrationCds.Product.LegalEntityId;
         ImmutableCreditRatesProvider rates = ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).discountCurves(ImmutableMap.of(currency, discountFactors)).recoveryRateCurves(ImmutableMap.of(legalEntityId, recoveryRates)).creditCurves(ImmutableMap.of(Pair.of(legalEntityId, currency), LegalEntitySurvivalProbabilities.of(legalEntityId, IsdaCreditDiscountFactors.of(currency, valuationDate, tempCreditCurve)))).build();
         res[0] = calibrationCds.Product.FixedRate;
         res[1] = tradePricer.price(calibrationCds, rates, PriceType.CLEAN, refData);
         if (computeJacobian)
         {
             CurrencyParameterSensitivities pufSensi = rates.parameterSensitivity(tradePricer.priceSensitivity(calibrationCds, rates, refData));
             CurrencyParameterSensitivities spSensi  = rates.parameterSensitivity(tradePricer.parSpreadSensitivity(calibrationCds, rates, refData));
             res[2] = spSensi.getSensitivity(curveName, currency).Sensitivity.get(0) / pufSensi.getSensitivity(curveName, currency).Sensitivity.get(0);
         }
     }
     else if (marketQuote.QuoteConvention.Equals(CdsQuoteConvention.POINTS_UPFRONT))
     {
         res[0] = calibrationCds.Product.FixedRate;
         res[1] = marketQuote.QuotedValue;
     }
     else
     {
         throw new System.ArgumentException("Unknown CDSQuoteConvention type " + marketQuote.GetType());
     }
     return(res);
 }
        //-------------------------------------------------------------------------
        public virtual void calibration_transition_coherence_par_rate()
        {
            RatesProvider provider = CalibrationEurStandard.calibrateEurStandard(VAL_DATE, DSC_MARKET_QUOTES, DSC_OIS_TENORS, FWD3_FIXING_QUOTE, FWD3_FRA_QUOTES, FWD3_IRS_QUOTES, FWD3_FRA_TENORS, FWD3_IRS_TENORS, FWD6_FIXING_QUOTE, FWD6_FRA_QUOTES, FWD6_IRS_QUOTES, FWD6_FRA_TENORS, FWD6_IRS_TENORS);

            /* Curve Discounting/EUR-EONIA */
            string[] dscIdValues = CalibrationEurStandard.dscIdValues(DSC_OIS_TENORS);
            /* Curve EUR-EURIBOR-3M */
            double[] fwd3MarketQuotes = CalibrationEurStandard.fwdMarketQuotes(FWD3_FIXING_QUOTE, FWD3_FRA_QUOTES, FWD3_IRS_QUOTES);
            string[] fwd3IdValue      = CalibrationEurStandard.fwdIdValue(3, FWD3_FIXING_QUOTE, FWD3_FRA_QUOTES, FWD3_IRS_QUOTES, FWD3_FRA_TENORS, FWD3_IRS_TENORS);
            /* Curve EUR-EURIBOR-6M */
            double[] fwd6MarketQuotes = CalibrationEurStandard.fwdMarketQuotes(FWD6_FIXING_QUOTE, FWD6_FRA_QUOTES, FWD6_IRS_QUOTES);
            string[] fwd6IdValue      = CalibrationEurStandard.fwdIdValue(6, FWD6_FIXING_QUOTE, FWD6_FRA_QUOTES, FWD6_IRS_QUOTES, FWD6_FRA_TENORS, FWD6_IRS_TENORS);
            /* All quotes for the curve calibration */
            MarketData allQuotes = CalibrationEurStandard.allQuotes(VAL_DATE, DSC_MARKET_QUOTES, dscIdValues, fwd3MarketQuotes, fwd3IdValue, fwd6MarketQuotes, fwd6IdValue);
            /* All nodes by groups. */
            RatesCurveGroupDefinition config = CalibrationEurStandard.config(DSC_OIS_TENORS, dscIdValues, FWD3_FRA_TENORS, FWD3_IRS_TENORS, fwd3IdValue, FWD6_FRA_TENORS, FWD6_IRS_TENORS, fwd6IdValue);

            ImmutableList <CurveDefinition> definitions = config.CurveDefinitions;
            // Test PV Dsc
            ImmutableList <CurveNode> dscNodes  = definitions.get(0).Nodes;
            IList <ResolvedTrade>     dscTrades = new List <ResolvedTrade>();

            for (int i = 0; i < dscNodes.size(); i++)
            {
                dscTrades.Add(dscNodes.get(i).resolvedTrade(1d, allQuotes, REF_DATA));
            }
            // OIS
            for (int loopnode = 0; loopnode < DSC_MARKET_QUOTES.Length; loopnode++)
            {
                PointSensitivities             pts = SWAP_PRICER.parRateSensitivity(((ResolvedSwapTrade)dscTrades[loopnode]).Product, provider).build();
                CurrencyParameterSensitivities ps  = provider.parameterSensitivity(pts);
                CurrencyParameterSensitivities mqs = MQC.sensitivity(ps, provider);
                assertEquals(mqs.size(), 3);   // Calibration of all curves simultaneously
                CurrencyParameterSensitivity mqsDsc = mqs.getSensitivity(CalibrationEurStandard.DSCON_CURVE_NAME, EUR);
                assertTrue(mqsDsc.MarketDataName.Equals(CalibrationEurStandard.DSCON_CURVE_NAME));
                assertTrue(mqsDsc.Currency.Equals(EUR));
                DoubleArray mqsData = mqsDsc.Sensitivity;
                assertEquals(mqsData.size(), DSC_MARKET_QUOTES.Length);
                for (int i = 0; i < mqsData.size(); i++)
                {
                    assertEquals(mqsData.get(i), (i == loopnode) ? 1.0 : 0.0, TOLERANCE_DELTA);
                }
            }
            // Test PV Fwd3
            ImmutableList <CurveNode> fwd3Nodes  = definitions.get(1).Nodes;
            IList <ResolvedTrade>     fwd3Trades = new List <ResolvedTrade>();

            for (int i = 0; i < fwd3Nodes.size(); i++)
            {
                fwd3Trades.Add(fwd3Nodes.get(i).resolvedTrade(1d, allQuotes, REF_DATA));
            }
            for (int loopnode = 0; loopnode < fwd3MarketQuotes.Length; loopnode++)
            {
                PointSensitivities pts = null;
                if (fwd3Trades[loopnode] is ResolvedIborFixingDepositTrade)
                {
                    pts = PRICER_FIXING.parSpreadSensitivity(((ResolvedIborFixingDepositTrade)fwd3Trades[loopnode]).Product, provider);
                }
                if (fwd3Trades[loopnode] is ResolvedFraTrade)
                {
                    pts = PRICER_FRA.parSpreadSensitivity(((ResolvedFraTrade)fwd3Trades[loopnode]).Product, provider);
                }
                if (fwd3Trades[loopnode] is ResolvedSwapTrade)
                {
                    pts = SWAP_PRICER.parSpreadSensitivity(((ResolvedSwapTrade)fwd3Trades[loopnode]).Product, provider).build();
                }
                CurrencyParameterSensitivities ps  = provider.parameterSensitivity(pts);
                CurrencyParameterSensitivities mqs = MQC.sensitivity(ps, provider);
                assertEquals(mqs.size(), 3);   // Calibration of all curves simultaneously
                CurrencyParameterSensitivity mqsDsc  = mqs.getSensitivity(CalibrationEurStandard.DSCON_CURVE_NAME, EUR);
                CurrencyParameterSensitivity mqsFwd3 = mqs.getSensitivity(CalibrationEurStandard.FWD3_CURVE_NAME, EUR);
                DoubleArray mqsDscData = mqsDsc.Sensitivity;
                assertEquals(mqsDscData.size(), DSC_MARKET_QUOTES.Length);
                for (int i = 0; i < mqsDscData.size(); i++)
                {
                    assertEquals(mqsDscData.get(i), 0.0, TOLERANCE_DELTA);
                }
                DoubleArray mqsFwd3Data = mqsFwd3.Sensitivity;
                assertEquals(mqsFwd3Data.size(), fwd3MarketQuotes.Length);
                for (int i = 0; i < mqsFwd3Data.size(); i++)
                {
                    assertEquals(mqsFwd3Data.get(i), (i == loopnode) ? 1.0 : 0.0, TOLERANCE_DELTA);
                }
            }
            // Test PV Fwd6
            ImmutableList <CurveNode> fwd6Nodes  = definitions.get(2).Nodes;
            IList <ResolvedTrade>     fwd6Trades = new List <ResolvedTrade>();

            for (int i = 0; i < fwd6Nodes.size(); i++)
            {
                fwd6Trades.Add(fwd6Nodes.get(i).resolvedTrade(1d, allQuotes, REF_DATA));
            }
            for (int loopnode = 0; loopnode < fwd6MarketQuotes.Length; loopnode++)
            {
                PointSensitivities pts = null;
                if (fwd6Trades[loopnode] is ResolvedIborFixingDepositTrade)
                {
                    pts = PRICER_FIXING.parSpreadSensitivity(((ResolvedIborFixingDepositTrade)fwd6Trades[loopnode]).Product, provider);
                }
                if (fwd6Trades[loopnode] is ResolvedFraTrade)
                {
                    pts = PRICER_FRA.parSpreadSensitivity(((ResolvedFraTrade)fwd6Trades[loopnode]).Product, provider);
                }
                if (fwd6Trades[loopnode] is ResolvedSwapTrade)
                {
                    pts = SWAP_PRICER.parSpreadSensitivity(((ResolvedSwapTrade)fwd6Trades[loopnode]).Product, provider).build();
                }
                CurrencyParameterSensitivities ps  = provider.parameterSensitivity(pts);
                CurrencyParameterSensitivities mqs = MQC.sensitivity(ps, provider);
                assertEquals(mqs.size(), 3);
                CurrencyParameterSensitivity mqsDsc  = mqs.getSensitivity(CalibrationEurStandard.DSCON_CURVE_NAME, EUR);
                CurrencyParameterSensitivity mqsFwd3 = mqs.getSensitivity(CalibrationEurStandard.FWD3_CURVE_NAME, EUR);
                CurrencyParameterSensitivity mqsFwd6 = mqs.getSensitivity(CalibrationEurStandard.FWD6_CURVE_NAME, EUR);
                DoubleArray mqsDscData = mqsDsc.Sensitivity;
                assertEquals(mqsDscData.size(), DSC_MARKET_QUOTES.Length);
                for (int i = 0; i < mqsDscData.size(); i++)
                {
                    assertEquals(mqsDscData.get(i), 0.0, TOLERANCE_DELTA);
                }
                DoubleArray mqsFwd3Data = mqsFwd3.Sensitivity;
                assertEquals(mqsFwd3Data.size(), fwd3MarketQuotes.Length);
                for (int i = 0; i < mqsFwd3Data.size(); i++)
                {
                    assertEquals(mqsFwd3Data.get(i), 0.0, TOLERANCE_DELTA);
                }
                DoubleArray mqsFwd6Data = mqsFwd6.Sensitivity;
                assertEquals(mqsFwd6Data.size(), fwd6MarketQuotes.Length);
                for (int i = 0; i < mqsFwd6Data.size(); i++)
                {
                    assertEquals(mqsFwd6Data.get(i), (i == loopnode) ? 1.0 : 0.0, TOLERANCE_DELTA);
                }
            }
        }