//------------------------------------------------------------------------- /// <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); }
//------------------------------------------------------------------------- /// <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)); }
//------------------------------------------------------------------------- /// <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)); }