2016-08-17 53 views
2

我在Python中使用QL並翻譯了示例文件的一部分 http://quantlib.org/reference/_fitted_bond_curve_8cpp-example.html#_a25; 如何擬合帶有債券的收益率曲線,以便將Nelson-Siegel收益率曲線擬合到一組給定的校準債券。Quantal中的Nelson-Siegel產量曲線的參數限制

與往常一樣,當執行這樣的非線性擬合時,結果在很大程度上取決於初始條件下的 ,並且存在許多(經濟上無意義的)目標函數的最小值。這就是爲什麼對參數 施加限制對成功至關重要。舉一個例子,有時我會得到負數 tau/lambda參數,我的收益率曲線發散。

我沒有找到如何在 NelsonSiegelFitting或FittedBondDiscountCurve類中指定這些參數約束。我想 想象任何人在QL執行NS裝配將遇到相同的 問題。

回答

2

感謝Andres Hernandez的回答:

目前這是不可能的。不過,擴展QL以允許它很容易,但我認爲它需要在C++上完成。因此,即使您在Python中使用QL,您是否可以修改C++代碼並導出新的綁定?如果是的話,那麼你可以使用下面的代碼,如果沒有,那麼我可以將它檢入到代碼中,但是需要一段時間才能接受pull請求。在nonlinearfittingmethods.cpp

class NelsonSiegelConstrainedFitting 
     : public FittedBondDiscountCurve::FittingMethod { 
     public: 
     NelsonSiegelConstrainedFitting(const Array& lower, const Array& upper, 
          const Array& weights = Array(), 
          boost::shared_ptr<OptimizationMethod> optimizationMethod 
              = boost::shared_ptr<OptimizationMethod>()); 
     std::auto_ptr<FittedBondDiscountCurve::FittingMethod> clone() const; 
     private: 
     Size size() const; 
     DiscountFactor discountFunction(const Array& x, Time t) const; 
     Array lower_, upper_; 
    }; 

:如果你可以觸摸的代碼,你可以添加這樣的事情:

在nonlinearfittingmethods.hpp

NelsonSiegelConstrainedFitting::NelsonSiegelConstrainedFitting(
             const Array& lower, const Array& upper, const Array& weights, 
             boost::shared_ptr<OptimizationMethod> optimizationMethod) 
: FittedBondDiscountCurve::FittingMethod(true, weights, optimizationMethod), 
    lower_(lower), upper_(upper){ 
    QL_REQUIRE(lower_.size() == 4, "Lower constraint must have 4 elements"); 
    QL_REQUIRE(upper_.size() == 4, "Lower constraint must have 4 elements"); 
} 
std::auto_ptr<FittedBondDiscountCurve::FittingMethod> 
NelsonSiegelConstrainedFitting::clone() const { 
    return std::auto_ptr<FittedBondDiscountCurve::FittingMethod>(
              new NelsonSiegelFitting(*this)); 
} 
Size NelsonSiegelConstrainedFitting::size() const { 
    return 4; 
} 
DiscountFactor NelsonSiegelConstrainedFitting::discountFunction(const Array& x, 
                Time t) const { 
    ///extreme values of kappa result in colinear behaviour of x[1] and x[2], so it should be constrained not only 
    ///to be positive, but also not very extreme 
    Real kappa = lower_[3] + upper_[3]/(1.0+exp(-x[3])); 
    Real x0 = lower_[0] + upper_[0]/(1.0+exp(-x[0])), 
      x1 = lower_[1] + upper_[1]/(1.0+exp(-x[1])), 
      x2 = lower_[2] + upper_[2]/(1.0+exp(-x[2])),; 
    Real zeroRate = x0 + (x1 + x2)* 
         (1.0 - std::exp(-kappa*t))/ 
         ((kappa+QL_EPSILON)*(t+QL_EPSILON)) - 
         x2*std::exp(-kappa*t); 
    DiscountFactor d = std::exp(-zeroRate * t) ; 
    return d; 
} 

然後,您需要將其添加到swig界面,但這樣做應該是微不足道的。