SwapAnnuity.java
package net.finmath.finitedifference.interestrate.products;
import net.finmath.finitedifference.interestrate.models.FiniteDifferenceInterestRateModel;
import net.finmath.time.Schedule;
/**
* Utility methods for swap annuities in the finite-difference interest-rate
* framework.
*
* <p>
* The reduced-scope swap annuity at time {@code t} is defined as
* </p>
*
* <p>
* <i>
* A(t,x) = \sum_{i} \delta_i P(t,T_i;x),
* </i>
* </p>
*
* <p>
* where the sum runs over the fixed-leg periods which have not yet started,
* i.e. periods with {@code periodStart >= t}. This is consistent with the
* remaining forward-looking interpretation used by {@link SwapLeg} and
* {@link Swap}.
* </p>
*
* @author Alessandro Gnoatto
*/
public final class SwapAnnuity {
/**
* The time tolerance.
*/
private static final double TIME_TOLERANCE = 1E-12;
private SwapAnnuity() {
}
/**
* Returns the reduced-scope swap annuity at the given evaluation time and
* state.
*
* @param evaluationTime The evaluation time.
* @param schedule The fixed-leg schedule.
* @param model The finite-difference interest-rate model.
* @param stateVariables The current state variables.
* @return The swap annuity.
*/
public static double getSwapAnnuity(
final double evaluationTime,
final Schedule schedule,
final FiniteDifferenceInterestRateModel model,
final double... stateVariables) {
if (schedule == null) {
throw new IllegalArgumentException("schedule must not be null.");
}
if (model == null) {
throw new IllegalArgumentException("model must not be null.");
}
if (stateVariables == null || stateVariables.length != 1) {
throw new IllegalArgumentException("Exactly one state variable is required.");
}
double value = 0.0;
for (int periodIndex = 0; periodIndex < schedule.getNumberOfPeriods(); periodIndex++) {
final double periodStart = schedule.getPeriodStart(periodIndex);
final double paymentDate = schedule.getPayment(periodIndex);
if ((periodStart < evaluationTime - TIME_TOLERANCE) || (paymentDate <= evaluationTime + TIME_TOLERANCE)) {
continue;
}
value += schedule.getPeriodLength(periodIndex)
* model.getDiscountBond(
evaluationTime,
paymentDate,
stateVariables[0]
);
}
return value;
}
}