//------------------------------------------------------------------------- public virtual void test_trade() { CdsIndexIsdaCreditCurveNode node = CdsIndexIsdaCreditCurveNode.ofQuotedSpread(TEMPLATE, QUOTE_ID, INDEX_ID, LEGAL_ENTITIES, 0.01); double rate = 0.0125; double quantity = -1234.56; MarketData marketData = ImmutableMarketData.builder(VAL_DATE).addValue(QUOTE_ID, rate).build(); CdsIndexCalibrationTrade trade = node.trade(quantity, marketData, REF_DATA); CdsTrade cdsTrade = TEMPLATE.createTrade(INDEX_ID, VAL_DATE, SELL, -quantity, 0.01, REF_DATA); CdsIndex cdsIndex = CdsIndex.of(SELL, INDEX_ID, LEGAL_ENTITIES, TEMPLATE.Convention.Currency, -quantity, date(2015, 6, 20), date(2025, 6, 20), Frequency.P3M, TEMPLATE.Convention.SettlementDateOffset.Calendar, 0.01); CdsIndex cdsIndexMod = cdsIndex.toBuilder().paymentSchedule(cdsIndex.PaymentSchedule.toBuilder().rollConvention(RollConventions.DAY_20).startDateBusinessDayAdjustment(cdsIndex.PaymentSchedule.BusinessDayAdjustment).build()).build(); CdsIndexTrade expected = CdsIndexTrade.builder().product(cdsIndexMod).info(cdsTrade.Info).build(); assertEquals(trade.UnderlyingTrade, expected); assertEquals(trade.Quote, CdsQuote.of(CdsQuoteConvention.QUOTED_SPREAD, rate)); CdsIndexIsdaCreditCurveNode node1 = CdsIndexIsdaCreditCurveNode.ofParSpread(TEMPLATE, QUOTE_ID, INDEX_ID, LEGAL_ENTITIES); CdsTrade cdsTrade1 = TEMPLATE.createTrade(INDEX_ID, VAL_DATE, SELL, -quantity, rate, REF_DATA); CdsIndexCalibrationTrade trade1 = node1.trade(quantity, marketData, REF_DATA); CdsIndex cdsIndex1 = CdsIndex.of(SELL, INDEX_ID, LEGAL_ENTITIES, TEMPLATE.Convention.Currency, -quantity, date(2015, 6, 20), date(2025, 6, 20), Frequency.P3M, TEMPLATE.Convention.SettlementDateOffset.Calendar, rate); CdsIndex cdsIndexMod1 = cdsIndex1.toBuilder().paymentSchedule(cdsIndex.PaymentSchedule.toBuilder().rollConvention(RollConventions.DAY_20).startDateBusinessDayAdjustment(cdsIndex1.PaymentSchedule.BusinessDayAdjustment).build()).build(); CdsIndexTrade expected1 = CdsIndexTrade.builder().product(cdsIndexMod1).info(cdsTrade1.Info).build(); assertEquals(trade1.UnderlyingTrade, expected1); assertEquals(trade1.Quote, CdsQuote.of(CdsQuoteConvention.PAR_SPREAD, rate)); }
static CreditDataSet() { ImmutableList.Builder <StandardId> builder = ImmutableList.builder(); for (int i = 0; i < 97; ++i) { builder.add(StandardId.of("OG", i.ToString())); } LEGAL_ENTITIES = builder.build(); double flatRate = 0.05; double t = 20.0; IsdaCreditDiscountFactors yieldCurve = IsdaCreditDiscountFactors.of(USD, VALUATION_DATE, CurveName.of("discount"), DoubleArray.of(t), DoubleArray.of(flatRate), ACT_365F); DISCOUNT_CURVE = yieldCurve.Curve; RecoveryRates recoveryRate = ConstantRecoveryRates.of(LEGAL_ENTITY, VALUATION_DATE, RECOVERY_RATE); // create the curve nodes and input market quotes ImmutableMarketDataBuilder marketQuoteBuilder = ImmutableMarketData.builder(VALUATION_DATE); ImmutableList.Builder <CdsIsdaCreditCurveNode> nodesBuilder = ImmutableList.builder(); ImmutableList.Builder <ResolvedTradeParameterMetadata> cdsMetadataBuilder = ImmutableList.builder(); ImmutableList.Builder <ResolvedTradeParameterMetadata> cdsIndexMetadataBuilder = ImmutableList.builder(); for (int i = 0; i < NUM_MARKET_CDS; i++) { QuoteId quoteId = QuoteId.of(StandardId.of("OG", PAR_SPD_DATES[i].ToString())); CdsIsdaCreditCurveNode node = CdsIsdaCreditCurveNode.ofParSpread(DatesCdsTemplate.of(VALUATION_DATE, PAR_SPD_DATES[i], CDS_CONV), quoteId, LEGAL_ENTITY); MARKET_CDS[i] = CdsTrade.builder().product(Cds.of(BUY, LEGAL_ENTITY, USD, NOTIONAL, VALUATION_DATE, PAR_SPD_DATES[i], P3M, SAT_SUN, PAR_SPREADS[i] * ONE_BP)).info(TradeInfo.of(VALUATION_DATE)).build().resolve(REF_DATA); MARKET_CDS_INDEX[i] = CdsIndexTrade.builder().product(CdsIndex.of(BuySell.BUY, INDEX_ID, LEGAL_ENTITIES, USD, NOTIONAL, VALUATION_DATE, PAR_SPD_DATES[i], P3M, SAT_SUN, PAR_SPREADS[i] * ONE_BP)).info(TradeInfo.of(VALUATION_DATE)).build().resolve(REF_DATA); marketQuoteBuilder.addValue(quoteId, PAR_SPREADS[i] * ONE_BP); nodesBuilder.add(node); cdsMetadataBuilder.add(ResolvedTradeParameterMetadata.of(MARKET_CDS[i], MARKET_CDS[i].Product.ProtectionEndDate.ToString())); cdsIndexMetadataBuilder.add(ResolvedTradeParameterMetadata.of(MARKET_CDS_INDEX[i], MARKET_CDS_INDEX[i].Product.ProtectionEndDate.ToString())); } ImmutableMarketData marketQuotes = marketQuoteBuilder.build(); ImmutableList <CdsIsdaCreditCurveNode> nodes = nodesBuilder.build(); CDS_METADATA = cdsMetadataBuilder.build(); CDS_INDEX_METADATA = cdsIndexMetadataBuilder.build(); ImmutableCreditRatesProvider rates = ImmutableCreditRatesProvider.builder().valuationDate(VALUATION_DATE).recoveryRateCurves(ImmutableMap.of(LEGAL_ENTITY, recoveryRate)).discountCurves(ImmutableMap.of(USD, yieldCurve)).build(); IsdaCreditCurveDefinition definition = IsdaCreditCurveDefinition.of(CREDIT_CURVE_NAME, USD, VALUATION_DATE, ACT_365F, nodes, true, true); // calibrate LegalEntitySurvivalProbabilities calibrated = BUILDER.calibrate(definition, marketQuotes, rates, REF_DATA); NodalCurve underlyingCurve = ((IsdaCreditDiscountFactors)calibrated.SurvivalProbabilities).Curve; CDS_CREDIT_CURVE = underlyingCurve; INDEX_CREDIT_CURVE = underlyingCurve.withMetadata(underlyingCurve.Metadata.withInfo(CurveInfoType.CDS_INDEX_FACTOR, INDEX_FACTOR).withParameterMetadata(CDS_INDEX_METADATA)); // replace parameter metadata CDS_RECOVERY_RATE = ConstantCurve.of(Curves.recoveryRates("CDS recovery rate", ACT_365F), RECOVERY_RATE); INDEX_RECOVERY_RATE = ConstantCurve.of(Curves.recoveryRates("Index recovery rate", ACT_365F), RECOVERY_RATE); }
static SpreadSensitivityCalculatorTest() { double flatRate = 0.05; double t = 20.0; YIELD_CURVE = IsdaCreditDiscountFactors.of(USD, VALUATION_DATE, CurveName.of("discount"), DoubleArray.of(t), DoubleArray.of(flatRate), ACT_365F); ImmutableMarketDataBuilder dataBuilder = ImmutableMarketData.builder(VALUATION_DATE); ImmutableList.Builder <CdsIsdaCreditCurveNode> nodesBuilder = ImmutableList.builder(); ImmutableList.Builder <ResolvedTradeParameterMetadata> cdsMetadataBuilder = ImmutableList.builder(); ImmutableList.Builder <ResolvedTradeParameterMetadata> cdsIndexMetadataBuilder = ImmutableList.builder(); for (int i = 0; i < NUM_MARKET_CDS; i++) { QuoteId quoteId = QuoteId.of(StandardId.of("OG", PAR_SPD_DATES[i].ToString())); CdsIsdaCreditCurveNode node = CdsIsdaCreditCurveNode.ofParSpread(DatesCdsTemplate.of(VALUATION_DATE, PAR_SPD_DATES[i], CDS_CONV), quoteId, LEGAL_ENTITY); MARKET_CDS[i] = CdsTrade.builder().product(Cds.of(BUY, LEGAL_ENTITY, USD, NOTIONAL, VALUATION_DATE, PAR_SPD_DATES[i], P3M, SAT_SUN, PAR_SPREADS[i] * ONE_BP)).info(TradeInfo.of(VALUATION_DATE)).build().resolve(REF_DATA); MARKET_CDS_INDEX[i] = CdsIndexTrade.builder().product(CdsIndex.of(BuySell.BUY, INDEX_ID, LEGAL_ENTITIES, USD, NOTIONAL, VALUATION_DATE, PAR_SPD_DATES[i], P3M, SAT_SUN, PAR_SPREADS[i] * ONE_BP)).info(TradeInfo.of(VALUATION_DATE)).build().resolve(REF_DATA); dataBuilder.addValue(quoteId, PAR_SPREADS[i] * ONE_BP); nodesBuilder.add(node); cdsMetadataBuilder.add(ResolvedTradeParameterMetadata.of(MARKET_CDS[i], MARKET_CDS[i].Product.ProtectionEndDate.ToString())); cdsIndexMetadataBuilder.add(ResolvedTradeParameterMetadata.of(MARKET_CDS_INDEX[i], MARKET_CDS_INDEX[i].Product.ProtectionEndDate.ToString())); } ImmutableMarketData marketData = dataBuilder.build(); ImmutableList <CdsIsdaCreditCurveNode> nodes = nodesBuilder.build(); CDS_METADATA = cdsMetadataBuilder.build(); CDS_INDEX_METADATA = cdsIndexMetadataBuilder.build(); ImmutableCreditRatesProvider rates = ImmutableCreditRatesProvider.builder().valuationDate(VALUATION_DATE).recoveryRateCurves(ImmutableMap.of(LEGAL_ENTITY, RECOVERY_CURVE)).discountCurves(ImmutableMap.of(USD, YIELD_CURVE)).build(); IsdaCreditCurveDefinition definition = IsdaCreditCurveDefinition.of(CREDIT_CURVE_NAME, USD, VALUATION_DATE, ACT_365F, nodes, true, true); CREDIT_CURVE = BUILDER.calibrate(definition, marketData, rates, REF_DATA); NodalCurve underlyingCurve = ((IsdaCreditDiscountFactors)CREDIT_CURVE.SurvivalProbabilities).Curve; NodalCurve curveWithFactor = underlyingCurve.withMetadata(underlyingCurve.Metadata.withInfo(CurveInfoType.CDS_INDEX_FACTOR, INDEX_FACTOR).withParameterMetadata(CDS_INDEX_METADATA)); // replace parameter metadata CREDIT_CURVE_INDEX = LegalEntitySurvivalProbabilities.of(INDEX_ID, IsdaCreditDiscountFactors.of(USD, VALUATION_DATE, curveWithFactor)); }
// parses the CDS internal Trade parseCds(FpmlDocument document, XmlElement tradeEl, TradeInfoBuilder tradeInfoBuilder) { XmlElement cdsEl = tradeEl.getChild("creditDefaultSwap"); XmlElement generalTermsEl = cdsEl.getChild("generalTerms"); XmlElement feeLegEl = cdsEl.getChild("feeLeg"); document.validateNotPresent(generalTermsEl, "basketReferenceInformation"); document.validateNotPresent(feeLegEl, "singlePayment"); BuySell buySell = document.parseBuyerSeller(generalTermsEl, tradeInfoBuilder); // effective and termination date are optional in FpML but mandatory for Strata AdjustableDate effectiveDate = document.parseAdjustableDate(generalTermsEl.getChild("effectiveDate")); AdjustableDate terminationDate = document.parseAdjustableDate(generalTermsEl.getChild("scheduledTerminationDate")); BusinessDayAdjustment bda = generalTermsEl.findChild("dateAdjustments").map(el => document.parseBusinessDayAdjustments(el)).orElse(BusinessDayAdjustment.NONE); PeriodicSchedule.Builder scheduleBuilder = PeriodicSchedule.builder().startDate(effectiveDate.Unadjusted).startDateBusinessDayAdjustment(effectiveDate.Adjustment).endDate(terminationDate.Unadjusted).endDateBusinessDayAdjustment(terminationDate.Adjustment).businessDayAdjustment(bda); // an upfront fee Optional <XmlElement> initialPaymentOptEl = feeLegEl.findChild("initialPayment"); AdjustablePayment upfrontFee = null; if (initialPaymentOptEl.Present) { XmlElement initialPaymentEl = initialPaymentOptEl.get(); PayReceive payRec = document.parsePayerReceiver(initialPaymentEl, tradeInfoBuilder); CurrencyAmount amount = document.parseCurrencyAmount(initialPaymentEl.getChild("paymentAmount")); LocalDate date = initialPaymentEl.findChild("adjustablePaymentDate").map(el => document.parseDate(el)).orElse(effectiveDate.Unadjusted); AdjustableDate adjDate = AdjustableDate.of(date, bda); upfrontFee = payRec.Pay ? AdjustablePayment.ofPay(amount, adjDate) : AdjustablePayment.ofReceive(amount, adjDate); } // we require a periodicPayment and fixedAmountCalculation XmlElement periodicPaymentEl = feeLegEl.getChild("periodicPayment"); scheduleBuilder.frequency(periodicPaymentEl.findChild("paymentFrequency").map(el => document.parseFrequency(el)).orElse(Frequency.P3M)); periodicPaymentEl.findChild("firstPaymentDate").ifPresent(el => scheduleBuilder.firstRegularStartDate(document.parseDate(el))); periodicPaymentEl.findChild("firstPeriodStartDate").ifPresent(el => scheduleBuilder.overrideStartDate(AdjustableDate.of(document.parseDate(el)))); periodicPaymentEl.findChild("lastRegularPaymentDate").ifPresent(el => scheduleBuilder.lastRegularEndDate(document.parseDate(el))); scheduleBuilder.rollConvention(periodicPaymentEl.findChild("rollConvention").map(el => document.convertRollConvention(el.Content)).orElse(null)); XmlElement fixedAmountCalcEl = periodicPaymentEl.getChild("fixedAmountCalculation"); double fixedRate = document.parseDecimal(fixedAmountCalcEl.getChild("fixedRate")); DayCount dayCount = fixedAmountCalcEl.findChild("dayCountFraction").map(el => document.parseDayCountFraction(el)).orElse(DayCounts.ACT_360); // handle a single protectionTerms element XmlElement protectionTermEl = cdsEl.getChild("protectionTerms"); CurrencyAmount notional = document.parseCurrencyAmount(protectionTermEl.getChild("calculationAmount")); // single name CDS Optional <XmlElement> singleOptEl = generalTermsEl.findChild("referenceInformation"); if (singleOptEl.Present) { // we require a single entityId XmlElement referenceEntityEl = singleOptEl.get().getChild("referenceEntity"); XmlElement entityIdEl = referenceEntityEl.getChild("entityId"); string scheme = entityIdEl.findAttribute("entityIdScheme").orElse("http://www.fpml.org/coding-scheme/external/entity-id-RED-1-0"); string value = entityIdEl.Content; StandardId entityId = StandardId.of(scheme, value); Cds cds = Cds.builder().buySell(buySell).legalEntityId(entityId).currency(notional.Currency).notional(notional.Amount).paymentSchedule(scheduleBuilder.build()).fixedRate(fixedRate).dayCount(dayCount).build(); return(CdsTrade.builder().info(tradeInfoBuilder.build()).product(cds).upfrontFee(upfrontFee).build()); } // CDS index Optional <XmlElement> indexOptEl = generalTermsEl.findChild("indexReferenceInformation"); if (indexOptEl.Present) { string indexName = indexOptEl.get().getChild("indexName").Content; CdsIndex cdsIndex = CdsIndex.builder().buySell(buySell).cdsIndexId(StandardId.of("CDX-Name", indexName)).currency(notional.Currency).notional(notional.Amount).paymentSchedule(scheduleBuilder.build()).fixedRate(fixedRate).dayCount(dayCount).build(); return(CdsIndexTrade.builder().info(tradeInfoBuilder.build()).product(cdsIndex).upfrontFee(upfrontFee).build()); } // unknown type throw new FpmlParseException("FpML CDS must be single name or index"); }