/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame.credit;
import org.apache.commons.lang.ArrayUtils;
import com.opengamma.analytics.financial.credit.isdastandardmodel.ISDACompliantYieldCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.DiscountCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve;
import com.opengamma.sesame.Environment;
import com.opengamma.sesame.MulticurveBundle;
import com.opengamma.sesame.marketdata.MulticurveId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.result.Result;
/**
* Builds an ISDA curve for the passed currency. The function provides a mapping from a Yield Curve contained in
* the market data environment to the Isda compliant Yield curve. The returned {@link ISDACompliantYieldCurve}
* is the yield curve used in ISDA compliant analytic credit computations.
*
* The Isda compliant yield curve has a requirement to be log-linear interpolated. Thus the original interpolation used
* to create the curve in the market data environment will be converted to log-linear interpolation.
*
*/
public class MappingIsdaCompliantYieldCurveFn implements IsdaCompliantYieldCurveFn {
private final String _multicurveName;
/**
* Builds a new instance.
* @param multicurveName the name of the multicurve
*/
public MappingIsdaCompliantYieldCurveFn(String multicurveName) {
_multicurveName = ArgumentChecker.notNull(multicurveName, "multicurveName");
}
@Override
public Result<IsdaYieldCurve> buildIsdaCompliantCurve(Environment env, Currency ccy) {
Result<MulticurveBundle> bundleResult = env.getMarketDataBundle().get(MulticurveId.of(_multicurveName),
MulticurveBundle.class);
if (bundleResult.isSuccess()) {
MulticurveBundle multicurve = bundleResult.getValue();
YieldAndDiscountCurve curve = multicurve.getMulticurveProvider().getCurve(ccy);
ISDACompliantYieldCurve isdaCompliantYieldCurve = buildCurve(curve);
IsdaYieldCurve yieldCurve = IsdaYieldCurve.builder()
.calibratedCurve(isdaCompliantYieldCurve)
.build();
return Result.success(yieldCurve);
} else {
return Result.failure(bundleResult);
}
}
/**
* Creates the ISDACompliantYieldCurve from the YieldAndDiscountCurve
*/
private ISDACompliantYieldCurve buildCurve(YieldAndDiscountCurve curve) {
Double[] tenors;
Double[] rates;
if (curve instanceof YieldCurve) {
tenors = ((YieldCurve) curve).getCurve().getXData();
rates = ((YieldCurve) curve).getCurve().getYData();
} else if (curve instanceof DiscountCurve) {
tenors = ((DiscountCurve) curve).getCurve().getXData();
Double[] rawRates = ((DiscountCurve) curve).getCurve().getYData();
// Convert discount factors
Double[] zeroRates = new Double[rawRates.length];
for (int i = 0; i < rawRates.length; ++i) {
if (tenors[i] <= 0) {
throw new IllegalArgumentException("Mapping to the ISDA compliant yield curve does not handle time <= 0");
}
zeroRates[i] = -Math.log(rawRates[i]) / tenors[i];
}
rates = zeroRates;
} else {
throw new IllegalArgumentException("Mapping to the ISDA compliant yield curve is supported for the YieldCurve" +
" and DiscountCurve instances of YieldAndDiscountCurve");
}
return new ISDACompliantYieldCurve(ArrayUtils.toPrimitive(tenors), ArrayUtils.toPrimitive(rates));
}
}