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

net.finmath.montecarlo.interestrate.LIBORMarketModel 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. All rights reserved. Contact: [email protected].
 *
 * Created on 09.02.2004
 */
package net.finmath.montecarlo.interestrate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.finmath.exception.CalculationException;
import net.finmath.functions.AnalyticFormulas;
import net.finmath.marketdata.model.AnalyticModelInterface;
import net.finmath.marketdata.model.curves.DiscountCurveFromForwardCurve;
import net.finmath.marketdata.model.curves.DiscountCurveInterface;
import net.finmath.marketdata.model.curves.ForwardCurveInterface;
import net.finmath.marketdata.model.volatilities.AbstractSwaptionMarketData;
import net.finmath.marketdata.products.Swap;
import net.finmath.marketdata.products.SwapAnnuity;
import net.finmath.montecarlo.interestrate.modelplugins.AbstractLIBORCovarianceModel;
import net.finmath.montecarlo.interestrate.modelplugins.AbstractLIBORCovarianceModelParametric;
import net.finmath.montecarlo.interestrate.products.AbstractLIBORMonteCarloProduct;
import net.finmath.montecarlo.interestrate.products.SwaptionAnalyticApproximation;
import net.finmath.montecarlo.interestrate.products.SwaptionSimple;
import net.finmath.montecarlo.model.AbstractModel;
import net.finmath.stochastic.RandomVariableInterface;
import net.finmath.time.RegularSchedule;
import net.finmath.time.ScheduleInterface;
import net.finmath.time.TimeDiscretization;
import net.finmath.time.TimeDiscretizationInterface;

