為什麼 QuantLib 用這個公式計算固定腿掉期利率?
我試圖了解 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 $$. 希望能幫助到你。(如果你找到它,請告訴我這個實現在哪裡)