如何在 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> isdaSwapDates
和 std::vector<Real> isdaSwapDiscountFactors
是我可以提供的向量。但是,通过此修改,该示例不再有效(事实上,编译但在运行时失败)。
任何指向正确方向的指示将不胜感激。提前致谢。
您可以尝试更复杂的 InterpolatedDiscountCurve:
Handle<YieldTermStructure> isdaSwapDiscountCurve =
boost::shared_ptr<YieldTermStructure>(
new InterpolatedDiscountCurve<LogLinear>(
isdaSwapDates,
isdaSwapDiscountFactors,
Actual365Fixed(),
LogLinear()
)
);
isdaSwapZeroCurve->enableExtrapolation();
您可以将任何插值器与定义一起使用,例如线性、对数线性、立方、对数立方等
我猜你用 isdaSwapDiscountCurve 替换了示例代码中所有出现的 isdaYts,对吧?
我刚开始使用 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> isdaSwapDates
和 std::vector<Real> isdaSwapDiscountFactors
是我可以提供的向量。但是,通过此修改,该示例不再有效(事实上,编译但在运行时失败)。
任何指向正确方向的指示将不胜感激。提前致谢。
您可以尝试更复杂的 InterpolatedDiscountCurve:
Handle<YieldTermStructure> isdaSwapDiscountCurve =
boost::shared_ptr<YieldTermStructure>(
new InterpolatedDiscountCurve<LogLinear>(
isdaSwapDates,
isdaSwapDiscountFactors,
Actual365Fixed(),
LogLinear()
)
);
isdaSwapZeroCurve->enableExtrapolation();
您可以将任何插值器与定义一起使用,例如线性、对数线性、立方、对数立方等
我猜你用 isdaSwapDiscountCurve 替换了示例代码中所有出现的 isdaYts,对吧?