/** * Calculates the convexity from the conventional real yield using finite difference approximation. * <p> * The convexity is defined as the second derivative of clean price with respect to yield, divided by the clean price. * <p> * The clean price here is real price or nominal price depending on the yield convention. This is coherent to * the implementation of {@link #dirtyPriceFromRealYield(ResolvedCapitalIndexedBond, RatesProvider, LocalDate, double)}. * <p> * The input yield and output are expressed in fraction. * * @param bond the product * @param ratesProvider the rates provider, used to determine price index values * @param settlementDate the settlement date * @param yield the yield * @return the covexity of the product */ public double convexityFromRealYieldFiniteDifference( ResolvedCapitalIndexedBond bond, RatesProvider ratesProvider, LocalDate settlementDate, double yield) { double price = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield); double priceplus = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield + FD_EPS); double priceminus = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield - FD_EPS); return (priceplus - 2 * price + priceminus) / (price * FD_EPS * FD_EPS); }
/** * Calculates the modified duration from the conventional real yield using finite difference approximation. * <p> * The modified duration is defined as the minus of the first derivative of clean price with respect to yield, * divided by the clean price. * <p> * The clean price here is real price or nominal price depending on the yield convention. This is coherent to * the implementation of {@link #dirtyPriceFromRealYield(ResolvedCapitalIndexedBond, RatesProvider, LocalDate, double)}. * <p> * The input yield and output are expressed in fraction. * * @param bond the product * @param ratesProvider the rates provider, used to determine price index values * @param settlementDate the settlement date * @param yield the yield * @return the modified duration of the product */ public double modifiedDurationFromRealYieldFiniteDifference( ResolvedCapitalIndexedBond bond, RatesProvider ratesProvider, LocalDate settlementDate, double yield) { double price = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield); double priceplus = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield + FD_EPS); double priceminus = cleanPriceFromRealYield(bond, ratesProvider, settlementDate, yield - FD_EPS); return -0.5 * (priceplus - priceminus) / (price * FD_EPS); }
public void test_modifiedDuration_convexity_ukGov() { double eps = 1.0e-5; LocalDate standardSettle = PRODUCT_GOV.getSettlementDateOffset().adjust(VAL_DATE_GB, REF_DATA); double mdComputed = PRICER.modifiedDurationFromRealYieldFiniteDifference(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV); double cvComputed = PRICER.convexityFromRealYieldFiniteDifference(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV); double price = PRICER.cleanPriceFromRealYield(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV); double up = PRICER.cleanPriceFromRealYield(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV + eps); double dw = PRICER.cleanPriceFromRealYield(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV - eps); assertEquals(mdComputed, 0.5 * (dw - up) / eps / price, eps); assertEquals(cvComputed, (up + dw - 2d * price) / price / eps / eps, eps); }
public void test_modifiedDuration_convexity_ukCor() { double eps = 1.0e-5; LocalDate standardSettle = PRODUCT_CORP.getSettlementDateOffset().adjust(VAL_DATE_GB, REF_DATA); double mdComputed = PRICER.modifiedDurationFromRealYieldFiniteDifference(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP); double cvComputed = PRICER.convexityFromRealYieldFiniteDifference(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP); double price = PRICER.cleanPriceFromRealYield(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP); double up = PRICER.cleanPriceFromRealYield(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP + eps); double dw = PRICER.cleanPriceFromRealYield(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP - eps); assertEquals(mdComputed, 0.5 * (dw - up) / eps / price, eps); assertEquals(cvComputed, (up + dw - 2d * price) / price / eps / eps, eps); }
public void test_modifiedDuration_convexity_us() { double eps = 1.0e-5; LocalDate standardSettle = PRODUCT_US.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double mdComputed = PRICER.modifiedDurationFromRealYieldFiniteDifference(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US); double cvComputed = PRICER.convexityFromRealYieldFiniteDifference(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US); double price = PRICER.cleanPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US); double up = PRICER.cleanPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US + eps); double dw = PRICER.cleanPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US - eps); assertEquals(mdComputed, 0.5 * (dw - up) / eps / price, eps); assertEquals(cvComputed, (up + dw - 2d * price) / price / eps / eps, eps); }
public void test_modifiedDuration_convexity_jpw() { double eps = 1.0e-5; LocalDate standardSettle = PRODUCT_JPW.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double mdComputed = PRICER.modifiedDurationFromRealYieldFiniteDifference(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW); double cvComputed = PRICER.convexityFromRealYieldFiniteDifference(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW); double price = PRICER.cleanPriceFromRealYield(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW); double up = PRICER.cleanPriceFromRealYield(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW + eps); double dw = PRICER.cleanPriceFromRealYield(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW - eps); assertEquals(mdComputed, 0.5 * (dw - up) / eps / price, eps); assertEquals(cvComputed, (up + dw - 2d * price) / price / eps / eps, eps); }
public void test_modifiedDuration_convexity_jpi() { double eps = 1.0e-5; LocalDate standardSettle = PRODUCT_JPI.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double mdComputed = PRICER.modifiedDurationFromRealYieldFiniteDifference(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI); double cvComputed = PRICER.convexityFromRealYieldFiniteDifference(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI); double price = PRICER.cleanPriceFromRealYield(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI); double up = PRICER.cleanPriceFromRealYield(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI + eps); double dw = PRICER.cleanPriceFromRealYield(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI - eps); assertEquals(mdComputed, 0.5 * (dw - up) / eps / price, eps); assertEquals(cvComputed, (up + dw - 2d * price) / price / eps / eps, eps); }
public void test_priceFromRealYield_us() { LocalDate standardSettle = PRODUCT_US.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double computed = PRICER.cleanPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US); assertEquals(computed, 1.06, 1.e-2); double computedSmall = PRICER.cleanPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, 0.0); assertEquals(computedSmall, 1.05, 1.e-2); double dirtyPrice = PRICER.dirtyPriceFromRealYield(PRODUCT_US, RATES_PROVS_US, standardSettle, YIELD_US); double cleanPrice = PRICER.cleanRealPriceFromDirtyRealPrice(PRODUCT_US, standardSettle, dirtyPrice); assertEquals(computed, cleanPrice); double yieldRe = PRICER.realYieldFromDirtyPrice(PRODUCT_US, RATES_PROVS_US, standardSettle, dirtyPrice); assertEquals(yieldRe, YIELD_US, TOL); }
public void test_priceFromRealYield_ukCorp() { LocalDate standardSettle = PRODUCT_CORP.getSettlementDateOffset().adjust(VAL_DATE_GB, REF_DATA); double computed = PRICER.cleanPriceFromRealYield(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP); assertEquals(computed, 1.39, 1.e-2); double computedOnePeriod = PRICER.cleanPriceFromRealYield( PRODUCT_CORP, RATES_PROVS_GB, LocalDate.of(2039, 12, 1), -0.02842); assertEquals(computedOnePeriod, 1.01, 1.e-2); double dirtyPrice = PRICER.dirtyPriceFromRealYield(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, YIELD_CORP); double cleanPrice = PRICER.cleanRealPriceFromDirtyRealPrice(PRODUCT_CORP, standardSettle, dirtyPrice); assertEquals(computed, cleanPrice); double yieldRe = PRICER.realYieldFromDirtyPrice(PRODUCT_CORP, RATES_PROVS_GB, standardSettle, dirtyPrice); assertEquals(yieldRe, YIELD_CORP, TOL); }
public void test_priceFromRealYield_ukGov() { LocalDate standardSettle = PRODUCT_GOV.getSettlementDateOffset().adjust(VAL_DATE_GB, REF_DATA); double computed = PRICER.cleanPriceFromRealYield(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV); assertEquals(computed, 3.60, 1.e-2); double computedOnePeriod = PRICER.cleanPriceFromRealYield(PRODUCT_GOV_OP, RATES_PROVS_GB, PRODUCT_GOV_OP .getSettlementDateOffset().adjust(VAL_DATE_GB, REF_DATA), YIELD_GOV_OP); assertEquals(computedOnePeriod, 3.21, 4.e-2); double dirtyPrice = PRICER.dirtyPriceFromRealYield(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, YIELD_GOV); double cleanPrice = PRICER.cleanNominalPriceFromDirtyNominalPrice( PRODUCT_GOV, RATES_PROVS_GB, standardSettle, dirtyPrice); assertEquals(computed, cleanPrice); double yieldRe = PRICER.realYieldFromDirtyPrice(PRODUCT_GOV, RATES_PROVS_GB, standardSettle, dirtyPrice); assertEquals(yieldRe, YIELD_GOV, TOL); }
public void test_priceFromRealYield_jpw() { LocalDate standardSettle = PRODUCT_JPW.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double computed = PRICER.cleanPriceFromRealYield(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW); assertEquals(computed, 1.10, 1.e-2); double dirtyPrice = PRICER.dirtyPriceFromRealYield(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, YIELD_JPW); double cleanPrice = PRICER.cleanRealPriceFromDirtyRealPrice(PRODUCT_JPW, standardSettle, dirtyPrice); assertEquals(computed, cleanPrice); double yieldRe = PRICER.realYieldFromDirtyPrice(PRODUCT_JPW, RATES_PROVS_JP, standardSettle, dirtyPrice); assertEquals(yieldRe, YIELD_JPW, TOL); }
public void test_priceFromRealYield_jpi() { LocalDate standardSettle = PRODUCT_JPI.getSettlementDateOffset().adjust(VAL_DATE, REF_DATA); double computed = PRICER.cleanPriceFromRealYield(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI); assertEquals(computed, 1.04, 1.e-2); double dirtyPrice = PRICER.dirtyPriceFromRealYield(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, YIELD_JPI); double cleanPrice = PRICER.cleanRealPriceFromDirtyRealPrice(PRODUCT_JPI, standardSettle, dirtyPrice); assertEquals(computed, cleanPrice); double yieldRe = PRICER.realYieldFromDirtyPrice(PRODUCT_JPI, RATES_PROVS_JP, standardSettle, dirtyPrice); assertEquals(yieldRe, YIELD_JPI, TOL); }