CrossGammaMultiCurveCalculator { public HashMap<String, DoubleMatrix2D> calculateCrossGammaIntraCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve) { ArgumentChecker.notNull(instrument, "instrument"); ArgumentChecker.notNull(multicurve, "multi-curve provider"); Set<String> names = multicurve.getAllNames(); int nbCurve = names.size(); String[] namesArray = names.toArray(new String[nbCurve]); Currency ccy = checkUniqueCurrency(multicurve); InterpolatedDoublesCurve[] interpolatedCurves = interpolatedCurves(multicurve, nbCurve, namesArray); double[][] y = new double[nbCurve][]; double[][] x = new double[nbCurve][]; int[] nbNode = new int[nbCurve]; for (int loopcurve = 0; loopcurve < nbCurve; loopcurve++) { y[loopcurve] = interpolatedCurves[loopcurve].getYDataAsPrimitive(); x[loopcurve] = interpolatedCurves[loopcurve].getXDataAsPrimitive(); nbNode[loopcurve] = x[loopcurve].length; } MultipleCurrencyParameterSensitivity ps0 = _psc.calculateSensitivity(instrument, multicurve); double[][] ps0Array = sensitivitiesAsArrayOfMatrix(nbCurve, namesArray, ccy, nbNode, ps0); HashMap<String, DoubleMatrix2D> result = new HashMap<>(); for (int loopcurve = 0; loopcurve < nbCurve; loopcurve++) { MultipleCurrencyParameterSensitivity[] psShift = new MultipleCurrencyParameterSensitivity[nbNode[loopcurve]]; double[][] gammaArray = new double[nbNode[loopcurve]][nbNode[loopcurve]]; for (int loopnode = 0; loopnode < nbNode[loopcurve]; loopnode++) { final double[] yieldBumped = y[loopcurve].clone(); yieldBumped[loopnode] += _shift; MulticurveProviderDiscount multicurveBumped = bumpedProvider(multicurve, namesArray[loopcurve], interpolatedCurves[loopcurve].getInterpolator(), x[loopcurve], yieldBumped); psShift[loopnode] = _psc.calculateSensitivity(instrument, multicurveBumped); DoubleMatrix1D sensiCurve = psShift[loopnode].getSensitivity(namesArray[loopcurve], ccy); double[] psShiftArray; if (sensiCurve != null) { psShiftArray = sensiCurve.getData(); } else { psShiftArray = new double[nbNode[loopcurve]]; } for (int loopnode2 = 0; loopnode2 < nbNode[loopcurve]; loopnode2++) { gammaArray[loopnode][loopnode2] = (psShiftArray[loopnode2] - ps0Array[loopcurve][loopnode2]) / _shift; } } DoubleMatrix2D gammaMat = new DoubleMatrix2D(gammaArray); result.put(namesArray[loopcurve], gammaMat); } return result; } CrossGammaMultiCurveCalculator(final double shift,
      final InstrumentDerivativeVisitor<ParameterProviderInterface, MultipleCurrencyMulticurveSensitivity> curveSensitivityCalculator);  CrossGammaMultiCurveCalculator(final InstrumentDerivativeVisitor<ParameterProviderInterface, MultipleCurrencyMulticurveSensitivity> curveSensitivityCalculator); HashMap<String, DoubleMatrix2D> calculateCrossGammaIntraCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve); DoubleMatrix2D calculateCrossGammaCrossCurve(final InstrumentDerivative instrument, final MulticurveProviderDiscount multicurve);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void multicurrencies() { MulticurveProviderDiscount multicurveMulticcy = StandardDataSetsEURUSDForex.getCurvesEUROisUSDOis().getFirst(); CGC.calculateCrossGammaIntraCurve(SWAP_FIXED_IBOR, multicurveMulticcy); }
@Test public void crossGammaCrossCurveIrs() { final SwapFixedCoupon<Coupon> swap = SWAP_FIXED_IBOR_DEFINITION.toDerivative(CALIBRATION_DATE); HashMap<String, DoubleMatrix2D> gammaIntraCurve = CGC.calculateCrossGammaIntraCurve(swap, MULTICURVE); Set<String> names = MULTICURVE.getAllNames(); int submatrixsize = 0; for (String name : names) { DoubleMatrix2D gamma = gammaIntraCurve.get(name); YieldAndDiscountCurve curve = MULTICURVE.getCurve(name); ArgumentChecker.isTrue(curve instanceof YieldCurve, "curve should be YieldCurve"); YieldCurve yieldCurve = (YieldCurve) curve; ArgumentChecker.isTrue(yieldCurve.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve"); InterpolatedDoublesCurve interpolatedCurve = (InterpolatedDoublesCurve) yieldCurve.getCurve(); int nbNode = interpolatedCurve.getXDataAsPrimitive().length; for (int i = 0; i < nbNode; i++) { for (int j = 0; j < nbNode; j++) { double ic = gamma.getEntry(i, j); double cc = GAMMA_CROSS_CURVES.getEntry(submatrixsize + i, submatrixsize + j); assertTrue("CrossGammaMultiCurveCalculator - cross-gamma cross-curves - " + i + " - " + j + " / " + ic + " - " + cc, (Math.abs(ic / cc - 1) < TOLERANCE_PV_GAMMA_RELATIF) || (Math.abs(ic - cc) < TOLERANCE_PV_GAMMA)); } } submatrixsize += nbNode; } }