//-------------------------------------------------------------------------
        /// <summary>
        /// Computes the present value sensitivity to the normal volatility used in the pricing.
        /// <para>
        /// The result is a single sensitivity to the volatility used.
        /// The volatility is associated with the expiry/delay/strike/future price key combination.
        /// </para>
        /// <para>
        /// This calculates the underlying future price using the future pricer.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOptionTrade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the price sensitivity </returns>
        public IborFutureOptionSensitivity presentValueSensitivityModelParamsVolatility(ResolvedIborFutureOptionTrade futureOptionTrade, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities)
        {
            ResolvedIborFuture future      = futureOptionTrade.Product.UnderlyingFuture;
            double             futurePrice = futureOptionPricer.FuturePricer.price(future, ratesProvider);

            return(presentValueSensitivityModelParamsVolatility(futureOptionTrade, ratesProvider, volatilities, futurePrice));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price of the Ibor future 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 virtual double price(ResolvedIborFuture future, RatesProvider ratesProvider)
        {
            IborIndexRates rates   = ratesProvider.iborIndexRates(future.Index);
            double         forward = rates.rate(future.IborRate.Observation);

            return(1.0 - forward);
        }
        /// <summary>
        /// Calculates the convexity adjustment (to the price) of the Ibor future product.
        /// <para>
        /// The convexity adjustment of the product is the value on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the convexity adjustment, in decimal form </returns>
        public virtual double convexityAdjustment(ResolvedIborFuture future, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            IborIndexObservation obs = future.IborRate.Observation;
            double forward           = ratesProvider.iborIndexRates(future.Index).rate(obs);
            double parRate           = this.parRate(future, ratesProvider, hwProvider);

            return(forward - parRate);
        }
        //-------------------------------------------------------------------------
        /// <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);
        }
Beispiel #5
0
        //-------------------------------------------------------------------------
        /// <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>
        /// <returns> the present value curve sensitivity of the trade </returns>
        public virtual PointSensitivities presentValueSensitivity(ResolvedIborFutureTrade trade, RatesProvider ratesProvider)
        {
            ResolvedIborFuture product          = trade.Product;
            PointSensitivities priceSensi       = productPricer.priceSensitivity(product, ratesProvider);
            PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi);

            return(marginIndexSensi.multipliedBy(trade.Quantity));
        }
        /// <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="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public virtual PointSensitivities priceSensitivity(ResolvedIborFuture future, RatesProvider ratesProvider)
        {
            IborRateSensitivity sensi = IborRateSensitivity.of(future.IborRate.Observation, -1d);

            // The sensitivity should be to no currency or currency XXX. To avoid useless conversion, the dimension-less
            // price sensitivity is reported in the future currency.
            return(PointSensitivities.of(sensi));
        }
        //-------------------------------------------------------------------------
        /// <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));
        }
