private double futurePrice(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider) { ResolvedBondFuture future = futureOption.getUnderlyingFuture(); return futurePricer.price(future, discountingProvider); }
/** * Calculates the present value sensitivity of the bond future trade. * <p> * The present value sensitivity of the trade is the sensitivity of the present value to * the underlying curves. * * @param trade the trade * @param discountingProvider the discounting provider * @return the present value curve sensitivity of the trade */ public PointSensitivities presentValueSensitivity( ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider) { ResolvedBondFuture product = trade.getProduct(); PointSensitivities priceSensi = productPricer.priceSensitivity(product, discountingProvider); PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi); return marginIndexSensi.multipliedBy(trade.getQuantity()); }
/** * Calculates the present value sensitivity of the bond future trade with z-spread. * <p> * The present value sensitivity of the trade is the sensitivity of the present value to * the underlying curves. * <p> * The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates * of the issuer discounting curve. * * @param trade the trade * @param discountingProvider the discounting provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodPerYear the number of periods per year * @return the present value curve sensitivity of the trade */ public PointSensitivities presentValueSensitivityWithZSpread( ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { ResolvedBondFuture product = trade.getProduct(); PointSensitivities priceSensi = productPricer.priceSensitivityWithZSpread(product, discountingProvider, zSpread, compoundedRateType, periodPerYear); PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi); return marginIndexSensi.multipliedBy(trade.getQuantity()); }
public void test_priceSensitivity() { PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) -> CurrencyAmount.of(USD, FUTURE_PRICER.price(FUTURE_PRODUCT, (p)))); assertTrue(computed.equalWithTolerance(expected, EPS * 10.0)); }
public void test_priceSensitivityWithZSpread_periodic() { PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread( FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) -> CurrencyAmount.of( USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, PERIODIC, PERIOD_PER_YEAR))); assertTrue(computed.equalWithTolerance(expected, EPS * 10.0)); }
/** * Calculates the price of the bond future trade with z-spread. * <p> * The price of the trade is the price on the valuation date. * <p> * The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates * of the issuer discounting curve. * * @param trade the trade * @param discountingProvider the discounting provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodPerYear the number of periods per year * @return the price of the trade, in decimal form */ public double priceWithZSpread( ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { return productPricer.priceWithZSpread(trade.getProduct(), discountingProvider, zSpread, compoundedRateType, periodPerYear); }
/** * Calculates the par spread sensitivity of the bond future trade. * <p> * The par spread sensitivity of the trade is the sensitivity of the par spread to * the underlying curves. * * @param trade the trade * @param discountingProvider the discounting provider * @return the par spread curve sensitivity of the trade */ public PointSensitivities parSpreadSensitivity( ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider) { return productPricer.priceSensitivity(trade.getProduct(), discountingProvider); }
/** * Calculates the par spread sensitivity of the bond future trade with z-spread. * <p> * The par spread sensitivity of the trade is the sensitivity of the par spread to * the underlying curves. * <p> * The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates * of the issuer discounting curve. * * @param trade the trade * @param discountingProvider the discounting provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodPerYear the number of periods per year * @return the par spread curve sensitivity of the trade */ public PointSensitivities parSpreadSensitivityWithZSpread( ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { return productPricer.priceSensitivityWithZSpread( trade.getProduct(), discountingProvider, zSpread, compoundedRateType, periodPerYear); }
/** * Calculates the present value of the bond future trade from the current price. * <p> * The present value of the product is the value on the valuation date. * <p> * 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. * * @param trade the trade * @param currentPrice the price on the valuation date * @param referencePrice the price with respect to which the margining should be done * @return the present value */ CurrencyAmount presentValue(ResolvedBondFutureTrade trade, double currentPrice, double referencePrice) { ResolvedBondFuture future = trade.getProduct(); double priceIndex = productPricer.marginIndex(future, currentPrice); double referenceIndex = productPricer.marginIndex(future, referencePrice); double pv = (priceIndex - referenceIndex) * trade.getQuantity(); return CurrencyAmount.of(future.getCurrency(), pv); }
public void regression() { double price = FUTURE_PRICER.price(FUTURE_PRODUCT, PROVIDER); assertEquals(price, 1.2106928633440506, TOL); PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER); CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point); DoubleArray expectedIssuer = DoubleArray.of( -3.940585873921608E-4, -0.004161527192990392, -0.014331606019672717, -1.0229665443857998, -4.220553063715371, 0); DoubleArray actualIssuer = test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity(); assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL)); DoubleArray expectedRepo = DoubleArray.of(0.14752541809405412, 0.20907575809356016, 0.0, 0.0, 0.0, 0.0); DoubleArray actualRepo = test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity(); assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL)); }
public void test_priceSensitivityWithZSpread_continuous() { PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread( FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) -> CurrencyAmount.of(USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, CONTINUOUS, 0))); assertTrue(computed.equalWithTolerance(expected, EPS * 10.0)); }
public void regression_withZSpread_continuous() { double price = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0); assertEquals(price, 1.1718691843665354, TOL); // curve parameter sensitivity is not supported for continuous z-spread in 2.x. }
/** * Calculates the price sensitivity of the bond future option product based on the price of the underlying future. * <p> * 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. * * @param futureOption the option product * @param discountingProvider the discounting provider * @param volatilities the volatilities * @param futurePrice the price of the underlying future * @return the price curve sensitivity of the product */ public PointSensitivities priceSensitivityRatesStickyStrike( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { double delta = deltaStickyStrike(futureOption, discountingProvider, volatilities, futurePrice); PointSensitivities futurePriceSensitivity = futurePricer.priceSensitivity(futureOption.getUnderlyingFuture(), discountingProvider); return futurePriceSensitivity.multipliedBy(delta); }
public void test_presentValueSensitivity() { PointSensitivities point = OPTION_TRADE_PRICER.presentValueSensitivityRates(OPTION_TRADE, RATE_PROVIDER, VOLS); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); double futurePrice = FUTURE_PRICER.price(OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER); double strike = OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double logMoneynessUp = Math.log(strike / (futurePrice + EPS)); double logMoneynessDw = Math.log(strike / (futurePrice - EPS)); double vol = SURFACE.zValue(expiryTime, logMoneyness); double volUp = SURFACE.zValue(expiryTime, logMoneynessUp); double volDw = SURFACE.zValue(expiryTime, logMoneynessDw); double volSensi = 0.5 * (volUp - volDw) / EPS; double vega = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol); CurrencyParameterSensitivities sensiVol = RATE_PROVIDER.parameterSensitivity( FUTURE_PRICER.priceSensitivity(OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER)) .multipliedBy(-vega * volSensi * NOTIONAL * QUANTITY); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> OPTION_TRADE_PRICER.presentValue(OPTION_TRADE, (p), VOLS, REFERENCE_PRICE)); assertTrue(computed.equalWithTolerance(expected.combinedWith(sensiVol), 30d * EPS * NOTIONAL * QUANTITY)); }
/** * Calculates the price of the bond future trade. * <p> * The price of the trade is the price on the valuation date. * <p> * Strata uses <i>decimal prices</i> for bond futures. This is coherent with the pricing of {@link FixedCouponBond}. * For example, a price of 99.32% is represented in Strata by 0.9932. * * @param trade the trade * @param discountingProvider the discounting provider * @return the price of the trade, in decimal form */ public double price(ResolvedBondFutureTrade trade, LegalEntityDiscountingProvider discountingProvider) { return productPricer.price(trade.getProduct(), discountingProvider); }
public void regression_withZSpread_periodic() { double price = FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); assertEquals(price, 1.1720190529653407, TOL); PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point); DoubleArray expectedIssuer = DoubleArray.of( -3.9201229100932256E-4, -0.0041367134351306374, -0.014173323438217467, -0.9886444827927878, -4.07533109609094, 0); DoubleArray actualIssuer = test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity(); assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL)); DoubleArray expectedRepo = DoubleArray.of(0.1428352116441475, 0.20242871054203687, 0.0, 0.0, 0.0, 0.0); DoubleArray actualRepo = test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity(); assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL)); }
public void test_parSpreadWithZSpread_periodic() { double computed = TRADE_PRICER.parSpreadWithZSpread( FUTURE_TRADE, PROVIDER, SETTLE_PRICE, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); double expected = PRODUCT_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR) - SETTLE_PRICE; assertEquals(computed, expected, TOL); }
public void test_priceSensitivity_from_future_price() { double futurePrice = 1.1d; PointSensitivities point = OPTION_PRICER.priceSensitivityRatesStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS, futurePrice); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); double delta = OPTION_PRICER.deltaStickyStrike(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS, futurePrice); CurrencyParameterSensitivities expected = RATE_PROVIDER.parameterSensitivity( FUTURE_PRICER.priceSensitivity(FUTURE_OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER)).multipliedBy(delta); assertTrue(computed.equalWithTolerance(expected, TOL)); }
public void test_priceSensitivity() { PointSensitivities point = OPTION_PRICER.priceSensitivityRatesStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> CurrencyAmount.of(EUR, OPTION_PRICER.price(FUTURE_OPTION_PRODUCT, (p), VOLS))); double futurePrice = FUTURE_PRICER.price(FUTURE_OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double logMoneynessUp = Math.log(strike / (futurePrice + EPS)); double logMoneynessDw = Math.log(strike / (futurePrice - EPS)); double vol = SURFACE.zValue(expiryTime, logMoneyness); double volUp = SURFACE.zValue(expiryTime, logMoneynessUp); double volDw = SURFACE.zValue(expiryTime, logMoneynessDw); double volSensi = 0.5 * (volUp - volDw) / EPS; double vega = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol); CurrencyParameterSensitivities sensiVol = RATE_PROVIDER.parameterSensitivity( FUTURE_PRICER.priceSensitivity(FUTURE_OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER)).multipliedBy( -vega * volSensi); expected = expected.combinedWith(sensiVol); assertTrue(computed.equalWithTolerance(expected, 30d * EPS)); }
public void test_price() { double computed = TRADE_PRICER.price(FUTURE_TRADE, PROVIDER); double expected = PRODUCT_PRICER.price(FUTURE_PRODUCT, PROVIDER); assertEquals(computed, expected, TOL); }