R語(yǔ)言和QuantLib中Nelson-Siegel模型收益曲線(xiàn)建模分析
?原文鏈接:http://tecdat.cn/?p=11803?
Nelson-Siegel- [Svensson]模型是擬合收益曲線(xiàn)的常用方法。它的優(yōu)點(diǎn)是其參數(shù)的經(jīng)濟(jì)可解釋性,被銀行廣泛使用。但它不一定在所有情況下都有效:模型參數(shù)有時(shí)非常不穩(wěn)定,無(wú)法收斂。
納爾遜(Nelson)和西格爾(Siegel)在其原始論文中從遠(yuǎn)期利率入手,然后推導(dǎo)了收益率至到期曲線(xiàn)的公式.

Nelson-Siegel模型是簡(jiǎn)約的,可以生成豐富的收益曲線(xiàn)。
但是,由于簡(jiǎn)單地使用它,它通常失去了經(jīng)濟(jì)上的可解釋性,甚至無(wú)法收斂。

上圖顯示了這種情況。
plot(MATURITY_BASES, oldYields
lines(MATURITY_BASES, oldYields)
points(newMats, newYields, col="blue")
lines(newMats, newYields, col="blue")
此代碼模仿了一個(gè)頻繁使用的案例,當(dāng)前的收益曲線(xiàn)與昨天的曲線(xiàn)進(jìn)行了比較。從某種意義上講,這是一個(gè)簡(jiǎn)單示例,因?yàn)閷?duì)于給定的到期日,我們已經(jīng)具有零收益率。實(shí)際上,我們通常與票息債券有關(guān),這會(huì)使事情變得更加復(fù)雜。
您可能會(huì)認(rèn)為,由于軟件的實(shí)施而導(dǎo)致收斂失敗。我要講的不是不好的實(shí)現(xiàn),而是要高度依賴(lài)所使用的數(shù)值方法,如下面的更實(shí)際的示例所示。
提供更逼真的建模
#include <ql/qldefines.hpp>
#ifdef BOOST_MSVC
#? include <ql/auto_link.hpp>
#endif
#include <ql/termstructures/yield/fittedbonddiscountcurve.hpp>
#include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/termstructures/yield/bondhelpers.hpp>
#include <ql/termstructures/yield/nonlinearfittingmethods.hpp>
using namespace QuantLib;
int main(int, char*[]) {
????try {
????????Calendar calendar = NullCalendar();
????????Date today = Date(18, December, 2017);
????????Settings::instance().evaluationDate() = today;
????????//市場(chǎng)數(shù)據(jù)
????????double cleanPrices1[] = { 107.96, 135.88, 110.6,?? 133.46, 135.8,? 142.155, 121.045, 134.97, 117.04,
????????????101.61, 128.67, 106.615, 106.36, 99.515, 101.21,? 105.655, 114.828 };
????????double cleanPrices2[] = { 107.9,? 134.965, 110.37,? 132.89, 135.62,140.845, 120.585, 133.995, 116.745,
????????????101.58, 128.115,105.985, 105.395,99.385, 100.79,104.955, 114.7985 };
????????double cleanPrices3[] = { 107.96, 134.625, 110.58, 132.65, 135.145, 140.585, 120.385, 133.735, 116.635,
????????????101.62, 127.925, 105.6, 105.085, 99.29, 100.6, 104.945, 114.7415 };
????????double cleanPrices4[] = { 107.78, 134.39, 110.175, 132.445, 134.905, 139.515, 120.115, 133.475, 116.455,
????????????101.58, 127.845, 105.53,104.805, 99.07, 100.46, 104.885, 114.6225 };
????????std::vector<boost::shared_ptr<BondHelper> > bondHelpersA;
????????std::vector< boost::shared_ptr<SimpleQuote> > quoteA;
????????std::vector<boost::shared_ptr<BondHelper> > bondHelpersB;
????????for (Size i = 0; i < numberOfBonds; i++) {
????????????boost::shared_ptr<SimpleQuote> cp1(new SimpleQuote(cleanPrices1<em class="d4pbbc-italic"></em>));
????????????quoteA.push_back(cp1);
????????????boost::shared_ptr<SimpleQuote> cp2(new SimpleQuote(cleanPrices2<em class="d4pbbc-italic"></em>));
????????????quoteB.push_back(cp2);
????????????boost::shared_ptr<SimpleQuote> cp3(new SimpleQuote(cleanPrices3<em class="d4pbbc-italic"></em>));
????????????quoteC.push_back(cp3);
????????????boost::shared_ptr<SimpleQuote> cp4(new SimpleQuote(cleanPrices4<em class="d4pbbc-italic"></em>));
????????????quoteD.push_back(cp4);
????????}
????????RelinkableHandle<Quote> quoteHandleA[numberOfBonds];
????????//Nelson-Siegel模型擬合
????????Real tolerance = 1.0e-14;
????????Size max = 10000;
????????boost::shared_ptr<FittedBondDiscountCurve> tsA(
????????????new FittedBondDiscountCurve(curveSettlementDays,
????????????????calendar,
????????????????instrumentsA,
????????????????ActualActual(),
????????????????NelsonSiegelFitting(),
????????????????tolerance,
????????????????max));
????????boost::shared_ptr<FittedBondDiscountCurve> tsB(
????????????new FittedBondDiscountCurve(curveSettlementDays,
????????????????calendar,
????????????????instrumentsB,
????????????????ActualActual(),
????????????????NelsonSiegelFitting(),
????????????????tolerance,
????????????????max));
????????boost::shared_ptr<FittedBondDiscountCurve> tsC(
????????????new FittedBondDiscountCurve(curveSettlementDays,
????????????????calendar,
????????????????instrumentsC,
????????????????ActualActual(),
????????????????NelsonSiegelFitting(),
????????????????tolerance,
????????????????max));
????????boost::shared_ptr<FittedBondDiscountCurve> tsD(
????????????new FittedBondDiscountCurve(curveSettlementDays,
????????????????calendar,
????????????????instrumentsD,
????????????????ActualActual(),
????????????????NelsonSiegelFitting(),
????????????????tolerance,
????????????????max));
????????std::cout << tsA->fitResults().numberOfIterations() << std::endl;
????????std::cout << tsB->fitResults().numberOfIterations() << std::endl;
?
正式而言,收益曲線(xiàn)每天的變化并不顯著,但是模型參數(shù)卻可以:

?
Nelson-Siegel意識(shí)到了這些問(wèn)題,并提供了解決這些問(wèn)題的方法。特別是,他們考慮了Taus的時(shí)間序列,并確定了Taus的最佳擬合值的中值和合理范圍。
但是,與往常一樣,原始論文被引用的次數(shù)可能多于閱讀次數(shù)。此外,如果需要按時(shí)間順序排列的收益率數(shù)據(jù),可能會(huì)感到困惑,而不是僅僅考慮相關(guān)日期的數(shù)據(jù)。即使處理時(shí)間序列不是問(wèn)題,Nelson和Siegel也沒(méi)有指定正式的算法來(lái)選擇的最佳值。
?

最受歡迎的見(jiàn)解
1.在python中使用lstm和pytorch進(jìn)行時(shí)間序列預(yù)測(cè)
2.python中利用長(zhǎng)短期記憶模型lstm進(jìn)行時(shí)間序列預(yù)測(cè)分析
3.使用r語(yǔ)言進(jìn)行時(shí)間序列(arima,指數(shù)平滑)分析
4.r語(yǔ)言多元copula-garch-模型時(shí)間序列預(yù)測(cè)
5.r語(yǔ)言copulas和金融時(shí)間序列案例
6.使用r語(yǔ)言隨機(jī)波動(dòng)模型sv處理時(shí)間序列中的隨機(jī)波動(dòng)
7.r語(yǔ)言時(shí)間序列tar閾值自回歸模型
8.r語(yǔ)言k-shape時(shí)間序列聚類(lèi)方法對(duì)股票價(jià)格時(shí)間序列聚類(lèi)
9.python3用arima模型進(jìn)行時(shí)間序列預(yù)測(cè)
?