/// <summary> /// Calculates the present value of the fixed coupon bond trade with z-spread 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> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// </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> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value of the fixed coupon bond trade </returns> public virtual CurrencyAmount presentValueFromCleanPriceWithZSpread(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, ReferenceData refData, double cleanPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { 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.presentValueCouponWithZSpread(product, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear); } else { pvDiff = -productPricer.presentValueCouponWithZSpread(product, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear); } return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard + pvDiff))); }
public DayCountAnonymousInnerClass(ResolvedFixedCouponBondTest outerInstance, com.opengamma.strata.product.bond.ResolvedFixedCouponBond @base, com.opengamma.strata.product.bond.FixedCouponBondPaymentPeriod period, AtomicBoolean eom) { this.outerInstance = outerInstance; this.@base = @base; this.period = period; this.eom = eom; }
/// <summary> /// Calculates the price sensitivity of the bond future product with z-spread. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates /// of the issuer discounting curve. /// </para> /// <para> /// Note that the price sensitivity should be no currency. /// /// </para> /// </summary> /// <param name="future"> the future </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodPerYear"> the number of periods per year </param> /// <returns> the price curve sensitivity of the product </returns> public PointSensitivities priceSensitivityWithZSpread(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodPerYear) { ImmutableList <ResolvedFixedCouponBond> basket = future.DeliveryBasket; int size = basket.size(); double[] priceBonds = new double[size]; int indexCTD = 0; double priceMin = 2d; for (int i = 0; i < size; i++) { ResolvedFixedCouponBond bond = basket.get(i); double dirtyPrice = bondPricer.dirtyPriceFromCurvesWithZSpread(bond, discountingProvider, zSpread, compoundedRateType, periodPerYear, future.LastDeliveryDate); priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.LastDeliveryDate, dirtyPrice) / future.ConversionFactors.get(i); if (priceBonds[i] < priceMin) { priceMin = priceBonds[i]; indexCTD = i; } } ResolvedFixedCouponBond bond = basket.get(indexCTD); PointSensitivityBuilder pointSensi = bondPricer.dirtyPriceSensitivityWithZspread(bond, discountingProvider, zSpread, compoundedRateType, periodPerYear, future.LastDeliveryDate); return(pointSensi.multipliedBy(1d / future.ConversionFactors.get(indexCTD)).build()); }
private double currentCashCouponPayment(ResolvedFixedCouponBond product, LocalDate referenceDate) { double cash = 0d; foreach (FixedCouponBondPaymentPeriod period in product.PeriodicPayments) { if (period.PaymentDate.isEqual(referenceDate)) { cash += period.FixedRate * period.Notional * period.YearFraction; } } return(cash); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the price of the bond future product. /// <para> /// The price of the product is the price on the valuation date. /// </para> /// <para> /// Strata uses <i>decimal prices</i> for bond futures. This is coherent with the pricing of <seealso cref="FixedCouponBond"/>. /// For example, a price of 99.32% is represented in Strata by 0.9932. /// /// </para> /// </summary> /// <param name="future"> the future </param> /// <param name="discountingProvider"> the discounting provider </param> /// <returns> the price of the product, in decimal form </returns> public double price(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider) { ImmutableList <ResolvedFixedCouponBond> basket = future.DeliveryBasket; int size = basket.size(); double[] priceBonds = new double[size]; for (int i = 0; i < size; ++i) { ResolvedFixedCouponBond bond = basket.get(i); double dirtyPrice = bondPricer.dirtyPriceFromCurves(bond, discountingProvider, future.LastDeliveryDate); priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(bond, future.LastDeliveryDate, dirtyPrice) / future.ConversionFactors.get(i); } return(Doubles.min(priceBonds)); }
//------------------------------------------------------------------------- public virtual void test_accruedInterest() { // settle before start LocalDate settleDate1 = START_DATE.minusDays(5); double accruedInterest1 = PRICER.accruedInterest(PRODUCT, settleDate1); assertEquals(accruedInterest1, 0d); // settle between endDate and endDate -lag LocalDate settleDate2 = date(2015, 10, 8); double accruedInterest2 = PRICER.accruedInterest(PRODUCT, settleDate2); assertEquals(accruedInterest2, -4.0 / 365.0 * FIXED_RATE * NOTIONAL, EPS); // normal LocalDate settleDate3 = date(2015, 4, 18); // not adjusted ResolvedFixedCouponBond product = FixedCouponBond.builder().securityId(SECURITY_ID).dayCount(DAY_COUNT).fixedRate(FIXED_RATE).legalEntityId(ISSUER_ID).currency(EUR).notional(NOTIONAL).accrualSchedule(PERIOD_SCHEDULE).settlementDateOffset(DATE_OFFSET).yieldConvention(YIELD_CONVENTION).exCouponPeriod(DaysAdjustment.NONE).build().resolve(REF_DATA); double accruedInterest3 = PRICER.accruedInterest(product, settleDate3); assertEquals(accruedInterest3, 6.0 / 365.0 * FIXED_RATE * NOTIONAL, EPS); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the payment that was made for the trade. /// <para> /// This is the payment that was made on the settlement date, based on the quantity and clean price. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <returns> the payment that was made </returns> public virtual Payment upfrontPayment(ResolvedFixedCouponBondTrade trade) { ResolvedFixedCouponBond product = trade.Product; Currency currency = product.Currency; if (!trade.Settlement.Present) { return(Payment.of(CurrencyAmount.zero(currency), product.StartDate)); // date doesn't matter as it is zero } // payment is based on the dirty price ResolvedFixedCouponBondSettlement settlement = trade.Settlement.get(); LocalDate settlementDate = settlement.SettlementDate; double cleanPrice = settlement.Price; double dirtyPrice = productPricer.dirtyPriceFromCleanPrice(product, settlementDate, cleanPrice); // calculate payment double quantity = trade.Quantity; double notional = product.Notional; return(Payment.of(CurrencyAmount.of(currency, -quantity * notional * dirtyPrice), settlementDate)); }
/// <summary> /// Calculates the current cash of the fixed coupon bond trade. /// </summary> /// <param name="trade"> the trade </param> /// <param name="valuationDate"> the valuation date </param> /// <returns> the current cash amount </returns> public virtual CurrencyAmount currentCash(ResolvedFixedCouponBondTrade trade, LocalDate valuationDate) { Payment upfrontPayment = this.upfrontPayment(trade); Currency currency = upfrontPayment.Currency; // assumes single currency is involved in trade CurrencyAmount currentCash = CurrencyAmount.zero(currency); if (upfrontPayment.Date.Equals(valuationDate)) { currentCash = currentCash.plus(upfrontPayment.Value); } if (trade.Settlement.Present) { LocalDate settlementDate = trade.Settlement.get().SettlementDate; ResolvedFixedCouponBond product = trade.Product; if (!settlementDate.isAfter(valuationDate)) { double cashCoupon = product.hasExCouponPeriod() ? 0d : currentCashCouponPayment(product, valuationDate); Payment payment = product.NominalPayment; double cashNominal = payment.Date.isEqual(valuationDate) ? payment.Amount : 0d; currentCash = currentCash.plus(CurrencyAmount.of(currency, (cashCoupon + cashNominal) * trade.Quantity)); } } return(currentCash); }
// calculates the settlement date using the offset from the valuation date private LocalDate standardSettlementDate(ResolvedFixedCouponBond product, LegalEntityDiscountingProvider provider, ReferenceData refData) { return(product.SettlementDateOffset.adjust(provider.ValuationDate, refData)); }