/** * Calculates the delta of the bond future option product based on the price of the underlying future. * <p> * 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. * * @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 double deltaStickyStrike( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.getPremiumStyle().equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.getStrikePrice(); ResolvedBondFuture future = futureOption.getUnderlyingFuture(); double volatility = volatilities.volatility(futureOption.getExpiry(), future.getLastTradeDate(), strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.getExpiry()); double delta = BlackFormulaRepository.delta( futurePrice, strike, timeToExpiry, volatility, futureOption.getPutCall().isCall()); return delta; }
public void test_getters() { ResolvedBondFutureOption test = sut(); assertEquals(test.getExpiryDate(), test.getExpiry().toLocalDate()); }
@Override public ResolvedBondFutureOption build() { return new ResolvedBondFutureOption( securityId, putCall, strikePrice, expiry, premiumStyle, rounding, underlyingFuture); }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(ResolvedBondFutureOption beanToCopy) { this.securityId = beanToCopy.getSecurityId(); this.putCall = beanToCopy.getPutCall(); this.strikePrice = beanToCopy.getStrikePrice(); this.expiry = beanToCopy.getExpiry(); this.premiumStyle = beanToCopy.getPremiumStyle(); this.rounding = beanToCopy.getRounding(); this.underlyingFuture = beanToCopy.getUnderlyingFuture(); }
public void test_delta() { double computed = OPTION_PRICER.deltaStickyStrike(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, 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 vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.delta(futurePrice, strike, expiryTime, vol, true); assertEquals(computed, expected, TOL); }
public void test_price_from_future_price() { double futurePrice = 1.1d; double computed = OPTION_PRICER.price(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS, futurePrice); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.price(futurePrice, strike, expiryTime, vol, true); assertEquals(computed, expected, TOL); }
/** * Calculates the number related to bond futures product on which the daily margin is computed. * <p> * For two consecutive settlement prices C1 and C2, the daily margin is computed as * {@code marginIndex(future, C2) - marginIndex(future, C1)}. * * @param option the option product * @param price the price of the product, in decimal form * @return the index */ double marginIndex(ResolvedBondFutureOption option, double price) { double notional = option.getUnderlyingFuture().getNotional(); return price * notional; }
/** * Calculates the price sensitivity of the bond future option product based on curves. * <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. * <p> * This calculates the underlying future price using the future pricer. * * @param futureOption the option product * @param discountingProvider the discounting provider * @param volatilities the volatilities * @return the price curve sensitivity of the product */ public PointSensitivities priceSensitivityRatesStickyStrike( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities) { ArgChecker.isTrue(futureOption.getPremiumStyle().equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double futurePrice = futurePrice(futureOption, discountingProvider); return priceSensitivityRatesStickyStrike(futureOption, discountingProvider, volatilities, futurePrice); }
public void test_resolve() { BondFutureOption test = sut(); ResolvedBondFutureOption expected = ResolvedBondFutureOption.builder() .securityId(SECURITY_ID) .putCall(CALL) .strikePrice(STRIKE_PRICE) .expiry(EXPIRY_DATE.atTime(EXPIRY_TIME).atZone(EXPIRY_ZONE)) .premiumStyle(FutureOptionPremiumStyle.DAILY_MARGIN) .underlyingFuture(FUTURE.resolve(REF_DATA)) .build(); assertEquals(test.resolve(REF_DATA), expected); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 1574023291: // securityId return ((ResolvedBondFutureOption) bean).getSecurityId(); case -219971059: // putCall return ((ResolvedBondFutureOption) bean).getPutCall(); case 50946231: // strikePrice return ((ResolvedBondFutureOption) bean).getStrikePrice(); case -1289159373: // expiry return ((ResolvedBondFutureOption) bean).getExpiry(); case -1257652838: // premiumStyle return ((ResolvedBondFutureOption) bean).getPremiumStyle(); case -142444: // rounding return ((ResolvedBondFutureOption) bean).getRounding(); case -165476480: // underlyingFuture return ((ResolvedBondFutureOption) bean).getUnderlyingFuture(); } return super.propertyGet(bean, propertyName, quiet); }
public void test_gamma() { double computed = OPTION_PRICER.gammaStickyStrike(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, 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 vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.gamma(futurePrice, strike, expiryTime, vol); assertEquals(computed, expected, TOL); }
public void test_delta_from_future_price() { double futurePrice = 1.1d; double computed = OPTION_PRICER.deltaStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS, futurePrice); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.delta(futurePrice, strike, expiryTime, vol, true); assertEquals(computed, expected, TOL); }
private double futurePrice(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider) { ResolvedBondFuture future = futureOption.getUnderlyingFuture(); return futurePricer.price(future, discountingProvider); }
/** * Calculates the gamma of the bond future option product based on the price of the underlying future. * <p> * The gamma of the product is the sensitivity of the option delta to the future price. * 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 double gammaStickyStrike( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.getPremiumStyle().equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.getStrikePrice(); ResolvedBondFuture future = futureOption.getUnderlyingFuture(); double volatility = volatilities.volatility(futureOption.getExpiry(), future.getLastTradeDate(), strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.getExpiry()); double gamma = BlackFormulaRepository.gamma(futurePrice, strike, timeToExpiry, volatility); return gamma; }
public void test_theta() { double computed = OPTION_PRICER.theta(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, 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 vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.driftlessTheta(futurePrice, strike, expiryTime, vol); assertEquals(computed, expected, TOL); }
public void test_gamma_from_future_price() { double futurePrice = 1.1d; double computed = OPTION_PRICER.gammaStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS, futurePrice); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.gamma(futurePrice, strike, expiryTime, vol); assertEquals(computed, expected, TOL); }
/** * Calculates the margin index sensitivity of the bond future product. * <p> * 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. * * @param option the option product * @param priceSensitivity the price sensitivity of the product * @return the index sensitivity */ PointSensitivities marginIndexSensitivity(ResolvedBondFutureOption option, PointSensitivities priceSensitivity) { double notional = option.getUnderlyingFuture().getNotional(); return priceSensitivity.multipliedBy(notional); }
@Override public ResolvedBondFutureOption resolve(ReferenceData refData) { ResolvedBondFuture resolved = underlyingFuture.resolve(refData); return new ResolvedBondFutureOption(securityId, putCall, strikePrice, getExpiry(), premiumStyle, rounding, resolved); }
/** * Calculates the theta of the bond future option product based on the price of the underlying future. * <p> * The theta of the product is minus of the option price sensitivity to the time to expiry. * 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 double theta( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.getPremiumStyle().equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.getStrikePrice(); ResolvedBondFuture future = futureOption.getUnderlyingFuture(); double volatility = volatilities.volatility(futureOption.getExpiry(), future.getLastTradeDate(), strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.getExpiry()); double theta = BlackFormulaRepository.driftlessTheta(futurePrice, strike, timeToExpiry, volatility); return theta; }
public void test_price() { double computed = OPTION_PRICER.price(FUTURE_OPTION_PRODUCT, RATE_PROVIDER, 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 vol = SURFACE.zValue(expiryTime, logMoneyness); double expected = BlackFormulaRepository.price(futurePrice, strike, expiryTime, vol, true); assertEquals(computed, expected, TOL); }