net.finmath.marketdata2.calibration.CalibratedCurves 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.
/*
* (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
*
* Created on 30.11.2012
*/
package net.finmath.marketdata2.calibration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.finmath.marketdata2.model.AnalyticModel;
import net.finmath.marketdata2.model.AnalyticModelFromCurvesAndVols;
import net.finmath.marketdata2.model.curves.Curve;
import net.finmath.marketdata2.model.curves.DiscountCurveInterface;
import net.finmath.marketdata2.model.curves.DiscountCurveInterpolation;
import net.finmath.marketdata2.model.curves.ForwardCurveFromDiscountCurve;
import net.finmath.marketdata2.model.curves.ForwardCurveInterface;
import net.finmath.marketdata2.model.curves.ForwardCurveInterpolation;
import net.finmath.marketdata2.products.AnalyticProduct;
import net.finmath.marketdata2.products.Deposit;
import net.finmath.marketdata2.products.ForwardRateAgreement;
import net.finmath.marketdata2.products.Swap;
import net.finmath.marketdata2.products.SwapLeg;
import net.finmath.optimizer.SolverException;
import net.finmath.time.RegularSchedule;
import net.finmath.time.Schedule;
import net.finmath.time.TimeDiscretizationFromArray;
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products.
*
* An object of this class provides a calibration of curves (using multi-curves, forward curve, discount curve).
* Sometimes this is referred as curve bootstrapping, however the algorithm used here is not a bootstrap.
*
* The calibration products have to be provided via a vector of CalibrationSpec
s.
*
* The products provides are
*
* List of calibration products types
*
* Value of Type String
* Classes
* Note
*
*
* swap
* {@link net.finmath.marketdata2.products.Swap}
*
*
*
* swapleg
* {@link net.finmath.marketdata2.products.SwapLeg}
* Only the receiver part of CalibrationSpec
is used.
*
*
* swapwithresetonreceiver
* {@link net.finmath.marketdata2.products.SwapLeg}
*
*
*
* swapwithresetonpayer
* {@link net.finmath.marketdata2.products.SwapLeg}
*
*
*
* deposit
* {@link net.finmath.marketdata2.products.Deposit}
* Only the receiver part of CalibrationSpec
is used.
*
*
* fra
* {@link net.finmath.marketdata2.products.ForwardRateAgreement}
* Only the receiver part of CalibrationSpec
is used.
*
*
*
* For a demo spreadsheet using this class see finmath.net/topics/curvecalibration/.
*
* @author Christian Fries
* @version 1.0
*/
public class CalibratedCurves {
private static final boolean isUseForwardCurve;
private static final boolean isCreateDefaultCurvesForMissingCurves;
static {
// Default value is true
isUseForwardCurve = Boolean.parseBoolean(System.getProperty("net.finmath.analytic.calibration.CalibratedCurves.isUseForwardCurve","true"));
// Default value is false
isCreateDefaultCurvesForMissingCurves = Boolean.parseBoolean(System.getProperty("net.finmath.analytic.calibration.CalibratedCurves.isCreateDefaultCurvesForMissingCurves","false"));
}
/**
* Specification of calibration product.
*
* @author Christian Fries
*/
public static class CalibrationSpec {
private String symbol;
private final String type;
private final Schedule swapTenorDefinitionReceiver;
private final String forwardCurveReceiverName;
private final double spreadReceiver;
private final String discountCurveReceiverName;
private Schedule swapTenorDefinitionPayer;
private String forwardCurvePayerName;
private double spreadPayer;
private String discountCurvePayerName;
private final String calibrationCurveName;
private final double calibrationTime;
/**
* Calibration specification.
*
* @param symbol A string identifying the calibration product. This string can be used in sensitivity calculation, allowing to bump the spread in a finite difference approximation. See getCloneShifted
method.
* @param type The type of the calibration product.
* @param swapTenorDefinitionReceiver The schedule of periods of the receiver leg.
* @param forwardCurveReceiverName The forward curve of the receiver leg (may be null).
* @param spreadReceiver The spread or fixed coupon of the receiver leg.
* @param discountCurveReceiverName The discount curve of the receiver leg.
* @param swapTenorDefinitionPayer The schedule of periods of the payer leg.
* @param forwardCurvePayerName The forward curve of the payer leg (may be null).
* @param spreadPayer The spread or fixed coupon of the payer leg.
* @param discountCurvePayerName The discount curve of the payer leg.
* @param calibrationCurveName The curve to calibrate, by this product.
* @param calibrationTime The time point in calibrationCurveName used to calibrate, by this product.
*/
public CalibrationSpec(
final String symbol,
final String type,
final Schedule swapTenorDefinitionReceiver,
final String forwardCurveReceiverName, final double spreadReceiver,
final String discountCurveReceiverName,
final Schedule swapTenorDefinitionPayer,
final String forwardCurvePayerName, final double spreadPayer,
final String discountCurvePayerName,
final String calibrationCurveName,
final double calibrationTime) {
super();
this.symbol = symbol;
this.type = type;
this.swapTenorDefinitionReceiver = swapTenorDefinitionReceiver;
this.forwardCurveReceiverName = forwardCurveReceiverName;
this.spreadReceiver = spreadReceiver;
this.discountCurveReceiverName = discountCurveReceiverName;
this.swapTenorDefinitionPayer = swapTenorDefinitionPayer;
this.forwardCurvePayerName = forwardCurvePayerName;
this.spreadPayer = spreadPayer;
this.discountCurvePayerName = discountCurvePayerName;
this.calibrationCurveName = calibrationCurveName;
this.calibrationTime = calibrationTime;
}
/**
* Calibration specification.
*
* @param type The type of the calibration product.
* @param swapTenorDefinitionReceiver The schedule of periods of the receiver leg.
* @param forwardCurveReceiverName The forward curve of the receiver leg (may be null).
* @param spreadReceiver The spread or fixed coupon of the receiver leg.
* @param discountCurveReceiverName The discount curve of the receiver leg.
* @param swapTenorDefinitionPayer The schedule of periods of the payer leg.
* @param forwardCurvePayerName The forward curve of the payer leg (may be null).
* @param spreadPayer The spread or fixed coupon of the payer leg.
* @param discountCurvePayerName The discount curve of the payer leg.
* @param calibrationCurveName The curve to calibrate, by this product.
* @param calibrationTime The time point in calibrationCurveName used to calibrate, by this product.
*/
public CalibrationSpec(
final String type,
final Schedule swapTenorDefinitionReceiver,
final String forwardCurveReceiverName, final double spreadReceiver,
final String discountCurveReceiverName,
final Schedule swapTenorDefinitionPayer,
final String forwardCurvePayerName, final double spreadPayer,
final String discountCurvePayerName,
final String calibrationCurveName,
final double calibrationTime) {
this(null, type, swapTenorDefinitionReceiver, forwardCurveReceiverName, spreadReceiver, discountCurveReceiverName, swapTenorDefinitionPayer, forwardCurvePayerName, spreadPayer, discountCurvePayerName, calibrationCurveName, calibrationTime);
}
/**
* Calibration specification.
*
* @param type The type of the calibration product.
* @param swapTenorDefinitionReceiver The schedule of periods of the receiver leg.
* @param forwardCurveReceiverName The forward curve of the receiver leg (may be null).
* @param spreadReceiver The spread or fixed coupon of the receiver leg.
* @param discountCurveReceiverName The discount curve of the receiver leg.
* @param swapTenorDefinitionPayer The schedule of periods of the payer leg.
* @param forwardCurvePayerName The forward curve of the payer leg (may be null).
* @param spreadPayer The spread or fixed coupon of the payer leg.
* @param discountCurvePayerName The discount curve of the payer leg.
* @param calibrationCurveName The curve to calibrate, by this product.
* @param calibrationTime The time point in calibrationCurveName used to calibrate, by this product.
*/
public CalibrationSpec(
final String type,
final double[] swapTenorDefinitionReceiver,
final String forwardCurveReceiverName, final double spreadReceiver,
final String discountCurveReceiverName,
final double[] swapTenorDefinitionPayer,
final String forwardCurvePayerName, final double spreadPayer,
final String discountCurvePayerName,
final String calibrationCurveName,
final double calibrationTime) {
super();
this.type = type;
this.swapTenorDefinitionReceiver = new RegularSchedule(new TimeDiscretizationFromArray(swapTenorDefinitionReceiver[0] /* initial */, swapTenorDefinitionReceiver[1] /* numberOfTimeSteps */, swapTenorDefinitionReceiver[2] /* deltaT */, TimeDiscretizationFromArray.ShortPeriodLocation.SHORT_PERIOD_AT_START));
this.forwardCurveReceiverName = forwardCurveReceiverName;
this.spreadReceiver = spreadReceiver;
this.discountCurveReceiverName = discountCurveReceiverName;
this.swapTenorDefinitionPayer = new RegularSchedule(new TimeDiscretizationFromArray(swapTenorDefinitionPayer[0] /* initial */, swapTenorDefinitionPayer[1] /* numberOfTimeSteps */, swapTenorDefinitionPayer[2] /* deltaT */, TimeDiscretizationFromArray.ShortPeriodLocation.SHORT_PERIOD_AT_START));
this.forwardCurvePayerName = forwardCurvePayerName;
this.spreadPayer = spreadPayer;
this.discountCurvePayerName = discountCurvePayerName;
this.calibrationCurveName = calibrationCurveName;
this.calibrationTime = calibrationTime;
}
/**
* Calibration specification.
*
* @param type The type of the calibration product.
* @param swapTenorDefinitionReceiver The schedule of periods of the receiver leg.
* @param forwardCurveReceiverName The forward curve of the receiver leg (may be null).
* @param spreadReceiver The spread or fixed coupon of the receiver leg.
* @param discountCurveReceiverName The discount curve of the receiver leg.
* @param calibrationCurveName The curve to calibrate, by this product.
* @param calibrationTime The time point in calibrationCurveName used to calibrate, by this product.
*/
public CalibrationSpec(
final String type,
final double[] swapTenorDefinitionReceiver,
final String forwardCurveReceiverName, final double spreadReceiver,
final String discountCurveReceiverName,
final String calibrationCurveName,
final double calibrationTime) {
super();
this.type = type;
this.swapTenorDefinitionReceiver = new RegularSchedule(new TimeDiscretizationFromArray(swapTenorDefinitionReceiver[0] /* initial */, swapTenorDefinitionReceiver[1] /* numberOfTimeSteps */, swapTenorDefinitionReceiver[2] /* deltaT */, TimeDiscretizationFromArray.ShortPeriodLocation.SHORT_PERIOD_AT_START));
this.forwardCurveReceiverName = forwardCurveReceiverName;
this.spreadReceiver = spreadReceiver;
this.discountCurveReceiverName = discountCurveReceiverName;
this.calibrationCurveName = calibrationCurveName;
this.calibrationTime = calibrationTime;
}
public CalibrationSpec getCloneShifted(final double shift) {
if(discountCurvePayerName == null || type.toLowerCase().equals("swapleg") || type.toLowerCase().equals("deposit") || type.toLowerCase().equals("fra")) {
return new CalibrationSpec(symbol, type, swapTenorDefinitionReceiver, forwardCurveReceiverName, spreadReceiver+shift, discountCurveReceiverName, swapTenorDefinitionPayer, forwardCurvePayerName, spreadPayer, discountCurvePayerName, calibrationCurveName, calibrationTime);
}
else {
return new CalibrationSpec(symbol, type, swapTenorDefinitionReceiver, forwardCurveReceiverName, spreadReceiver, discountCurveReceiverName, swapTenorDefinitionPayer, forwardCurvePayerName, spreadPayer+shift, discountCurvePayerName, calibrationCurveName, calibrationTime);
}
}
@Override
public String toString() {
return "CalibrationSpec [symbol=" + symbol + ", type=" + type + ", swapTenorDefinitionReceiver="
+ swapTenorDefinitionReceiver + ", forwardCurveReceiverName=" + forwardCurveReceiverName
+ ", spreadReceiver=" + spreadReceiver + ", discountCurveReceiverName=" + discountCurveReceiverName
+ ", swapTenorDefinitionPayer=" + swapTenorDefinitionPayer + ", forwardCurvePayerName="
+ forwardCurvePayerName + ", spreadPayer=" + spreadPayer + ", discountCurvePayerName="
+ discountCurvePayerName + ", calibrationCurveName=" + calibrationCurveName + ", calibrationTime="
+ calibrationTime + "]";
}
}
private AnalyticModel model = new AnalyticModelFromCurvesAndVols();
private final Set objectsToCalibrate = new LinkedHashSet<>();
private final Vector calibrationProducts = new Vector<>();
private final Vector calibrationProductsSymbols = new Vector<>();
private final List calibrationSpecs = new ArrayList<>();
private final double evaluationTime;
private final double calibrationAccuracy;
private final int lastNumberOfInterations;
private double lastAccuracy;
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products and a given model.
*
* If the model already contains a curve referenced as calibration curve that
* curve is replaced by a clone, retaining the given curve information and
* adding a new calibration point.
*
* If the model does not contain the curve referenced as calibration curve, the
* curve will be added to the model.
*
* Use case: You already have a discount curve as part of the model and like
* to calibrate an additional curve to an additional set of instruments.
*
* @param calibrationSpecs Array of calibration specs.
* @param calibrationModel A given model used to value the calibration products.
* @param evaluationTime Evaluation time applied to the calibration products.
* @param calibrationAccuracy Error tolerance of the solver. Set to 0 if you need machine precision.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final List calibrationSpecs, final AnalyticModel calibrationModel, final double evaluationTime, final double calibrationAccuracy) throws SolverException, CloneNotSupportedException {
if(calibrationModel != null) {
model = calibrationModel.getCloneForParameter(null);
}
this.evaluationTime = evaluationTime;
this.calibrationAccuracy = calibrationAccuracy;
for(final CalibrationSpec calibrationSpec : calibrationSpecs) {
add(calibrationSpec);
}
lastNumberOfInterations = calibrate(calibrationAccuracy);
}
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products and a given model.
*
* If the model already contains a curve referenced as calibration curve that
* curve is replaced by a clone, retaining the given curve information and
* adding a new calibration point.
*
* If the model does not contain the curve referenced as calibration curve, the
* curve will be added to the model.
*
* Use case: You already have a discount curve as part of the model and like
* to calibrate an additional curve to an additional set of instruments.
*
* @param calibrationSpecs Array of calibration specs.
* @param calibrationModel A given model used to value the calibration products.
* @param evaluationTime Evaluation time applied to the calibration products.
* @param calibrationAccuracy Error tolerance of the solver. Set to 0 if you need machine precision.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final CalibrationSpec[] calibrationSpecs, final AnalyticModelFromCurvesAndVols calibrationModel, final double evaluationTime, final double calibrationAccuracy) throws SolverException, CloneNotSupportedException {
if(calibrationModel != null) {
model = calibrationModel.getCloneForParameter(null);
}
this.evaluationTime = evaluationTime;
this.calibrationAccuracy = calibrationAccuracy;
for(final CalibrationSpec calibrationSpec : calibrationSpecs) {
add(calibrationSpec);
}
lastNumberOfInterations = calibrate(calibrationAccuracy);
}
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products and a given model.
*
* If the model already contains a curve referenced as calibration curve that
* curve is replaced by a clone, retaining the given curve information and
* adding a new calibration point.
*
* If the model does not contain the curve referenced as calibration curve, the
* curve will be added to the model.
*
* Use case: You already have a discount curve as part of the model and like
* to calibrate an additional curve to an additional set of instruments.
*
* @param calibrationSpecs Array of calibration specs.
* @param calibrationModel A given model used to value the calibration products.
* @param calibrationAccuracy Error tolerance of the solver. Set to 0 if you need machine precision.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final CalibrationSpec[] calibrationSpecs, final AnalyticModelFromCurvesAndVols calibrationModel, final double calibrationAccuracy) throws SolverException, CloneNotSupportedException {
this(calibrationSpecs, calibrationModel, 0.0, calibrationAccuracy);
}
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products and a given model.
*
* If the model already contains a curve referenced as calibration curve that
* curve is replaced by a clone, retaining the given curve information and
* adding a new calibration point.
*
* If the model does not contain the curve referenced as calibration curve, the
* curve will be added to the model.
*
* Use case: You already have a discount curve as part of the model and like
* to calibrate an additional curve to an additional set of instruments.
*
* @param calibrationSpecs Array of calibration specs.
* @param calibrationModel A given model used to value the calibration products.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final CalibrationSpec[] calibrationSpecs, final AnalyticModelFromCurvesAndVols calibrationModel) throws SolverException, CloneNotSupportedException {
this(calibrationSpecs, calibrationModel, 0.0);
}
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products.
*
* @param calibrationSpecs Array of calibration specs.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final Collection calibrationSpecs) throws SolverException, CloneNotSupportedException {
this(calibrationSpecs.toArray(new CalibrationSpec[calibrationSpecs.size()]), null);
}
/**
* Generate a collection of calibrated curves (discount curves, forward curves)
* from a vector of calibration products.
*
* @param calibrationSpecs Array of calibration specs.
* @throws net.finmath.optimizer.SolverException May be thrown if the solver does not cannot find a solution of the calibration problem.
* @throws CloneNotSupportedException Thrown, when a curve could not be cloned.
*/
public CalibratedCurves(final CalibrationSpec[] calibrationSpecs) throws SolverException, CloneNotSupportedException {
this(calibrationSpecs, null, 0.0);
}
public AnalyticProduct getCalibrationProductForSpec(final CalibrationSpec calibrationSpec) {
String forwardCurveReceiverName = calibrationSpec.forwardCurveReceiverName;
String forwardCurvePayerName = calibrationSpec.forwardCurvePayerName;
/*
* If required, default curves are created if missing.
*/
if(isCreateDefaultCurvesForMissingCurves) {
createDiscountCurve(calibrationSpec.discountCurveReceiverName);
createDiscountCurve(calibrationSpec.discountCurvePayerName);
forwardCurveReceiverName = createForwardCurve(calibrationSpec.swapTenorDefinitionReceiver, calibrationSpec.forwardCurveReceiverName);
forwardCurvePayerName = createForwardCurve(calibrationSpec.swapTenorDefinitionPayer, calibrationSpec.forwardCurvePayerName);
}
else {
final Predicate discountCurveMissing = new Predicate() {
@Override
public boolean test(final String curveName) {
return curveName != null && curveName.length() > 0 && model.getDiscountCurve(curveName) == null;
}
};
final Predicate forwardCurveMissing = new Predicate() {
@Override
public boolean test(final String curveName) {
return curveName != null && curveName.length() > 0 && model.getForwardCurve(curveName) == null;
}
};
if(discountCurveMissing.test(calibrationSpec.discountCurveReceiverName)) {
throw new IllegalArgumentException("Discount curve " + calibrationSpec.discountCurveReceiverName + " missing. Needs to be part of model " + model + ".");
}
if(discountCurveMissing.test(calibrationSpec.discountCurvePayerName)) {
throw new IllegalArgumentException("Discount curve " + calibrationSpec.discountCurvePayerName + " missing. Needs to be part of model " + model + ".");
}
if(forwardCurveMissing.test(calibrationSpec.forwardCurveReceiverName)) {
throw new IllegalArgumentException("Forward curve " + calibrationSpec.forwardCurveReceiverName + " missing. Needs to be part of model " + model + ".");
}
if(forwardCurveMissing.test(calibrationSpec.forwardCurvePayerName)) {
throw new IllegalArgumentException("Forward curve " + calibrationSpec.forwardCurvePayerName + " missing. Needs to be part of model " + model + ".");
}
}
final Schedule tenorReceiver = calibrationSpec.swapTenorDefinitionReceiver;
final Schedule tenorPayer = calibrationSpec.swapTenorDefinitionPayer;
AnalyticProduct product = null;
if(calibrationSpec.type.toLowerCase().equals("deposit")){
product = new Deposit(tenorReceiver, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName);
}
else if(calibrationSpec.type.toLowerCase().equals("fra")){
product = new ForwardRateAgreement(tenorReceiver, calibrationSpec.spreadReceiver, forwardCurveReceiverName, calibrationSpec.discountCurveReceiverName);
}
else if(calibrationSpec.type.toLowerCase().equals("future")){
// like a fra but future price needs to be translated into rate
product = new ForwardRateAgreement(calibrationSpec.swapTenorDefinitionReceiver, 1.0-calibrationSpec.spreadReceiver/100.0, forwardCurveReceiverName, calibrationSpec.discountCurveReceiverName);
}
else if(calibrationSpec.type.toLowerCase().equals("swapleg")) {
// note that a swapLeg is always assumed to have a notional reset
product = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, true);
}
else if(calibrationSpec.type.toLowerCase().equals("swap")) {
final SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, true);
final SwapLeg legPayer = new SwapLeg(tenorPayer, forwardCurvePayerName, calibrationSpec.spreadPayer, calibrationSpec.discountCurvePayerName, true);
product = new Swap(legReceiver, legPayer);
}
else if(calibrationSpec.type.toLowerCase().equals("swapwithresetonreceiver")) {
final String discountCurveForNotionalResetName = calibrationSpec.discountCurvePayerName;
final SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, discountCurveForNotionalResetName, true);
final SwapLeg legPayer = new SwapLeg(tenorPayer, forwardCurvePayerName, calibrationSpec.spreadPayer, calibrationSpec.discountCurvePayerName, true);
product = new Swap(legReceiver, legPayer);
}
else if(calibrationSpec.type.toLowerCase().equals("swapwithresetonpayer")) {
final String discountCurveForNotionalResetName = calibrationSpec.discountCurveReceiverName;
final SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, true);
final SwapLeg legPayer = new SwapLeg(tenorPayer, forwardCurvePayerName, calibrationSpec.spreadPayer, calibrationSpec.discountCurvePayerName, discountCurveForNotionalResetName, true);
product = new Swap(legReceiver, legPayer);
}
else {
throw new RuntimeException("Product of type " + calibrationSpec.type + " unknown.");
}
return product;
}
/**
* Return the calibrated model, i.e., the model maintaining a collection of curves calibrated to the
* given calibration specifications.
*
* @return The calibrated model.
*/
public AnalyticModel getModel() {
return model;
}
/**
* Get a curve for a given name.
*
* @param name Name of the curve
* @return The curve model.
*/
public Curve getCurve(final String name) {
return model.getCurve(name);
}
/**
* Return the number of iterations needed to calibrate the model.
*
* @return The number of iterations needed to calibrate the model.
*/
public int getLastNumberOfInterations() {
return lastNumberOfInterations;
}
/**
* Returns the set curves calibrated to "shifted" market data, that is,
* the market date of this
object, modified by the shifts
* provided to this methods.
*
* @param symbol The symbol to shift. All other symbols remain unshifted.
* @param shift The shift to apply to the symbol.
* @return A new set of calibrated curves, calibrated to shifted market data.
* @throws SolverException The likely cause of this exception is a failure of the solver used in the calibration.
* @throws CloneNotSupportedException The likely cause of this exception is the inability to clone or modify a curve.
*/
public CalibratedCurves getCloneShifted(final String symbol, final double shift) throws SolverException, CloneNotSupportedException {
// Clone calibration specs, shifting the desired symbol
final List calibrationSpecsShifted = new ArrayList<>();
for(final CalibrationSpec calibrationSpec : calibrationSpecs) {
if(calibrationSpec.symbol.equals(symbol)) {
calibrationSpecsShifted.add(calibrationSpec.getCloneShifted(shift));
}
else {
calibrationSpecsShifted.add(calibrationSpec);
}
}
return new CalibratedCurves(calibrationSpecsShifted, model, evaluationTime, calibrationAccuracy);
}
/**
* Returns the set curves calibrated to "shifted" market data, that is,
* the market date of this
object, modified by the shifts
* provided to this methods.
*
* @param shifts A map of shifts associating each symbol with a shifts. If symbols are not part of this map, they remain unshifted.
* @return A new set of calibrated curves, calibrated to shifted market data.
* @throws SolverException The likely cause of this exception is a failure of the solver used in the calibration.
* @throws CloneNotSupportedException The likely cause of this exception is the inability to clone or modify a curve.
*/
public CalibratedCurves getCloneShifted(final Map shifts) throws SolverException, CloneNotSupportedException {
// Clone calibration specs, shifting the desired symbol
final List calibrationSpecsShifted = new ArrayList<>();
for(final CalibrationSpec calibrationSpec : calibrationSpecs) {
if(shifts.containsKey(calibrationSpec)) {
calibrationSpecsShifted.add(calibrationSpec.getCloneShifted(shifts.get(calibrationSpec)));
}
else {
calibrationSpecsShifted.add(calibrationSpec);
}
}
return new CalibratedCurves(calibrationSpecsShifted, model, evaluationTime, calibrationAccuracy);
}
/**
* Returns the set curves calibrated to "shifted" market data, that is,
* the market date of this
object, modified by the shifts
* provided to this methods.
*
* This method will shift all symbols matching a given regular expression Pattern
.
*
* @see java.util.regex.Pattern
*
* @param symbolRegExp A pattern, identifying the symbols to shift.
* @param shift The shift to apply to the symbol(s).
* @return A new set of calibrated curves, calibrated to shifted market data.
* @throws SolverException The likely cause of this exception is a failure of the solver used in the calibration.
* @throws CloneNotSupportedException The likely cause of this exception is the inability to clone or modify a curve.
*/
public CalibratedCurves getCloneShifted(final Pattern symbolRegExp, final double shift) throws SolverException, CloneNotSupportedException {
// Clone calibration specs, shifting the desired symbol
final List calibrationSpecsShifted = new ArrayList<>();
for(final CalibrationSpec calibrationSpec : calibrationSpecs) {
final Matcher matcher = symbolRegExp.matcher(calibrationSpec.symbol);
if(matcher.matches()) {
calibrationSpecsShifted.add(calibrationSpec.getCloneShifted(shift));
}
else {
calibrationSpecsShifted.add(calibrationSpec);
}
}
return new CalibratedCurves(calibrationSpecsShifted, model, evaluationTime, calibrationAccuracy);
}
/**
* Returns the set curves calibrated to "shifted" market data, that is,
* the market date of this
object, modified by the shifts
* provided to this methods.
*
* This method will shift all symbols matching a given regular expression.
*
* @see java.util.regex.Pattern
*
* @param symbolRegExp A string representing a regular expression, identifying the symbols to shift.
* @param shift The shift to apply to the symbol(s).
* @return A new set of calibrated curves, calibrated to shifted market data.
* @throws SolverException The likely cause of this exception is a failure of the solver used in the calibration.
* @throws CloneNotSupportedException The likely cause of this exception is the inability to clone or modify a curve.
*/
public CalibratedCurves getCloneShiftedForRegExp(final String symbolRegExp, final double shift) throws SolverException, CloneNotSupportedException {
return getCloneShifted(Pattern.compile(symbolRegExp), shift);
}
/**
* Return the accuracy achieved in the last calibration.
*
* @return The accuracy achieved in the last calibration.
*/
public double getLastAccuracy() {
return lastAccuracy;
}
/**
* Returns the first product found in the vector of calibration products
* which matches the given symbol, where symbol is the String set in
* the calibrationSpecs.
*
* @param symbol A given symbol string.
* @return The product associated with that symbol.
*/
public AnalyticProduct getCalibrationProductForSymbol(final String symbol) {
/*
* The internal data structure is not optimal here (a map would make more sense here),
* if the user does not require access to the products, we would allow non-unique symbols.
* Hence we store both in two side by side vectors.
*/
for(int i=0; i