Quantlib zur Kalibrierung von Interest Rate Caps

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Dieter157
User
Beiträge: 1
Registriert: Dienstag 30. Januar 2024, 14:01

Hallo,

ich versuche mit der Quantlib Library das G2++ Model auf Interest Rate Caps zu kalibrieren.
Dabei habe ich das Problem, dass ich nicht genau weis, wie ich die Cap Helper aufsetzen muss. Deshalb bekomme ich entweder verschiedene Fehlermeldungen oder die Startwerte der Optimierung zurück.

Ich hoffe, dass jemand Erfahrung mit Quantlib hat und mir dabei weiterhelfen kann. Anbei mein Code mit Beispieldaten.

Vielen Dank!!


# Libraries
import QuantLib as ql

# Initial settings
valuation_date = ql.Date(29, 1, 2024)
ql.Settings.instance().evaluationDate = valuation_date

# Setting up yield curve
swap_maturities = [ql.Period(6, ql.Months), ql.Period(1, ql.Years), ql.Period(2, ql.Years),
ql.Period(3, ql.Years), ql.Period(4, ql.Years), ql.Period(5, ql.Years),
ql.Period(6, ql.Years), ql.Period(7, ql.Years), ql.Period(8, ql.Years),
ql.Period(9, ql.Years), ql.Period(10, ql.Years), ql.Period(12, ql.Years),
ql.Period(15, ql.Years), ql.Period(20, ql.Years), ql.Period(25, ql.Years),
ql.Period(30, ql.Years)]
dates = [valuation_date + maturity for maturity in swap_maturities]

yields = [0.03873, 0.03524, 0.02955, 0.02745, 0.02662, 0.02631, 0.02625, 0.02631,
0.02644, 0.02661, 0.02680, 0.02720, 0.02749, 0.02696, 0.02598, 0.02499]

day_count = ql.Actual360()
calendar = ql.Germany()
interpolation = ql.Linear()
compounding = ql.Compounded
compounding_frequency = ql.Semiannual

term_structure = ql.ZeroCurve(dates, yields, day_count, calendar,
interpolation, compounding, compounding_frequency)
ts_handle = ql.YieldTermStructureHandle(term_structure)

# Cap Vols
market_vols = {
1: 0.9081,
2: 1.0488,
3: 1.0533,
4: 1.0391,
5: 1.0232,
6: 1.008,
7: 0.9926,
8: 0.978,
9: 0.9633,
10: 0.9498,
12: 0.9246,
15: 0.8901,
20: 0.8439,
25: 0.8091,
}


# Set up Model
model = ql.G2(ts_handle)

# Create Cap-Objects
#euribor_index = ql.Euribor6M(ts_handle)
cap_helpers = []
start_date = valuation_date + ql.Period(6,ql.Months)

for maturity, vol in market_vols.items():
period = ql.Period(maturity, ql.Years)
end_date = calendar.advance(valuation_date, period)
schedule = ql.Schedule(start_date, end_date, ql.Period(ql.Annual), calendar,
ql.Unadjusted, ql.Unadjusted, ql.DateGeneration.Forward, False)

# Calculation of Strike Rate
fwd_rate = term_structure.forwardRate(start_date, end_date, day_count, compounding, compounding_frequency).rate()
strike_quote = ql.SimpleQuote(fwd_rate)


# Vola quote
vol_quote = ql.QuoteHandle(ql.SimpleQuote(vol))

# Setup of Cap Helper
helper = ql.CapHelper(period, vol_quote, strike_quote, ql.Annual, day_count, False, ts_handle)
helper.setPricingEngine(ql.BlackCapFloorEngine(ts_handle, vol_quote))
cap_helpers.append(helper)

# Setup calibration method
optimization_method = ql.LevenbergMarquardt(1e-8, 1e-8, 1e-8)

# Definition of ending criteria
end_criteria = ql.EndCriteria(1000, 500, 1e-8, 1e-8, 1e-8)

# Calibration
model.calibrate(cap_helpers, optimization_method, end_criteria)

# Results
a, sigma, b, eta, rho = model.params()
print(f"G2++ Model parameters: a = {a}, sigma = {sigma}, b = {b}, eta = {eta}, rho = {rho}")
Antworten