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

net.finmath.marketdata.calibration.CalibratedCurves 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 30.11.2012
 */
package net.finmath.marketdata.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 org.jetbrains.annotations.NotNull;

import net.finmath.marketdata.model.AnalyticModel;
import net.finmath.marketdata.model.AnalyticModelFromCurvesAndVols;
import net.finmath.marketdata.model.curves.Curve;
import net.finmath.marketdata.model.curves.DiscountCurve;
import net.finmath.marketdata.model.curves.DiscountCurveInterpolation;
import net.finmath.marketdata.model.curves.ForwardCurve;
import net.finmath.marketdata.model.curves.ForwardCurveFromDiscountCurve;
import net.finmath.marketdata.model.curves.ForwardCurveInterpolation;
import net.finmath.marketdata.products.AnalyticProduct;
import net.finmath.marketdata.products.Deposit;
import net.finmath.marketdata.products.ForwardRateAgreement;
import net.finmath.marketdata.products.Swap;
import net.finmath.marketdata.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 CalibrationSpecs.
 *
 * The products provides are
 * 
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 	
 * 		
 * 		
 * 		
 * 	
 * 
Value of Type StringClassesNote
swap{@link net.finmath.marketdata.products.Swap}
swapleg{@link net.finmath.marketdata.products.SwapLeg}Only the receiver part of CalibrationSpec is used.
swapwithresetonreceiver{@link net.finmath.marketdata.products.SwapLeg}
swapwithresetonpayer{@link net.finmath.marketdata.products.SwapLeg}
deposit{@link net.finmath.marketdata.products.Deposit}Only the receiver part of CalibrationSpec is used.
fra{@link net.finmath.marketdata.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.marketdata.calibration.CalibratedCurves.isUseForwardCurve","true")); // Default value is false isCreateDefaultCurvesForMissingCurves = Boolean.parseBoolean(System.getProperty("net.finmath.marketdata.calibration.CalibratedCurves.isCreateDefaultCurvesForMissingCurves","false")); } /** * Specification of calibration product. * * @author Christian Fries */ public static class CalibrationSpec { private String symbol; private String type; private Schedule swapTenorDefinitionReceiver; private String forwardCurveReceiverName; private double spreadReceiver; private String discountCurveReceiverName; private Schedule swapTenorDefinitionPayer; private String forwardCurvePayerName; private double spreadPayer; private String discountCurvePayerName; private String calibrationCurveName; private 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( String symbol, String type, Schedule swapTenorDefinitionReceiver, String forwardCurveReceiverName, double spreadReceiver, String discountCurveReceiverName, Schedule swapTenorDefinitionPayer, String forwardCurvePayerName, double spreadPayer, String discountCurvePayerName, String calibrationCurveName, 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( String type, Schedule swapTenorDefinitionReceiver, String forwardCurveReceiverName, double spreadReceiver, String discountCurveReceiverName, Schedule swapTenorDefinitionPayer, String forwardCurvePayerName, double spreadPayer, String discountCurvePayerName, String calibrationCurveName, 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( String type, double[] swapTenorDefinitionReceiver, String forwardCurveReceiverName, double spreadReceiver, String discountCurveReceiverName, double[] swapTenorDefinitionPayer, String forwardCurvePayerName, double spreadPayer, String discountCurvePayerName, String calibrationCurveName, 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( String type, double[] swapTenorDefinitionReceiver, String forwardCurveReceiverName, double spreadReceiver, String discountCurveReceiverName, String calibrationCurveName, 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(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 + "]"; } @NotNull public String getSymbol() { return symbol; } } private AnalyticModel model = new AnalyticModelFromCurvesAndVols(); private Set objectsToCalibrate = new LinkedHashSet<>(); private Vector calibrationProducts = new Vector<>(); private Vector calibrationProductsSymbols = new Vector<>(); private List calibrationSpecs = new ArrayList<>(); private final double evaluationTime; private final double calibrationAccuracy; private 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(List calibrationSpecs, AnalyticModel calibrationModel, double evaluationTime, double calibrationAccuracy) throws SolverException, CloneNotSupportedException { if(calibrationModel != null) { model = calibrationModel.getCloneForParameter(null); } this.evaluationTime = evaluationTime; this.calibrationAccuracy = calibrationAccuracy; for(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(CalibrationSpec[] calibrationSpecs, AnalyticModelFromCurvesAndVols calibrationModel, double evaluationTime, double calibrationAccuracy) throws SolverException, CloneNotSupportedException { if(calibrationModel != null) { model = calibrationModel.getCloneForParameter(null); } this.evaluationTime = evaluationTime; this.calibrationAccuracy = calibrationAccuracy; for(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(CalibrationSpec[] calibrationSpecs, AnalyticModelFromCurvesAndVols calibrationModel, 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(CalibrationSpec[] calibrationSpecs, 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(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(CalibrationSpec[] calibrationSpecs) throws SolverException, CloneNotSupportedException { this(calibrationSpecs, null, 0.0); } public AnalyticProduct getCalibrationProductForSpec(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 { Predicate discountCurveMissing = (String curveName) -> curveName != null && curveName.length() > 0 && model.getDiscountCurve(curveName) == null; Predicate forwardCurveMissing = (String curveName) -> 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 + "."); } } Schedule tenorReceiver = calibrationSpec.swapTenorDefinitionReceiver; 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")) { SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, true); SwapLeg legPayer = new SwapLeg(tenorPayer, forwardCurvePayerName, calibrationSpec.spreadPayer, calibrationSpec.discountCurvePayerName, true); product = new Swap(legReceiver, legPayer); } else if(calibrationSpec.type.toLowerCase().equals("swapwithresetonreceiver")) { String discountCurveForNotionalResetName = calibrationSpec.discountCurvePayerName; SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, discountCurveForNotionalResetName, true); SwapLeg legPayer = new SwapLeg(tenorPayer, forwardCurvePayerName, calibrationSpec.spreadPayer, calibrationSpec.discountCurvePayerName, true); product = new Swap(legReceiver, legPayer); } else if(calibrationSpec.type.toLowerCase().equals("swapwithresetonpayer")) { String discountCurveForNotionalResetName = calibrationSpec.discountCurveReceiverName; SwapLeg legReceiver = new SwapLeg(tenorReceiver, forwardCurveReceiverName, calibrationSpec.spreadReceiver, calibrationSpec.discountCurveReceiverName, true); 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(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(String symbol, double shift) throws SolverException, CloneNotSupportedException { // Clone calibration specs, shifting the desired symbol List calibrationSpecsShifted = new ArrayList<>(); for(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(Map shifts) throws SolverException, CloneNotSupportedException { // Clone calibration specs, shifting the desired symbol List calibrationSpecsShifted = new ArrayList<>(); for(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(Pattern symbolRegExp, double shift) throws SolverException, CloneNotSupportedException { // Clone calibration specs, shifting the desired symbol List calibrationSpecsShifted = new ArrayList<>(); for(CalibrationSpec calibrationSpec : calibrationSpecs) { 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(String symbolRegExp, 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(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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy