//------------------------------------------------------------------------- /// <summary> /// Calculates the present value of the fixed coupon bond trade from the clean price of the underlying product. /// <para> /// The present value of the trade is the value on the valuation date. /// The result is expressed using the payment currency of the bond. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <param name="refData"> the reference data used to calculate the settlement date </param> /// <param name="cleanPrice"> the clean price </param> /// <returns> the present value of the fixed coupon bond trade </returns> public virtual CurrencyAmount presentValueFromCleanPrice(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, ReferenceData refData, double cleanPrice) { ResolvedFixedCouponBond product = trade.Product; LocalDate standardSettlementDate = this.standardSettlementDate(product, provider, refData); LocalDate tradeSettlementDate = settlementDate(trade, provider.ValuationDate); Currency currency = product.Currency; RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(product, provider); double df = repoDf.discountFactor(standardSettlementDate); double pvStandard = (cleanPrice * product.Notional + productPricer.accruedInterest(product, standardSettlementDate)) * df; if (standardSettlementDate.isEqual(tradeSettlementDate)) { return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard))); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingFixedCouponBondProductPricer.issuerCurveDf(product, provider); double pvDiff = 0d; if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvDiff = productPricer.presentValueCoupon(product, issuerDf, tradeSettlementDate, standardSettlementDate); } else { pvDiff = -productPricer.presentValueCoupon(product, issuerDf, standardSettlementDate, tradeSettlementDate); } return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard + pvDiff))); }
public virtual void test_dirtyPriceFromCleanPrice_cleanPriceFromDirtyPrice() { double dirtyPrice = PRICER.dirtyPriceFromCurves(PRODUCT, PROVIDER, REF_DATA); LocalDate settlement = DATE_OFFSET.adjust(VAL_DATE, REF_DATA); double cleanPrice = PRICER.cleanPriceFromDirtyPrice(PRODUCT, settlement, dirtyPrice); double accruedInterest = PRICER.accruedInterest(PRODUCT, settlement); assertEquals(cleanPrice, dirtyPrice - accruedInterest / NOTIONAL, NOTIONAL * TOL); double dirtyPriceRe = PRICER.dirtyPriceFromCleanPrice(PRODUCT, settlement, cleanPrice); assertEquals(dirtyPriceRe, dirtyPrice, TOL); }