public virtual void test_resolve() { BusinessDayAdjustment bussAdj = BusinessDayAdjustment.of(FOLLOWING, SAT_SUN); ResolvedCdsIndex test = PRODUCT.resolve(REF_DATA); int nDates = 44; LocalDate[] dates = new LocalDate[nDates]; for (int i = 0; i < nDates; ++i) { dates[i] = START_DATE.plusMonths(3 * i); } IList <CreditCouponPaymentPeriod> payments = new List <CreditCouponPaymentPeriod>(nDates - 1); for (int i = 0; i < nDates - 2; ++i) { LocalDate start = i == 0 ? dates[i] : bussAdj.adjust(dates[i], REF_DATA); LocalDate end = bussAdj.adjust(dates[i + 1], REF_DATA); payments.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end).unadjustedStartDate(dates[i]).unadjustedEndDate(dates[i + 1]).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end.minusDays(1)).paymentDate(end).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end)).build()); } LocalDate start = bussAdj.adjust(dates[nDates - 2], REF_DATA); LocalDate end = dates[nDates - 1]; payments.Add(CreditCouponPaymentPeriod.builder().startDate(start).endDate(end.plusDays(1)).unadjustedStartDate(dates[nDates - 2]).unadjustedEndDate(end).effectiveStartDate(start.minusDays(1)).effectiveEndDate(end).paymentDate(bussAdj.adjust(end, REF_DATA)).currency(USD).notional(NOTIONAL).fixedRate(COUPON).yearFraction(ACT_360.relativeYearFraction(start, end.plusDays(1))).build()); ResolvedCdsIndex expected = ResolvedCdsIndex.builder().buySell(BUY).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).dayCount(ACT_360).paymentOnDefault(ACCRUED_PREMIUM).paymentPeriods(payments).protectionStart(BEGINNING).protectionEndDate(END_DATE).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); assertEquals(test, expected); }
public virtual void test_totoSingleNameCds() { ResolvedCdsIndex @base = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); ResolvedCds test = @base.toSingleNameCds(); ResolvedCds expected = ResolvedCds.builder().buySell(BUY).dayCount(ACT_360).legalEntityId(INDEX_ID).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); assertEquals(test, expected); }
private ResolvedCdsIndexTrade(TradeInfo info, ResolvedCdsIndex product, Payment upfrontFee) { JodaBeanUtils.notNull(info, "info"); JodaBeanUtils.notNull(product, "product"); this.info = info; this.product = product; this.upfrontFee = upfrontFee; }
//------------------------------------------------------------------------- public virtual void coverage() { ResolvedCdsIndex test1 = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); coverImmutableBean(test1); ResolvedCdsIndex test2 = ResolvedCdsIndex.builder().buySell(BuySell.SELL).dayCount(DayCounts.ACT_365F).cdsIndexId(StandardId.of("OG", "AA-INDEX")).legalEntityIds(ImmutableList.of(StandardId.of("OG", "ABC1"), StandardId.of("OG", "ABC2"))).paymentOnDefault(PaymentOnDefault.NONE).protectionStart(ProtectionStartOfDay.NONE).paymentPeriods(PAYMENTS[0]).protectionEndDate(PAYMENTS[0].EffectiveEndDate).settlementDateOffset(DaysAdjustment.NONE).stepinDateOffset(DaysAdjustment.NONE).build(); coverBeanEquals(test1, test2); }
//------------------------------------------------------------------------- public virtual void coverage() { ResolvedCdsIndexTrade test1 = ResolvedCdsIndexTrade.builder().product(PRODUCT).upfrontFee(UPFRONT).info(TRADE_INFO).build(); coverImmutableBean(test1); ResolvedCdsIndex product = CdsIndex.of(BUY, INDEX_ID, LEGAL_ENTITIES, USD, 1.e9, START_DATE, END_DATE, P6M, SAT_SUN, 0.067).resolve(REF_DATA); ResolvedCdsIndexTrade test2 = ResolvedCdsIndexTrade.builder().product(product).info(TradeInfo.empty()).build(); coverBeanEquals(test1, test2); }
/// <summary> /// Calculates the expected loss of the CDS index product. /// <para> /// The expected loss is the (undiscounted) expected default settlement value paid by the protection seller. /// The resulting value is always positive. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <returns> the expected loss </returns> public virtual CurrencyAmount expectedLoss(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider) { if (isExpired(cdsIndex, ratesProvider)) { return(CurrencyAmount.of(cdsIndex.Currency, 0d)); } ResolvedCds cds = cdsIndex.toSingleNameCds(); double recoveryRate = underlyingPricer.recoveryRate(cds, ratesProvider); Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider); double survivalProbability = rates.Second.survivalProbability(cds.ProtectionEndDate); double el = (1d - recoveryRate) * (1d - survivalProbability) * rates.Third; return(CurrencyAmount.of(cds.Currency, Math.Abs(cds.Notional) * el)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the risky PV01 of the CDS index product. /// <para> /// RPV01 is defined as minus of the present value sensitivity to coupon rate. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="priceType"> the price type </param> /// <param name="refData"> the reference date </param> /// <returns> the RPV01 </returns> public virtual CurrencyAmount rpv01(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, PriceType priceType, ReferenceData refData) { if (isExpired(cdsIndex, ratesProvider)) { return(CurrencyAmount.of(cdsIndex.Currency, 0d)); } ResolvedCds cds = cdsIndex.toSingleNameCds(); LocalDate stepinDate = cds.StepinDateOffset.adjust(ratesProvider.ValuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider); double riskyAnnuity = underlyingPricer.riskyAnnuity(cds, rates.First, rates.Second, referenceDate, stepinDate, effectiveStartDate, priceType); double amount = cds.BuySell.normalize(cds.Notional) * riskyAnnuity * rates.Third; return(CurrencyAmount.of(cds.Currency, amount)); }
public virtual void test_effectiveStartDate() { ResolvedCdsIndex test1 = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); LocalDate date1 = LocalDate.of(2016, 3, 22); assertEquals(test1.calculateEffectiveStartDate(date1), date1.minusDays(1)); LocalDate date2 = LocalDate.of(2013, 9, 22); assertEquals(test1.calculateEffectiveStartDate(date2), START_DATE.minusDays(1)); ResolvedCdsIndex test2 = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(ProtectionStartOfDay.NONE).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); LocalDate date3 = LocalDate.of(2016, 3, 22); assertEquals(test2.calculateEffectiveStartDate(date3), date3); LocalDate date4 = LocalDate.of(2013, 9, 22); assertEquals(test2.calculateEffectiveStartDate(date4), START_DATE); }
// extract CDS index trades from credit curve private ImmutableList <ResolvedCdsIndexTrade> getBucketCdsIndex(ResolvedCdsIndex product, CreditRatesProvider ratesProvider) { CreditDiscountFactors creditCurve = ratesProvider.survivalProbabilities(product.CdsIndexId, product.Currency).SurvivalProbabilities; int nNodes = creditCurve.ParameterCount; ImmutableList.Builder <ResolvedCdsIndexTrade> builder = ImmutableList.builder(); for (int i = 0; i < nNodes; ++i) { ParameterMetadata metadata = creditCurve.getParameterMetadata(i); ArgChecker.isTrue(metadata is ResolvedTradeParameterMetadata, "ParameterMetadata of credit curve must be ResolvedTradeParameterMetadata"); ResolvedTradeParameterMetadata tradeMetadata = (ResolvedTradeParameterMetadata)metadata; ResolvedTrade trade = tradeMetadata.Trade; ArgChecker.isTrue(trade is ResolvedCdsIndexTrade, "ResolvedTrade must be ResolvedCdsIndexTrade"); builder.add((ResolvedCdsIndexTrade)trade); } return(builder.build()); }
public virtual void test_builder() { ResolvedCdsIndex test = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); assertEquals(test.BuySell, BUY); assertEquals(test.Currency, USD); assertEquals(test.AccrualStartDate, PAYMENTS[0].StartDate); assertEquals(test.AccrualEndDate, PAYMENTS[42].EndDate); assertEquals(test.DayCount, ACT_360); assertEquals(test.FixedRate, COUPON); assertEquals(test.CdsIndexId, INDEX_ID); assertEquals(test.LegalEntityIds, LEGAL_ENTITIES); assertEquals(test.Notional, NOTIONAL); assertEquals(test.PaymentOnDefault, ACCRUED_PREMIUM); assertEquals(test.PaymentPeriods, PAYMENTS); assertEquals(test.ProtectionEndDate, PAYMENTS[42].EffectiveEndDate); assertEquals(test.SettlementDateOffset, SETTLE_DAY_ADJ); assertEquals(test.ProtectionStart, BEGINNING); assertEquals(test.StepinDateOffset, STEPIN_DAY_ADJ); }
public virtual void test_accruedYearFraction() { double eps = 1.0e-15; ResolvedCdsIndex test = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); double accStart = test.accruedYearFraction(START_DATE.minusDays(1)); double accNextMinusOne = test.accruedYearFraction(START_DATE.plusMonths(3).minusDays(1)); double accNext = test.accruedYearFraction(START_DATE.plusMonths(3)); double accNextOne = test.accruedYearFraction(START_DATE.plusMonths(3).plusDays(1)); double accMod = test.accruedYearFraction(START_DATE.plusYears(1)); double accEnd = test.accruedYearFraction(END_DATE); double accEndOne = test.accruedYearFraction(END_DATE.plusDays(1)); assertEquals(accStart, 0d); assertEquals(accNext, 0d); assertEquals(accNextMinusOne, ACT_360.relativeYearFraction(START_DATE, START_DATE.plusMonths(3).minusDays(1)), eps); assertEquals(accNextOne, 1d / 360d, eps); // 2.x assertEquals(accMod, 0.24722222222222223, eps); assertEquals(accEnd, 0.25555555555555554, eps); assertEquals(accEndOne, 0.25833333333333336, eps); }
public override Builder set(string propertyName, object newValue) { switch (propertyName.GetHashCode()) { case 3237038: // info this.info_Renamed = (TradeInfo)newValue; break; case -309474065: // product this.product_Renamed = (ResolvedCdsIndex)newValue; break; case 963468344: // upfrontFee this.upfrontFee_Renamed = (Payment)newValue; break; default: throw new NoSuchElementException("Unknown property: " + propertyName); } return(this); }
/// <summary> /// Calculates the present value sensitivity of the product. /// <para> /// The present value sensitivity of the product is the sensitivity of present value to the underlying curves. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="refData"> the reference data </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivity(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { if (isExpired(cdsIndex, ratesProvider)) { return(PointSensitivityBuilder.none()); } ResolvedCds cds = cdsIndex.toSingleNameCds(); LocalDate stepinDate = cds.StepinDateOffset.adjust(ratesProvider.ValuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = underlyingPricer.recoveryRate(cds, ratesProvider); Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider); double signedNotional = cds.BuySell.normalize(cds.Notional); PointSensitivityBuilder protectionLegSensi = underlyingPricer.protectionLegSensitivity(cds, rates.First, rates.Second, referenceDate, effectiveStartDate, recoveryRate); protectionLegSensi = protectionLegSensi.multipliedBy(signedNotional * rates.Third); PointSensitivityBuilder riskyAnnuitySensi = underlyingPricer.riskyAnnuitySensitivity(cds, rates.First, rates.Second, referenceDate, stepinDate, effectiveStartDate); riskyAnnuitySensi = riskyAnnuitySensi.multipliedBy(-cds.FixedRate * signedNotional * rates.Third); return(protectionLegSensi.combinedWith(riskyAnnuitySensi)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the jump-to-default of the CDS index product. /// <para> /// The jump-to-default is the value of the product in case of immediate default of a constituent single name. /// </para> /// <para> /// Under the homogeneous pool assumption, the jump-to-default values are the same for all of the undefaulted names, /// and zero for defaulted names. Thus the resulting object contains a single number. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="refData"> the reference data </param> /// <returns> the recovery01 </returns> public virtual JumpToDefault jumpToDefault(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { StandardId indexId = cdsIndex.CdsIndexId; Currency currency = cdsIndex.Currency; if (isExpired(cdsIndex, ratesProvider)) { return(JumpToDefault.of(currency, ImmutableMap.of(indexId, 0d))); } ResolvedCds cds = cdsIndex.toSingleNameCds(); LocalDate stepinDate = cds.StepinDateOffset.adjust(ratesProvider.ValuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = underlyingPricer.recoveryRate(cds, ratesProvider); Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider); double protectionFull = underlyingPricer.protectionFull(cds, rates.First, rates.Second, referenceDate, effectiveStartDate); double rpv01 = underlyingPricer.riskyAnnuity(cds, rates.First, rates.Second, referenceDate, stepinDate, effectiveStartDate, PriceType.CLEAN); double lgd = 1d - recoveryRate; double numTotal = cdsIndex.LegalEntityIds.size(); double jtd = (lgd - (lgd * protectionFull - cds.FixedRate * rpv01)) / numTotal; return(JumpToDefault.of(currency, ImmutableMap.of(indexId, cds.BuySell.normalize(cds.Notional) * jtd))); }
public virtual void test_serialization() { ResolvedCdsIndex test = ResolvedCdsIndex.builder().buySell(BUY).dayCount(ACT_360).cdsIndexId(INDEX_ID).legalEntityIds(LEGAL_ENTITIES).paymentOnDefault(ACCRUED_PREMIUM).protectionStart(BEGINNING).paymentPeriods(PAYMENTS).protectionEndDate(PAYMENTS[PAYMENTS.Count - 1].EffectiveEndDate).settlementDateOffset(SETTLE_DAY_ADJ).stepinDateOffset(STEPIN_DAY_ADJ).build(); assertSerialization(test); }
/// <summary> /// Calculates the par spread sensitivity of the product. /// <para> /// The par spread sensitivity of the product is the sensitivity of par spread to the underlying curves. /// The resulting sensitivity is based on the currency of the CDS index product. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="refData"> the reference data </param> /// <returns> the par spread </returns> public virtual PointSensitivityBuilder parSpreadSensitivity(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { ResolvedCds cds = cdsIndex.toSingleNameCds(); return(underlyingPricer.parSpreadSensitivity(cds, ratesProvider, referenceDate, refData)); }
/// <summary> /// Sets the resolved CDS index product. /// <para> /// The product captures the contracted financial details of the trade. /// </para> /// </summary> /// <param name="product"> the new value, not null </param> /// <returns> this, for chaining, not null </returns> public Builder product(ResolvedCdsIndex product) { JodaBeanUtils.notNull(product, "product"); this.product_Renamed = product; return(this); }
/// <summary> /// Restricted copy constructor. </summary> /// <param name="beanToCopy"> the bean to copy from, not null </param> internal Builder(ResolvedCdsIndexTrade beanToCopy) { this.info_Renamed = beanToCopy.Info; this.product_Renamed = beanToCopy.Product; this.upfrontFee_Renamed = beanToCopy.upfrontFee; }
//------------------------------------------------------------------------- /// <summary> /// Calculates the price of the CDS index product, which is the minus of the present value per unit notional. /// <para> /// This method can calculate the clean or dirty price, see <seealso cref="PriceType"/>. /// If calculating the clean price, the accrued interest is calculated based on the step-in date. /// /// </para> /// </summary> /// <param name="cdsIndex"> the product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="referenceDate"> the reference date </param> /// <param name="priceType"> the price type </param> /// <param name="refData"> the reference data </param> /// <returns> the price </returns> public virtual double price(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, PriceType priceType, ReferenceData refData) { ResolvedCds cds = cdsIndex.toSingleNameCds(); return(underlyingPricer.price(cds, ratesProvider, referenceDate, priceType, refData)); }
//------------------------------------------------------------------------- internal virtual bool isExpired(ResolvedCdsIndex index, CreditRatesProvider ratesProvider) { return(!index.ProtectionEndDate.isAfter(ratesProvider.ValuationDate)); }