BondCapitalIndexedSecurityDiscountingMethod { public double dirtyPriceFromRealYield(final BondCapitalIndexedSecurity<?> bond, final double yield) { Validate.isTrue(bond.getNominal().getNumberOfPayments() == 1, "Yield: more than one nominal repayment."); final int nbCoupon = bond.getCoupon().getNumberOfPayments(); final YieldConvention yieldConvention = bond.getYieldConvention(); if (yieldConvention.equals(US_IL_REAL)) { double pvAtFirstCoupon; if (Math.abs(yield) > 1.0E-8) { final double factorOnPeriod = 1 + yield / bond.getCouponPerYear(); final double vn = Math.pow(factorOnPeriod, 1 - nbCoupon); pvAtFirstCoupon = ((CouponInflationGearing) bond.getCoupon().getNthPayment(0)).getFactor() / yield * (factorOnPeriod - vn) + vn; } else { pvAtFirstCoupon = ((CouponInflationGearing) bond.getCoupon().getNthPayment(0)).getFactor() / bond.getCouponPerYear() * nbCoupon + 1; } return pvAtFirstCoupon / (1 + bond.getAccrualFactorToNextCoupon() * yield / bond.getCouponPerYear()); } if (yieldConvention.equals(INDEX_LINKED_FLOAT)) { final double realRate = ((CouponInflationGearing) bond.getCoupon().getNthPayment(1)).getFactor(); final double firstYearFraction = bond.getCoupon().getNthPayment(0).getPaymentYearFraction(); double firstCouponEndFixingTime = 0.0; double firstCouponPayementTime = 0.0; if (bond.getCoupon().getNthPayment(1) instanceof CouponInflationZeroCouponInterpolationGearing) { firstCouponEndFixingTime = ((CouponInflationZeroCouponInterpolationGearing) bond.getCoupon().getNthPayment(1)).getReferenceEndTime()[1]; firstCouponPayementTime = ((CouponInflationZeroCouponInterpolationGearing) bond.getCoupon().getNthPayment(1)).getPaymentTime(); } else if (bond.getCoupon().getNthPayment(1) instanceof CouponInflationZeroCouponMonthlyGearing) { firstCouponEndFixingTime = ((CouponInflationZeroCouponMonthlyGearing) bond.getCoupon().getNthPayment(1)).getReferenceEndTime(); firstCouponPayementTime = ((CouponInflationZeroCouponMonthlyGearing) bond.getCoupon().getNthPayment(1)).getPaymentTime(); } final double lag = firstCouponPayementTime - firstCouponEndFixingTime; final double v = 1 / (1 + yield / bond.getCouponPerYear()); final double rpibase = bond.getIndexStartValue(); final double rpiLast = bond.getLastIndexKnownFixing(); final double indexRatio = rpiLast / rpibase; final int nbMonth = (int) Math.max(Math.round((bond.getLastKnownFixingTime() - bond.getCoupon().getNthPayment(0).getPaymentTime() + lag) * 12), 0.0); final double u = Math.pow(1 / (1 + .03), .5); final double a = indexRatio * Math.pow(u, 2.0 * nbMonth / 12.0); final double firstCashFlow = firstYearFraction * realRate * indexRatio; if (bond.getCoupon().getNumberOfPayments() == 1) { return Math.pow(u * v, bond.getAccrualFactorToNextCoupon()) * (firstCashFlow + 1) * a / u; } else { final double secondYearFraction = bond.getCoupon().getNthPayment(1).getPaymentYearFraction(); final double secondCashFlow = secondYearFraction * realRate * indexRatio; final double vn = Math.pow(v, nbCoupon - 1); final double pvAtFirstCoupon = firstCashFlow + secondCashFlow * u * v + a * realRate * v * v * (1 - vn / v) / (1 - v) + a * vn; return pvAtFirstCoupon * Math.pow(u * v, bond.getRatioPeriodToNextCoupon()); } } if (yieldConvention.equals(UK_IL_BOND)) { final double firstYearFraction = bond.getCoupon().getNthPayment(0).getPaymentYearFraction(); final double realRate = ((CouponInflationGearing) bond.getCoupon().getNthPayment(1)).getFactor(); final double firstCashFlow = firstYearFraction * realRate; final double v = 1 / (1 + yield / bond.getCouponPerYear()); if (bond.getCoupon().getNumberOfPayments() == 1) { return Math.pow(v, bond.getAccrualFactorToNextCoupon()) * (firstCashFlow + 1); } else { final double secondYearFraction = bond.getCoupon().getNthPayment(1).getPaymentYearFraction(); final double secondCashFlow = secondYearFraction * realRate; final double vn = Math.pow(v, nbCoupon - 1); final double pvAtFirstCoupon = firstCashFlow + secondCashFlow * v + realRate * v * v * (1 - vn / v) / (1 - v) + vn; return pvAtFirstCoupon * Math.pow(v, bond.getAccrualFactorToNextCoupon()); } } throw new UnsupportedOperationException("The convention " + bond.getYieldConvention().getName() + " is not supported."); }  static BondCapitalIndexedSecurityDiscountingMethod getInstance(); MultipleCurrencyAmount presentValue(final BondCapitalIndexedSecurity<?> bond, 
      final ParameterInflationIssuerProviderInterface provider); MultipleCurrencyAmount presentValueFromCleanRealPrice(final BondCapitalIndexedSecurity<?> bond, 
      final InflationIssuerProviderInterface market, final double cleanPriceReal); MultipleCurrencyAmount presentValueFromCleanNominalPrice(final BondCapitalIndexedSecurity<?> bond, 
      final InflationIssuerProviderInterface market, final double cleanPriceNominal); double accruedInterestFromCleanRealPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); double accruedInterestFromCleanYield(final BondCapitalIndexedSecurity<?> bond, final double yield); double cleanRealPriceFromDirtyRealPrice(final BondCapitalIndexedSecurity<?> bond, final double dirtyPrice); double cleanNominalPriceFromDirtyNominalPrice(final BondCapitalIndexedSecurity<?> bond, final double dirtyPrice); double cleanRealPriceFromCurves(final BondCapitalIndexedSecurity<?> bond, 
      final InflationIssuerProviderInterface curves); double cleanNominalPriceFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves); double cleanRealPriceFromCleanNominalPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanNominalPrice, final InflationIssuerProviderInterface issuerMulticurves); double dirtyNominalPriceFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves); double dirtyRealPriceFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves); double dirtyRealPriceFromCleanRealPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); MultipleCurrencyAmount netAmount(final BondCapitalIndexedSecurity<Coupon> bond, final InflationIssuerProviderInterface market, final double cleanPriceReal); double dirtyPriceFromRealYield(final BondCapitalIndexedSecurity<?> bond, final double yield); double cleanPriceFromYield(final BondCapitalIndexedSecurity<?> bond, final double yield); double yieldRealFromDirtyRealPrice(final BondCapitalIndexedSecurity<?> bond, final double dirtyPrice); MultipleCurrencyInflationSensitivity presentValueCurveSensitivity(final BondCapitalIndexedSecurity<?> bond, 
      final ParameterInflationIssuerProviderInterface provider); double yieldRealFromCleanPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); double modifiedDurationFromYieldStandard(final BondCapitalIndexedSecurity<?> bond, final double yield); double modifiedDurationFromYieldFiniteDifference(final BondCapitalIndexedSecurity<?> bond, final double yield); double convexityFromYieldFiniteDifference(final BondCapitalIndexedSecurity<?> bond, final double yield); double yieldRealFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface provider); double modifiedDurationFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves); double yieldRealFromCleanRealPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); double modifiedDurationFromCleanPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); double convexityFromYieldStandard(final BondCapitalIndexedSecurity<?> bond, final double yield); double convexityFromCurves(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves); double convexityFromCleanPrice(final BondCapitalIndexedSecurity<?> bond, final double cleanPrice); MultipleCurrencyAmount presentValueFromZSpread(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final double zSpread); double cleanPriceFromZSpread(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final double zSpread); double zSpreadFromCurvesAndCleanPriceDirect(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final double cleanPrice); double zSpreadFromCurvesAndCleanRealPriceDirect(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final double cleanRealPrice); double zSpreadFromCurvesAndCleanNominalPriceDirect(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final double cleanRealPrice); double zSpreadFromCurvesAndPV(final BondCapitalIndexedSecurity<?> bond, final InflationIssuerProviderInterface issuerMulticurves, final MultipleCurrencyAmount pv); double zSpreadFromCurvesAndCleanPrice(final BondCapitalIndexedSecurity<Coupon> bond, final InflationIssuerProviderInterface issuerMulticurves, final double cleanPrice);  }
