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

net.finmath.marketdata2.model.curves.DiscountCurveFromForwardCurve Maven / Gradle / Ivy

Go to download

finmath lib is a Mathematical Finance Library in Java. It provides algorithms and methodologies related to mathematical finance.

There is a newer version: 6.0.19
Show 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); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy