public void test_builder() { ResolvedCds test = ResolvedCds.builder() .buySell(BUY) .dayCount(ACT_360) .legalEntityId(LEGAL_ENTITY) .paymentOnDefault(ACCRUED_PREMIUM) .protectionStart(BEGINNING) .paymentPeriods(PAYMENTS) .protectionEndDate(PAYMENTS.get(PAYMENTS.size() - 1).getEffectiveEndDate()) .settlementDateOffset(SETTLE_DAY_ADJ) .stepinDateOffset(STEPIN_DAY_ADJ) .build(); assertEquals(test.getBuySell(), BUY); assertEquals(test.getCurrency(), USD); assertEquals(test.getAccrualStartDate(), PAYMENTS.get(0).getStartDate()); assertEquals(test.getAccrualEndDate(), PAYMENTS.get(42).getEndDate()); assertEquals(test.getDayCount(), ACT_360); assertEquals(test.getFixedRate(), COUPON); assertEquals(test.getLegalEntityId(), LEGAL_ENTITY); assertEquals(test.getNotional(), NOTIONAL); assertEquals(test.getPaymentOnDefault(), ACCRUED_PREMIUM); assertEquals(test.getPaymentPeriods(), PAYMENTS); assertEquals(test.getProtectionEndDate(), PAYMENTS.get(42).getEffectiveEndDate()); assertEquals(test.getSettlementDateOffset(), SETTLE_DAY_ADJ); assertEquals(test.getProtectionStart(), BEGINNING); assertEquals(test.getStepinDateOffset(), STEPIN_DAY_ADJ); }
public void accruedInterestTest() { double acc = PRODUCT_BEFORE.accruedYearFraction(VALUATION_DATE) * PRODUCT_BEFORE.getFixedRate(); double accAccEndDate = PRODUCT_BEFORE.accruedYearFraction(LocalDate.of(2014, 3, 22)) * PRODUCT_BEFORE.getFixedRate(); double accEffectiveEndDateOne = PRODUCT_BEFORE.accruedYearFraction(LocalDate.of(2014, 3, 20)) * PRODUCT_BEFORE.getFixedRate(); double accEffectiveEndDate = PRODUCT_BEFORE.accruedYearFraction(LocalDate.of(2014, 3, 21)) * PRODUCT_BEFORE.getFixedRate(); assertEquals(acc, 0.0019444444444444446, TOL); assertEquals(accAccEndDate, 2.777777777777778E-4, TOL); assertEquals(accEffectiveEndDateOne, 0d, TOL); assertEquals(accEffectiveEndDate, 1.388888888888889E-4, TOL); }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(ResolvedCds beanToCopy) { this.buySell = beanToCopy.getBuySell(); this.legalEntityId = beanToCopy.getLegalEntityId(); this.paymentPeriods = beanToCopy.getPaymentPeriods(); this.protectionEndDate = beanToCopy.getProtectionEndDate(); this.dayCount = beanToCopy.getDayCount(); this.paymentOnDefault = beanToCopy.getPaymentOnDefault(); this.protectionStart = beanToCopy.getProtectionStart(); this.stepinDateOffset = beanToCopy.getStepinDateOffset(); this.settlementDateOffset = beanToCopy.getSettlementDateOffset(); }
protected void checkCdsBucket(ResolvedCdsTrade trade, List<ResolvedCdsTrade> bucketCds) { Iterator<StandardId> legalEntities = bucketCds.stream().map(t -> t.getProduct().getLegalEntityId()).collect(Collectors.toSet()).iterator(); ArgChecker.isTrue(legalEntities.next().equals(trade.getProduct().getLegalEntityId()), "legal entity must be common"); ArgChecker.isFalse(legalEntities.hasNext(), "legal entity must be common"); Iterator<Currency> currencies = bucketCds.stream().map(t -> t.getProduct().getCurrency()).collect(Collectors.toSet()).iterator(); ArgChecker.isTrue(currencies.next().equals(trade.getProduct().getCurrency()), "currency must be common"); ArgChecker.isFalse(currencies.hasNext(), "currency must be common"); }
double recoveryRate(ResolvedCds cds, CreditRatesProvider ratesProvider) { RecoveryRates recoveryRates = ratesProvider.recoveryRates(cds.getLegalEntityId()); ArgChecker.isTrue(recoveryRates instanceof ConstantRecoveryRates, "recoveryRates must be ConstantRecoveryRates"); return recoveryRates.recoveryRate(cds.getProtectionEndDate()); }
/** * Calculates the recovery01 of the CDS product. * <p> * The recovery01 is defined as the present value sensitivity to the recovery rate. * Since the ISDA standard model requires the recovery rate to be constant throughout the lifetime of the CDS, * one currency amount is returned by this method. * * @param cds the product * @param ratesProvider the rates provider * @param referenceDate the reference date * @param refData the reference data * @return the recovery01 */ public CurrencyAmount recovery01( ResolvedCds cds, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { if (isExpired(cds, ratesProvider)) { return CurrencyAmount.of(cds.getCurrency(), 0d); } LocalDate stepinDate = cds.getStepinDateOffset().adjust(ratesProvider.getValuationDate(), refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); validateRecoveryRates(cds, ratesProvider); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); double protectionFull = protectionFull(cds, rates.getFirst(), rates.getSecond(), referenceDate, effectiveStartDate); return CurrencyAmount.of(cds.getCurrency(), -cds.getBuySell().normalize(cds.getNotional()) * protectionFull); }
puf = pointsUpfront; productEffectiveStart = yieldCurve.relativeYearFraction(effectiveStartDate); double protectionEnd = yieldCurve.relativeYearFraction(cds.getProtectionEndDate()); nPayments = cds.getPaymentPeriods().size(); paymentDF = new double[nPayments]; int indexTmp = -1; for (int i = 0; i < nPayments; i++) { if (stepinDate.isBefore(cds.getPaymentPeriods().get(i).getEndDate())) { paymentDF[i] = yieldCurve.discountFactor(cds.getPaymentPeriods().get(i).getPaymentDate()); } else { indexTmp = i; if (cds.getPaymentOnDefault().isAccruedInterest()) { LocalDate tmp = nPayments == 1 ? effectiveStartDate : cds.getAccrualStartDate(); DoubleArray integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints( premDt = new double[nPayments][]; for (int i = startPeriodIndex; i < nPayments; i++) { CreditCouponPaymentPeriod coupon = cds.getPaymentPeriods().get(i); offsetAccStart[i] = yieldCurve.relativeYearFraction(coupon.getEffectiveStartDate()); offsetAccEnd[i] = yieldCurve.relativeYearFraction(coupon.getEffectiveEndDate());
double[] lgd = new double[n]; for (int i = 0; i < n; i++) { LocalDate endDate = calibrationCDSs.get(i).getProduct().getProtectionEndDate(); t[i] = discountFactors.relativeYearFraction(endDate); lgd[i] = 1d - recoveryRates.recoveryRate(endDate); LocalDate stepinDate = cds.getStepinDateOffset().adjust(valuationDate, refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); LocalDate settlementDate = calibrationCDSs.get(i).getInfo().getSettlementDate() .orElse(cds.getSettlementDateOffset().adjust(valuationDate, refData)); double accrued = cds.accruedYearFraction(stepinDate);
double price( ResolvedCds cds, CreditRatesProvider ratesProvider, double fractionalSpread, LocalDate referenceDate, PriceType priceType, ReferenceData refData) { if (!cds.getProtectionEndDate().isAfter(ratesProvider.getValuationDate())) { //short cut already expired CDSs return 0d; } LocalDate stepinDate = cds.getStepinDateOffset().adjust(ratesProvider.getValuationDate(), refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = recoveryRate(cds, ratesProvider); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); double protectionLeg = protectionLeg(cds, rates.getFirst(), rates.getSecond(), referenceDate, effectiveStartDate, recoveryRate); double rpv01 = riskyAnnuity( cds, rates.getFirst(), rates.getSecond(), referenceDate, stepinDate, effectiveStartDate, priceType); return protectionLeg - rpv01 * fractionalSpread; }
public void jumpToDefaultTest() { JumpToDefault computed = PRICER.jumpToDefault(PRODUCT_BEFORE, RATES_PROVIDER, VALUATION_DATE, REF_DATA); LocalDate stepinDate = PRODUCT_BEFORE.getStepinDateOffset().adjust(VALUATION_DATE, REF_DATA); double dirtyPv = PRICER.presentValue(PRODUCT_BEFORE, RATES_PROVIDER, VALUATION_DATE, PriceType.DIRTY, REF_DATA).getAmount(); double accrued = PRODUCT_BEFORE.accruedYearFraction(stepinDate) * PRODUCT_BEFORE.getFixedRate() * PRODUCT_BEFORE.getBuySell().normalize(NOTIONAL); double protection = PRODUCT_BEFORE.getBuySell().normalize(NOTIONAL) * (1d - RECOVERY_RATES.getRecoveryRate()); double expected = protection - accrued - dirtyPv; assertEquals(computed.getCurrency(), USD); assertTrue(computed.getAmounts().size() == 1); assertEquals(computed.getAmounts().get(LEGAL_ENTITY), expected, NOTIONAL * TOL); }
public void withCouponTest() { double coupon = 0.15; double price = PRICER.price(PRODUCT_NEXTDAY, RATES_PROVIDER, coupon, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(RATES_PROVIDER.getValuationDate(), REF_DATA), CLEAN, REF_DATA); double protPv = PRICER.protectionLeg(PRODUCT_NEXTDAY, RATES_PROVIDER, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(RATES_PROVIDER.getValuationDate(), REF_DATA), REF_DATA); double annuity = PRICER.riskyAnnuity(PRODUCT_NEXTDAY, RATES_PROVIDER, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(RATES_PROVIDER.getValuationDate(), REF_DATA), CLEAN, REF_DATA); assertEquals(price, protPv - coupon * annuity, TOL); }
/** * Calculates the par spread of the CDS product. * <p> * The par spread is a coupon rate such that the clean PV is 0. * The result is represented in decimal form. * * @param cds the product * @param ratesProvider the rates provider * @param referenceDate the reference date * @param refData the reference data * @return the par spread */ public double parSpread( ResolvedCds cds, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { ArgChecker.isTrue(cds.getProtectionEndDate().isAfter(ratesProvider.getValuationDate()), "CDS already expired"); LocalDate stepinDate = cds.getStepinDateOffset().adjust(ratesProvider.getValuationDate(), refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = recoveryRate(cds, ratesProvider); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); double protectionLeg = protectionLeg(cds, rates.getFirst(), rates.getSecond(), referenceDate, effectiveStartDate, recoveryRate); double riskyAnnuity = riskyAnnuity(cds, rates.getFirst(), rates.getSecond(), referenceDate, stepinDate, effectiveStartDate, PriceType.CLEAN); return protectionLeg / riskyAnnuity; }
private boolean isExpired(ResolvedCds cds, CreditRatesProvider ratesProvider) { return !cds.getProtectionEndDate().isAfter(ratesProvider.getValuationDate()); }
/** * Calculates the expected loss of the CDS product. * <p> * The expected loss is the (undiscounted) expected default settlement value paid by the protection seller. * The resulting value is always positive. * * @param cds the product * @param ratesProvider the rates provider * @return the expected loss */ public CurrencyAmount expectedLoss( ResolvedCds cds, CreditRatesProvider ratesProvider) { if (isExpired(cds, ratesProvider)) { return CurrencyAmount.of(cds.getCurrency(), 0d); } double recoveryRate = recoveryRate(cds, ratesProvider); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); double survivalProbability = rates.getSecond().survivalProbability(cds.getProtectionEndDate()); double el = (1d - recoveryRate) * (1d - survivalProbability); return CurrencyAmount.of(cds.getCurrency(), Math.abs(cds.getNotional()) * el); }
/** * Calculates the risky PV01 of the CDS product. * <p> * RPV01 is defined as minus of the present value sensitivity to coupon rate. * * @param cds the product * @param ratesProvider the rates provider * @param referenceDate the reference date * @param priceType the price type * @param refData the reference date * @return the RPV01 */ public CurrencyAmount rpv01( ResolvedCds cds, CreditRatesProvider ratesProvider, LocalDate referenceDate, PriceType priceType, ReferenceData refData) { double riskyAnnuity = riskyAnnuity(cds, ratesProvider, referenceDate, priceType, refData); return CurrencyAmount.of(cds.getCurrency(), cds.getBuySell().normalize(cds.getNotional()) * riskyAnnuity); }
recoveryRates, refData); Currency currency = calibrationCds.getProduct().getCurrency(); StandardId legalEntityId = calibrationCds.getProduct().getLegalEntityId(); ImmutableCreditRatesProvider rates = ImmutableCreditRatesProvider.builder() .valuationDate(valuationDate) IsdaCreditDiscountFactors.of(currency, valuationDate, tempCreditCurve)))) .build(); res[0] = calibrationCds.getProduct().getFixedRate(); res[1] = tradePricer.price(calibrationCds, rates, PriceType.CLEAN, refData); if (computeJacobian) { res[0] = calibrationCds.getProduct().getFixedRate(); res[1] = marketQuote.getQuotedValue(); } else {
/** * Calculates the price sensitivity of the product. * <p> * The price sensitivity of the product is the sensitivity of price to the underlying curves. * * @param cds the product * @param ratesProvider the rates provider * @param referenceDate the reference date * @param refData the reference data * @return the present value sensitivity */ public PointSensitivityBuilder priceSensitivity( ResolvedCds cds, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData) { if (isExpired(cds, ratesProvider)) { return PointSensitivityBuilder.none(); } LocalDate stepinDate = cds.getStepinDateOffset().adjust(ratesProvider.getValuationDate(), refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); double recoveryRate = recoveryRate(cds, ratesProvider); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); PointSensitivityBuilder protectionLegSensi = protectionLegSensitivity(cds, rates.getFirst(), rates.getSecond(), referenceDate, effectiveStartDate, recoveryRate); PointSensitivityBuilder riskyAnnuitySensi = riskyAnnuitySensitivity(cds, rates.getFirst(), rates.getSecond(), referenceDate, stepinDate, effectiveStartDate) .multipliedBy(-cds.getFixedRate()); return protectionLegSensi.combinedWith(riskyAnnuitySensi); }
public void endedTest() { LocalDate valuationDate = PRODUCT_NEXTDAY.getProtectionEndDate().plusDays(1); CreditRatesProvider provider = createCreditRatesProvider(valuationDate); double price = PRICER.price(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), CLEAN, REF_DATA); assertEquals(price, 0d); CurrencyAmount pv = PRICER.presentValue(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), CLEAN, REF_DATA); assertEquals(pv, CurrencyAmount.zero(USD)); assertThrowsIllegalArg(() -> PRICER.parSpread(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), REF_DATA)); double protectionLeg = PRICER.protectionLeg(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), REF_DATA); assertEquals(protectionLeg, 0d); double riskyAnnuity = PRICER.riskyAnnuity(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), CLEAN, REF_DATA); assertEquals(riskyAnnuity, 0d); CurrencyAmount rpv01 = PRICER.rpv01(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), CLEAN, REF_DATA); assertEquals(rpv01, CurrencyAmount.zero(USD)); CurrencyAmount recovery01 = PRICER.recovery01(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), REF_DATA); assertEquals(recovery01, CurrencyAmount.zero(USD)); PointSensitivityBuilder sensi = PRICER.presentValueSensitivity(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), REF_DATA); assertEquals(sensi, PointSensitivityBuilder.none()); PointSensitivityBuilder sensiPrice = PRICER.priceSensitivity(PRODUCT_NEXTDAY, provider, PRODUCT_NEXTDAY.getSettlementDateOffset().adjust(provider.getValuationDate(), REF_DATA), REF_DATA); assertEquals(sensiPrice, PointSensitivityBuilder.none()); assertThrowsIllegalArg(() -> PRICER.parSpreadSensitivity(PRODUCT_NEXTDAY, provider,
private CurrencyParameterSensitivity bucketedCs01( ResolvedCdsTrade trade, List<ResolvedCdsTrade> bucketCds, List<ResolvedTradeParameterMetadata> metadata, CreditRatesProvider ratesProvider, ReferenceData refData) { DoubleArray sensiValue = computedBucketedCs01(trade, bucketCds, ratesProvider, refData); return CurrencyParameterSensitivity.of( CurveName.of("impliedSpreads"), metadata, trade.getProduct().getCurrency(), sensiValue); }
/** * Calculates the risky annuity, which is RPV01 per unit notional. * * @param cds the product * @param ratesProvider the rates provider * @param referenceDate the reference date * @param priceType the price type * @param refData the reference data * @return the risky annuity */ public double riskyAnnuity( ResolvedCds cds, CreditRatesProvider ratesProvider, LocalDate referenceDate, PriceType priceType, ReferenceData refData) { if (isExpired(cds, ratesProvider)) { return 0d; } LocalDate stepinDate = cds.getStepinDateOffset().adjust(ratesProvider.getValuationDate(), refData); LocalDate effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate); Pair<CreditDiscountFactors, LegalEntitySurvivalProbabilities> rates = reduceDiscountFactors(cds, ratesProvider); return riskyAnnuity(cds, rates.getFirst(), rates.getSecond(), referenceDate, stepinDate, effectiveStartDate, priceType); }