/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.impl.credit.isda;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import org.joda.beans.Bean;
import org.joda.beans.BeanBuilder;
import org.joda.beans.BeanDefinition;
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.DirectBeanBuilder;
import org.joda.beans.impl.direct.DirectMetaBean;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.curve.CurveMetadata;
import com.opengamma.strata.market.curve.DefaultCurveMetadata;
import com.opengamma.strata.market.curve.NodalCurve;
import com.opengamma.strata.market.param.ParameterMetadata;
import com.opengamma.strata.market.param.UnitParameterSensitivity;
/**
* A yield or hazard curve values between nodes are linearly interpolated from t*r points,
* where t is time and r is the zero rate.
*/
@BeanDefinition
public class IsdaCompliantCurve
implements NodalCurve, Bean {
/**
* The curve metadata.
* <p>
* The metadata includes an optional list of parameter metadata.
* If present, the size of the parameter metadata list will match the number of parameters of this curve.
*/
@PropertyDefinition(validate = "notNull", overrideGet = true)
private CurveMetadata metadata;
/**
* The knot positions.
*/
@PropertyDefinition(get = "manual", set = "private")
private double[] t;
/**
* The knot values.
*/
@PropertyDefinition(get = "manual", set = "private")
private double[] rt;
public static IsdaCompliantCurve makeFromForwardRates(double[] t, double[] fwd) {
ArgChecker.notEmpty(t, "t");
ArgChecker.notEmpty(fwd, "fwd");
int n = t.length;
ArgChecker.isTrue(n == fwd.length, "length of t not equal to length of fwd");
double[] rt = new double[n];
rt[0] = t[0] * fwd[0];
for (int i = 1; i < n; i++) {
rt[i] = rt[i - 1] + fwd[i] * (t[i] - t[i - 1]);
}
return new IsdaCompliantCurve(new double[][] {t, rt});
}
public static IsdaCompliantCurve makeFromRT(double[] t, double[] rt) {
ArgChecker.notEmpty(t, "t");
ArgChecker.notEmpty(rt, "rt");
ArgChecker.isTrue(t.length == rt.length, "length of t not equal to length of rt");
return new IsdaCompliantCurve(new double[][] {t, rt});
}
public static IsdaCompliantCurve makeFromRT(DoubleArray t, DoubleArray rt) {
return makeFromRT(t.toArray(), rt.toArray());
}
/**
* Constructor for Joda-Beans.
*/
protected IsdaCompliantCurve() {
this.metadata = DefaultCurveMetadata.of("IsdaCompliantCurve");
}
/**
* Creates a flat curve at level r.
*
* @param t (arbitrary) single knot point (t > 0)
* @param r the level
*/
public IsdaCompliantCurve(double t, double r) {
this(new double[] {t}, new double[] {r});
}
/**
* Creates an instance from a set of times and zero rates.
*
* @param t the set of times that form the knots of the curve, must be ascending with the first value >= 0, not null
* @param r the set of zero rates, not null
*/
public IsdaCompliantCurve(double[] t, double[] r) {
ArgChecker.notEmpty(t, "t");
ArgChecker.notEmpty(r, "r");
this.metadata = DefaultCurveMetadata.of("IsdaCompliantCurve");
int n = t.length;
ArgChecker.isTrue(n == r.length, "times and rates different lengths");
ArgChecker.isTrue(t[0] >= 0, "first t must be >= 0.0");
for (int i = 1; i < n; i++) {
ArgChecker.isTrue(t[i] > t[i - 1], "Times must be ascending");
}
this.t = new double[n];
this.rt = new double[n];
System.arraycopy(t, 0, this.t, 0, n);
for (int i = 0; i < n; i++) {
this.rt[i] = r[i] * t[i]; // We make no check that rt is ascending (i.e. we allow negative forward rates)
}
}
protected IsdaCompliantCurve(double[][] tAndRt) {
ArgChecker.notNull(tAndRt, "tAndRt");
this.metadata = DefaultCurveMetadata.of("IsdaCompliantCurve");
this.t = tAndRt[0].clone();
this.rt = tAndRt[1].clone();
}
/**
* Creates a shallow clone of the specified curve.
*
* @param from the curve to clone from, not null
*/
protected IsdaCompliantCurve(IsdaCompliantCurve from) {
ArgChecker.notNull(from, "from");
this.metadata = from.getMetadata();
// Shallow copy
this.t = from.t;
this.rt = from.rt;
}
/**
* A curve in which the knots are measured (in fractions of a year) from a particular base-date but the curve is 'observed'
* from a different base-date. As an example<br>
* Today (the observation point) is 11-Jul-13, but the yield curve is snapped (bootstrapped from money market and swap rates)
* on 10-Jul-13 - seen from today there is an offset of -1/365 (assuming a day count of ACT/365) that must be applied to use
* the yield curve today. <br>
* In general, a discount curve observed at time $t_1$ can be written as $P(t_1,T)$. Observed from time $t_2$ this is
* $P(t_2,T) = \frac{P(t_1,T)}{P(t_1,t_2)}$
*
* @param timesFromBaseDate the times measured from the base date of the curve, not null
* @param r zero rates, not null
* @param newBaseFromOriginalBase if this curve is to be used from a new base-date, this is the offset from the original curve base
*/
protected IsdaCompliantCurve(double[] timesFromBaseDate, double[] r, double newBaseFromOriginalBase) {
int n = timesFromBaseDate.length;
ArgChecker.isTrue(n == r.length, "times and rates different lengths");
ArgChecker.isTrue(timesFromBaseDate[0] >= 0.0, "timesFromBaseDate must be >= 0");
for (int i = 1; i < n; i++) {
ArgChecker.isTrue(timesFromBaseDate[i] > timesFromBaseDate[i - 1], "Times must be ascending");
}
this.metadata = DefaultCurveMetadata.of("IsdaCompliantCurve");
if (newBaseFromOriginalBase == 0) { //no offset
this.t = new double[n];
this.rt = new double[n];
System.arraycopy(timesFromBaseDate, 0, t, 0, n);
for (int i = 0; i < n; i++) {
this.rt[i] = r[i] * t[i]; // We make no check that rt is ascending (i.e. we allow negative forward rates)
}
} else if (newBaseFromOriginalBase < timesFromBaseDate[0]) {
//offset less than t value of 1st knot, so no knots are not removed
this.t = new double[n];
this.rt = new double[n];
double eta = r[0] * newBaseFromOriginalBase;
for (int i = 0; i < n; i++) {
this.t[i] = timesFromBaseDate[i] - newBaseFromOriginalBase;
this.rt[i] = r[i] * timesFromBaseDate[i] - eta;
}
} else if (newBaseFromOriginalBase >= timesFromBaseDate[n - 1]) {
this.t = new double[1];
rt = new double[1];
this.t[0] = 1.0;
this.rt[0] = (r[n - 1] * timesFromBaseDate[n - 1] - r[n - 2] * timesFromBaseDate[n - 2]) /
(timesFromBaseDate[n - 1] - timesFromBaseDate[n - 2]);
} else {
//offset greater than (or equal to) t value of 1st knot, so at least one knot must be removed
int index = Arrays.binarySearch(timesFromBaseDate, newBaseFromOriginalBase);
if (index < 0) {
index = -(index + 1);
} else {
index++;
}
double eta = (r[index - 1] * timesFromBaseDate[index - 1] *
(timesFromBaseDate[index] - newBaseFromOriginalBase) + r[index] * timesFromBaseDate[index] *
(newBaseFromOriginalBase - timesFromBaseDate[index - 1])) /
(timesFromBaseDate[index] - timesFromBaseDate[index - 1]);
int m = n - index;
this.t = new double[m];
this.rt = new double[m];
for (int i = 0; i < m; i++) {
t[i] = timesFromBaseDate[i + index] - newBaseFromOriginalBase;
this.rt[i] = r[i + index] * timesFromBaseDate[i + index] - eta;
}
}
}
//-------------------------------------------------------------------------
/**
* Gets the knot times.
*
* @return the knot times, not null
*/
public double[] getKnotTimes() {
return t.clone();
}
/**
* Gets the knot zero rates.
*
* @return the knot zero rates, not null
*/
public double[] getKnotZeroRates() {
int n = t.length;
double[] r = new double[n];
for (int i = 0; i < n; i++) {
r[i] = rt[i] / t[i];
}
return r;
}
/**
* The discount factor or survival probability.
*
* @param t the time
* @return the discount factor value
*/
public double getDiscountFactor(double t) {
return Math.exp(-getRT(t));
}
/**
* Gets the time at the specified index.
*
* @param index the zero-based index
* @return the time
*/
public double getTimeAtIndex(int index) {
return t[index];
}
/**
* Gets the zero rate at the specified index.
*
* @param index the zero-based index
* @return the zero rate
*/
public double getZeroRateAtIndex(int index) {
return rt[index] / t[index];
}
/**
* Gets the RT value at the specified index.
* <p>
* RT is zero rate multiplied by time, which is the same as the negative log of the discount factor.
*
* @param index the zero-based index
* @return the RT value
*/
public double getRTAtIndex(int index) {
return rt[index];
}
/**
* Gets the zero rate or zero hazard rate at the specified time.
*
* @param t time
* @return zero rate value
*/
public double getZeroRate(double t) {
ArgChecker.isTrue(t >= 0, "require t >= 0.0");
// short-cut doing binary search
if (t <= this.t[0]) {
return rt[0] / this.t[0];
}
int n = this.t.length;
if (t > this.t[n - 1]) {
double rt = getRT(t, n - 1);
return rt / t;
}
int index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
return rt[index] / this.t[index];
}
int insertionPoint = -(1 + index);
double rt = getRT(t, insertionPoint);
return rt / t;
}
/**
* Gets the RT value at the specified time.
* <p>
* RT is zero rate multiplied by time, which is the same as the negative log of the discount factor.
*
* @param t time
* @return the RT value
*/
public double getRT(double t) {
// short-cut doing binary search
if (t <= this.t[0]) {
return rt[0] * t / this.t[0];
}
int n = this.t.length;
if (t > this.t[n - 1]) {
return getRT(t, n - 1); //linear extrapolation
}
int index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
return rt[index];
}
int insertionPoint = -(1 + index);
return getRT(t, insertionPoint);
}
public double[] getRTandSensitivity(double t, int nodeIndex) {
ArgChecker.isTrue(t >= 0, "require t >= 0.0, was, {}", t);
int n = this.t.length;
ArgChecker.isTrue(nodeIndex >= 0 && nodeIndex < n, "node index of {} out of range", nodeIndex);
// short-cut doing binary search
if (n == 1 || t <= this.t[0]) {
return new double[] {rt[0] * t / this.t[0], nodeIndex == 0 ? t : 0.0};
}
int index;
if (t > this.t[n - 1]) {
index = n - 1;
} else if (t == this.t[nodeIndex]) {
return new double[] {rt[nodeIndex], t};
} else if (nodeIndex > 0 && t > this.t[nodeIndex - 1] && t < this.t[nodeIndex]) {
index = nodeIndex;
} else {
index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
return new double[] {rt[index], 0.0}; //if nodeIndex == index, would have matched earlier
}
index = -(index + 1);
if (index == n) {
index--;
}
}
double t1 = this.t[index - 1];
double t2 = this.t[index];
double dt = t2 - t1;
double w1 = (t2 - t) / dt;
double w2 = (t - t1) / dt;
double rt = w1 * this.rt[index - 1] + w2 * this.rt[index];
double sense = 0.0;
if (nodeIndex == index) {
sense = t2 * w2;
} else if (nodeIndex == index - 1) {
sense = t1 * w1;
}
return new double[] {rt, sense};
}
private double getRT(double t, int insertionPoint) {
if (insertionPoint == 0) {
return t * rt[0] / this.t[0];
}
int n = this.t.length;
if (insertionPoint == n) {
return getRT(t, insertionPoint - 1); //linear extrapolation
}
double t1 = this.t[insertionPoint - 1];
double t2 = this.t[insertionPoint];
double dt = t2 - t1;
return ((t2 - t) * rt[insertionPoint - 1] + (t - t1) * rt[insertionPoint]) / dt;
}
public double getForwardRate(double t) {
// short-cut doing binary search
if (t <= this.t[0]) {
return rt[0] / this.t[0];
}
int n = this.t.length;
if (t > this.t[n - 1]) {
return getForwardRate(n - 1); //linear extrapolation
}
int index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
//Strictly, the forward rate is undefined at the nodes - this defined the value at the node to be that infinitesimally before
return getForwardRate(index);
}
int insertionPoint = -(1 + index);
return getForwardRate(insertionPoint);
}
private double getForwardRate(int insertionPoint) {
if (insertionPoint == 0) {
return rt[0] / t[0];
}
int n = t.length;
if (insertionPoint == n) {
return getForwardRate(insertionPoint - 1);
}
double dt = t[insertionPoint] - t[insertionPoint - 1];
return (rt[insertionPoint] - rt[insertionPoint - 1]) / dt;
}
/**
* Gets the number of knots in the curve.
*
* @return number of knots in curve
*/
public int getNumberOfKnots() {
return t.length;
}
/**
* Get the sensitivity of the interpolated rate at time t to the curve node.
* Note, since the interpolator is highly local, most of the returned values will be zero,
* so it maybe more efficient to call getSingleNodeSensitivity.
*
* @param t the time
* @return the sensitivity to the nodes, not null
*/
public DoubleArray getNodeSensitivity(double t) {
int n = this.t.length;
double[] res = new double[n];
// short-cut doing binary search
if (t <= this.t[0]) {
res[0] = 1.0;
return DoubleArray.copyOf(res);
}
if (t >= this.t[n - 1]) {
int insertionPoint = n - 1;
double t1 = this.t[insertionPoint - 1];
double t2 = this.t[insertionPoint];
double dt = t2 - t1;
res[insertionPoint - 1] = t1 * (t2 - t) / dt / t;
res[insertionPoint] = t2 * (t - t1) / dt / t;
return DoubleArray.copyOf(res);
}
int index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
res[index] = 1.0;
return DoubleArray.copyOf(res);
}
int insertionPoint = -(1 + index);
double t1 = this.t[insertionPoint - 1];
double t2 = this.t[insertionPoint];
double dt = t2 - t1;
res[insertionPoint - 1] = t1 * (t2 - t) / dt / t;
res[insertionPoint] = t2 * (t - t1) / dt / t;
return DoubleArray.copyOf(res);
}
/**
* Gets the sensitivity of the interpolated zero rate at time t to the value of the zero rate at a given node (knot).
* For a given index, i, this is zero unless $$t_{i-1} < t < t_{i+1}$$ since the interpolation is highly local.
*
* @param t the time
* @param nodeIndex the node index
* @return the sensitivity to a single node
*/
public double getSingleNodeSensitivity(double t, int nodeIndex) {
ArgChecker.isTrue(t >= 0, "require t >= 0.0");
ArgChecker.isTrue(nodeIndex >= 0 && nodeIndex < this.t.length, "index out of range");
if (t <= this.t[0]) {
return nodeIndex == 0 ? 1.0 : 0.0;
}
return getSingleNodeRTSensitivity(t, nodeIndex) / t;
}
/**
* Gets the sensitivity of the interpolated zero rate times time (RT or -ln(discount factor))
* at time t to the value of the zero rate at a given node (knot).
* For a given index, i, this is zero unless $$t_{i-1} < t < t_{i+1}$$ since the interpolation is highly local.
* @param t the time
* @param nodeIndex the node index
* @return the sensitivity to a single node
*/
public double getSingleNodeRTSensitivity(double t, int nodeIndex) {
ArgChecker.isTrue(t >= 0, "require t >= 0.0");
int n = this.t.length;
ArgChecker.isTrue(nodeIndex >= 0 && nodeIndex < n, "index out of range");
if (t <= this.t[0]) {
return nodeIndex == 0 ? t : 0.0;
}
int index = Arrays.binarySearch(this.t, t);
if (index >= 0) {
return nodeIndex == index ? t : 0.0;
}
int insertionPoint = Math.min(n - 1, -(1 + index));
if (nodeIndex != insertionPoint && nodeIndex != insertionPoint - 1) {
return 0.0;
}
double t1 = this.t[insertionPoint - 1];
double t2 = this.t[insertionPoint];
double dt = t2 - t1;
if (nodeIndex == insertionPoint) {
return t2 * (t - t1) / dt;
}
return t1 * (t2 - t) / dt;
}
/**
* The sensitivity of the discount factor at some time, t, to the value of the zero rate at a given node (knot).
* For a given index, i, this is zero unless $$t_{i-1} < t < t_{i+1}$$ since the interpolation is highly local.
*
* @param t the time value of the discount factor
* @param nodeIndex the node index
* @return the sensitivity of a discount factor to a single node
*/
public double getSingleNodeDiscountFactorSensitivity(double t, int nodeIndex) {
double[] temp = getRTandSensitivity(t, nodeIndex);
return -temp[1] * Math.exp(-temp[0]);
}
//-------------------------------------------------------------------------
/**
* A curve in which the knots are measured (in fractions of a year) from a particular base-date but the curve is 'observed'
* from a different base-date. As an example<br>
* Today (the observation point) is 11-Jul-13, but the yield curve is snapped (bootstrapped from money market and swap rates)
* on 10-Jul-13 - seen from the original base date (10-Jul-13) there is an offset of 1/365
* (assuming a day count of ACT/365) that must be applied to use
* the yield curve today. <br>
* In general, a discount curve observed at time $t_1$ can be written as $P(t_1,T)$. Observed from time $t_2$ this is
* $P(t_2,T) = \frac{P(t_1,T)}{P(t_1,t_2)}$
*
* @param newBaseFromOriginalBase if this curve is to be used from a new base-date, what is the offset from the original curve base
* @return a new curve with the offset
*/
public IsdaCompliantCurve withOffset(double newBaseFromOriginalBase) {
return new IsdaCompliantCurve(t, getKnotZeroRates(), newBaseFromOriginalBase);
}
/**
* Update are rates in curve.
*
* @param r the set of rates, not null
* @return a new curve, not null
*/
public IsdaCompliantCurve withRates(double[] r) {
return new IsdaCompliantCurve(t, r);
}
/**
* Adjust a rate at a particular index.
*
* @param rate the new rate
* @param index the index of the knot
* @return a new curve, not null
*/
public IsdaCompliantCurve withRate(double rate, int index) {
int n = t.length;
ArgChecker.isTrue(index >= 0 && index < n, "index out of range");
double[] t = this.t.clone();
double[] rt = this.rt.clone();
rt[index] = rate * t[index];
return new IsdaCompliantCurve(new double[][] {t, rt});
}
public void setRate(double rate, int index) {
int n = t.length;
ArgChecker.isTrue(index >= 0 && index < n, "index out of range");
rt[index] = rate * t[index];
}
/**
* Adjust a discount factor at a particular index.
*
* @param discountFactor the new discount factor
* @param index the index of the knot
* @return a new curve, not null
*/
public IsdaCompliantCurve withDiscountFactor(double discountFactor, int index) {
int n = t.length;
ArgChecker.isTrue(index >= 0 && index < n, "index out of range");
double[] t = this.t.clone();
double[] rt = this.rt.clone();
rt[index] = -Math.log(discountFactor);
return new IsdaCompliantCurve(new double[][] {t, rt});
}
/**
* Gets the times, which must not be altered.
*
* @return the times, not null
*/
public double[] getT() {
return t;
}
public double[] getRt() {
return rt;
}
//-------------------------------------------------------------------------
// NodalCurve implemented to expose zero-rates as the y-values
@Override
public int getParameterCount() {
return getNumberOfKnots();
}
@Override
public double getParameter(int parameterIndex) {
return getZeroRateAtIndex(parameterIndex);
}
@Override
public IsdaCompliantCurve withParameter(int parameterIndex, double newValue) {
return withRate(newValue, parameterIndex);
}
//-------------------------------------------------------------------------
@Override
public double yValue(double x) {
return getZeroRate(x);
}
@Override
public UnitParameterSensitivity yValueParameterSensitivity(double x) {
return createParameterSensitivity(getNodeSensitivity(x));
}
@Override
public double firstDerivative(double x) {
if (x <= t[0]) {
return 0.0;
}
return (getForwardRate(x) - getZeroRate(x)) / x;
}
@Override
public DoubleArray getXValues() {
return DoubleArray.copyOf(t);
}
@Override
public DoubleArray getYValues() {
return DoubleArray.copyOf(getKnotZeroRates());
}
@Override
public IsdaCompliantCurve withYValues(DoubleArray values) {
return IsdaCompliantCurve.makeFromRT(getXValues(), values);
}
@Override
public NodalCurve withValues(DoubleArray xValues, DoubleArray yValues) {
return IsdaCompliantCreditCurve.makeFromRT(xValues, yValues);
}
@Override
public IsdaCompliantCurve withMetadata(CurveMetadata metadata) {
return this;
}
@Override
public IsdaCompliantCurve withNode(double x, double y, ParameterMetadata paramMetadata) {
throw new UnsupportedOperationException("ISDA credit curve does not allow node to be inserted");
}
//------------------------- AUTOGENERATED START -------------------------
///CLOVER:OFF
/**
* The meta-bean for {@code IsdaCompliantCurve}.
* @return the meta-bean, not null
*/
public static IsdaCompliantCurve.Meta meta() {
return IsdaCompliantCurve.Meta.INSTANCE;
}
static {
JodaBeanUtils.registerMetaBean(IsdaCompliantCurve.Meta.INSTANCE);
}
@Override
public IsdaCompliantCurve.Meta metaBean() {
return IsdaCompliantCurve.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 metadata.
* <p>
* The metadata includes an optional list of parameter metadata.
* If present, the size of the parameter metadata list will match the number of parameters of this curve.
* @return the value of the property, not null
*/
@Override
public CurveMetadata getMetadata() {
return metadata;
}
/**
* Sets the curve metadata.
* <p>
* The metadata includes an optional list of parameter metadata.
* If present, the size of the parameter metadata list will match the number of parameters of this curve.
* @param metadata the new value of the property, not null
*/
public void setMetadata(CurveMetadata metadata) {
JodaBeanUtils.notNull(metadata, "metadata");
this.metadata = metadata;
}
/**
* Gets the the {@code metadata} property.
* <p>
* The metadata includes an optional list of parameter metadata.
* If present, the size of the parameter metadata list will match the number of parameters of this curve.
* @return the property, not null
*/
public final Property<CurveMetadata> metadata() {
return metaBean().metadata().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Sets the knot positions.
* @param t the new value of the property
*/
private void setT(double[] t) {
this.t = t;
}
/**
* Gets the the {@code t} property.
* @return the property, not null
*/
public final Property<double[]> t() {
return metaBean().t().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Sets the knot values.
* @param rt the new value of the property
*/
private void setRt(double[] rt) {
this.rt = rt;
}
/**
* Gets the the {@code rt} property.
* @return the property, not null
*/
public final Property<double[]> rt() {
return metaBean().rt().createProperty(this);
}
//-----------------------------------------------------------------------
@Override
public IsdaCompliantCurve clone() {
return JodaBeanUtils.cloneAlways(this);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj != null && obj.getClass() == this.getClass()) {
IsdaCompliantCurve other = (IsdaCompliantCurve) obj;
return JodaBeanUtils.equal(getMetadata(), other.getMetadata()) &&
JodaBeanUtils.equal(getT(), other.getT()) &&
JodaBeanUtils.equal(getRt(), other.getRt());
}
return false;
}
@Override
public int hashCode() {
int hash = getClass().hashCode();
hash = hash * 31 + JodaBeanUtils.hashCode(getMetadata());
hash = hash * 31 + JodaBeanUtils.hashCode(getT());
hash = hash * 31 + JodaBeanUtils.hashCode(getRt());
return hash;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder(128);
buf.append("IsdaCompliantCurve{");
int len = buf.length();
toString(buf);
if (buf.length() > len) {
buf.setLength(buf.length() - 2);
}
buf.append('}');
return buf.toString();
}
protected void toString(StringBuilder buf) {
buf.append("metadata").append('=').append(JodaBeanUtils.toString(getMetadata())).append(',').append(' ');
buf.append("t").append('=').append(JodaBeanUtils.toString(getT())).append(',').append(' ');
buf.append("rt").append('=').append(JodaBeanUtils.toString(getRt())).append(',').append(' ');
}
//-----------------------------------------------------------------------
/**
* The meta-bean for {@code IsdaCompliantCurve}.
*/
public static class Meta extends DirectMetaBean {
/**
* The singleton instance of the meta-bean.
*/
static final Meta INSTANCE = new Meta();
/**
* The meta-property for the {@code metadata} property.
*/
private final MetaProperty<CurveMetadata> metadata = DirectMetaProperty.ofReadWrite(
this, "metadata", IsdaCompliantCurve.class, CurveMetadata.class);
/**
* The meta-property for the {@code t} property.
*/
private final MetaProperty<double[]> t = DirectMetaProperty.ofReadWrite(
this, "t", IsdaCompliantCurve.class, double[].class);
/**
* The meta-property for the {@code rt} property.
*/
private final MetaProperty<double[]> rt = DirectMetaProperty.ofReadWrite(
this, "rt", IsdaCompliantCurve.class, double[].class);
/**
* The meta-properties.
*/
private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
this, null,
"metadata",
"t",
"rt");
/**
* Restricted constructor.
*/
protected Meta() {
}
@Override
protected MetaProperty<?> metaPropertyGet(String propertyName) {
switch (propertyName.hashCode()) {
case -450004177: // metadata
return metadata;
case 116: // t
return t;
case 3650: // rt
return rt;
}
return super.metaPropertyGet(propertyName);
}
@Override
public BeanBuilder<? extends IsdaCompliantCurve> builder() {
return new DirectBeanBuilder<IsdaCompliantCurve>(new IsdaCompliantCurve());
}
@Override
public Class<? extends IsdaCompliantCurve> beanType() {
return IsdaCompliantCurve.class;
}
@Override
public Map<String, MetaProperty<?>> metaPropertyMap() {
return metaPropertyMap$;
}
//-----------------------------------------------------------------------
/**
* The meta-property for the {@code metadata} property.
* @return the meta-property, not null
*/
public final MetaProperty<CurveMetadata> metadata() {
return metadata;
}
/**
* The meta-property for the {@code t} property.
* @return the meta-property, not null
*/
public final MetaProperty<double[]> t() {
return t;
}
/**
* The meta-property for the {@code rt} property.
* @return the meta-property, not null
*/
public final MetaProperty<double[]> rt() {
return rt;
}
//-----------------------------------------------------------------------
@Override
protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
switch (propertyName.hashCode()) {
case -450004177: // metadata
return ((IsdaCompliantCurve) bean).getMetadata();
case 116: // t
return ((IsdaCompliantCurve) bean).getT();
case 3650: // rt
return ((IsdaCompliantCurve) bean).getRt();
}
return super.propertyGet(bean, propertyName, quiet);
}
@Override
protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
switch (propertyName.hashCode()) {
case -450004177: // metadata
((IsdaCompliantCurve) bean).setMetadata((CurveMetadata) newValue);
return;
case 116: // t
((IsdaCompliantCurve) bean).setT((double[]) newValue);
return;
case 3650: // rt
((IsdaCompliantCurve) bean).setRt((double[]) newValue);
return;
}
super.propertySet(bean, propertyName, newValue, quiet);
}
@Override
protected void validate(Bean bean) {
JodaBeanUtils.notNull(((IsdaCompliantCurve) bean).metadata, "metadata");
}
}
///CLOVER:ON
//-------------------------- AUTOGENERATED END --------------------------
}