簡體   English   中英

Quantlib Python 收益率曲線自舉問題

[英]Quantlib Python Yield Curve bootstrapping issue

我正在使用 Quantlib 來計算掉期價格。 在計算掉期價格之前,我創建了在計算過程中使用的 quantlib 曲線。

不幸的是,我得到一個 RuntimerError: RuntimeError: 2nd leg: 1st iteration: failed at 1st alive instrument, pillar 4th, 2023, maturity 4th, 2023, reference date 2022.9.30: root not bracketed: f[0.600742,1.66461] - > [1.241044e-02,1.241044e-02]。

在 github/stackoverflow 上,我看到許多其他人遇到了相同的問題,即需要除以 100 的比率或未正確設置 quantlib 日期。 看來我遇到了另一個我無法解決的問題。

此外,當我只使用年費率(而不是月費率)時,代碼運行良好並給我一個答案。 任何幫助深表感謝。

我使用下面的代碼:

from QuantLib import *
import pandas as pd

today = Date(30, September, 2022)
Settings.instance().evaluationDate = today

def create_ql_curve():
    estr_short = pd.DataFrame({'Tenor': [6], 'Rate': [1.7466]})
    estr_long = pd.DataFrame({'Tenor': [1,2,5,10,15,20], 'Rate': [2.2828, 2.547, 2.661, 2.804, 2.85, 2.35]})
    euribor_short = pd.DataFrame({'Tenor': [6], 'Rate': [1.7466]})
    euribor_long = pd.DataFrame({'Tenor': [1,2,5,10,15,20], 'Rate': [2.2828, 2.547, 2.661, 2.804, 2.85, 2.35]})

ois_helpers = [OISRateHelper(0,
                             Period(int(tenor), Months),
                             QuoteHandle(SimpleQuote(rate / 100)),
                             Eonia(),
                             YieldTermStructureHandle(),
                             True)
               for rate, tenor in zip(estr_short['Rate'], estr_short['Tenor'])]

ois_helpers += [OISRateHelper(0,
                              Period(int(tenor), Years),
                              QuoteHandle(SimpleQuote(rate / 100)),
                              Eonia(),
                              YieldTermStructureHandle(),
                              True)  # telescopicValueDates. When set to True bootstrapping is a lot faster.
                for rate, tenor in zip(estr_long['Rate'], estr_long['Tenor'])]

discount_curve = PiecewiseLogCubicDiscount(0, TARGET(), ois_helpers, Actual365Fixed())

discount_curve.enableExtrapolation()

helpers = [SwapRateHelper(QuoteHandle(SimpleQuote(rate / 100)),
                          Period(int(tenor), Months),
                          TARGET(),
                          Annual,
                          Unadjusted,
                          Thirty360(),
                          Euribor6M(),
                          QuoteHandle(),
                          Period(0, Days),
                          YieldTermStructureHandle(discount_curve))
           for rate, tenor in zip(euribor_short['Rate'], euribor_short['Tenor'])]

helpers += [SwapRateHelper(QuoteHandle(SimpleQuote(rate / 100)),
                           Period(int(tenor), Years),
                           TARGET(),
                           Annual,
                           Unadjusted,
                           Thirty360(),
                           Euribor6M(),
                           QuoteHandle(),
                           Period(0, Days),
                           YieldTermStructureHandle(discount_curve))
            for rate, tenor in zip(euribor_long['Rate'], euribor_long['Tenor'])]

euribor_curve = PiecewiseLogCubicDiscount(0, TARGET(), helpers, Actual365Fixed())

euribor_curve.enableExtrapolation()

return discount_curve, euribor_curve

discount_curve, euribor_curve = create_ql_curve()

forecast_handle = RelinkableYieldTermStructureHandle(euribor_curve)
discount_handle = RelinkableYieldTermStructureHandle(discount_curve)

index_6M = Euribor6M(forecast_handle)
swap_engine = DiscountingSwapEngine(discount_handle)

#  swaps

start_date = Date(23, April, 2014)
maturity_date = Date(23, April, 2023)
fixed_schedule = Schedule(start_date, maturity_date,
                          Period(1, Years), TARGET(), Unadjusted, Unadjusted,
                          DateGeneration.Forward, False)

floating_schedule = Schedule(start_date, maturity_date,
                             Period(6, Months), TARGET(), ModifiedFollowing, ModifiedFollowing,
                             DateGeneration.Forward, True)

notional = 115000000
fixed_rate = 0.01727
fixed_leg_daycount = Actual360()
float_spread = 0
float_leg_daycount = Actual360()

calendar = TARGET()
previous = calendar.advance(today, -27, Weeks)
dates = [calendar.advance(previous, n, Days) for n in range(150)]
rates = [0.005] * 150

for date, rate in zip(dates, rates):
    index_6M.addFixing(date, rate)


swap = VanillaSwap(VanillaSwap.Receiver, notional,
                   fixed_schedule, fixed_rate, Thirty360(),
                   floating_schedule, index_6M, 0.0, Actual360())

swap.setPricingEngine(swap_engine)

price = swap.NPV()

找到它:我嘗試使用 SwapRateHelper 來獲取不起作用的月費率。 使用月利率制作曲線時,您應該使用以下內容:

helpers = [DepositRateHelper(QuoteHandle(SimpleQuote(rate / 100)),
                             Period(6, Months), 3,
                             TARGET(), Following, False, Actual360())]

代替:

helpers = [SwapRateHelper(QuoteHandle(SimpleQuote(rate / 100)),
                          Period(int(tenor), Months),
                          TARGET(),
                          Annual,
                          Unadjusted,
                          Thirty360(),
                          Euribor6M(),
                          QuoteHandle(),
                          Period(0, Days),
                          YieldTermStructureHandle(discount_curve))
           for rate, tenor in zip(euribor_short['Rate'], euribor_short['Tenor'])]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM