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

How to use directly in QuantLib a discount or zero-rate curve from Bloomberg, instead of building one from the underlying instruments

我刚开始使用 QuantLib,我希望将其用于 bootstrap 风险率和 CDS 利差的生存概率曲线。为此,我仔细阅读了 Examples/CDS/CDS.cpp 中的示例(QuantLib 附带的示例),它们似乎完全符合我的需要。然而,这是我的问题,我想绕过从基础工具构建 ISDA 收益率曲线,而是从日期向量和贴现因子向量构建收益率曲线(与 SpreadCDSHelpers 一起使用) (或零利率)。例如,为了具体起见,看上述文件(CDS.cpp)中的第3个例子,代码如下:

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, 2,
                                          WeekendsOnly(), ModifiedFollowing,
                                          false, Actual360());
ext::shared_ptr<DepositRateHelper> dp3m =
    ext::make_shared<DepositRateHelper>(0.01234, 3 * Months, 2,
                                          WeekendsOnly(), ModifiedFollowing,
                                          false, Actual360());
ext::shared_ptr<DepositRateHelper> dp6m =
    ext::make_shared<DepositRateHelper>(0.01776, 6 * Months, 2,
                                          WeekendsOnly(), ModifiedFollowing,
                                          false, Actual360());
ext::shared_ptr<DepositRateHelper> dp9m =
    ext::make_shared<DepositRateHelper>(0.01935, 9 * Months, 2,
                                          WeekendsOnly(), ModifiedFollowing,
                                          false, Actual360());
ext::shared_ptr<DepositRateHelper> dp1y =
    ext::make_shared<DepositRateHelper>(0.02084, 12 * Months, 2,
                                          WeekendsOnly(), ModifiedFollowing,
                                          false, 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", 6 * Months, 2, EURCurrency(), WeekendsOnly(),
    ModifiedFollowing, false, Actual360());

ext::shared_ptr<SwapRateHelper> sw2y = ext::make_shared<SwapRateHelper>(
    0.01652, 2 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw3y = ext::make_shared<SwapRateHelper>(
    0.02018, 3 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw4y = ext::make_shared<SwapRateHelper>(
    0.02303, 4 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw5y = ext::make_shared<SwapRateHelper>(
    0.02525, 5 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw6y = ext::make_shared<SwapRateHelper>(
    0.02696, 6 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw7y = ext::make_shared<SwapRateHelper>(
    0.02825, 7 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw8y = ext::make_shared<SwapRateHelper>(
    0.02931, 8 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw9y = ext::make_shared<SwapRateHelper>(
    0.03017, 9 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw10y = ext::make_shared<SwapRateHelper>(
    0.03092, 10 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw11y = ext::make_shared<SwapRateHelper>(
    0.03160, 11 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw12y = ext::make_shared<SwapRateHelper>(
    0.03231, 12 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw15y = ext::make_shared<SwapRateHelper>(
    0.03367, 15 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw20y = ext::make_shared<SwapRateHelper>(
    0.03419, 20 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw25y = ext::make_shared<SwapRateHelper>(
    0.03411, 25 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    euribor6m);
ext::shared_ptr<SwapRateHelper> sw30y = ext::make_shared<SwapRateHelper>(
    0.03412, 30 * Years, WeekendsOnly(), Annual, ModifiedFollowing, Thirty360(),
    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, WeekendsOnly(), isdaYieldHelpers, Actual365Fixed()));
isdaYts->enableExtrapolation();

// -- END

CreditDefaultSwap::PricingModel model = CreditDefaultSwap::ISDA;
ext::shared_ptr<CdsHelper> cds6m(new SpreadCdsHelper(
    0.007927, 6 * Months, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, model));
ext::shared_ptr<CdsHelper> cds1y(new SpreadCdsHelper(
    0.007927, 1 * Years, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, model));
ext::shared_ptr<CdsHelper> cds3y(new SpreadCdsHelper(
    0.012239, 3 * Years, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, model));
ext::shared_ptr<CdsHelper> cds5y(new SpreadCdsHelper(
    0.016979, 5 * Years, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, model));
ext::shared_ptr<CdsHelper> cds7y(new SpreadCdsHelper(
    0.019271, 7 * Years, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, model));
ext::shared_ptr<CdsHelper> cds10y(new SpreadCdsHelper(
    0.020860, 10 * Years, 1, WeekendsOnly(), Quarterly, Following,
    DateGeneration::CDS, Actual360(), 0.4, isdaYts, true, true, Date(),
    Actual360(true), true, 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, WeekendsOnly(), isdaCdsHelpers, Actual365Fixed()));

// set up isda engine
ext::shared_ptr<IsdaCdsEngine> isdaPricer =
    ext::make_shared<IsdaCdsEngine>(
        isdaCts, 0.4, 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,
            Actual365Fixed(),
            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();

您可以将任何插值器与定义一起使用,例如线性、对数线性、立方、对数立方等

我猜你用 isdaSwapDiscountCurve 替换了示例代码中所有出现的 isdaYts,对吧?