Pricing a Forward Rate Agreement using QuantLib Python

Can someone please help with the pricing of the following forward rate agreement using QuantLib Python?

A 3x6 forward rate agreement, with a notional of \$100,000, the FRA rate being 6%, The FRA settlement date is after 3 months (90 days) and the settlement is based on a 90-day USDLIBOR.

My valuation date is 30 June 2020.

This is my attempt:

import QuantLib as ql

startDate = ql.Date(30, 6, 2020)
ql.Settings.instance().evaluationDate = startDate

spotDates = [ql.Date(30, 6, 2020), ql.Date(31, 12, 2020), ql.Date(30, 6, 2021)]
spotRates = [0.05, 0.05, 0.05]

dayConvention = ql.Thirty360()
calendar = ql.UnitedStates()

maturityDate = calendar.advance(startDate, ql.Period('3M'))

compounding = ql.Simple
compoundingFrequency = ql.Annual

spotCurve = ql.ZeroCurve(spotDates, spotRates, dayConvention, calendar, ql.Linear(), compounding, compoundingFrequency)
spotCurve.enableExtrapolation()
spotCurveHandle = ql.YieldTermStructureHandle(spotCurve)

index = ql.USDLibor(ql.Period('3M'), spotCurveHandle)
index.addFixing(ql.Date(26, 6, 2020), 0.05)
notional = 100000
rate = 0.06

fra = ql.ForwardRateAgreement(startDate, maturityDate, ql.Position.Long, rate, notional, index, spotCurveHandle)
print('NPV:', fra.NPV())


And this is the answer that I get:

NPV: 0.0

The answer that I'm getting is not correct.

1 Answer

For a 3x6 FRA, you probably want to write something like:

today = ql.Date(30, 6, 2020)
ql.Settings.instance().evaluationDate = today

startDate = calendar.advance(today, ql.Period('3M'))
maturityDate = calendar.advance(startDate, ql.Period('3M'))


That is, the start and maturity dates you pass to the FRA constructor should be the underlying period of the LIBOR.

What you were writing instead was a FRA over a period from today to three months hence, which the library considered as already expired.

• Thank you Luigi! QuantLib is returning an NPV of -288.3302632825472, however, from my manual computation, I'm obtaining -288.8029442214667 by doing the following operation: (100000 * (fra.forwardRate().rate() - 0.06) * 0.25)/(1 + (fra.forwardRate().rate() * 0.25)). Why does this slight difference arise? Sep 7, 2021 at 20:14
• The daycount for USD FRAs is Act/360. So the daycount fraction is probably not exactly 0.25. You need to find the number of days in the FRA and divide by 360. Sep 7, 2021 at 20:25
• I did try to use the ACT/360 day convention, but the difference become larger... Sep 8, 2021 at 3:44
• This is what I obtain when I use the ACT/360 day count convention: -291.97315350604094 Sep 8, 2021 at 5:24
• Hmm, I'm looking at the code and it might need some changes in the way it's discounted. Please open an issue on the QuantLib GitHub repository. Sep 8, 2021 at 11:50