From ffbc855e33550ee663fe60d73648471adc77b7e4 Mon Sep 17 00:00:00 2001 From: Cay Oest Date: Tue, 18 Jul 2023 14:19:28 +0200 Subject: [PATCH] add constraint to nonlinearfittingmethods --- .../yield/nonlinearfittingmethods.cpp | 66 ++++++++++++------- .../yield/nonlinearfittingmethods.hpp | 36 ++++++---- 2 files changed, 66 insertions(+), 36 deletions(-) diff --git a/ql/termstructures/yield/nonlinearfittingmethods.cpp b/ql/termstructures/yield/nonlinearfittingmethods.cpp index f9f1b217cc9..42f55010bab 100644 --- a/ql/termstructures/yield/nonlinearfittingmethods.cpp +++ b/ql/termstructures/yield/nonlinearfittingmethods.cpp @@ -33,9 +33,10 @@ namespace QuantLib { const Real minCutoffTime, const Real maxCutoffTime, const Size numCoeffs, - const Real fixedKappa) + const Real fixedKappa, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( - constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime), + constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime, constraint), numCoeffs_(numCoeffs), fixedKappa_(fixedKappa) { QL_REQUIRE(ExponentialSplinesFitting::size() > 0, "At least 1 unconstrained coefficient required"); @@ -44,9 +45,11 @@ namespace QuantLib { ExponentialSplinesFitting::ExponentialSplinesFitting(bool constrainAtZero, const Array& weights, const Array& l2, const Real minCutoffTime, const Real maxCutoffTime, - const Size numCoeffs, const Real fixedKappa) + const Size numCoeffs, + const Real fixedKappa, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod(constrainAtZero, weights, ext::shared_ptr(), l2, - minCutoffTime, maxCutoffTime), + minCutoffTime, maxCutoffTime, constraint), numCoeffs_(numCoeffs),fixedKappa_(fixedKappa) { QL_REQUIRE(ExponentialSplinesFitting::size() > 0, "At least 1 unconstrained coefficient required"); @@ -55,8 +58,9 @@ namespace QuantLib { ExponentialSplinesFitting::ExponentialSplinesFitting(bool constrainAtZero, const Size numCoeffs, const Real fixedKappa, - const Array& weights ) - : FittedBondDiscountCurve::FittingMethod(constrainAtZero, weights, ext::shared_ptr(), Array(),0.0,QL_MAX_REAL), + const Array& weights, + Constraint constraint) + : FittedBondDiscountCurve::FittingMethod(constrainAtZero, weights, ext::shared_ptr(), Array(),0.0,QL_MAX_REAL, constraint), numCoeffs_(numCoeffs), fixedKappa_(fixedKappa) { QL_REQUIRE(ExponentialSplinesFitting::size() > 0, "At least 1 unconstrained coefficient required"); @@ -106,16 +110,19 @@ namespace QuantLib { const Array& weights, const ext::shared_ptr& optimizationMethod, const Array& l2, - const Real minCutoffTime, - const Real maxCutoffTime) + Real minCutoffTime, + Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( - true, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime) {} + true, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime, constraint) {} NelsonSiegelFitting::NelsonSiegelFitting(const Array& weights, const Array& l2, - const Real minCutoffTime, const Real maxCutoffTime) + Real minCutoffTime, + Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod(true, weights, ext::shared_ptr(), l2, - minCutoffTime, maxCutoffTime) {} + minCutoffTime, maxCutoffTime, constraint) {} std::unique_ptr NelsonSiegelFitting::clone() const { @@ -143,14 +150,18 @@ namespace QuantLib { const ext::shared_ptr& optimizationMethod, const Array& l2, const Real minCutoffTime, - const Real maxCutoffTime) + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( - true, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime) {} + true, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime, constraint) {} SvenssonFitting::SvenssonFitting(const Array& weights, - const Array& l2, const Real minCutoffTime, const Real maxCutoffTime) + const Array& l2, + const Real minCutoffTime, + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod(true, weights, ext::shared_ptr(), l2, - minCutoffTime, maxCutoffTime) {} + minCutoffTime, maxCutoffTime, constraint) {} std::unique_ptr SvenssonFitting::clone() const { @@ -184,9 +195,10 @@ namespace QuantLib { const ext::shared_ptr& optimizationMethod, const Array& l2, const Real minCutoffTime, - const Real maxCutoffTime) + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( - constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime), + constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime, constraint), splines_(3, knots.size() - 5, knots) { QL_REQUIRE(knots.size() >= 8, @@ -212,9 +224,11 @@ namespace QuantLib { bool constrainAtZero, const Array& weights, const Array& l2, - const Real minCutoffTime, const Real maxCutoffTime) + const Real minCutoffTime, + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod(constrainAtZero, weights, ext::shared_ptr(), l2, - minCutoffTime, maxCutoffTime), + minCutoffTime, maxCutoffTime, constraint), splines_(3, knots.size() - 5, knots) { QL_REQUIRE(knots.size() >= 8, @@ -287,16 +301,19 @@ namespace QuantLib { const ext::shared_ptr& optimizationMethod, const Array& l2, const Real minCutoffTime, - const Real maxCutoffTime) + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( - constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime), + constrainAtZero, weights, optimizationMethod, l2, minCutoffTime, maxCutoffTime, constraint), size_(constrainAtZero ? degree : degree + 1) {} SimplePolynomialFitting::SimplePolynomialFitting(Natural degree, bool constrainAtZero, const Array& weights, const Array& l2, - const Real minCutoffTime, const Real maxCutoffTime) + const Real minCutoffTime, + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod(constrainAtZero, weights, - ext::shared_ptr(), l2, minCutoffTime, maxCutoffTime), + ext::shared_ptr(), l2, minCutoffTime, maxCutoffTime, constraint), size_(constrainAtZero ? degree : degree + 1) {} std::unique_ptr @@ -327,7 +344,8 @@ namespace QuantLib { SpreadFittingMethod::SpreadFittingMethod(const ext::shared_ptr& method, Handle discountCurve, const Real minCutoffTime, - const Real maxCutoffTime) + const Real maxCutoffTime, + Constraint constraint) : FittedBondDiscountCurve::FittingMethod( method != nullptr ? method->constrainAtZero() : true, method != nullptr ? method->weights() : Array(), diff --git a/ql/termstructures/yield/nonlinearfittingmethods.hpp b/ql/termstructures/yield/nonlinearfittingmethods.hpp index 17732fe5236..1d5058cebf4 100644 --- a/ql/termstructures/yield/nonlinearfittingmethods.hpp +++ b/ql/termstructures/yield/nonlinearfittingmethods.hpp @@ -57,18 +57,21 @@ namespace QuantLib { Real minCutoffTime = 0.0, Real maxCutoffTime = QL_MAX_REAL, Size numCoeffs = 9, - Real fixedKappa = Null()); + Real fixedKappa = Null(), + Constraint constraint = NoConstraint{}); ExponentialSplinesFitting(bool constrainAtZero, const Array& weights, const Array& l2, Real minCutoffTime = 0.0, Real maxCutoffTime = QL_MAX_REAL, Size numCoeffs = 9, - Real fixedKappa = Null()); + Real fixedKappa = Null(), + Constraint constraint = NoConstraint{}); ExponentialSplinesFitting(bool constrainAtZero, Size numCoeffs, Real fixedKappa, - const Array& weights = Array() ); + const Array& weights = Array(), + Constraint constraint = NoConstraint{}); std::unique_ptr clone() const override; @@ -98,11 +101,13 @@ namespace QuantLib { ext::shared_ptr(), const Array& l2 = Array(), Real minCutoffTime = 0.0, - Real maxCutoffTime = QL_MAX_REAL); + Real maxCutoffTime = QL_MAX_REAL, + Constraint constraint = NoConstraint{}); NelsonSiegelFitting(const Array& weights, const Array& l2, Real minCutoffTime = 0.0, - Real maxCutoffTime = QL_MAX_REAL); + Real maxCutoffTime = QL_MAX_REAL, + Constraint constraint = NoConstraint{}); std::unique_ptr clone() const override; private: Size size() const override; @@ -130,11 +135,13 @@ namespace QuantLib { ext::shared_ptr(), const Array& l2 = Array(), Real minCutoffTime = 0.0, - Real maxCutoffTime = QL_MAX_REAL); + Real maxCutoffTime = QL_MAX_REAL, + Constraint constraint = NoConstraint{}); SvenssonFitting(const Array& weights, const Array& l2, Real minCutoffTime = 0.0, - Real maxCutoffTime = QL_MAX_REAL); + Real maxCutoffTime = QL_MAX_REAL, + Constraint constraint = NoConstraint{}); std::unique_ptr clone() const override; private: Size size() const override; @@ -171,13 +178,15 @@ namespace QuantLib { ext::shared_ptr(), const Array& l2 = Array(), Real minCutoffTime = 0.0, - Real maxCutoffTime = QL_MAX_REAL); + Real maxCutoffTime = QL_MAX_REAL, + Constraint constraint = NoConstraint{}); CubicBSplinesFitting(const std::vector