net.finmath.marketdata2.model.curves.DiscountCurveFromForwardCurve Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of finmath-lib Show documentation
Show all versions of finmath-lib Show documentation
finmath lib is a Mathematical Finance Library in Java.
It provides algorithms and methodologies related to mathematical finance.
The newest version!
/* (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
*
* Created on 20.05.2005
*/
package net.finmath.marketdata2.model.curves;
import java.io.Serializable;
import net.finmath.marketdata2.model.AnalyticModel;
import net.finmath.montecarlo.RandomVariableFromDoubleArray;
import net.finmath.stochastic.RandomVariable;
/**
* A discount curve derived from a given forward curve.
*
* The discount factors df(t) are defined at t = k * d
* for integers k via
* df(t+d) = df(t) / (1 + f(t) * d) and
* for t = k * d and 0 < r < d
* via df(t+r) = df(t) / (1 + f(t) * r)
* where d is a given the payment offset and f(t) is the forward curve.
*
*
* Note that a special interpolation is performed for in-between points.
* Hence, creating a {@link ForwardCurveFromDiscountCurve} and from it
* a DiscountCurveFromForwardCurve will not recover the original curve
* since interpolation points may be lost.
*
*
*
* @author Christian Fries
* @version 1.0
*/
public class DiscountCurveFromForwardCurve extends AbstractCurve implements Serializable, DiscountCurveInterface {
private static final long serialVersionUID = -4126228588123963885L;
private String forwardCurveName;
private ForwardCurveInterface forwardCurve;
private final double timeScaling;
/**
* Create a discount curve using a given forward curve.
* The discount factors df(t) are defined at t = k * d for integers k
* via df(t+d) = df(t) / (1 + f(t) * d) and
* for t = k * d and 0 < r < d
* via df(t+r) = df(t) / (1 + f(t) * r)
* where d is a given the payment offset and f(t) is the forward curve.
*
* @param forwardCurveName The name of the forward curve used for calculation of the discount factors.
* @param periodLengthTimeScaling A scaling factor applied to d, adjusting for the internal double time to the period length daycount fraction (note that this may only be an approximate solution to capture daycount effects).
*/
public DiscountCurveFromForwardCurve(final String forwardCurveName, final double periodLengthTimeScaling) {
super("DiscountCurveFromForwardCurve(" + forwardCurveName + ")", null);
this.forwardCurveName = forwardCurveName;
timeScaling = periodLengthTimeScaling;
}
/**
* Create a discount curve using a given forward curve.
* The discount factors df(t) are defined at t = k * d for integers k
* via df(t+d) = df(t) / (1 + f(t) * d) and
* for t = k * d and 0 < r < d
* via df(t+r) = df(t) / (1 + f(t) * r)
* where d is a given the payment offset and f(t) is the forward curve.
*
* @param forwardCurve The forward curve used for calculation of the discount factors.
* @param periodLengthTimeScaling A scaling factor applied to d, adjusting for the internal double time to the period length daycount fraction (note that this may only be an approximate solution to capture daycount effects).
*/
public DiscountCurveFromForwardCurve(final ForwardCurveInterface forwardCurve, final double periodLengthTimeScaling) {
super("DiscountCurveFromForwardCurve" + forwardCurve.getName() + ")", null);
this.forwardCurve = forwardCurve;
timeScaling = periodLengthTimeScaling;
}
/**
* Create a discount curve using a given forward curve.
* The discount factors df(t) are defined at t = k * d for integers k
* via df(t+d) = df(t) / (1 + f(t) * d) and
* for t = k * d and 0 < r < d
* via df(t+r) = df(t) / (1 + f(t) * r)
* where d is a given the payment offset and f(t) is the forward curve.
*
* @param forwardCurveName The name of the forward curve used for calculation of the discount factors.
*/
public DiscountCurveFromForwardCurve(final String forwardCurveName) {
this(forwardCurveName, 1.0);
}
/**
* Create a discount curve using a given forward curve.
* The discount factors df(t) are defined at t = k * d for integers k
* via df(t+d) = df(t) / (1 + f(t) * d) and
* for t = k * d and 0 < r < d
* via df(t+r) = df(t) / (1 + f(t) * r)
* where d is a given the payment offset and f(t) is the forward curve.
*
* @param forwardCurve The forward curve used for calculation of the discount factors.
*/
public DiscountCurveFromForwardCurve(final ForwardCurveInterface forwardCurve) {
this(forwardCurve, 1.0);
}
/* (non-Javadoc)
* @see net.finmath.marketdata.DiscountCurveInterface#getDiscountFactor(double)
*/
@Override
public RandomVariable getDiscountFactor(final double maturity) {
return getDiscountFactor(null, maturity);
}
/* (non-Javadoc)
* @see net.finmath.marketdata.DiscountCurveInterface#getDiscountFactor(double)
*/
@Override
public RandomVariable getDiscountFactor(final AnalyticModel model, final double maturity) {
ForwardCurveInterface forwardCurve;
if(this.forwardCurve != null) {
forwardCurve = this.forwardCurve;
} else {
forwardCurve = model.getForwardCurve(forwardCurveName);
}
if(forwardCurve == null) {
throw new IllegalArgumentException("No forward curve given and no forward curve found in the model under the name " + forwardCurveName + ".");
}
RandomVariable discountFactor = new RandomVariableFromDoubleArray(1.0);
double time = 0;
double paymentOffset = 0;
while(time < maturity) {
paymentOffset = forwardCurve.getPaymentOffset(time);
if(paymentOffset <= 0) {
throw new RuntimeException("Trying to calculate a discount curve from a forward curve with non-positive payment offset.");
}
discountFactor = forwardCurve.getForward(model, time).mult(Math.min(paymentOffset, maturity-time) * timeScaling).add(1.0).pow(-1.0).mult(discountFactor);
time += paymentOffset;
}
return discountFactor;
}
/* (non-Javadoc)
* @see net.finmath.marketdata.model.curves.CurveInterface#getValue(double)
*/
@Override
public RandomVariable getValue(final AnalyticModel model, final double time) {
return getDiscountFactor(model, time);
}
@Override
public RandomVariable[] getParameter() {
return null;
}
@Override
public void setParameter(final RandomVariable[] parameter) {
}
@Override
public CurveBuilder getCloneBuilder() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((forwardCurve == null) ? 0 : forwardCurve.hashCode());
result = prime * result + ((forwardCurveName == null) ? 0 : forwardCurveName.hashCode());
long temp;
temp = Double.doubleToLongBits(timeScaling);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DiscountCurveFromForwardCurve other = (DiscountCurveFromForwardCurve) obj;
if (forwardCurve == null) {
if (other.forwardCurve != null) {
return false;
}
} else if (!forwardCurve.equals(other.forwardCurve)) {
return false;
}
if (forwardCurveName == null) {
if (other.forwardCurveName != null) {
return false;
}
} else if (!forwardCurveName.equals(other.forwardCurveName)) {
return false;
}
return Double.doubleToLongBits(timeScaling) == Double
.doubleToLongBits(other.timeScaling);
}
}