如何在 QuantLib 中直接使用来自彭​​博社的折扣或零利率曲线,而不是从基础工具构建一个

问题描述

我刚刚开始使用 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> isdaSwapDatesstd::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,对吧?