FiniteDifferenceInterestRateModel.java
package net.finmath.finitedifference.interestrate.models;
import net.finmath.finitedifference.FiniteDifferenceModel;
import net.finmath.finitedifference.boundaries.BoundaryCondition;
import net.finmath.finitedifference.boundaries.StandardBoundaryCondition;
import net.finmath.finitedifference.grids.SpaceTimeDiscretization;
import net.finmath.finitedifference.interestrate.products.FiniteDifferenceInterestRateProduct;
import net.finmath.marketdata.model.AnalyticModel;
/**
* Base interface for finite-difference interest-rate models.
*
* <p>
* The interface is designed to remain close to the philosophy of the Monte
* Carlo
* interest-rate framework of finmath while exposing the additional ingredients
* required by a partial-differential-equation discretization.
* </p>
*
* <p>
* A model implementing this interface is assumed to satisfy the following two
* principles:
* </p>
* <ul>
* <li>it fits the initially observed term structure automatically through an
* underlying bootstrapped {@link AnalyticModel},</li>
* <li>it admits a finite-dimensional Markovian state representation, so that
* the PDE is solved on a grid of state variables rather than on a full
* curve of maturities.</li>
* </ul>
*
* <p>
* More precisely, the model is described by a state vector
* </p>
*
* <p>
* <i>
* X_t = (X_t^{(1)}, \ldots, X_t^{(d)})
* </i>
* </p>
*
* <p>
* evolving under dynamics of the form
* </p>
*
* <p>
* <i>
* dX_t = \mu(t,X_t)\,dt + \lambda(t,X_t)\,dW_t,
* </i>
* </p>
*
* <p>
* where the drift vector {@code \mu} and factor-loading matrix
* {@code \lambda} are returned by {@link #getDrift(double, double...)} and
* {@link #getFactorLoading(double, double...)}. Observable term-structure
* quantities are reconstructed from the state. In particular, forward rates are
* obtained through
* </p>
*
* <p>
* <i>
* F(t;T_1,T_2) = \Phi(t,T_1,T_2,X_t),
* </i>
* </p>
*
* <p>
* where the forwarding curve is identified explicitly in the multi-curve
* setting.
* </p>
*
* <p>
* The interface does <b>not</b> encode a short-rate-only point of view. In
* particular, no method like {@code getShortRate(...)} is required at this
* level. This keeps the contract suitable for short-rate models, Gaussian HJM /
* Cheyette models, and other Markovian term-structure specifications.
* </p>
*
* <p>
* The default boundary implementation returns
* {@link StandardBoundaryCondition#none()} in every spatial direction.
* Model-specific classes may override this when Dirichlet or Neumann boundary
* information is available analytically.
* </p>
*s
* @author Alessandro Gnoatto
*/
public interface FiniteDifferenceInterestRateModel extends FiniteDifferenceModel {
/**
* Returns the analytic multi-curve model used as the initial condition of
* the
* stochastic term-structure model.
*
* <p>
* The returned {@link AnalyticModel} is assumed to contain the bootstrapped
* market curves used to anchor the model to the observed initial term
* structure.
* </p>
*
* @return The initial analytic multi-curve model.
*/
AnalyticModel getAnalyticModel();
/**
* Returns the initial value of the Markovian state variables.
*
* @return The initial state vector.
*/
double[] getInitialValue();
/**
* Returns the drift vector of the Markovian state process.
*
* <p>
* This method provides the deterministic part of the state dynamics
* </p>
*
* <p>
* <i>
* dX_t = \mu(t,X_t)\,dt + \lambda(t,X_t)\,dW_t.
* </i>
* </p>
*
* @param time The current time.
* @param stateVariables The current state vector.
* @return The drift vector at the given state.
*/
double[] getDrift(double time, double... stateVariables);
/**
* Returns the factor-loading matrix of the Markovian state process.
*
* <p>
* If {@code d} denotes the state dimension and {@code m} the Brownian
* dimension, then the returned array has shape {@code d x m}.
* </p>
*
* @param time The current time.
* @param stateVariables The current state vector.
* @return The factor-loading matrix at the given state.
*/
double[][] getFactorLoading(double time, double... stateVariables);
/**
* Returns the value at time {@code time} of the discount bond maturing at
* {@code maturity}, conditional on the current model state.
*
* <p>
* In a multi-curve setting this method refers to the discounting curve.
* </p>
*
* @param time The evaluation time.
* @param maturity The maturity of the discount bond.
* @param stateVariables The current state vector.
* @return The discount bond value.
*/
double getDiscountBond(double time, double maturity, double... stateVariables);
/**
* Returns the simply compounded forward rate associated with a given
* forwarding curve and accrual period.
*
* <p>
* This is the finite-difference analogue of the Monte Carlo
* {@code getLibor(...)} philosophy. The forwarding curve is identified
* explicitly because, in a multi-curve framework, it is in general distinct
* from the discount curve.
* </p>
*
* @param forwardCurveName The name of the forwarding curve.
* @param time The evaluation time.
* @param periodStart The start of the accrual period.
* @param periodEnd The end of the accrual period.
* @param stateVariables The current state vector.
* @return The forward rate for the specified accrual period.
*/
double getForwardRate(
String forwardCurveName,
double time,
double periodStart,
double periodEnd,
double... stateVariables);
/**
* Alias for {@link #getForwardRate(String, double, double, double,
* double...)}
* using the Monte Carlo terminology.
*
* @param forwardCurveName The name of the forwarding curve.
* @param time The evaluation time.
* @param periodStart The start of the accrual period.
* @param periodEnd The end of the accrual period.
* @param stateVariables The current state vector.
* @return The forward rate for the specified accrual period.
*/
default double getLibor(
final String forwardCurveName,
final double time,
final double periodStart,
final double periodEnd,
final double... stateVariables) {
return getForwardRate(forwardCurveName, time, periodStart, periodEnd, stateVariables);
}
/**
* Returns a clone of the model using a modified space-time discretization.
*
* @param spaceTimeDiscretization The new space-time discretization.
* @return A clone with the modified discretization.
*/
FiniteDifferenceInterestRateModel getCloneWithModifiedSpaceTimeDiscretization(
SpaceTimeDiscretization spaceTimeDiscretization);
/**
* Returns the lower-boundary conditions for the current product and state.
*
* <p>
* The default implementation returns
* {@link StandardBoundaryCondition#none()} in every spatial direction.
* </p>
*
* @param product The product being priced.
* @param time The current time.
* @param stateVariables The current boundary state.
* @return Boundary conditions at the lower boundary.
*/
default BoundaryCondition[] getBoundaryConditionsAtLowerBoundary(
final FiniteDifferenceInterestRateProduct product,
final double time,
final double... stateVariables) {
final int numberOfSpaceGrids = getSpaceTimeDiscretization().getNumberOfSpaceGrids();
final BoundaryCondition[] boundaryConditions = new BoundaryCondition[numberOfSpaceGrids];
for (int i = 0; i < numberOfSpaceGrids; i++) {
boundaryConditions[i] = StandardBoundaryCondition.none();
}
return boundaryConditions;
}
/**
* Returns the upper-boundary conditions for the current product and state.
*
* <p>
* The default implementation returns
* {@link StandardBoundaryCondition#none()} in every spatial direction.
* </p>
*
* @param product The product being priced.
* @param time The current time.
* @param stateVariables The current boundary state.
* @return Boundary conditions at the upper boundary.
*/
default BoundaryCondition[] getBoundaryConditionsAtUpperBoundary(
final FiniteDifferenceInterestRateProduct product,
final double time,
final double... stateVariables) {
final int numberOfSpaceGrids = getSpaceTimeDiscretization().getNumberOfSpaceGrids();
final BoundaryCondition[] boundaryConditions = new BoundaryCondition[numberOfSpaceGrids];
for (int i = 0; i < numberOfSpaceGrids; i++) {
boundaryConditions[i] = StandardBoundaryCondition.none();
}
return boundaryConditions;
}
}