/// <summary> /// Calculates the margin index sensitivity of the Ibor future product. /// <para> /// The margin index sensitivity if 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="option"> the option product </param> /// <param name="priceSensitivity"> the price sensitivity of the product </param> /// <returns> the index sensitivity </returns> internal virtual PointSensitivities marginIndexSensitivity(ResolvedIborFutureOption option, PointSensitivities priceSensitivity) { double notional = option.UnderlyingFuture.Notional; double accrualFactor = option.UnderlyingFuture.AccrualFactor; return(priceSensitivity.multipliedBy(notional * accrualFactor)); }
/// <summary> /// Calculates the price sensitivity of the Ibor future option product /// based on the price of the underlying future. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// 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 PointSensitivities priceSensitivityRatesStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice) { double delta = deltaStickyStrike(futureOption, ratesProvider, volatilities, futurePrice); PointSensitivities futurePriceSensitivity = futurePricer.priceSensitivity(futureOption.UnderlyingFuture, ratesProvider); return(futurePriceSensitivity.multipliedBy(delta)); }
/// <summary> /// Calculates the price sensitivity of the bond future option product based on the price of the underlying future. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// 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="discountingProvider"> the discounting provider </param> /// <param name="volatilities"> the volatilities </param> /// <param name="futurePrice"> the price of the underlying future </param> /// <returns> the price curve sensitivity of the product </returns> public PointSensitivities priceSensitivityRatesStickyStrike(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { double delta = deltaStickyStrike(futureOption, discountingProvider, volatilities, futurePrice); PointSensitivities futurePriceSensitivity = futurePricer.priceSensitivity(futureOption.UnderlyingFuture, discountingProvider); return(futurePriceSensitivity.multipliedBy(delta)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the Ibor future option 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="volatilities"> the volatilities </param> /// <returns> the present value curve sensitivity of the trade </returns> public PointSensitivities presentValueSensitivityRates(ResolvedIborFutureOptionTrade trade, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities) { ResolvedIborFutureOption product = trade.Product; PointSensitivities priceSensi = futureOptionPricer.priceSensitivityRatesStickyStrike(product, ratesProvider, volatilities); PointSensitivities marginIndexSensi = futureOptionPricer.marginIndexSensitivity(product, priceSensi); return(marginIndexSensi.multipliedBy(trade.Quantity)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the bond future option 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="discountingProvider"> the discounting provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the present value curve sensitivity of the trade </returns> public PointSensitivities presentValueSensitivityRates(ResolvedBondFutureOptionTrade trade, LegalEntityDiscountingProvider discountingProvider, BondFutureVolatilities volatilities) { ResolvedBondFutureOption product = trade.Product; PointSensitivities priceSensi = productPricer.priceSensitivity(product, discountingProvider, volatilities); PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi); return(marginIndexSensi.multipliedBy(trade.Quantity)); }
//------------------------------------------------------------------------- /// <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 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 sensitivity of the bond future trade with z-spread. /// <para> /// The present value sensitivity of the trade is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates /// of the issuer discounting curve. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodPerYear"> the number of periods per year </param> /// <returns> the present value curve sensitivity of the trade </returns> public PointSensitivities presentValueSensitivityWithZSpread(ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { ResolvedBondFuture product = trade.Product; PointSensitivities priceSensi = productPricer.priceSensitivityWithZSpread(product, discountingProvider, zSpread, compoundedRateType, periodPerYear); PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi); return(marginIndexSensi.multipliedBy(trade.Quantity)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the bond 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="discountingProvider"> the discounting provider </param> /// <returns> the present value curve sensitivity of the trade </returns> public PointSensitivities presentValueSensitivity(ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider) { ResolvedBondFuture product = trade.Product; PointSensitivities priceSensi = productPricer.priceSensitivity(product, discountingProvider); PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi); return(marginIndexSensi.multipliedBy(trade.Quantity)); }
//------------------------------------------------------------------------- public virtual void test_marginIndexSensitivity() { double notional = FUTURE.Notional; double accrualFactor = FUTURE.AccrualFactor; PointSensitivities priceSensitivity = PRICER.priceSensitivity(FUTURE, RATES_PROVIDER); PointSensitivities sensiComputed = PRICER.marginIndexSensitivity(FUTURE, priceSensitivity); assertTrue(sensiComputed.equalWithTolerance(priceSensitivity.multipliedBy(accrualFactor * notional), TOL * notional)); }
public virtual void presentValueSensitivity_onFix_nots() { PointSensitivities pv = PRICER_CMS.presentValueSensitivity(COUPON, RATES_PROVIDER_ON_FIX).build(); double df = RATES_PROVIDER_ON_FIX.discountFactor(EUR, PAYMENT); ZeroRateSensitivity dfdr = RATES_PROVIDER_ON_FIX.discountFactors(EUR).zeroRatePointSensitivity(PAYMENT); double forward = PRICER_SWAP.parRate(COUPON.UnderlyingSwap, RATES_PROVIDER_ON_FIX); PointSensitivities forwarddr = PRICER_SWAP.parRateSensitivity(COUPON.UnderlyingSwap, RATES_PROVIDER_ON_FIX).build(); PointSensitivities expected = forwarddr.multipliedBy(df).combinedWith(dfdr.multipliedBy(forward).build()).multipliedBy(NOTIONAL * ACC_FACTOR); assertTrue(pv.equalWithTolerance(expected, TOLERANCE_DELTA)); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivity() { IborIndexRates mockIbor = mock(typeof(IborIndexRates)); SimpleRatesProvider prov = new SimpleRatesProvider(); prov.IborRates = mockIbor; PointSensitivities sensiPrice = PRICER_PRODUCT.priceSensitivity(FUTURE, prov); PointSensitivities sensiPresentValueExpected = sensiPrice.multipliedBy(FUTURE.Notional * FUTURE.AccrualFactor * FUTURE_TRADE.Quantity); PointSensitivities sensiPresentValueComputed = PRICER_TRADE.presentValueSensitivity(FUTURE_TRADE, prov); assertTrue(sensiPresentValueComputed.equalWithTolerance(sensiPresentValueExpected, TOLERANCE_PV_DELTA)); }
// ---------- present value sensitivity ---------- public virtual void presentValueSensitivity_from_env() { IborIndexRates mockIbor = mock(typeof(IborIndexRates)); SimpleRatesProvider prov = new SimpleRatesProvider(); prov.IborRates = mockIbor; when(mockIbor.rate(OPTION.UnderlyingFuture.IborRate.Observation)).thenReturn(RATE); PointSensitivities psProduct = OPTION_PRODUCT_PRICER.priceSensitivityRatesStickyStrike(OPTION, prov, VOL_SIMPLE_MONEY_PRICE); PointSensitivities psExpected = psProduct.multipliedBy(OPTION_PRODUCT_PRICER.marginIndex(OPTION, 1) * OPTION_QUANTITY); PointSensitivities psComputed = OPTION_TRADE_PRICER.presentValueSensitivityRates(FUTURE_OPTION_TRADE, prov, VOL_SIMPLE_MONEY_PRICE); assertTrue(psComputed.equalWithTolerance(psExpected, TOLERANCE_PV_DELTA)); }
public virtual void priceSensitivityStickyStrike_from_env() { IborIndexRates mockIbor = mock(typeof(IborIndexRates)); SimpleRatesProvider prov = new SimpleRatesProvider(); prov.IborRates = mockIbor; when(mockIbor.rate(OPTION.UnderlyingFuture.IborRate.Observation)).thenReturn(RATE); PointSensitivities futurePriceSensitivity = OPTION_PRICER.FuturePricer.priceSensitivity(OPTION.UnderlyingFuture, prov); double delta = OPTION_PRICER.deltaStickyStrike(OPTION, prov, VOL_SIMPLE_MONEY_PRICE); PointSensitivities optionPriceSensitivityExpected = futurePriceSensitivity.multipliedBy(delta); PointSensitivities optionPriceSensitivityComputed = OPTION_PRICER.priceSensitivityRatesStickyStrike(OPTION, prov, VOL_SIMPLE_MONEY_PRICE); assertTrue(optionPriceSensitivityExpected.equalWithTolerance(optionPriceSensitivityComputed, TOLERANCE_PRICE_DELTA)); }
/// <summary> /// Calculates the par spread sensitivity to the curves. /// <para> /// The sensitivity is reported in the counter currency of the product, but is actually dimensionless. /// /// </para> /// </summary> /// <param name="swap"> the product </param> /// <param name="provider"> the rates provider </param> /// <returns> the spread curve sensitivity </returns> public virtual PointSensitivities parSpreadSensitivity(ResolvedFxSwap swap, RatesProvider provider) { Payment counterPaymentNear = swap.NearLeg.CounterCurrencyPayment; MultiCurrencyAmount pv = presentValue(swap, provider); double pvCounterCcy = pv.convertedTo(counterPaymentNear.Currency, provider).Amount; double dfEnd = provider.discountFactor(counterPaymentNear.Currency, swap.FarLeg.PaymentDate); double notionalBaseCcy = swap.NearLeg.BaseCurrencyPayment.Amount; double ps = -pvCounterCcy / (notionalBaseCcy * dfEnd); // backward sweep double psBar = 1d; double pvCounterCcyBar = -1d / (notionalBaseCcy * dfEnd) * psBar; double dfEndBar = -ps / dfEnd * psBar; ZeroRateSensitivity ddfEnddr = provider.discountFactors(counterPaymentNear.Currency).zeroRatePointSensitivity(swap.FarLeg.PaymentDate); PointSensitivities result = ddfEnddr.multipliedBy(dfEndBar).build(); PointSensitivities dpvdr = presentValueSensitivity(swap, provider); PointSensitivities dpvdrConverted = dpvdr.convertedTo(counterPaymentNear.Currency, provider); return(result.combinedWith(dpvdrConverted.multipliedBy(pvCounterCcyBar))); }
/// <summary> /// Calculates the margin index sensitivity of the deliverable swap futures 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 PointSensitivities marginIndexSensitivity(ResolvedDsf future, PointSensitivities priceSensitivity) { return(priceSensitivity.multipliedBy(future.Notional)); }
/// <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 margin index sensitivity of the bond future product. /// <para> /// For two consecutive settlement prices C1 and C2, the daily margin is computed as /// {@code marginIndex(future, C2) - marginIndex(future, C1)}. /// The margin index sensitivity if the sensitivity of the margin index to the underlying curves. /// /// </para> /// </summary> /// <param name="option"> the option product </param> /// <param name="priceSensitivity"> the price sensitivity of the product </param> /// <returns> the index sensitivity </returns> internal PointSensitivities marginIndexSensitivity(ResolvedBondFutureOption option, PointSensitivities priceSensitivity) { double notional = option.UnderlyingFuture.Notional; return(priceSensitivity.multipliedBy(notional)); }