问题描述
我刚刚开始使用 QuantLib,我希望用它来引导风险率和 CDS 点差的生存概率曲线。为此,我仔细阅读了 Examples/CDS/CDS.cpp
中的示例(QuantLib 附带的),这些示例似乎完全符合我的需要。然而,这是我的问题,我想绕过从基础工具构建 ISDA 收益率曲线,而是从日期向量和贴现因子向量构建收益率曲线(与 SpreadCDSHelpers 一起使用) (或零利率)。例如,为了具体起见,查看上述文件(CDS.cpp)中的第三个示例,代码如下:
void example03() {
Date TradeDate(13,June,2011);
Settings::instance().evaluationDate() = TradeDate;
// -- BEGINNING
ext::shared_ptr<DepositRateHelper> dp1m =
ext::make_shared<DepositRateHelper>(0.00445,1 * Months,2,WeekendsOnly(),ModifiedFollowing,false,Actual360());
ext::shared_ptr<DepositRateHelper> dp2m =
ext::make_shared<DepositRateHelper>(0.00949,2 * Months,Actual360());
ext::shared_ptr<DepositRateHelper> dp3m =
ext::make_shared<DepositRateHelper>(0.01234,3 * Months,Actual360());
ext::shared_ptr<DepositRateHelper> dp6m =
ext::make_shared<DepositRateHelper>(0.01776,6 * Months,Actual360());
ext::shared_ptr<DepositRateHelper> dp9m =
ext::make_shared<DepositRateHelper>(0.01935,9 * Months,Actual360());
ext::shared_ptr<DepositRateHelper> dp1y =
ext::make_shared<DepositRateHelper>(0.02084,12 * Months,Actual360());
// this index is probably not important since we are not using
// IborCoupon::usingAtParCoupons() == false
// - define it "isda compliant" anyway
ext::shared_ptr<IborIndex> euribor6m = ext::make_shared<IborIndex>(
"IsdaIbor",EURCurrency(),Actual360());
ext::shared_ptr<SwapRateHelper> sw2y = ext::make_shared<SwapRateHelper>(
0.01652,2 * Years,Annual,Thirty360(),euribor6m);
ext::shared_ptr<SwapRateHelper> sw3y = ext::make_shared<SwapRateHelper>(
0.02018,3 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw4y = ext::make_shared<SwapRateHelper>(
0.02303,4 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw5y = ext::make_shared<SwapRateHelper>(
0.02525,5 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw6y = ext::make_shared<SwapRateHelper>(
0.02696,6 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw7y = ext::make_shared<SwapRateHelper>(
0.02825,7 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw8y = ext::make_shared<SwapRateHelper>(
0.02931,8 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw9y = ext::make_shared<SwapRateHelper>(
0.03017,9 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw10y = ext::make_shared<SwapRateHelper>(
0.03092,10 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw11y = ext::make_shared<SwapRateHelper>(
0.03160,11 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw12y = ext::make_shared<SwapRateHelper>(
0.03231,12 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw15y = ext::make_shared<SwapRateHelper>(
0.03367,15 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw20y = ext::make_shared<SwapRateHelper>(
0.03419,20 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw25y = ext::make_shared<SwapRateHelper>(
0.03411,25 * Years,euribor6m);
ext::shared_ptr<SwapRateHelper> sw30y = ext::make_shared<SwapRateHelper>(
0.03412,30 * Years,euribor6m);
std::vector<ext::shared_ptr<RateHelper> > isdaYieldHelpers;
isdaYieldHelpers.push_back(dp1m);
isdaYieldHelpers.push_back(dp2m);
isdaYieldHelpers.push_back(dp3m);
isdaYieldHelpers.push_back(dp6m);
isdaYieldHelpers.push_back(dp9m);
isdaYieldHelpers.push_back(dp1y);
isdaYieldHelpers.push_back(sw2y);
isdaYieldHelpers.push_back(sw3y);
isdaYieldHelpers.push_back(sw4y);
isdaYieldHelpers.push_back(sw5y);
isdaYieldHelpers.push_back(sw6y);
isdaYieldHelpers.push_back(sw7y);
isdaYieldHelpers.push_back(sw8y);
isdaYieldHelpers.push_back(sw9y);
isdaYieldHelpers.push_back(sw10y);
isdaYieldHelpers.push_back(sw11y);
isdaYieldHelpers.push_back(sw12y);
isdaYieldHelpers.push_back(sw15y);
isdaYieldHelpers.push_back(sw20y);
isdaYieldHelpers.push_back(sw25y);
isdaYieldHelpers.push_back(sw30y);
// build yield curve
Handle<YieldTermStructure> isdaYts = Handle<YieldTermStructure>(
ext::make_shared<PiecewiseYieldCurve<discount,LogLinear> >(
0,isdaYieldHelpers,Actual365Fixed()));
isdaYts->enableExtrapolation();
// -- END
CreditDefaultSwap::PricingModel model = CreditDefaultSwap::ISDA;
ext::shared_ptr<CdsHelper> cds6m(new SpreadCdsHelper(
0.007927,1,Quarterly,Following,DateGeneration::CDS,Actual360(),0.4,isdaYts,true,Date(),Actual360(true),model));
ext::shared_ptr<CdsHelper> cds1y(new SpreadCdsHelper(
0.007927,1 * Years,model));
ext::shared_ptr<CdsHelper> cds3y(new SpreadCdsHelper(
0.012239,model));
ext::shared_ptr<CdsHelper> cds5y(new SpreadCdsHelper(
0.016979,model));
ext::shared_ptr<CdsHelper> cds7y(new SpreadCdsHelper(
0.019271,model));
ext::shared_ptr<CdsHelper> cds10y(new SpreadCdsHelper(
0.020860,model));
std::vector<ext::shared_ptr<DefaultProbabilityHelper> > isdaCdsHelpers;
isdaCdsHelpers.push_back(cds6m);
isdaCdsHelpers.push_back(cds1y);
isdaCdsHelpers.push_back(cds3y);
isdaCdsHelpers.push_back(cds5y);
isdaCdsHelpers.push_back(cds7y);
isdaCdsHelpers.push_back(cds10y);
// build credit curve
Handle<DefaultProbabilityTermStructure> isdaCts =
Handle<DefaultProbabilityTermStructure>(ext::make_shared<
PiecewiseDefaultCurve<SurvivalProbability,LogLinear> >(
0,isdaCdsHelpers,Actual365Fixed()));
// set up isda engine
ext::shared_ptr<IsdaCdsEngine> isdaPricer =
ext::make_shared<IsdaCdsEngine>(
isdaCts,isdaYts);
// check the curves
std::cout << "ISDA yield curve:" << std::endl;
std::cout << "date;time;zeroyield" << std::endl;
for (auto& isdaYieldHelper : isdaYieldHelpers) {
Date d = isdaYieldHelper->latestDate();
Real t = isdaYts->timeFromreference(d);
std::cout << d << ";" << t << ";"
<< isdaYts->zeroRate(d,Actual365Fixed(),Continuous).rate()
<< std::endl;
}
std::cout << "ISDA credit curve:" << std::endl;
std::cout << "date;time;survivalprob" << std::endl;
for (auto& isdaCdsHelper : isdaCdsHelpers) {
Date d = isdaCdsHelper->latestDate();
Real t = isdaCts->timeFromreference(d);
std::cout << d << ";" << t << ";" << isdaCts->survivalProbability(d)
<< std::endl;
}}
它编译并运行良好。现在,我想用以下内容替换注释 // -- BEGINNING
和 // -- END
之间的代码
Handle<YieldTermStructure> isdaSwapdiscountCurve = Handle<YieldTermStructure>(
ext::make_shared<discountCurve>(
isdaSwapDates,isdaSwapdiscountFactors,LogLinear()
)
);
isdaSwapZeroCurve->enableExtrapolation();
其中 std::vector<Date> isdaSwapDates
和 std::vector<Real> isdaSwapdiscountFactors
是我可以提供的向量。但是,通过此修改,该示例不再起作用(实际上,编译但在运行时失败)。
任何指向正确方向的指针都将受到高度赞赏。提前致谢。
解决方法
您可以尝试使用更复杂的 InterpolatedDiscountCurve:
Handle<YieldTermStructure> isdaSwapDiscountCurve =
boost::shared_ptr<YieldTermStructure>(
new InterpolatedDiscountCurve<LogLinear>(
isdaSwapDates,isdaSwapDiscountFactors,Actual365Fixed(),LogLinear()
)
);
isdaSwapZeroCurve->enableExtrapolation();
您可以将任何插值器与定义一起使用,例如线性、LogLinear、Cubic、LogCubic 等
我想你用 isdaSwapDiscountCurve 替换了示例代码中所有出现的 isdaYts,对吧?