2
$\begingroup$

I've checked similar questions and answers but even after setting the evaluation date in ql.settings I still get zero. Like another poster, I also have the QL cookbook and have read everything I could find, but still struggling. Thanks for any help!

import QuantLib as ql 
calc_date= ql.Date(21,ql.July,2023)
ql.Settings.instance().setEvaluationDate(calc_date)

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

trade_date = ql.Date(20,ql.July,2023)
maturityDate = ql.Date(4,ql.August,2023)

spotDates = [ql.Date(20,ql.July,2023), ql.Date(4,ql.August,2023), ql.Date(4,ql.August,2024)]
spotRates = [0.01318, 00.01318,0.01318]

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('1W'), spotCurveHandle)
index.addFixing(ql.Date(18, ql.July, 2023),0.01318)
# index.addFixing(ql.Date(26, 6, 2020), 0.05)
notional = 54760000
rate = 1.37825/100

fra = ql.ForwardRateAgreement(trade_date, maturityDate, ql.Position.Long, rate, notional, index, spotCurveHandle)
print('NPV:', fra.NPV())
$\endgroup$

1 Answer 1

4
$\begingroup$

This is not an FX Forward but a Forward Rate Agreement (a rates product). I'm not sure if QuantLib has a FX Forward pricer but they do have one for FX swaps (see FXSwapRateHelper).

Now, to get a non-zero NPV you probably want to add a valuation date before the settlement date:

for day in [18, 19, 20]:
    ql.Settings.instance().evaluationDate = ql.Date(day, 7, 2023)
    fra = ql.ForwardRateAgreement(trade_date, maturityDate, ql.Position.Long, rate, notional, index, spotCurveHandle)
    print('NPV:', round(fra.NPV(), 2), "Expired:", fra.isExpired())

Which gives:

NPV: -1373.95 Expired: False
NPV: -1373.95 Expired: False
NPV: 0.0 Expired: True

Remember that a FRA pays at the beginning of the period (see e.g. this paper). This is also explained in the QL documentation here: "the FRA settles and expires on the valueDate, not on the (later) maturityDate". The life cycle looks as follows:

enter image description here

$\endgroup$
2
  • $\begingroup$ thanks so much!! $\endgroup$ Aug 1, 2023 at 23:35
  • 2
    $\begingroup$ No worries - if you're happy with the answer, feel free to accept it @PythonAutomation $\endgroup$
    – oronimbus
    Aug 2, 2023 at 7:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.