public virtual void sensitivity_single_curve() { CrossGammaParameterSensitivities forward = FORWARD.calculateCrossGammaIntraCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); CrossGammaParameterSensitivities central = CENTRAL.calculateCrossGammaIntraCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); CrossGammaParameterSensitivities backward = BACKWARD.calculateCrossGammaIntraCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); DoubleArray times = RatesProviderDataSets.TIMES_1; foreach (CrossGammaParameterSensitivities sensi in new CrossGammaParameterSensitivities[] { forward, central, backward }) { CurrencyParameterSensitivities diagonalComputed = sensi.diagonal(); assertEquals(sensi.size(), 1); assertEquals(diagonalComputed.size(), 1); DoubleMatrix s = sensi.Sensitivities.get(0).Sensitivity; assertEquals(s.columnCount(), times.size()); for (int i = 0; i < times.size(); i++) { for (int j = 0; j < times.size(); j++) { double expected = 32d * times.get(i) * times.get(j); assertEquals(s.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } } // no difference for single curve CrossGammaParameterSensitivities forwardCross = FORWARD.calculateCrossGammaCrossCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); assertTrue(forward.equalWithTolerance(forwardCross, TOL)); CrossGammaParameterSensitivities centralCross = CENTRAL.calculateCrossGammaCrossCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); assertTrue(central.equalWithTolerance(centralCross, TOL)); CrossGammaParameterSensitivities backwardCross = BACKWARD.calculateCrossGammaCrossCurve(RatesProviderDataSets.SINGLE_USD, this.sensiFn); assertTrue(backward.equalWithTolerance(backwardCross, TOL)); }
public virtual void sensitivity_multi_combined_bond_curve() { CrossGammaParameterSensitivities sensiComputed = CENTRAL.calculateCrossGammaIntraCurve(RatesProviderDataSets.MULTI_BOND_COMBINED, this.sensiCombinedFnBond); DoubleArray timesUsL3 = RatesProviderDataSets.TIMES_2; DoubleArray timesUsRepo = RatesProviderDataSets.TIMES_1; DoubleArray timesUsIssuer1 = RatesProviderDataSets.TIMES_3; DoubleArray timesUsIssuer2 = RatesProviderDataSets.TIMES_2; assertEquals(sensiComputed.size(), 4); DoubleMatrix s1 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; assertEquals(s1.columnCount(), timesUsL3.size()); for (int i = 0; i < timesUsL3.size(); i++) { for (int j = 0; j < timesUsL3.size(); j++) { double expected = 2d * timesUsL3.get(i) * timesUsL3.get(j) * 3d * 3d; assertEquals(s1.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s2 = sensiComputed.getSensitivity(RatesProviderDataSets.US_REPO_CURVE_NAME, USD).Sensitivity; assertEquals(s2.columnCount(), timesUsRepo.size()); for (int i = 0; i < timesUsRepo.size(); i++) { for (int j = 0; j < timesUsRepo.size(); j++) { double expected = 2d * timesUsRepo.get(i) * timesUsRepo.get(j); assertEquals(s2.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s3 = sensiComputed.getSensitivity(RatesProviderDataSets.US_ISSUER_CURVE_1_NAME, USD).Sensitivity; assertEquals(s3.columnCount(), timesUsIssuer1.size()); for (int i = 0; i < timesUsIssuer1.size(); i++) { for (int j = 0; j < timesUsIssuer1.size(); j++) { double expected = 2d * timesUsIssuer1.get(i) * timesUsIssuer1.get(j); assertEquals(s3.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s4 = sensiComputed.getSensitivity(RatesProviderDataSets.US_ISSUER_CURVE_2_NAME, USD).Sensitivity; assertEquals(s4.columnCount(), timesUsIssuer2.size()); for (int i = 0; i < timesUsIssuer2.size(); i++) { for (int j = 0; j < timesUsIssuer2.size(); j++) { double expected = 2d * timesUsIssuer2.get(i) * timesUsIssuer2.get(j); assertEquals(s4.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 20d); } } }
public virtual void sensitivity_intra_multi_curve() { CrossGammaParameterSensitivities sensiComputed = CENTRAL.calculateCrossGammaIntraCurve(RatesProviderDataSets.MULTI_CPI_USD, this.sensiFn); DoubleArray times1 = RatesProviderDataSets.TIMES_1; DoubleArray times2 = RatesProviderDataSets.TIMES_2; DoubleArray times3 = RatesProviderDataSets.TIMES_3; DoubleArray times4 = RatesProviderDataSets.TIMES_4; assertEquals(sensiComputed.size(), 4); DoubleMatrix s1 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD).Sensitivity; assertEquals(s1.columnCount(), times1.size()); for (int i = 0; i < times1.size(); i++) { for (int j = 0; j < times1.size(); j++) { double expected = 8d * times1.get(i) * times1.get(j); assertEquals(s1.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s2 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; assertEquals(s2.columnCount(), times2.size()); for (int i = 0; i < times2.size(); i++) { for (int j = 0; j < times2.size(); j++) { double expected = 2d * times2.get(i) * times2.get(j); assertEquals(s2.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } DoubleMatrix s3 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity; assertEquals(s3.columnCount(), times3.size()); for (int i = 0; i < times3.size(); i++) { for (int j = 0; j < times3.size(); j++) { double expected = 2d * times3.get(i) * times3.get(j); assertEquals(s3.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } DoubleMatrix s4 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD).Sensitivity; assertEquals(s4.columnCount(), times4.size()); for (int i = 0; i < times4.size(); i++) { for (int j = 0; j < times4.size(); j++) { double expected = 2d * times4.get(i) * times4.get(j); assertEquals(s4.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } }
public virtual void sensitivity_cross_multi_curve_empty() { CrossGammaParameterSensitivities sensiComputed = CENTRAL.calculateCrossGammaCrossCurve(RatesProviderDataSets.MULTI_CPI_USD, this.sensiModFn); DoubleArray times2 = RatesProviderDataSets.TIMES_2; DoubleArray times3 = RatesProviderDataSets.TIMES_3; int paramsTotal = times2.size() + times3.size(); double[] timesTotal = new double[paramsTotal]; Array.Copy(times2.toArray(), 0, timesTotal, 0, times2.size()); Array.Copy(times3.toArray(), 0, timesTotal, times2.size(), times3.size()); assertEquals(sensiComputed.size(), 2); DoubleMatrix s2 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; assertEquals(s2.columnCount(), paramsTotal); for (int i = 0; i < times2.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times2.get(i) * timesTotal[j]; assertEquals(s2.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } DoubleMatrix s3 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity; assertEquals(s3.columnCount(), paramsTotal); for (int i = 0; i < times3.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times3.get(i) * timesTotal[j]; assertEquals(s3.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS); } } Optional <CrossGammaParameterSensitivity> oisSensi = sensiComputed.findSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD); assertFalse(oisSensi.Present); Optional <CrossGammaParameterSensitivity> priceIndexSensi = sensiComputed.findSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD); assertFalse(priceIndexSensi.Present); }
// single-node gamma PV01 for one scenario private CurrencyParameterSensitivities pv01SingleNodeGammaBucketed(ResolvedFraTrade trade, RatesProvider ratesProvider) { CrossGammaParameterSensitivities crossGamma = CROSS_GAMMA.calculateCrossGammaIntraCurve(ratesProvider, p => p.parameterSensitivity(tradePricer.presentValueSensitivity(trade, p))); return(crossGamma.diagonal().multipliedBy(ONE_BASIS_POINT * ONE_BASIS_POINT)); }
public virtual void sensitivity_multi_combined_curve() { CrossGammaParameterSensitivities sensiCrossComputed = CENTRAL.calculateCrossGammaCrossCurve(RatesProviderDataSets.MULTI_CPI_USD_COMBINED, this.sensiCombinedFn); DoubleArray times1 = RatesProviderDataSets.TIMES_1; // ois DoubleArray times2 = RatesProviderDataSets.TIMES_2; // l3 DoubleArray times3 = RatesProviderDataSets.TIMES_3; // l6 DoubleArray times4 = RatesProviderDataSets.TIMES_4; // cpi int paramsTotal = times1.size() + times2.size() + times3.size() + times4.size(); double[] timesTotal = new double[paramsTotal]; DoubleArray times1Twice = times1.multipliedBy(2d); Array.Copy(times4.toArray(), 0, timesTotal, 0, times4.size()); Array.Copy(times1Twice.toArray(), 0, timesTotal, times4.size(), times1.size()); Array.Copy(times2.toArray(), 0, timesTotal, times1.size() + times4.size(), times2.size()); Array.Copy(times3.toArray(), 0, timesTotal, times1.size() + times2.size() + times4.size(), times3.size()); assertEquals(sensiCrossComputed.size(), 4); DoubleMatrix s1 = sensiCrossComputed.getSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD).Sensitivity; assertEquals(s1.columnCount(), paramsTotal); for (int i = 0; i < times1.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 4d * times1.get(i) * timesTotal[j]; assertEquals(s1.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s2 = sensiCrossComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; assertEquals(s2.columnCount(), paramsTotal); for (int i = 0; i < times2.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 8d * times2.get(i) * timesTotal[j]; assertEquals(s2.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s3 = sensiCrossComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity; assertEquals(s3.columnCount(), paramsTotal); for (int i = 0; i < times3.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times3.get(i) * timesTotal[j]; assertEquals(s3.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s4 = sensiCrossComputed.getSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD).Sensitivity; assertEquals(s4.columnCount(), paramsTotal); for (int i = 0; i < times4.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times4.get(i) * timesTotal[j]; assertEquals(s4.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 20d); } } CrossGammaParameterSensitivities sensiIntraComputed = CENTRAL.calculateCrossGammaIntraCurve(RatesProviderDataSets.MULTI_CPI_USD_COMBINED, this.sensiCombinedFn); DoubleMatrix s1Intra = sensiIntraComputed.getSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD).Sensitivity; DoubleMatrix s2Intra = sensiIntraComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; DoubleMatrix s3Intra = sensiIntraComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity; DoubleMatrix s4Intra = sensiIntraComputed.getSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD).Sensitivity; int offsetOis = times4.size(); for (int i = 0; i < times1.size(); i++) { for (int j = 0; j < times1.size(); j++) { assertEquals(s1Intra.get(i, j), s1.get(i, offsetOis + j), TOL); } } int offset3m = times4.size() + times1.size(); for (int i = 0; i < times2.size(); i++) { for (int j = 0; j < times2.size(); j++) { assertEquals(s2Intra.get(i, j), s2.get(i, offset3m + j), TOL); } } int offset6m = times4.size() + times1.size() + times2.size(); for (int i = 0; i < times3.size(); i++) { for (int j = 0; j < times3.size(); j++) { assertEquals(s3Intra.get(i, j), s3.get(i, offset6m + j), TOL); } } for (int i = 0; i < times4.size(); i++) { for (int j = 0; j < times4.size(); j++) { assertEquals(s4Intra.get(i, j), s4.get(i, j), TOL); } } }
public virtual void sensitivity_cross_multi_curve() { CrossGammaParameterSensitivities sensiComputed = CENTRAL.calculateCrossGammaCrossCurve(RatesProviderDataSets.MULTI_CPI_USD, this.sensiFn); DoubleArray times1 = RatesProviderDataSets.TIMES_1; DoubleArray times2 = RatesProviderDataSets.TIMES_2; DoubleArray times3 = RatesProviderDataSets.TIMES_3; DoubleArray times4 = RatesProviderDataSets.TIMES_4; int paramsTotal = times1.size() + times2.size() + times3.size() + times4.size(); double[] timesTotal = new double[paramsTotal]; DoubleArray times1Twice = times1.multipliedBy(2d); Array.Copy(times4.toArray(), 0, timesTotal, 0, times4.size()); Array.Copy(times1Twice.toArray(), 0, timesTotal, times4.size(), times1.size()); Array.Copy(times2.toArray(), 0, timesTotal, times1.size() + times4.size(), times2.size()); Array.Copy(times3.toArray(), 0, timesTotal, times1.size() + times2.size() + times4.size(), times3.size()); assertEquals(sensiComputed.size(), 4); DoubleMatrix s1 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_DSC_NAME, USD).Sensitivity; assertEquals(s1.columnCount(), paramsTotal); for (int i = 0; i < times1.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 4d * times1.get(i) * timesTotal[j]; assertEquals(s1.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s2 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L3_NAME, USD).Sensitivity; assertEquals(s2.columnCount(), paramsTotal); for (int i = 0; i < times2.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times2.get(i) * timesTotal[j]; assertEquals(s2.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s3 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_L6_NAME, USD).Sensitivity; assertEquals(s3.columnCount(), paramsTotal); for (int i = 0; i < times3.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times3.get(i) * timesTotal[j]; assertEquals(s3.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 10d); } } DoubleMatrix s4 = sensiComputed.getSensitivity(RatesProviderDataSets.USD_CPI_NAME, USD).Sensitivity; assertEquals(s4.columnCount(), paramsTotal); for (int i = 0; i < times4.size(); i++) { for (int j = 0; j < paramsTotal; j++) { double expected = 2d * times4.get(i) * timesTotal[j]; assertEquals(s4.get(i, j), expected, Math.Max(Math.Abs(expected), 1d) * EPS * 20d); } } }
private CrossGammaParameterSensitivity combineSensitivities(CurrencyParameterSensitivity baseDeltaSingle, CrossGammaParameterSensitivities blockCrossGamma) { double[][] valuesTotal = new double[baseDeltaSingle.ParameterCount][]; //JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET: //ORIGINAL LINE: java.util.List<com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.data.MarketDataName<?>, java.util.List<? extends com.opengamma.strata.market.param.ParameterMetadata>>> order = new java.util.ArrayList<>(); IList <Pair <MarketDataName <object>, IList <ParameterMetadata> > > order = new List <Pair <MarketDataName <object>, IList <ParameterMetadata> > >(); for (int i = 0; i < baseDeltaSingle.ParameterCount; ++i) { List <double> innerList = new List <double>(); foreach (CrossGammaParameterSensitivity gammaSingle in blockCrossGamma.Sensitivities) { innerList.AddRange(gammaSingle.Sensitivity.row(i).toList()); if (i == 0) { order.Add(gammaSingle.Order.get(0)); } } valuesTotal[i] = Doubles.toArray(innerList); } return(CrossGammaParameterSensitivity.of(baseDeltaSingle.MarketDataName, baseDeltaSingle.ParameterMetadata, order, baseDeltaSingle.Currency, DoubleMatrix.ofUnsafe(valuesTotal))); }
//------------------------------------------------------------------------- /// <summary> /// Computes cross-curve gamma by applying finite difference method to curve delta. /// <para> /// This computes the cross-curve gamma, i.e., the second order sensitivities to full curves. /// Thus the sensitivities of curve delta to other curves are produced. /// </para> /// <para> /// The sensitivities are computed for discount curves, and forward curves for {@code RateIndex} and {@code PriceIndex}. /// This implementation works only for single currency trades. /// /// </para> /// </summary> /// <param name="ratesProvider"> the rates provider </param> /// <param name="sensitivitiesFn"> the sensitivity function </param> /// <returns> the cross gamma </returns> public CrossGammaParameterSensitivities calculateCrossGammaCrossCurve(RatesProvider ratesProvider, System.Func <ImmutableRatesProvider, CurrencyParameterSensitivities> sensitivitiesFn) { ImmutableRatesProvider immProv = ratesProvider.toImmutableRatesProvider(); CurrencyParameterSensitivities baseDelta = sensitivitiesFn(immProv); // used to check target sensitivity exits. CrossGammaParameterSensitivities result = CrossGammaParameterSensitivities.empty(); foreach (CurrencyParameterSensitivity baseDeltaSingle in baseDelta.Sensitivities) { CrossGammaParameterSensitivities resultInner = CrossGammaParameterSensitivities.empty(); // discount curve foreach (KeyValuePair <Currency, Curve> entry in immProv.DiscountCurves.entrySet()) { Currency currency = entry.Key; Curve curve = entry.Value; if (baseDelta.findSensitivity(curve.Name, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(baseDeltaSingle, curve, c => immProv.toBuilder().discountCurve(currency, c).build(), sensitivitiesFn); resultInner = resultInner.combinedWith(gammaSingle); } else if (curve.split().size() > 1) { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); if (baseDelta.findSensitivity(underlyingCurve.Name, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(baseDeltaSingle, underlyingCurve, c => immProv.toBuilder().discountCurve(currency, curve.withUnderlyingCurve(currentIndex, c)).build(), sensitivitiesFn); resultInner = resultInner.combinedWith(gammaSingle); } } } } // forward curve foreach (KeyValuePair <Index, Curve> entry in immProv.IndexCurves.entrySet()) { Index index = entry.Key; if (index is RateIndex || index is PriceIndex) { Currency currency = getCurrency(index); Curve curve = entry.Value; if (baseDelta.findSensitivity(curve.Name, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(baseDeltaSingle, curve, c => immProv.toBuilder().indexCurve(index, c).build(), sensitivitiesFn); resultInner = resultInner.combinedWith(gammaSingle); } else if (curve.split().size() > 1) { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); if (baseDelta.findSensitivity(underlyingCurve.Name, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(baseDeltaSingle, underlyingCurve, c => immProv.toBuilder().indexCurve(index, curve.withUnderlyingCurve(currentIndex, c)).build(), sensitivitiesFn); resultInner = resultInner.combinedWith(gammaSingle); } } } } } result = result.combinedWith(combineSensitivities(baseDeltaSingle, resultInner)); } return(result); }
//------------------------------------------------------------------------- /// <summary> /// Computes intra-curve cross gamma for bond curves by applying finite difference method to curve delta. /// <para> /// This computes the intra-curve cross gamma, i.e., the second order sensitivities to individual curves. /// Thus the sensitivity of a curve delta to another curve is not produced. /// </para> /// <para> /// The underlying instruments must be single-currency, i.e., the curve currency must be the same as the sensitivity currency. /// /// </para> /// </summary> /// <param name="ratesProvider"> the rates provider </param> /// <param name="sensitivitiesFn"> the sensitivity function </param> /// <returns> the cross gamma </returns> public CrossGammaParameterSensitivities calculateCrossGammaIntraCurve(LegalEntityDiscountingProvider ratesProvider, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyParameterSensitivities> sensitivitiesFn) { LocalDate valuationDate = ratesProvider.ValuationDate; ImmutableLegalEntityDiscountingProvider immProv = ratesProvider.toImmutableLegalEntityDiscountingProvider(); CurrencyParameterSensitivities baseDelta = sensitivitiesFn(immProv); // used to check target sensitivity exits CrossGammaParameterSensitivities result = CrossGammaParameterSensitivities.empty(); // issuer curve foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in immProv.IssuerCurves.entrySet()) { Pair <LegalEntityGroup, Currency> legCcy = entry.Key; Currency currency = legCcy.Second; Curve curve = getCurve(entry.Value); CurveName curveName = curve.Name; if (baseDelta.findSensitivity(curveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(curveName, curve, currency, c => replaceIssuerCurve(immProv, legCcy, DiscountFactors.of(currency, valuationDate, c)), sensitivitiesFn); result = result.combinedWith(gammaSingle); } else { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); if (nCurves > 1) { for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); CurveName underlyingCurveName = underlyingCurve.Name; if (baseDelta.findSensitivity(underlyingCurveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(underlyingCurveName, underlyingCurve, currency, c => replaceIssuerCurve(immProv, legCcy, DiscountFactors.of(currency, valuationDate, curve.withUnderlyingCurve(currentIndex, c))), sensitivitiesFn); result = result.combinedWith(gammaSingle); } } } } } // repo curve foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in immProv.RepoCurves.entrySet()) { Pair <RepoGroup, Currency> rgCcy = entry.Key; Currency currency = rgCcy.Second; Curve curve = getCurve(entry.Value); CurveName curveName = curve.Name; if (baseDelta.findSensitivity(curveName, currency).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(curveName, curve, currency, c => replaceRepoCurve(immProv, rgCcy, DiscountFactors.of(currency, valuationDate, c)), sensitivitiesFn); result = result.combinedWith(gammaSingle); } else { ImmutableList <Curve> curves = curve.split(); int nCurves = curves.size(); if (nCurves > 1) { for (int i = 0; i < nCurves; ++i) { int currentIndex = i; Curve underlyingCurve = curves.get(currentIndex); CurveName underlyingCurveName = underlyingCurve.Name; if (baseDelta.findSensitivity(underlyingCurveName, rgCcy.Second).Present) { CrossGammaParameterSensitivity gammaSingle = computeGammaForCurve(underlyingCurveName, underlyingCurve, currency, c => replaceRepoCurve(immProv, rgCcy, DiscountFactors.of(currency, valuationDate, curve.withUnderlyingCurve(currentIndex, c))), sensitivitiesFn); result = result.combinedWith(gammaSingle); } } } } } return(result); }