//-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price of the deliverable swap futures product.
        /// <para>
        /// The price of the product is the price on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the price of the product, in decimal form </returns>
        public double price(ResolvedDsf future, RatesProvider ratesProvider)
        {
            ResolvedSwap   swap     = future.UnderlyingSwap;
            Currency       currency = future.Currency;
            CurrencyAmount pvSwap   = swapPricer.presentValue(swap, currency, ratesProvider);
            double         df       = ratesProvider.discountFactor(currency, future.DeliveryDate);

            return(1d + pvSwap.Amount / df);
        }
        public virtual void test_cashFlowEquivalent_pv()
        {
            ResolvedSwap                 swap       = ResolvedSwap.of(IBOR_LEG, FIXED_LEG);
            ResolvedSwapLeg              cfe        = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, PROVIDER);
            DiscountingSwapLegPricer     pricerLeg  = DiscountingSwapLegPricer.DEFAULT;
            DiscountingSwapProductPricer pricerSwap = DiscountingSwapProductPricer.DEFAULT;
            CurrencyAmount               pvCfe      = pricerLeg.presentValue(cfe, PROVIDER);
            MultiCurrencyAmount          pvSwap     = pricerSwap.presentValue(swap, PROVIDER);

            assertEquals(pvCfe.Amount, pvSwap.getAmount(GBP).Amount, TOLERANCE_PV);
        }
        //-------------------------------------------------------------------------
        public virtual void semiParallelGammaValue()
        {
            ImmutableRatesProvider provider = SINGLE;
            Currency    curveCurrency       = SINGLE_CURRENCY;
            DoubleArray y             = USD_SINGLE_CURVE.YValues;
            int         nbNode        = y.size();
            DoubleArray gammaExpected = DoubleArray.of(nbNode, i =>
            {
//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[][][] yBumped = new double[2][2][nbNode];
                double[][][] yBumped = RectangularArrays.ReturnRectangularDoubleArray(2, 2, nbNode);
//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[][] pv = new double[2][2];
                double[][] pv = RectangularArrays.ReturnRectangularDoubleArray(2, 2);
                for (int pmi = 0; pmi < 2; pmi++)
                {
                    for (int pmP = 0; pmP < 2; pmP++)
                    {
                        yBumped[pmi][pmP]     = y.toArray();
                        yBumped[pmi][pmP][i] += (pmi == 0 ? 1.0 : -1.0) * FD_SHIFT;
                        for (int j = 0; j < nbNode; j++)
                        {
                            yBumped[pmi][pmP][j] += (pmP == 0 ? 1.0 : -1.0) * FD_SHIFT;
                        }
                        Curve curveBumped = USD_SINGLE_CURVE.withYValues(DoubleArray.copyOf(yBumped[pmi][pmP]));
                        ImmutableRatesProvider providerBumped = provider.toBuilder().discountCurves(provider.DiscountCurves.Keys.collect(toImmutableMap(Function.identity(), k => curveBumped))).indexCurves(provider.IndexCurves.Keys.collect(toImmutableMap(Function.identity(), k => curveBumped))).build();
                        pv[pmi][pmP] = PRICER_SWAP.presentValue(SWAP, providerBumped).getAmount(USD).Amount;
                    }
                }
                return((pv[1][1] - pv[1][0] - pv[0][1] + pv[0][0]) / (4 * FD_SHIFT * FD_SHIFT));
            });
            CurrencyParameterSensitivity sensitivityComputed = GAMMA_CAL.calculateSemiParallelGamma(USD_SINGLE_CURVE, curveCurrency, c => buildSensitivities(c, provider));

            assertEquals(sensitivityComputed.MarketDataName, USD_SINGLE_CURVE.Name);
            DoubleArray gammaComputed = sensitivityComputed.Sensitivity;

            assertTrue(gammaComputed.equalWithTolerance(gammaExpected, TOLERANCE_GAMMA));
        }