定價

為什麼 QuantLib 用這個公式計算固定腿掉期利率?

  • September 5, 2015

我試圖了解 QuantLib 如何從源級別的普通交換創建(引導)收益率曲線。我有以下測試程式碼:

void testYieldFromIRSwap()
{
Settings::instance().evaluationDate() = Date(1, Jan, 2015);

auto dc = Actual360();

auto h1 = boost::shared_ptr<RateHelper>(new DepositRateHelper
                                              (0.03, Period(1, Years), 0.0, UnitedStates(), Following, false, Actual360()));
auto h2 = boost::shared_ptr<RateHelper>(new DepositRateHelper
                                              (0.04, Period(2, Years), 0.0, UnitedStates(), Following, false, Actual360()));

auto index = boost::shared_ptr<IborIndex>(new EURLibor1Y());
auto h3 = boost::shared_ptr<RateHelper>(
               new SwapRateHelper(0.05, Period(3, Years), UnitedStates(), Annual,
                                  Following, Actual360(), index));

std::vector<boost::shared_ptr<RateHelper>> helpers;
helpers.push_back(h1);
helpers.push_back(h2);
helpers.push_back(h3);

boost::shared_ptr<YieldTermStructure> yield(
               new PiecewiseYieldCurve<Discount,LogLinear>(
                   Settings::instance().evaluationDate(), helpers,
                       Actual360()));

const auto t1 = dc.yearFraction(Date(1, Jan, 2015), Date(1, Jan, 2016)); // 1.014
const auto t2 = dc.yearFraction(Date(1, Jan, 2015), Date(1, Jan, 2017)); // 2.031
const auto t3 = dc.yearFraction(Date(1, Jan, 2015), Date(1, Jan, 2018)); // 3.044

std::cout << yield->discount(0)  << std::endl; // Must be 1
std::cout << yield->discount(t1) << std::endl; // 1/((1+0.03) ^ 1.014) = 0.9704721
std::cout << yield->discount(t2) << std::endl; // 1/(1+0.04) ^ 2.031   = 0.9234328
std::cout << yield->discount(t3) << std::endl;
}

這顯然是一個玩具範例。我有兩筆存款,提供前兩年的貼現率。我的掉期是一年一次的 3 年掉期,我希望掉期能給我第三年的貼現率。我確實得到了值,但我不明白它是如何計算的。

從掉期引導折扣因子的程式碼是:

Real SwapRateHelper::impliedQuote() const {
   QL_REQUIRE(termStructure_ != 0, "term structure not set");
   // we didn't register as observers - force calculation
   swap_->recalculate();
   // weak implementation... to be improved
   static const Spread basisPoint = 1.0e-4;
   Real floatingLegNPV = swap_->floatingLegNPV();
   Spread spread = spread_.empty() ? 0.0 : spread_->value();
   Real spreadNPV = swap_->floatingLegBPS()/basisPoint*spread;
   Real totNPV = - (floatingLegNPV+spreadNPV);
   Real result = totNPV/(swap_->fixedLegBPS()/basisPoint);
   return result;
}

每次當 QuantLib 猜測一個新的折扣因子(即迭代自舉)時,該函式都會為浮動邊計算一個新的 NPV。我希望這個 NPV 設置為等於固定邊的 NPV,從中可以計算出新的掉期利率。

我不明白的是這一

Real result = totNPV/(swap_->fixedLegBPS()/basisPoint);

我認為 BPS 是準確利息的總和,由以下公式計算:

bps += cp->nominal() * cp->accrualPeriod() * df;

問題:

為什麼我們需要將新的固定腿 NPV 除以 BPS 和基點?為什麼basePoint設置為1.0e-4(1個基點)?這樣做有什麼意義?

fixedLegBPS是固定腿的基點敏感度,即固定利率變動一個基點時其 NPV 的變化幅度:計算為固定利率 1 個基點對應的 NPV。

由於固定腿的 NPV 與固定利率成線性比例,您可以寫出等式

targetNPV : fixedRate = BPS : 1 basis point

您突出顯示的行只是解決固定利率問題。

似乎方法**fixedLegBPS()返回與固定腿相關的折扣因子的總和乘以 1 個基點。所以SwapRateHelper::impliedQuote()**返回的實際上是最小化算法中使用的新的公平交換率。

我試圖從類VanillaSwap::engine中找到 calculate() 方法的實現(VanillaSwap.recalculate() 呼叫 calculate() 呼叫其引擎的 calculate() 方法)但我沒有成功。**我認為您可以在那裡找到方法fixedLegBPS()**行為的確認,因為它呼叫 calculate() 然後返回 legBPS_

$$ 0 $$. 希望能幫助到你。(如果你找到它,請告訴我這個實現在哪裡)

引用自:https://quant.stackexchange.com/questions/20621