All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opengamma.strata.pricer.credit.IsdaCompliantIndexCurveCalibrator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.pricer.credit;

import static com.opengamma.strata.collect.Guavate.casting;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import com.google.common.collect.ImmutableList;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.Guavate;
import com.opengamma.strata.data.MarketData;
import com.opengamma.strata.market.curve.CurveInfoType;
import com.opengamma.strata.market.curve.CurveMetadata;
import com.opengamma.strata.market.curve.IsdaCreditCurveDefinition;
import com.opengamma.strata.market.curve.NodalCurve;
import com.opengamma.strata.market.curve.node.CdsIndexIsdaCreditCurveNode;
import com.opengamma.strata.market.curve.node.CdsIsdaCreditCurveNode;
import com.opengamma.strata.market.observable.LegalEntityInformation;
import com.opengamma.strata.market.observable.LegalEntityInformationId;
import com.opengamma.strata.market.param.ParameterMetadata;
import com.opengamma.strata.market.param.ResolvedTradeParameterMetadata;

/**
 * ISDA compliant index curve calibrator.
 * 

* A single credit curve (index curve) is calibrated for CDS index trades. *

* The curve is defined using one or more {@linkplain CdsIndexIsdaCreditCurveNode nodes}. * Each node primarily defines enough information to produce a reference CDS index trade. * All of the curve nodes must be based on a common CDS index ID and currency. *

* Calibration involves pricing, and re-pricing, these trades to find the best fit using a root finder, * where the pricing is based on {@link IsdaHomogenousCdsIndexTradePricer}, thus the calibration is * completed by using a calibrator for single name CDS trades, {@link IsdaCompliantCreditCurveCalibrator}. *

* Relevant discount curve and recovery rate curve are required to complete the calibration. */ public class IsdaCompliantIndexCurveCalibrator { /** * Default implementation. */ private static final IsdaCompliantIndexCurveCalibrator STANDARD = new IsdaCompliantIndexCurveCalibrator(FastCreditCurveCalibrator.standard()); /** * The underlying credit curve calibrator. */ private final IsdaCompliantCreditCurveCalibrator creditCurveCalibrator; //------------------------------------------------------------------------- /** * Obtains the standard curve calibrator. *

* The accuracy of the root finder is set to be its default, 1.0e-12; * * @return the standard curve calibrator */ public static IsdaCompliantIndexCurveCalibrator standard() { return IsdaCompliantIndexCurveCalibrator.STANDARD; } /** * Constructor with the underlying credit curve calibrator specified. * * @param creditCurveCalibrator the credit curve calibrator */ public IsdaCompliantIndexCurveCalibrator(IsdaCompliantCreditCurveCalibrator creditCurveCalibrator) { this.creditCurveCalibrator = ArgChecker.notNull(creditCurveCalibrator, "creditCurveCalibrator"); } //------------------------------------------------------------------------- /** * Calibrates the index curve to the market data. *

* This creates the single credit curve for CDS index trades. * The curve nodes in {@code IsdaCreditCurveDefinition} must be CDS index. *

* The relevant discount curve and recovery rate curve must be stored in {@code ratesProvider}. * The day count convention for the resulting credit curve is the same as that of the discount curve. * * @param curveDefinition the curve definition * @param marketData the market data * @param ratesProvider the rates provider * @param refData the reference data * @return the index curve */ public LegalEntitySurvivalProbabilities calibrate( IsdaCreditCurveDefinition curveDefinition, MarketData marketData, ImmutableCreditRatesProvider ratesProvider, ReferenceData refData) { ArgChecker.isTrue(curveDefinition.getCurveValuationDate().equals(ratesProvider.getValuationDate()), "ratesProvider and curveDefinition must be based on the same valuation date"); ImmutableList curveNodes = curveDefinition.getCurveNodes().stream() .filter(n -> n instanceof CdsIndexIsdaCreditCurveNode) .map(n -> (CdsIndexIsdaCreditCurveNode) n) .collect(Guavate.toImmutableList()); // Homogeneity of curveNode will be checked within IsdaCompliantCreditCurveCalibrator double indexFactor = computeIndexFactor(curveNodes.get(0), marketData); List cdsNodes = curveNodes.stream().map(i -> toCdsNode(i)).collect(Guavate.toImmutableList()); LegalEntitySurvivalProbabilities creditCurve = creditCurveCalibrator.calibrate( cdsNodes, curveDefinition.getName(), marketData, ratesProvider, curveDefinition.getDayCount(), curveDefinition.getCurrency(), curveDefinition.isComputeJacobian(), false, refData); NodalCurve underlyingCurve = ((IsdaCreditDiscountFactors) creditCurve.getSurvivalProbabilities()).getCurve(); CurveMetadata metadata = underlyingCurve.getMetadata().withInfo(CurveInfoType.CDS_INDEX_FACTOR, indexFactor); if (curveDefinition.isStoreNodeTrade()) { int nNodes = curveDefinition.getCurveNodes().size(); ImmutableList parameterMetadata = IntStream.range(0, nNodes) .mapToObj( n -> ResolvedTradeParameterMetadata.of( curveNodes.get(n).trade(1d, marketData, refData).getUnderlyingTrade().resolve(refData), curveNodes.get(n).getLabel())) .collect(Guavate.toImmutableList()); metadata = metadata.withParameterMetadata(parameterMetadata); } NodalCurve curveWithFactor = underlyingCurve.withMetadata(metadata); return LegalEntitySurvivalProbabilities.of( creditCurve.getLegalEntityId(), IsdaCreditDiscountFactors.of(creditCurve.getCurrency(), creditCurve.getValuationDate(), curveWithFactor)); } //------------------------------------------------------------------------- private CdsIsdaCreditCurveNode toCdsNode(CdsIndexIsdaCreditCurveNode index) { return CdsIsdaCreditCurveNode.builder() .label(index.getLabel()) .legalEntityId(index.getCdsIndexId()) .observableId(index.getObservableId()) .quoteConvention(index.getQuoteConvention()) .template(index.getTemplate()) .fixedRate(index.getFixedRate().isPresent() ? index.getFixedRate().getAsDouble() : null) .build(); } private double computeIndexFactor(CdsIndexIsdaCreditCurveNode node, MarketData marketData) { double numDefaulted = node.getLegalEntityIds().stream() .map(s -> marketData.getValue(LegalEntityInformationId.of(s))) .map(casting(LegalEntityInformation.class)) .filter(LegalEntityInformation::isDefaulted) .collect(Collectors.toList()) .size(); double numTotal = node.getLegalEntityIds().size(); return (numTotal - numDefaulted) / numTotal; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy