I would like to calculate the par swap rates (ie, the fixed leg rates), for swaps traded at par (ie market value = 0), given a zero-coupon curve with observed maturities ranging from 3 months to 120 months.
Here's what I did:
# define constants
face_amount = 100
settlementDays = 0
calendar = ql.NullCalendar()
fixedLegAdjustment = ql.Unadjusted
floatingLegAdjustment = ql.Unadjusted
fixedLegDayCounter = ql.SimpleDayCounter()
floatingLegDayCounter = ql.SimpleDayCounter()
end_of_month = False
floating_rate = ql.IborIndex("MyIndex", ql.Period("3m"), settlementDays, ql.USDCurrency(), calendar, floatingLegAdjustment, end_of_month, floatingLegDayCounter)
# pre-allocate
irs = {}
# calculate dates
curve_date = ql.DateParser.parseFormatted("2020-05-26", "%Y-%m-%d")
ql.Settings.instance().evaluationDate = curve_date
spot_date = calendar.advance(curve_date, settlementDays, ql.Days)
# pre-allocate
irs_rate = []
tenors = []
maturity_dates = []
# loop over maturities
for tenor in np.arange(3, 120 + 1, 3):
# maturity date
maturity_date = calendar.advance(spot_date, ql.Period(int(tenor), ql.Months))
# gather maturity dates
maturity_dates.append(maturity_date)
# build zero coupon curve object
zero_curve = ql.YieldTermStructureHandle(ql.ZeroCurve(maturity_dates, zero_rates, fixedLegAdjustment, calendar))
# build swap curve
# loop over maturities
for tenor in np.arange(3, 120 + 1, 3):
# fixed leg tenor
fixedLegTenor = ql.Period(tenor, ql.Months)
# fixed leg coupon schedule
fixedLegSchedule = ql.Schedule(spot_date, maturity_date,
fixedLegTenor, calendar,
fixedLegAdjustment, fixedLegAdjustment,
ql.DateGeneration.Forward, end_of_month)
# floating leg tenor
floatingLegTenor = ql.Period(3, ql.Months)
# floating leg coupon schedule
floatingLegSchedule = ql.Schedule(spot_date, maturity_date,
floatingLegTenor, calendar,
floatingLegAdjustment, floatingLegAdjustment,
ql.DateGeneration.Forward, end_of_month)
# build swap pricer
irs = ql.VanillaSwap(ql.VanillaSwap.Receiver, face_amount, fixedLegSchedule, FIXED_RATE, fixedLegDayCounter, floatingLegSchedule, floating_rate, 0, floatingLegDayCounter)
# build swap curve
swap_curve = ql.DiscountingSwapEngine(zero_curve)
# get swap rate
irs.setPricingEngine(swap_curve)
# get par swap rate
irs_rate.append(irs.fairRate())
However, this is to obtain the market value of a swap with observed fixed rate = FIXED_RATE
Instead, I want the rate for a given observed market value (zero).
Many thanks in advance for your help.
Calling irs.fairRate()
is correct: it ignores the passed fixed rate and gives you the rate corresponding to value = 0. Instead, irs.NPV()
would give you the market rate given the fixed rate.
However, the way you're creating the swaps is not correct. The second loop should be something like:
for maturity_date in maturities:
which will give you the correct maturity date for each swap. Currently, you're iterating again over tenor
but you don't redefine maturity_date
, so you're reusing over and over again its current value, which happens to be the last value from the previous loop.
Inside the loop, fixedLegTenor
should be set to the length of a fixed-rate coupon (I'm guessing ql.Period(3, ql.Months)
like the floating-rate coupons?)
Finally: yes, you can use any interest-rate term structure for Libor, including ql.ZeroCurve
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.