lballabio / QuantLib

The QuantLib C++ library
http://quantlib.org
Other
5k stars 1.73k forks source link

FittedBondDiscountCurve: allow constraints #1954

Open klin333 opened 2 months ago

klin333 commented 2 months ago

Hi,

It appears previous efforts (#982) to allow constraints in FittedBondDiscountCurve did not reach the finish line. Any chance we can resurrect the effort? No worries it causes too much trouble, as I can just override QuantLib in my uses.

Note that i have poor c++ capabilities and poor OOP design knowledge. This diff is just for illustrative purposes.

diff --git a/src/fittedbonddiscountcurve.cpp b/src/fittedbonddiscountcurve.cpp
index 9a14cfa..123a853 100644
--- a/src/fittedbonddiscountcurve.cpp
+++ b/src/fittedbonddiscountcurve.cpp
@@ -129,9 +129,11 @@ namespace QuantLibOvrd {
         ext::shared_ptr<OptimizationMethod> optimizationMethod,
         Array l2,
         const Real minCutoffTime,
-        const Real maxCutoffTime)
+        const Real maxCutoffTime,
+        ext::shared_ptr<Constraint> constraint)
     : constrainAtZero_(constrainAtZero), weights_(weights), l2_(std::move(l2)),
       calculateWeights_(weights.empty()), optimizationMethod_(std::move(optimizationMethod)),
+      constraint_(std::move(constraint)),
       minCutoffTime_(minCutoffTime), maxCutoffTime_(maxCutoffTime) {}

     void FittedBondDiscountCurve::FittingMethod::init() {
@@ -184,7 +186,6 @@ namespace QuantLibOvrd {
     void FittedBondDiscountCurve::FittingMethod::calculate() {

         FittingCost& costFunction = *costFunction_;
-        Constraint constraint = NoConstraint();

         // start with the guess solution, if it exists
         Array x(size(), 0.0);
@@ -216,7 +217,7 @@ namespace QuantLibOvrd {
         if(!optimization){
             optimization = ext::make_shared<Simplex>(curve_->simplexLambda_);
         }
-        Problem problem(costFunction, constraint, x);
+        Problem problem(costFunction, *constraint_, x);

         Real rootEpsilon = curve_->accuracy_;
         Real functionEpsilon =  curve_->accuracy_;
diff --git a/src/fittedbonddiscountcurve.hpp b/src/fittedbonddiscountcurve.hpp
index 6d0eb7c..835e8ce 100644
--- a/src/fittedbonddiscountcurve.hpp
+++ b/src/fittedbonddiscountcurve.hpp
@@ -31,6 +31,7 @@
 #include <ql/patterns/lazyobject.hpp>
 #include <ql/math/array.hpp>
 #include <ql/utilities/clone.hpp>
+#include <ql/math/optimization/constraint.hpp>

 using namespace QuantLib;

@@ -207,6 +208,8 @@ namespace QuantLibOvrd {
         Array l2() const;
         //! return optimization method being used
         ext::shared_ptr<OptimizationMethod> optimizationMethod() const;
+        //! return optimization contraint
+        ext::shared_ptr<Constraint> constraint() const;
         //! open discountFunction to public
         DiscountFactor discount(const Array& x, Time t) const;
       protected:
@@ -217,7 +220,8 @@ namespace QuantLibOvrd {
                           ext::shared_ptr<OptimizationMethod>(),
                       Array l2 = Array(),
                       Real minCutoffTime = 0.0,
-                      Real maxCutoffTime = QL_MAX_REAL);
+                      Real maxCutoffTime = QL_MAX_REAL,
+                      ext::shared_ptr<Constraint> constraint = ext::shared_ptr<NoConstraint>());
         //! rerun every time instruments/referenceDate changes
         virtual void init();
         //! discount function called by FittedBondDiscountCurve
@@ -255,6 +259,8 @@ namespace QuantLibOvrd {
         EndCriteria::Type errorCode_ = EndCriteria::None;
         // optimization method to be used, if none provided use Simplex
         ext::shared_ptr<OptimizationMethod> optimizationMethod_;
+        // optimization constraint, if none provided use NoConstraint
+        ext::shared_ptr<Constraint> constraint_;
         // flat extrapolation of instantaneous forward before / after cutoff
         Real minCutoffTime_, maxCutoffTime_;
     };
@@ -327,6 +333,11 @@ namespace QuantLibOvrd {
         return optimizationMethod_;
     }

+    inline ext::shared_ptr<Constraint>
+      FittedBondDiscountCurve::FittingMethod::constraint() const {
+        return constraint_;
+      }
+
     inline DiscountFactor FittedBondDiscountCurve::FittingMethod::discount(const Array& x, Time t) const {
         if (t < minCutoffTime_) {
             // flat fwd extrapolation before min cutoff time
github-actions[bot] commented 2 weeks ago

This issue was automatically marked as stale because it has been open 60 days with no activity. Remove stale label or comment, or this will be closed in two weeks.