@Test public void dirtyRealPriceFromRealYieldTips1() { final double[] yield = new double[] {-0.01, 0.00, 0.01, 0.02, 0.03 }; final int nbCoupon = BOND_SECURITY_TIPS_1.getCoupon().getNumberOfPayments(); final double[] dirtyRealPrice = new double[yield.length]; final double[] dirtyRealPriceExpected = new double[yield.length]; for (int loopyield = 0; loopyield < yield.length; loopyield++) { dirtyRealPrice[loopyield] = METHOD_BOND_INFLATION.dirtyPriceFromRealYield(BOND_SECURITY_TIPS_1, yield[loopyield]); final double factorOnPeriod = 1 + yield[loopyield] / BOND_SECURITY_TIPS_1.getCouponPerYear(); double pvAtFirstCoupon = 0; for (int loopcpn = 0; loopcpn < nbCoupon; loopcpn++) { pvAtFirstCoupon += ((CouponInflationGearing) BOND_SECURITY_TIPS_1.getCoupon().getNthPayment(loopcpn)).getFactor() / BOND_SECURITY_TIPS_1.getCouponPerYear() / Math.pow(factorOnPeriod, loopcpn); } pvAtFirstCoupon += 1.0 / Math.pow(factorOnPeriod, nbCoupon - 1); dirtyRealPriceExpected[loopyield] = pvAtFirstCoupon / (1 + BOND_SECURITY_TIPS_1.getAccrualFactorToNextCoupon() * yield[loopyield] / BOND_SECURITY_TIPS_1.getCouponPerYear()); assertEquals("Inflation Capital Indexed bond: yield " + loopyield, dirtyRealPriceExpected[loopyield], dirtyRealPrice[loopyield], 1.0E-8); } }