QuantLib中Nelson-Siegel收益率曲线的参数限制。

3

我正在使用Python中的QL,并已翻译了示例文件的一部分,该文件可以在以下链接中找到: http://quantlib.org/reference/_fitted_bond_curve_8cpp-example.html#_a25; 该示例演示如何使用债券拟合收益率曲线以适应一组给定的标定债券,以生成Nelson-Siegel收益率曲线。

通常情况下,在执行此类非线性拟合时,结果强烈依赖于初始条件,且存在许多(在经济意义上无意义的)目标函数的局部最小值。这就是为什么对参数进行限制对于成功非常重要的原因。例如,有时我会得到负的tau/lambda参数,并且我的收益率曲线会发散。

我没有发现如何指定这些参数约束在NelsonSiegelFitting或FittedBondDiscountCurve类中。我想任何使用QL进行NS拟合的人都会遇到同样的问题。

1个回答

2

感谢Andres Hernandez的答案:

目前还不可能。然而,扩展QL以允许这样做非常容易,但我认为需要在C++上完成。因此,即使您在Python中使用QL,也可以修改C++代码并导出新的绑定吗?如果是,则可以使用以下代码;如果不是,则我可以将其检入代码中,但需要一些时间才能接受拉取请求。如果您可以触摸代码,则可以添加类似以下内容:

在nonlinearfittingmethods.hpp中:

  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.cpp文件中:

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 接口中,但这应该很容易做到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接