/// <summary>
        /// Calculates the present value of the swaption trade.
        /// <para>
        /// The result is expressed using the currency of the swapion.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter trade </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedSwaption product   = trade.Product;
            CurrencyAmount   pvProduct = PRICER_PRODUCT.presentValue(product, ratesProvider, hwProvider);
            Payment          premium   = trade.Premium;
            CurrencyAmount   pvPremium = PRICER_PREMIUM.presentValue(premium, ratesProvider);

            return(pvProduct.plus(pvPremium));
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Computes the currency exposure of the swaption trade.
 /// </summary>
 /// <param name="trade">  the swaption trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="hwProvider">  the Hull-White model parameter provider </param>
 /// <returns> the currency exposure </returns>
 public virtual MultiCurrencyAmount currencyExposure(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
 {
     return(MultiCurrencyAmount.of(presentValue(trade, ratesProvider, hwProvider)));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption product.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of the present value to
        /// the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivities presentValueSensitivityRates(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedSwaption        product     = trade.Product;
            PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT.presentValueSensitivityRates(product, ratesProvider, hwProvider);
            Payment premium = trade.Premium;
            PointSensitivityBuilder pvcsPremium = PRICER_PREMIUM.presentValueSensitivity(premium, ratesProvider);

            return(pvcsProduct.combinedWith(pvcsPremium).build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity piecewise constant volatility parameters of the Hull-White model.
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value Hull-White model parameter sensitivity of the swaption trade </returns>
        public virtual DoubleArray presentValueSensitivityModelParamsHullWhite(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedSwaption product = trade.Product;

            return(PRICER_PRODUCT.presentValueSensitivityModelParamsHullWhite(product, ratesProvider, hwProvider));
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the price of the Ibor future trade.
 /// <para>
 /// The price of the trade is the price on the valuation date.
 /// The price is calculated using the Hull-White model.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="hwProvider">  the Hull-White model parameter provider </param>
 /// <returns> the price of the trade, in decimal form </returns>
 public virtual double price(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
 {
     return(productPricer.price(trade.Product, ratesProvider, hwProvider));
 }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the price sensitivity of the Ibor future product.
 /// <para>
 /// The price sensitivity of the product is the sensitivity of the price to the underlying curves.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="hwProvider">  the Hull-White model parameter provider </param>
 /// <returns> the price curve sensitivity of the product </returns>
 public virtual PointSensitivities priceSensitivityRates(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
 {
     return(productPricer.priceSensitivityRates(trade.Product, ratesProvider, hwProvider));
 }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the currency exposure of the Ibor future trade.
 /// <para>
 /// Since the Ibor future is based on a single currency, the trade is exposed to only this currency.
 /// </para>
 /// <para>
 /// This method calculates based on the difference between the model price and the
 /// last settlement price, or the trade price if traded on the valuation date.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="provider">  the rates provider </param>
 /// <param name="hwProvider">  the Hull-White model parameter provider </param>
 /// <param name="lastSettlementPrice">  the last settlement price used for margining, in decimal form </param>
 /// <returns> the currency exposure of the trade </returns>
 public virtual MultiCurrencyAmount currencyExposure(ResolvedIborFutureTrade trade, RatesProvider provider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider, double lastSettlementPrice)
 {
     return(MultiCurrencyAmount.of(presentValue(trade, provider, hwProvider, lastSettlementPrice)));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the par spread of the Ibor future trade.
        /// <para>
        /// The par spread is defined in the following way. When the reference price (or market quote)
        /// is increased by the par spread, the present value of the trade is zero.
        /// The current price is calculated using the Hull-White model.
        /// </para>
        /// <para>
        /// This method calculates based on the difference between the model price and the
        /// last settlement price, or the trade price if traded on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <param name="lastSettlementPrice">  the last settlement price used for margining, in decimal form </param>
        /// <returns> the par spread. </returns>
        public virtual double parSpread(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider, double lastSettlementPrice)
        {
            double referencePrice = this.referencePrice(trade, ratesProvider.ValuationDate, lastSettlementPrice);

            return(price(trade, ratesProvider, hwProvider) - referencePrice);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to piecewise constant volatility parameters of the Hull-White model.
        /// </summary>
        /// <param name="trade">  the trade to price </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value parameter sensitivity of the trade </returns>
        public virtual DoubleArray presentValueSensitivityModelParamsHullWhite(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedIborFuture product = trade.Product;
            DoubleArray        hwSensi = productPricer.priceSensitivityModelParamsHullWhite(product, ratesProvider, hwProvider);

            hwSensi = hwSensi.multipliedBy(product.Notional * product.AccrualFactor * trade.Quantity);
            return(hwSensi);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the Ibor future trade.
        /// <para>
        /// The present value sensitivity of the trade is the sensitivity of the present value to
        /// the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value curve sensitivity of the trade </returns>
        public virtual PointSensitivities presentValueSensitivityRates(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedIborFuture product          = trade.Product;
            PointSensitivities priceSensi       = productPricer.priceSensitivityRates(product, ratesProvider, hwProvider);
            PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi);

            return(marginIndexSensi.multipliedBy(trade.Quantity));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the Ibor future trade.
        /// <para>
        /// The present value of the product is the value on the valuation date.
        /// The current price is calculated using the Hull-White model.
        /// </para>
        /// <para>
        /// This method calculates based on the difference between the model price and the
        /// last settlement price, or the trade price if traded on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <param name="lastSettlementPrice">  the last settlement price used for margining, in decimal form </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(ResolvedIborFutureTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider, double lastSettlementPrice)
        {
            double referencePrice = this.referencePrice(trade, ratesProvider.ValuationDate, lastSettlementPrice);
            double price          = this.price(trade, ratesProvider, hwProvider);

            return(presentValue(trade, price, referencePrice));
        }