Beispiel #8
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the Ibor future trade from the current price.
        /// <para>
        /// The present value of the product is the value on the valuation date.
        /// </para>
        /// <para>
        /// The calculation is performed against a reference price. The reference price
        /// must be the last settlement price used for margining, except on the trade date,
        /// when it must be the trade price.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="currentPrice">  the current price, in decimal form </param>
        /// <param name="referencePrice">  the reference price to margin against, typically the last settlement price, in decimal form </param>
        /// <returns> the present value </returns>
        internal virtual CurrencyAmount presentValue(ResolvedIborFutureTrade trade, double currentPrice, double referencePrice)
        {
            ResolvedIborFuture future         = trade.Product;
            double             priceIndex     = productPricer.marginIndex(future, currentPrice);
            double             referenceIndex = productPricer.marginIndex(future, referencePrice);
            double             pv             = (priceIndex - referenceIndex) * trade.Quantity;

            return(CurrencyAmount.of(future.Currency, pv));
        }
        /// <summary>
        /// Calculates the par rate of the Ibor future product.
        /// <para>
        /// The par rate is given by ({@code 1 - price}).
        /// The par rate of the product is the value on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the par rate of the product, in decimal form </returns>
        public virtual double parRate(ResolvedIborFuture future, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            IborIndexObservation obs     = future.IborRate.Observation;
            double    forward            = ratesProvider.iborIndexRates(future.Index).rate(obs);
            LocalDate fixingStartDate    = obs.EffectiveDate;
            LocalDate fixingEndDate      = obs.MaturityDate;
            double    fixingYearFraction = obs.YearFraction;
            double    convexity          = hwProvider.futuresConvexityFactor(future.LastTradeDate, fixingStartDate, fixingEndDate);

            return(convexity * forward - (1d - convexity) / fixingYearFraction);
        }
        /// <summary>
        /// Calculates the delta of the Ibor future option product
        /// based on the price of the underlying future.
        /// <para>
        /// The delta of the product is the sensitivity of the option price to the future price.
        /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the price of the underlying future, in decimal form </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public virtual double deltaStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");

            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             strike       = futureOption.StrikePrice;
            ResolvedIborFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice);

            return(NormalFormulaRepository.delta(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall));
        }
        /// <summary>
        /// Calculates the price sensitivity to piecewise constant volatility parameters of the Hull-White model.
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the price parameter sensitivity of the product </returns>
        public virtual DoubleArray priceSensitivityModelParamsHullWhite(ResolvedIborFuture future, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            IborIndexObservation obs       = future.IborRate.Observation;
            double      forward            = ratesProvider.iborIndexRates(future.Index).rate(obs);
            LocalDate   fixingStartDate    = obs.EffectiveDate;
            LocalDate   fixingEndDate      = obs.MaturityDate;
            double      fixingYearFraction = obs.YearFraction;
            DoubleArray convexityDeriv     = hwProvider.futuresConvexityFactorAdjoint(future.LastTradeDate, fixingStartDate, fixingEndDate).Derivatives;

            convexityDeriv = convexityDeriv.multipliedBy(-forward - 1d / fixingYearFraction);
            return(convexityDeriv);
        }
        /// <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="future">  the future </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(ResolvedIborFuture future, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            IborIndexObservation obs             = future.IborRate.Observation;
            LocalDate            fixingStartDate = obs.EffectiveDate;
            LocalDate            fixingEndDate   = obs.MaturityDate;
            double convexity          = hwProvider.futuresConvexityFactor(future.LastTradeDate, fixingStartDate, fixingEndDate);
            IborRateSensitivity sensi = IborRateSensitivity.of(obs, -convexity);

            // The sensitivity should be to no currency or currency XXX. To avoid useless conversion, the dimension-less
            // price sensitivity is reported in the future currency.
            return(PointSensitivities.of(sensi));
        }
        /// <summary>
        /// Calculates the price sensitivity to the normal volatility used for the pricing of the Ibor future option
        /// based on the price of the underlying future.
        /// <para>
        /// This sensitivity is also called the <i>price normal vega</i>.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the underlying future price, in decimal form </param>
        /// <returns> the sensitivity </returns>
        public virtual IborFutureOptionSensitivity priceSensitivityModelParamsVolatility(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");

            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             strike       = futureOption.StrikePrice;
            ResolvedIborFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice);

            double vega = NormalFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall);

            return(IborFutureOptionSensitivity.of(volatilities.Name, timeToExpiry, future.LastTradeDate, strike, futurePrice, future.Currency, vega));
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the number related to Ibor futures product on which the daily margin is computed.
 /// <para>
 /// For two consecutive settlement prices C1 and C2, the daily margin is computed as
 ///    {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
 ///
 /// </para>
 /// </summary>
 /// <param name="future">  the future </param>
 /// <param name="price">  the price of the product, in decimal form </param>
 /// <returns> the index </returns>
 internal virtual double marginIndex(ResolvedIborFuture future, double price)
 {
     return(price * future.Notional * future.AccrualFactor);
 }
 /// <summary>
 /// Calculates the margin index sensitivity of the Ibor future product.
 /// <para>
 /// The margin index sensitivity is the sensitivity of the margin index to the underlying curves.
 /// For two consecutive settlement prices C1 and C2, the daily margin is computed as
 ///    {@code (marginIndex(future, C2) - marginIndex(future, C1))}.
 ///
 /// </para>
 /// </summary>
 /// <param name="future">  the future </param>
 /// <param name="priceSensitivity">  the price sensitivity of the product </param>
 /// <returns> the index sensitivity </returns>
 internal virtual PointSensitivities marginIndexSensitivity(ResolvedIborFuture future, PointSensitivities priceSensitivity)
 {
     return(priceSensitivity.multipliedBy(future.Notional * future.AccrualFactor));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price of the Ibor future 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>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the price of the product, in decimal form </returns>
        public virtual double price(ResolvedIborFuture future, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            double parRate = this.parRate(future, ratesProvider, hwProvider);

            return(1d - parRate);
        }
        //-------------------------------------------------------------------------
        // calculate the price of the underlying future
        private double futurePrice(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider)
        {
            ResolvedIborFuture future = futureOption.UnderlyingFuture;

            return(futurePricer.price(future, ratesProvider));
        }