Quantlib

时间:2016-08-17 12:16:47

标签: python quantlib

我在Python中使用QL并翻译了部分示例文件 http://quantlib.org/reference/_fitted_bond_curve_8cpp-example.html#_a25; 如何使用债券拟合收益率曲线以适应Nelson-Siegel 一组给定校准键的收益率曲线。

通常在执行这种非线性拟合时,结果强烈依赖 在初始条件和许多(经济上毫无意义)的最小值 目标函数存在。这就是为什么对参数设置约束 是成功的关键。举个例子,有时候我会变得消极 tau / lambda参数和我的收益率曲线不同。

我没有找到如何指定这些参数约束 NelsonSiegelFitting或FittedBondDiscountCurve课程。我可以 想象任何在QL中执行NS拟合的人都会遇到同样的问题 问题。

2 个答案:

答案 0 :(得分:2)

感谢Andres Hernandez的回答:

目前不可能。但是,扩展QL以允许它是非常容易的,但我认为它需要在c ++上完成。所以即使你在python中使用QL,你能修改c ++代码并导出一个新的绑定吗?如果是,那么您可以使用以下代码,如果没有,那么我可以将其检查到代码中,但是拉取请求需要一些时间才能被接受。如果您可以触摸代码,可以添加以下内容:

in 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_;
    };

in 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界面,但这样做应该是微不足道的。

答案 1 :(得分:0)

我没有足够的声誉对上述答案发表评论,但我认为接受的答案可能会略有改善。使用此代码,参数受lower_[n]+upper_[n]约束。但是,它们应仅限于upper_[n]。为此,可以使用以下代码:

    Real kappa = lower_[3] + (upper_[3]-lower_[3])/(1.0+exp(-x[3]));
Real x0 = lower_[0] + (upper_[0]-lower_[0])/(1.0+exp(-x[0])),
        x1 = lower_[1] + (upper_[1]-lower_[1])/(1.0+exp(-x[1])),
        x2 = lower_[2] + (upper_[2]-lower_[2])/(1.0+exp(-x[2])),;