/**
 * Implements a (generalized) LIBOR market model with some drift approximation methods.
 * 

* In its default case the class specifies a multi-factor LIBOR market model in its log-normal formulation, that is * Lj = exp(Yj) where * \[ * dY_{j} = \mu_{j} dt + \lambda_{1,j} dW_{1} + \ldots + \lambda_{m,j} dW_{m} * \] *
* The model uses an AbstractLIBORCovarianceModel for the specification of * 1,j,...,λm,j) as a covariance model. * See {@link net.finmath.montecarlo.model.AbstractModelInterface} for details on the implemented interface *

* However, the class is more general: *
    *
  • * The model may be log-normal or normal specification with a given local volatility. *
  • *
  • * The class implements different measure(drift) / numeraire pairs: terminal measure and spot measure. *
  • *
  • * The class allows to configure a discounting curve (e.g. for "OIS discounting") using a simple deterministic zero spread. * In this case, the numeraire \( N(t) \) is adjusted by \( \exp( \int_0^t -\lambda(\tau) d\tau ) \). *
  • *
* *
* The class specifies a LIBOR market model, that is * Lj = f(Yj) where *
    *
  • * f is f(x) = exp(x) (default, log-normal LIBOR Market Model) or *
  • *
  • * f is f(x) = x (normal model, used if property.set("stateSpace","NORMAL")) *
  • *
* and *
* dYj = μj dt + λ1,j dW1 + ... + λm,j dWm
*
* see {@link net.finmath.montecarlo.model.AbstractModelInterface} for details on the implemented interface. *
* The model uses an AbstractLIBORCovarianceModel as a covariance model. * If the covariance model is of type AbstractLIBORCovarianceModelParametric * a calibration to swaptions can be performed. *
* Note that λ may still depend on L, hence generating a log-normal dynamic for L even * if the stateSpace property has been set to NORMAL. *
* * The map properties allows to configure the model. The following keys may be used: *
    *
  • * measure: Possible values: *
      *
    • * SPOT: Simulate under spot measure. In this case, the single curve numeraire * is \( N(T_{i}) = \prod_{j=0}^{i-1} (1 + L(T_{j},T_{j+1};T_{j}) (T_{j+1}-T_{j})) \). *
    • *
    • * TERMINAL: Simulate under terminal measure. In this case, the single curve numeraire * is \( N(T_{i}) = P(T_{n};T_{i}) = \prod_{j=i}^{n-1} (1 + L(T_{j},T_{j+1};T_{i}) (T_{j+1}-T_{j}))^{-1} \). *
    • *
    *
  • *
  • * stateSpace: Possible values: *
      *
    • * LOGNORMAL: The state space transform is set to exp, i.e., L = exp(Y). When the covariance model is deterministic, then this is the classical lognormal LIBOR market model. Note that the covariance model may still provide a local volatility function. *
    • *
    • * NORMAL: The state space transform is set to identity, i.e., L = Y. When the covariance model is deterministic, then this is a normal LIBOR market model. Note that the covariance model may still provide a local volatility function. *
    • *
    *
  • *
*
* The main task of this class is to calculate the risk-neutral drift and the * corresponding numeraire given the covariance model. * * The calibration of the covariance structure is not part of this class. For the calibration * of parametric models of the instantaneous covariance see * {@link net.finmath.montecarlo.interestrate.modelplugins.AbstractLIBORCovarianceModelParametric#getCloneCalibrated(LIBORMarketModelInterface, AbstractLIBORMonteCarloProduct[], double[], double[], Map)}. * * @author Christian Fries * @version 1.1 * @see net.finmath.montecarlo.process.AbstractProcessInterface The interface for numerical schemes. * @see net.finmath.montecarlo.model.AbstractModelInterface The interface for models provinding parameters to numerical schemes. * @see net.finmath.montecarlo.interestrate.modelplugins.AbstractLIBORCovarianceModel The abstract covariance model plug ins. * @see net.finmath.montecarlo.interestrate.modelplugins.AbstractLIBORCovarianceModelParametric A parametic covariance model including a generic calibration algorithm. */ public class LIBORMarketModel extends AbstractModel implements LIBORMarketModelInterface { public enum Driftapproximation { EULER, LINE_INTEGRAL, PREDICTOR_CORRECTOR } public enum Measure { SPOT, TERMINAL } public enum StateSpace { NORMAL, LOGNORMAL } private final TimeDiscretizationInterface liborPeriodDiscretization; private String forwardCurveName; private AnalyticModelInterface curveModel; private ForwardCurveInterface forwardRateCurve; private DiscountCurveInterface discountCurve; private AbstractLIBORCovarianceModel covarianceModel; private AbstractSwaptionMarketData swaptionMarketData; private Driftapproximation driftApproximationMethod = Driftapproximation.EULER; private Measure measure = Measure.SPOT; private StateSpace stateSpace = StateSpace.LOGNORMAL; // This is a cache of the integrated covariance. private double[][][] integratedLIBORCovariance; public static class CalibrationItem { public final AbstractLIBORMonteCarloProduct calibrationProduct; public final double calibrationTargetValue; public final double calibrationWeight; public CalibrationItem(AbstractLIBORMonteCarloProduct calibrationProduct, double calibrationTargetValue, double calibrationWeight) { super(); this.calibrationProduct = calibrationProduct; this.calibrationTargetValue = calibrationTargetValue; this.calibrationWeight = calibrationWeight; } @Override public String toString() { return "CalibrationItem [calibrationProduct=" + calibrationProduct + ", calibrationTargetValue=" + calibrationTargetValue + ", calibrationWeight=" + calibrationWeight + "]"; } } /** * Creates a LIBOR Market Model for given covariance. * * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param covarianceModel The covariance model to use. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, AbstractLIBORCovarianceModel covarianceModel ) throws CalculationException { this(liborPeriodDiscretization, forwardRateCurve, null, covarianceModel, new CalibrationItem[0], null); } /** * Creates a LIBOR Market Model for given covariance. * * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param discountCurve The discount curve to use. This will create an LMM model with a deterministic zero-spread discounting adjustment. * @param covarianceModel The covariance model to use. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, DiscountCurveInterface discountCurve, AbstractLIBORCovarianceModel covarianceModel ) throws CalculationException { this(liborPeriodDiscretization, forwardRateCurve, discountCurve, covarianceModel, new CalibrationItem[0], null); } /** * Creates a LIBOR Market Model using a given covariance model and calibrating this model * to given swaption volatility data. * * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param covarianceModel The covariance model to use. * @param swaptionMarketData The set of swaption values to calibrate to. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, AbstractLIBORCovarianceModel covarianceModel, AbstractSwaptionMarketData swaptionMarketData ) throws CalculationException { this(liborPeriodDiscretization, forwardRateCurve, null, covarianceModel, swaptionMarketData, null); } /** * Creates a LIBOR Market Model for given covariance. * * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param discountCurve The discount curve to use. This will create an LMM model with a deterministic zero-spread discounting adjustment. * @param covarianceModel The covariance model to use. * @param swaptionMarketData The set of swaption values to calibrate to. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, DiscountCurveInterface discountCurve, AbstractLIBORCovarianceModel covarianceModel, AbstractSwaptionMarketData swaptionMarketData ) throws CalculationException { this( liborPeriodDiscretization, forwardRateCurve, discountCurve, covarianceModel, swaptionMarketData, null ); } /** * Creates a LIBOR Market Model for given covariance. * * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param discountCurve The discount curve to use. This will create an LMM model with a deterministic zero-spread discounting adjustment. * @param covarianceModel The covariance model to use. * @param swaptionMarketData The set of swaption values to calibrate to. * @param properties Key value map specifying properties like measure and stateSpace. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, DiscountCurveInterface discountCurve, AbstractLIBORCovarianceModel covarianceModel, AbstractSwaptionMarketData swaptionMarketData, Map properties ) throws CalculationException { this( liborPeriodDiscretization, forwardRateCurve, discountCurve, covarianceModel, getCalibrationItems( liborPeriodDiscretization, forwardRateCurve, swaptionMarketData, // Condition under which we use analytic approximation (properties == null || properties.get("stateSpace") == null || ((String)properties.get("stateSpace")).toUpperCase().equals(StateSpace.LOGNORMAL.name())) && AbstractLIBORCovarianceModelParametric.class.isAssignableFrom(covarianceModel.getClass()) ), properties ); } /** * Creates a LIBOR Market Model for given covariance. *
* If calibrationItems in non-empty and the covariance model is a parametric model, * the covariance will be replaced by a calibrate version of the same model, i.e., * the LIBOR Market Model will be calibrated. *
* The map properties allows to configure the model. The following keys may be used: *
    *
  • * measure: Possible values: *
      *
    • * SPOT (String): Simulate under spot measure. *
    • *
    • * TERMINAL (String): Simulate under terminal measure. *
    • *
    *
  • *
  • * stateSpace: Possible values: *
      *
    • * LOGNORMAL (String): Simulate L = exp(Y). *
    • *
    • * NORMAL (String): Simulate L = Y. *
    • *
    *
  • *
  • * calibrationParameters: Possible values: *
      *
    • * Map<String,Object> a parameter map with the following key/value pairs: *
        *
      • * accuracy: Double specifying the required solver accuracy. *
      • *
      • * maxIterations: Integer specifying the maximum iterations for the solver. *
      • *
      *
    • *
    *
  • *
* * @param liborPeriodDiscretization The discretization of the interest rate curve into forward rates (tenor structure). * @param forwardRateCurve The initial values for the forward rates. * @param discountCurve The discount curve to use. This will create an LMM model with a deterministic zero-spread discounting adjustment. * @param covarianceModel The covariance model to use. * @param calibrationItems The vector of calibration items (a union of a product, target value and weight) for the objective function sum weight(i) * (modelValue(i)-targetValue(i). * @param properties Key value map specifying properties like measure and stateSpace. * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ public LIBORMarketModel( TimeDiscretizationInterface liborPeriodDiscretization, ForwardCurveInterface forwardRateCurve, DiscountCurveInterface discountCurve, AbstractLIBORCovarianceModel covarianceModel, CalibrationItem[] calibrationItems, Map properties ) throws CalculationException { // Set some properties if(properties != null && properties.containsKey("measure")) measure = Measure.valueOf(((String)properties.get("measure")).toUpperCase()); if(properties != null && properties.containsKey("stateSpace")) stateSpace = StateSpace.valueOf(((String)properties.get("stateSpace")).toUpperCase()); Map calibrationParameters = null; if(properties != null && properties.containsKey("calibrationParameters")) calibrationParameters = (Map)properties.get("calibrationParameters"); this.liborPeriodDiscretization = liborPeriodDiscretization; double[] times = new double[liborPeriodDiscretization.getNumberOfTimeSteps()]; for(int i=0; i 0) { AbstractLIBORCovarianceModelParametric covarianceModelParametric = null; try { covarianceModelParametric = (AbstractLIBORCovarianceModelParametric)covarianceModel; } catch(Exception e) { throw new ClassCastException("Calibration is currently restricted to parametric covariance models (AbstractLIBORCovarianceModelParametric)."); } // @TODO Should be more elegant. Convert array for constructor AbstractLIBORMonteCarloProduct[] calibrationProducts = new AbstractLIBORMonteCarloProduct[calibrationItems.length]; double[] calibrationTargetValues = new double[calibrationItems.length]; double[] calibrationWeights = new double[calibrationItems.length]; for(int i=0; i calibrationItems = new ArrayList(); for(int exerciseIndex=0; exerciseIndex<=optionMaturities.getNumberOfTimeSteps(); exerciseIndex++) { for(int tenorIndex=0; tenorIndex<=tenor.getNumberOfTimeSteps()-exerciseIndex; tenorIndex++) { // Create a swaption double exerciseDate = optionMaturities.getTime(exerciseIndex); double swapLength = tenor.getTime(tenorIndex); if(liborPeriodDiscretization.getTimeIndex(exerciseDate) < 0) continue; if(liborPeriodDiscretization.getTimeIndex(exerciseDate+swapLength) <= liborPeriodDiscretization.getTimeIndex(exerciseDate)) continue; int numberOfPeriods = (int)(swapLength / swapPeriodLength); double[] fixingDates = new double[numberOfPeriods]; double[] paymentDates = new double[numberOfPeriods]; double[] swapTenorTimes = new double[numberOfPeriods+1]; for(int periodStartIndex=0; periodStartIndext for which the numeraire should be returned N(t). * @return The numeraire at the specified time as RandomVariableInterface * @throws net.finmath.exception.CalculationException Thrown if the valuation fails, specific cause may be available via the cause() method. */ @Override public RandomVariableInterface getNumeraire(double time) throws CalculationException { int timeIndex = getLiborPeriodIndex(time); if(timeIndex < 0) { // Interpolation of Numeraire: log linear interpolation. int upperIndex = -timeIndex-1; int lowerIndex = upperIndex-1; if(lowerIndex < 0) throw new IllegalArgumentException("Numeraire requested for time " + time + ". Unsupported"); double alpha = (time-getLiborPeriod(lowerIndex)) / (getLiborPeriod(upperIndex) - getLiborPeriod(lowerIndex)); return getNumeraire(getLiborPeriod(upperIndex)).log().mult(alpha).add(getNumeraire(getLiborPeriod(lowerIndex)).log().mult(1.0-alpha)).exp(); } // Calculate the numeraire, when time is part of liborPeriodDiscretization // Get the start and end of the product int firstLiborIndex, lastLiborIndex; if(measure == Measure.TERMINAL) { firstLiborIndex = getLiborPeriodIndex(time); if(firstLiborIndex < 0) { throw new CalculationException("Simulation time discretization not part of forward rate tenor discretization."); } lastLiborIndex = liborPeriodDiscretization.getNumberOfTimeSteps()-1; } else if(measure == Measure.SPOT) { // Spot measure firstLiborIndex = 0; lastLiborIndex = getLiborPeriodIndex(time)-1; } else { throw new CalculationException("Numeraire not implemented for specified measure."); } /* * Calculation of the numeraire */ // Initialize to 1.0 RandomVariableInterface numeraire = getProcess().getBrownianMotion().getRandomVariableForConstant(1.0); // The product for(int liborIndex = firstLiborIndex; liborIndex<=lastLiborIndex; liborIndex++) { RandomVariableInterface libor = getLIBOR(getTimeIndex(Math.min(time,liborPeriodDiscretization.getTime(liborIndex))), liborIndex); double periodLength = liborPeriodDiscretization.getTimeStep(liborIndex); if(measure == Measure.SPOT) { numeraire = numeraire.accrue(libor, periodLength); } else { numeraire = numeraire.discount(libor, periodLength); } } /* * Adjust for discounting, i.e. funding or collateralization */ if(discountCurve != null) { DiscountCurveInterface discountCurveFromForwardPerformance = new DiscountCurveFromForwardCurve(forwardRateCurve); double deterministicNumeraireAdjustment = discountCurveFromForwardPerformance.getDiscountFactor(time) / discountCurve.getDiscountFactor(time); numeraire = numeraire.mult(deterministicNumeraireAdjustment); } return numeraire; } @Override public RandomVariableInterface[] getInitialState() { double[] liborInitialStates = new double[liborPeriodDiscretization.getNumberOfTimeSteps()]; for(int timeIndex=0; timeIndexgetNumeraire
. * * @param timeIndex Time index i for which the drift should be returned μ(ti). * @param realizationAtTimeIndex Time current forward rate vector at time index i which should be used in the calculation. * @return The drift vector μ(ti) as RandomVariable[] */ @Override public RandomVariableInterface[] getDrift(int timeIndex, RandomVariableInterface[] realizationAtTimeIndex, RandomVariableInterface[] realizationPredictor) { double time = getTime(timeIndex); int firstLiborIndex = this.getLiborPeriodIndex(time)+1; if(firstLiborIndex<0) firstLiborIndex = -firstLiborIndex-1 + 1; // Allocate drift vector and initialize to zero (will be used to sum up drift components) RandomVariableInterface[] drift = new RandomVariableInterface[getNumberOfComponents()]; RandomVariableInterface[][] covarianceFactorSums = new RandomVariableInterface[getNumberOfComponents()][getNumberOfFactors()]; for(int componentIndex=firstLiborIndex; componentIndex firstLiborIndex) covarianceFactorSums[componentIndex][factorIndex] = covarianceFactorSums[componentIndex][factorIndex].add(covarianceFactorSums[componentIndex-1][factorIndex]); } for(int factorIndex=0; factorIndex= liborPeriodDiscretization.getNumberOfTimes() || timeIndex < 0) { throw new ArrayIndexOutOfBoundsException("Index for LIBOR period discretization out of bounds: " + timeIndex + "."); } return liborPeriodDiscretization.getTime(timeIndex); } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getLiborPeriodIndex(double) */ @Override public int getLiborPeriodIndex(double time) { return liborPeriodDiscretization.getTimeIndex(time); } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getLiborPeriodDiscretization() */ @Override public TimeDiscretizationInterface getLiborPeriodDiscretization() { return liborPeriodDiscretization; } /** * @return Returns the measure. */ public Measure getMeasure() { return measure; } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getIntegratedLIBORCovariance() */ @Override public synchronized double[][][] getIntegratedLIBORCovariance() { if(integratedLIBORCovariance != null) return integratedLIBORCovariance; TimeDiscretizationInterface liborPeriodDiscretization = getLiborPeriodDiscretization(); TimeDiscretizationInterface simulationTimeDiscretization = getCovarianceModel().getTimeDiscretization(); integratedLIBORCovariance = new double[simulationTimeDiscretization.getNumberOfTimeSteps()][liborPeriodDiscretization.getNumberOfTimeSteps()][liborPeriodDiscretization.getNumberOfTimeSteps()]; for(int timeIndex = 0; timeIndex < simulationTimeDiscretization.getNumberOfTimeSteps(); timeIndex++) { double dt = simulationTimeDiscretization.getTime(timeIndex+1) - simulationTimeDiscretization.getTime(timeIndex); RandomVariableInterface[][] factorLoadings = new RandomVariableInterface[liborPeriodDiscretization.getNumberOfTimeSteps()][]; // Prefetch factor loadings for(int componentIndex = 0; componentIndex < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) { factorLoadings[componentIndex] = getCovarianceModel().getFactorLoading(timeIndex, componentIndex, null); } for(int componentIndex1 = 0; componentIndex1 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex1++) { RandomVariableInterface[] factorLoadingOfComponent1 = factorLoadings[componentIndex1]; // Sum the libor cross terms (use symmetry) for(int componentIndex2 = componentIndex1; componentIndex2 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex2++) { double integratedLIBORCovarianceValue = 0.0; if(getLiborPeriod(componentIndex1) > getTime(timeIndex)) { RandomVariableInterface[] factorLoadingOfComponent2 = factorLoadings[componentIndex2]; for(int factorIndex = 0; factorIndex < getNumberOfFactors(); factorIndex++) { integratedLIBORCovarianceValue += factorLoadingOfComponent1[factorIndex].get(0) * factorLoadingOfComponent2[factorIndex].get(0) * dt; } } integratedLIBORCovariance[timeIndex][componentIndex1][componentIndex2] = integratedLIBORCovarianceValue; } } } // Integrate over time (i.e. sum up). for(int timeIndex = 1; timeIndex < simulationTimeDiscretization.getNumberOfTimeSteps(); timeIndex++) { double[][] prevIntegratedLIBORCovariance = integratedLIBORCovariance[timeIndex-1]; double[][] thisIntegratedLIBORCovariance = integratedLIBORCovariance[timeIndex]; for(int componentIndex1 = 0; componentIndex1 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex1++) { for(int componentIndex2 = componentIndex1; componentIndex2 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex2++) { thisIntegratedLIBORCovariance[componentIndex1][componentIndex2] = prevIntegratedLIBORCovariance[componentIndex1][componentIndex2] + thisIntegratedLIBORCovariance[componentIndex1][componentIndex2]; thisIntegratedLIBORCovariance[componentIndex2][componentIndex1] = thisIntegratedLIBORCovariance[componentIndex1][componentIndex2]; } } } return integratedLIBORCovariance; } @Override public Object clone() { try { Map properties = new HashMap(); properties.put("measure", measure.name()); properties.put("stateSpace", stateSpace.name()); return new LIBORMarketModel(liborPeriodDiscretization, forwardRateCurve, discountCurve, covarianceModel, new CalibrationItem[0], properties); } catch (CalculationException e) { return null; } } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getDiscountCurve() */ @Override public DiscountCurveInterface getDiscountCurve() { if(discountCurve == null) { DiscountCurveInterface discountCurveFromForwardCurve = new DiscountCurveFromForwardCurve(getForwardRateCurve()); return discountCurveFromForwardCurve; } return discountCurve; } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getForwardRateCurve() */ @Override public ForwardCurveInterface getForwardRateCurve() { return forwardRateCurve; } /** * Return the swaption market data used for calibration (if any, may be null). * * @return The swaption market data used for calibration (if any, may be null). */ public AbstractSwaptionMarketData getSwaptionMarketData() { return swaptionMarketData; } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.LIBORMarketModelInterface#getCovarianceModel() */ @Override public AbstractLIBORCovarianceModel getCovarianceModel() { return covarianceModel; } /** * @param covarianceModel A covariance model * @return A new LIBORMarketModel using the specified covariance model. */ @Override public LIBORMarketModel getCloneWithModifiedCovarianceModel(AbstractLIBORCovarianceModel covarianceModel) { LIBORMarketModel model = (LIBORMarketModel)this.clone(); model.covarianceModel = covarianceModel; return model; } @Override public LIBORMarketModel getCloneWithModifiedData(Map dataModified) throws CalculationException { TimeDiscretizationInterface liborPeriodDiscretization = this.liborPeriodDiscretization; ForwardCurveInterface forwardRateCurve = this.forwardRateCurve; DiscountCurveInterface discountCurve = this.discountCurve; AbstractLIBORCovarianceModel covarianceModel = this.covarianceModel; AbstractSwaptionMarketData swaptionMarketData = null; // No recalibration, unless new swaption data is specified Map properties = new HashMap(); properties.put("measure", measure.name()); properties.put("stateSpace", stateSpace.name()); if(dataModified.containsKey("liborPeriodDiscretization")) { liborPeriodDiscretization = (TimeDiscretizationInterface)dataModified.get("liborPeriodDiscretization"); } if(dataModified.containsKey("forwardRateCurve")) { forwardRateCurve = (ForwardCurveInterface)dataModified.get("forwardRateCurve"); } if(dataModified.containsKey("discountCurve")) { discountCurve = (DiscountCurveInterface)dataModified.get("discountCurve"); } if(dataModified.containsKey("forwardRateShift")) { throw new RuntimeException("Forward rate shift clone currently disabled."); } if(dataModified.containsKey("covarianceModel")) { covarianceModel = (AbstractLIBORCovarianceModel)dataModified.get("covarianceModel"); } if(dataModified.containsKey("swaptionMarketData")) { swaptionMarketData = (AbstractSwaptionMarketData)dataModified.get("swaptionMarketData"); } return new LIBORMarketModel(liborPeriodDiscretization, forwardRateCurve, discountCurve, covarianceModel, swaptionMarketData, properties); } @Override public String toString() { return "LIBORMarketModel [liborPeriodDiscretization=" + liborPeriodDiscretization + ", forwardCurveName=" + forwardCurveName + ", curveModel=" + curveModel + ", forwardRateCurve=" + forwardRateCurve + ", discountCurve=" + discountCurve + ", covarianceModel=" + covarianceModel + ", driftApproximationMethod=" + driftApproximationMethod + ", measure=" + measure + ", stateSpace=" + stateSpace + "]"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy