/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.credit;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.Period;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.joda.beans.Bean;
import org.joda.beans.BeanBuilder;
import org.joda.beans.BeanDefinition;
import org.joda.beans.ImmutableBean;
import org.joda.beans.ImmutableValidator;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaProperty;
import org.joda.beans.Property;
import org.joda.beans.PropertyDefinition;
import org.joda.beans.impl.direct.DirectFieldsBeanBuilder;
import org.joda.beans.impl.direct.DirectMetaBean;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import com.google.common.collect.Lists;
import com.opengamma.strata.basics.date.Tenor;
import com.opengamma.strata.market.curve.CurveMetadata;
import com.opengamma.strata.market.curve.CurveName;
import com.opengamma.strata.market.curve.DefaultCurveMetadata;
import com.opengamma.strata.market.param.ParameterMetadata;
import com.opengamma.strata.market.param.TenorDateParameterMetadata;
import com.opengamma.strata.product.credit.type.CdsConvention;
/**
* The par rates used when calibrating an ISDA credit curve.
*/
@BeanDefinition(builderScope = "private")
public final class IsdaCreditCurveInputs
implements ImmutableBean, Serializable {
// TODO the recovery rate is not really a part of the curve, but the data is available along side when
// TODO as parsing the curves, so it is convenient to put it here for the moment.
// TODO the scaling factor is the index factor and not really part of the curve
// TODO replace arrays with lists
/**
* The curve name.
*/
@PropertyDefinition(validate = "notNull")
private final CurveName name;
/**
* The tenor at each curve node.
*/
@PropertyDefinition(validate = "notNull")
private final Period[] creditCurvePoints;
/**
* The end date at each curve node.
*/
@PropertyDefinition(validate = "notNull")
private final LocalDate[] endDatePoints;
/**
* The par rate at each curve node.
*/
@PropertyDefinition(validate = "notNull")
private final double[] parRates;
/**
* The underlying convention.
*/
@PropertyDefinition(validate = "notNull")
private final CdsConvention cdsConvention;
/**
* The scaling factor.
*/
@PropertyDefinition(validate = "notNull")
private final double scalingFactor;
//-------------------------------------------------------------------------
/**
* Provide curve meta data to capture tenor and anchor point date information
* @return curve metadata
*/
public CurveMetadata getCurveMetaData() {
List<ParameterMetadata> parameters = Lists.newArrayList();
for (int i = 0; i < creditCurvePoints.length; i++) {
TenorDateParameterMetadata pointData = TenorDateParameterMetadata.of(endDatePoints[i], Tenor.of(creditCurvePoints[i]));
parameters.add(pointData);
}
return DefaultCurveMetadata.builder()
.curveName(name)
.parameterMetadata(parameters)
.build();
}
/**
* Creates an instance of the par rates.
*
* @param name the curve name
* @param creditCurvePoints the tenor at each curve node
* @param parRates the par rate at each curve node
* @param endDatePoints the end date at each curve node
* @param cdsConvention the underlying convention
* @param scalingFactor the scaling factor
* @return the par rates
*/
public static IsdaCreditCurveInputs of(
CurveName name,
Period[] creditCurvePoints,
LocalDate[] endDatePoints,
double[] parRates,
CdsConvention cdsConvention,
double scalingFactor) {
return new IsdaCreditCurveInputs(
name,
creditCurvePoints,
endDatePoints,
parRates,
cdsConvention,
scalingFactor);
}
@ImmutableValidator
private void validate() {
if (creditCurvePoints.length <= 0) {
throw new IllegalArgumentException("Cannot have zero points");
}
if (creditCurvePoints.length != parRates.length) {
throw new IllegalArgumentException("Points do not line up");
}
}
//-------------------------------------------------------------------------
/**
* Applies a parallel shift to all the nodes.
*
* @param shift the shift to apply
* @return the bumped instance
*/
public IsdaCreditCurveInputs parallelShiftParRatesinBps(double shift) {
double[] shiftedRates = parRates.clone();
for (int i = 0; i < shiftedRates.length; i++) {
shiftedRates[i] = shiftedRates[i] + shift;
}
return applyShift(shiftedRates);
}
/**
* Applies a bucketed shift to a single node.
*
* @param index the index of the node to shift
* @param shift the shift to apply
* @return the bumped instance
*/
public IsdaCreditCurveInputs bucketedShiftParRatesinBps(int index, double shift) {
double[] shiftedRates = parRates.clone();
shiftedRates[index] = shiftedRates[index] + shift;
return applyShift(shiftedRates);
}
/**
* Gets the number of nodes.
*
* @return the number of points
*/
public int getNumberOfPoints() {
return creditCurvePoints.length;
}
// applies the shift
private IsdaCreditCurveInputs applyShift(double[] shiftedRates) {
return IsdaCreditCurveInputs.of(
name,
creditCurvePoints.clone(),
endDatePoints.clone(),
shiftedRates,
cdsConvention,
scalingFactor);
}
//------------------------- AUTOGENERATED START -------------------------
///CLOVER:OFF
/**
* The meta-bean for {@code IsdaCreditCurveInputs}.
* @return the meta-bean, not null
*/
public static IsdaCreditCurveInputs.Meta meta() {
return IsdaCreditCurveInputs.Meta.INSTANCE;
}
static {
JodaBeanUtils.registerMetaBean(IsdaCreditCurveInputs.Meta.INSTANCE);
}
/**
* The serialization version id.
*/
private static final long serialVersionUID = 1L;
private IsdaCreditCurveInputs(
CurveName name,
Period[] creditCurvePoints,
LocalDate[] endDatePoints,
double[] parRates,
CdsConvention cdsConvention,
double scalingFactor) {
JodaBeanUtils.notNull(name, "name");
JodaBeanUtils.notNull(creditCurvePoints, "creditCurvePoints");
JodaBeanUtils.notNull(endDatePoints, "endDatePoints");
JodaBeanUtils.notNull(parRates, "parRates");
JodaBeanUtils.notNull(cdsConvention, "cdsConvention");
JodaBeanUtils.notNull(scalingFactor, "scalingFactor");
this.name = name;
this.creditCurvePoints = creditCurvePoints;
this.endDatePoints = endDatePoints;
this.parRates = parRates.clone();
this.cdsConvention = cdsConvention;
this.scalingFactor = scalingFactor;
validate();
}
@Override
public IsdaCreditCurveInputs.Meta metaBean() {
return IsdaCreditCurveInputs.Meta.INSTANCE;
}
@Override
public <R> Property<R> property(String propertyName) {
return metaBean().<R>metaProperty(propertyName).createProperty(this);
}
@Override
public Set<String> propertyNames() {
return metaBean().metaPropertyMap().keySet();
}
//-----------------------------------------------------------------------
/**
* Gets the curve name.
* @return the value of the property, not null
*/
public CurveName getName() {
return name;
}
//-----------------------------------------------------------------------
/**
* Gets the tenor at each curve node.
* @return the value of the property, not null
*/
public Period[] getCreditCurvePoints() {
return creditCurvePoints;
}
//-----------------------------------------------------------------------
/**
* Gets the end date at each curve node.
* @return the value of the property, not null
*/
public LocalDate[] getEndDatePoints() {
return endDatePoints;
}
//-----------------------------------------------------------------------
/**
* Gets the par rate at each curve node.
* @return the value of the property, not null
*/
public double[] getParRates() {
return parRates.clone();
}
//-----------------------------------------------------------------------
/**
* Gets the underlying convention.
* @return the value of the property, not null
*/
public CdsConvention getCdsConvention() {
return cdsConvention;
}
//-----------------------------------------------------------------------
/**
* Gets the scaling factor.
* @return the value of the property, not null
*/
public double getScalingFactor() {
return scalingFactor;
}
//-----------------------------------------------------------------------
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj != null && obj.getClass() == this.getClass()) {
IsdaCreditCurveInputs other = (IsdaCreditCurveInputs) obj;
return JodaBeanUtils.equal(name, other.name) &&
JodaBeanUtils.equal(creditCurvePoints, other.creditCurvePoints) &&
JodaBeanUtils.equal(endDatePoints, other.endDatePoints) &&
JodaBeanUtils.equal(parRates, other.parRates) &&
JodaBeanUtils.equal(cdsConvention, other.cdsConvention) &&
JodaBeanUtils.equal(scalingFactor, other.scalingFactor);
}
return false;
}
@Override
public int hashCode() {
int hash = getClass().hashCode();
hash = hash * 31 + JodaBeanUtils.hashCode(name);
hash = hash * 31 + JodaBeanUtils.hashCode(creditCurvePoints);
hash = hash * 31 + JodaBeanUtils.hashCode(endDatePoints);
hash = hash * 31 + JodaBeanUtils.hashCode(parRates);
hash = hash * 31 + JodaBeanUtils.hashCode(cdsConvention);
hash = hash * 31 + JodaBeanUtils.hashCode(scalingFactor);
return hash;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder(224);
buf.append("IsdaCreditCurveInputs{");
buf.append("name").append('=').append(name).append(',').append(' ');
buf.append("creditCurvePoints").append('=').append(creditCurvePoints).append(',').append(' ');
buf.append("endDatePoints").append('=').append(endDatePoints).append(',').append(' ');
buf.append("parRates").append('=').append(parRates).append(',').append(' ');
buf.append("cdsConvention").append('=').append(cdsConvention).append(',').append(' ');
buf.append("scalingFactor").append('=').append(JodaBeanUtils.toString(scalingFactor));
buf.append('}');
return buf.toString();
}
//-----------------------------------------------------------------------
/**
* The meta-bean for {@code IsdaCreditCurveInputs}.
*/
public static final class Meta extends DirectMetaBean {
/**
* The singleton instance of the meta-bean.
*/
static final Meta INSTANCE = new Meta();
/**
* The meta-property for the {@code name} property.
*/
private final MetaProperty<CurveName> name = DirectMetaProperty.ofImmutable(
this, "name", IsdaCreditCurveInputs.class, CurveName.class);
/**
* The meta-property for the {@code creditCurvePoints} property.
*/
private final MetaProperty<Period[]> creditCurvePoints = DirectMetaProperty.ofImmutable(
this, "creditCurvePoints", IsdaCreditCurveInputs.class, Period[].class);
/**
* The meta-property for the {@code endDatePoints} property.
*/
private final MetaProperty<LocalDate[]> endDatePoints = DirectMetaProperty.ofImmutable(
this, "endDatePoints", IsdaCreditCurveInputs.class, LocalDate[].class);
/**
* The meta-property for the {@code parRates} property.
*/
private final MetaProperty<double[]> parRates = DirectMetaProperty.ofImmutable(
this, "parRates", IsdaCreditCurveInputs.class, double[].class);
/**
* The meta-property for the {@code cdsConvention} property.
*/
private final MetaProperty<CdsConvention> cdsConvention = DirectMetaProperty.ofImmutable(
this, "cdsConvention", IsdaCreditCurveInputs.class, CdsConvention.class);
/**
* The meta-property for the {@code scalingFactor} property.
*/
private final MetaProperty<Double> scalingFactor = DirectMetaProperty.ofImmutable(
this, "scalingFactor", IsdaCreditCurveInputs.class, Double.TYPE);
/**
* The meta-properties.
*/
private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
this, null,
"name",
"creditCurvePoints",
"endDatePoints",
"parRates",
"cdsConvention",
"scalingFactor");
/**
* Restricted constructor.
*/
private Meta() {
}
@Override
protected MetaProperty<?> metaPropertyGet(String propertyName) {
switch (propertyName.hashCode()) {
case 3373707: // name
return name;
case -1771294215: // creditCurvePoints
return creditCurvePoints;
case 578522476: // endDatePoints
return endDatePoints;
case 1157229426: // parRates
return parRates;
case 288334147: // cdsConvention
return cdsConvention;
case -794828874: // scalingFactor
return scalingFactor;
}
return super.metaPropertyGet(propertyName);
}
@Override
public BeanBuilder<? extends IsdaCreditCurveInputs> builder() {
return new IsdaCreditCurveInputs.Builder();
}
@Override
public Class<? extends IsdaCreditCurveInputs> beanType() {
return IsdaCreditCurveInputs.class;
}
@Override
public Map<String, MetaProperty<?>> metaPropertyMap() {
return metaPropertyMap$;
}
//-----------------------------------------------------------------------
/**
* The meta-property for the {@code name} property.
* @return the meta-property, not null
*/
public MetaProperty<CurveName> name() {
return name;
}
/**
* The meta-property for the {@code creditCurvePoints} property.
* @return the meta-property, not null
*/
public MetaProperty<Period[]> creditCurvePoints() {
return creditCurvePoints;
}
/**
* The meta-property for the {@code endDatePoints} property.
* @return the meta-property, not null
*/
public MetaProperty<LocalDate[]> endDatePoints() {
return endDatePoints;
}
/**
* The meta-property for the {@code parRates} property.
* @return the meta-property, not null
*/
public MetaProperty<double[]> parRates() {
return parRates;
}
/**
* The meta-property for the {@code cdsConvention} property.
* @return the meta-property, not null
*/
public MetaProperty<CdsConvention> cdsConvention() {
return cdsConvention;
}
/**
* The meta-property for the {@code scalingFactor} property.
* @return the meta-property, not null
*/
public MetaProperty<Double> scalingFactor() {
return scalingFactor;
}
//-----------------------------------------------------------------------
@Override
protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
switch (propertyName.hashCode()) {
case 3373707: // name
return ((IsdaCreditCurveInputs) bean).getName();
case -1771294215: // creditCurvePoints
return ((IsdaCreditCurveInputs) bean).getCreditCurvePoints();
case 578522476: // endDatePoints
return ((IsdaCreditCurveInputs) bean).getEndDatePoints();
case 1157229426: // parRates
return ((IsdaCreditCurveInputs) bean).getParRates();
case 288334147: // cdsConvention
return ((IsdaCreditCurveInputs) bean).getCdsConvention();
case -794828874: // scalingFactor
return ((IsdaCreditCurveInputs) bean).getScalingFactor();
}
return super.propertyGet(bean, propertyName, quiet);
}
@Override
protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
metaProperty(propertyName);
if (quiet) {
return;
}
throw new UnsupportedOperationException("Property cannot be written: " + propertyName);
}
}
//-----------------------------------------------------------------------
/**
* The bean-builder for {@code IsdaCreditCurveInputs}.
*/
private static final class Builder extends DirectFieldsBeanBuilder<IsdaCreditCurveInputs> {
private CurveName name;
private Period[] creditCurvePoints;
private LocalDate[] endDatePoints;
private double[] parRates;
private CdsConvention cdsConvention;
private double scalingFactor;
/**
* Restricted constructor.
*/
private Builder() {
}
//-----------------------------------------------------------------------
@Override
public Object get(String propertyName) {
switch (propertyName.hashCode()) {
case 3373707: // name
return name;
case -1771294215: // creditCurvePoints
return creditCurvePoints;
case 578522476: // endDatePoints
return endDatePoints;
case 1157229426: // parRates
return parRates;
case 288334147: // cdsConvention
return cdsConvention;
case -794828874: // scalingFactor
return scalingFactor;
default:
throw new NoSuchElementException("Unknown property: " + propertyName);
}
}
@Override
public Builder set(String propertyName, Object newValue) {
switch (propertyName.hashCode()) {
case 3373707: // name
this.name = (CurveName) newValue;
break;
case -1771294215: // creditCurvePoints
this.creditCurvePoints = (Period[]) newValue;
break;
case 578522476: // endDatePoints
this.endDatePoints = (LocalDate[]) newValue;
break;
case 1157229426: // parRates
this.parRates = (double[]) newValue;
break;
case 288334147: // cdsConvention
this.cdsConvention = (CdsConvention) newValue;
break;
case -794828874: // scalingFactor
this.scalingFactor = (Double) newValue;
break;
default:
throw new NoSuchElementException("Unknown property: " + propertyName);
}
return this;
}
@Override
public Builder set(MetaProperty<?> property, Object value) {
super.set(property, value);
return this;
}
@Override
public Builder setString(String propertyName, String value) {
setString(meta().metaProperty(propertyName), value);
return this;
}
@Override
public Builder setString(MetaProperty<?> property, String value) {
super.setString(property, value);
return this;
}
@Override
public Builder setAll(Map<String, ? extends Object> propertyValueMap) {
super.setAll(propertyValueMap);
return this;
}
@Override
public IsdaCreditCurveInputs build() {
return new IsdaCreditCurveInputs(
name,
creditCurvePoints,
endDatePoints,
parRates,
cdsConvention,
scalingFactor);
}
//-----------------------------------------------------------------------
@Override
public String toString() {
StringBuilder buf = new StringBuilder(224);
buf.append("IsdaCreditCurveInputs.Builder{");
buf.append("name").append('=').append(JodaBeanUtils.toString(name)).append(',').append(' ');
buf.append("creditCurvePoints").append('=').append(JodaBeanUtils.toString(creditCurvePoints)).append(',').append(' ');
buf.append("endDatePoints").append('=').append(JodaBeanUtils.toString(endDatePoints)).append(',').append(' ');
buf.append("parRates").append('=').append(JodaBeanUtils.toString(parRates)).append(',').append(' ');
buf.append("cdsConvention").append('=').append(JodaBeanUtils.toString(cdsConvention)).append(',').append(' ');
buf.append("scalingFactor").append('=').append(JodaBeanUtils.toString(scalingFactor));
buf.append('}');
return buf.toString();
}
}
///CLOVER:ON
//-------------------------- AUTOGENERATED END --------------------------
}