固定收益

QuantLib FittedBondDiscountCurve 擬合結果和rrorErrorError

  • August 4, 2016

我嘗試將FittedBondDiscountCurve與**NelsonSiegelFitting一起使用,但在呼叫****fitResults()**方法時遇到錯誤:

14415     def fitResults(self) -> "FittingMethod const &":
14416         return _QuantLib.FittedBondDiscountCurve_fitResults(self)
14417     __swig_destroy__ = _QuantLib.delete_FittedBondDiscountCurve
14418     __del__ = lambda self: None

RuntimeError: unable to bracket root in 100 function evaluations (last
bracket attempt: f[-2.29538e+025,5.968e+025] -> [-1.#IND,10200.1])

這個問題是什麼意思?什麼可以解決?此外,您能告訴我“NelsonSiegelFitting”中使用的最小化方法是什麼嗎?我怎樣才能改變它?還是預設使用幾種方法?我已將帶有輸入文件的完整程式碼上傳到我的github

導入 QuanLib

from datetime import datetime, date, time
import QuantLib as ql

class Bond(object):

   def __init__(self, issuer, bond_name, price, tenor, face_amount):
       self.dates = []
       self.cashflows = [] 
       self.issuer = issuer
       self.bond_name = bond_name
       self.price = ql.QuoteHandle(ql.SimpleQuote(price))        
       self.tenor = tenor
       self.face_amount = face_amount

   def add_date(self, date):
       day, month, year = map(int, date.split('.'))
       self.dates.append(ql.Date(day, month, year))

   def add_cashflow(self, cashflow):
       self.cashflows.append(float(cashflow))

導入數據

face_amount = 1000.0 # for all bonds face_amount = 1000.0
tenor = ql.Period(6, ql.Months) # for all bonds tenor = 6m

bonds = {}

with open('bonds.txt') as f:
   next(f) #skip header

for line in f:
   s = line.rstrip().split(';')
   bond_name = s[1]
   if bond_name not in bonds:
       issuer = s[0]        
       price = float(s[4])            
       bonds[bond_name] = Bond(issuer, bond_name, price, tenor, face_amount)

   bonds[bond_name].add_date(s[2])
   bonds[bond_name].add_cashflow(s[3])

設置 QuantLib 參數

evaluationDate = ql.Date(1, 6, 2016)
ql.Settings.instance().evaluationDate = evaluationDate
calendar = ql.TARGET()
day_counter = ql.Thirty360()
accrualConvention = ql.Unadjusted
bussiness_convention = ql.Unadjusted
bondSettlementDays = 0
curveSettlementDays = 0
bondSettlementDate = calendar.advance(evaluationDate, bondSettlementDays, ql.Days)

創建 QuantLib 對象

instruments = []
instruments_names = []

for bond in bonds.keys():

   schedule = ql.Schedule(bonds[bond].dates[0] - bonds[bond].tenor, 
                          bonds[bond].dates[-1], 
                          bonds[bond].tenor,
                          calendar,
                          accrualConvention,
                          accrualConvention,
                          ql.DateGeneration.Forward,
                          False)

   helperA = ql.FixedRateBondHelper(bonds[bond].price,
                                    bondSettlementDays,
                                    bonds[bond].face_amount,
                                    schedule,
                                    bonds[bond].cashflows,
                                    day_counter,
                                    bussiness_convention)

   instruments.append(helperA)
   instruments_names.append(bond)

QuantLib 優化

tolerance = 1.0e-5
iterations = 50000
nelsonSiegel = ql.NelsonSiegelFitting()
term_structure = ql.FittedBondDiscountCurve(curveSettlementDays, 
                            calendar, 
                            instruments,
                            day_counter,
                            nelsonSiegel,
                            tolerance,
                            iterations)
a = term_structure.fitResults()

QuantLib 程式碼中使用面額不是 100 時似乎存在問題。如果您使用面額 = 100 初始化債券助手並相應地重新調整價格,則擬合成功。

我建議您在https://github.com/lballabio/quantlib/issues提出問題,以便解決此問題。同時,您可以在適合期間重新調整價格。一旦有了期限結構,您就可以使用它來為Bond具有正確面額的對象定價。

關於最小化方法:預設使用單純形算法。目前,無法從 Python 中選擇另一個(從 C++ 中,選擇的優化器可以傳遞給NelsonSiegelFitting建構子)。

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