1
$\begingroup$

Below is the sample code to compute the inflation swaps. I have referred the Quantlib cookbook to get the flavor of Inflation swaps. But I feel that the term structure and final NPV is not accurate and also missing something. If anyone can look into the steps and provide the final NPV value of any hypothetical swap could be very useful.

import QuantLib as ql
import datetime
import pandas as pd

valuation_date = ql.Date(14, 5, 2021)
ql.Settings.instance().setEvaluationDate(valuation_date)
# sample par rate of eonia
#eonia_par_rates =  pd.read_csv('eonia.csv')
data = [['EONIA', 2022-5-14 ,2022-5-18,'1Y',-0.487185945], 
    ['EONIA', 2022-5-14 ,2023-5-18,'2Y',-0.47487549]]
eonia_par_rates = pd.DataFrame(data, columns = 
    ['Curve','last_update','maturity','tenor','mid_yield'])

index = ql.Eonia()
helpers = []
for idx, row in eonia_par_rates.iterrows():
    rate = row["mid_yield"] / 100
    tenor = row.tenor
if tenor == "1D":
    print('1D')
    #helpers.append(ql.DepositRateHelper(rate, index))
else:
    helpers.append(
        ql.OISRateHelper(
        0, ql.Period(tenor), ql.QuoteHandle(ql.SimpleQuote(rate)), index
    )
)
 ois = ql.PiecewiseLogCubicDiscount(0, ql.TARGET(), helpers, ql.Actual365Fixed())
ois.enableExtrapolation()
observationLag = ql.Period("3M")
dc = ql.ActualActual()
frequency = ql.Monthly
cal = ql.UnitedKingdom()
bdc = ql.ModifiedFollowing
inflationIndex = ql.EUHICP(True)
# sample inflation rates of EUR-RPI
#infl_data = pd.read_csv('inflation_rates.csv')
data_2 = [[1.377, '1Y', 2022-5-14], 
    [1.311, '2Y',   2023-5-14]]
infl_data = pd.DataFrame(data_2, columns = ['px_last', 'tenor_two,','maturity'])
infl_data['maturity'] = pd.to_datetime(infl_data['maturity'], format="%Y-%m-%d")


inflationRateHelpers = []
for idx, row in infl_data.iterrows():
    maturity = ql.Date().from_date(row.maturity)
    quote = ql.QuoteHandle(ql.SimpleQuote(row.px_last / 100.0))
    helper = ql.ZeroCouponInflationSwapHelper(
  quote,
  observationLag,
  maturity,
   cal,
   bdc,
   dc,
 inflationIndex
  )
 inflationRateHelpers.append(helper)
 baseZeroRate = infl_data.iloc[0].px_last / 100

 inflationCurve =ql.PiecewiseZeroInflation(          
                      valuation_date, 
                      cal, 
                      dc, 
                      observationLag, 
                      frequency, 
                      inflationIndex.interpolated(), 
                      baseZeroRate,
                      ql.YieldTermStructureHandle(ois), 
                      inflationRateHelpers, 
                      1.0e-12, #error
                      ql.Linear())

inflationCurve.enableExtrapolation()

discountYTS = ql.RelinkableYieldTermStructureHandle()
inflationYTS = ql.RelinkableZeroInflationTermStructureHandle()
discountYTS.linkTo(ois)
inflationYTS.linkTo(inflationCurve)
# sample historical rates of EUHICP
#rpi = pd.read_csv('historical_rates.csv')
data_3 = [[1982-1-1, 7889.25], 
    [1982-1-4, 7894.3]]
rpi = pd.DataFrame(data_3, columns = ['index', 'PX_LAST'])
rpi = rpi.set_index('index')

 inflationIndex = ql.EUHICP(True, inflationYTS)
rpi.index = pd.to_datetime(rpi.index)
for idx, row in rpi.iterrows():
    fixing_date = ql.Date().from_date(idx)
    inflationIndex.addFixing(fixing_date, row.PX_LAST, True)

swap computation

notional = 1e6
startDate = ql.Date(26, 1, 2006)
endDate = ql.Date(26, 1, 2055)
fixedRate = 0.032
swapType = ql.ZeroCouponInflationSwap.Payer
 swap = ql.ZeroCouponInflationSwap(
        swapType,
      notional,
     startDate,
     endDate,
      cal,
     ql.ModifiedFollowing,
      dc,
      fixedRate,
     inflationIndex,
      observationLag,
    )
  swapEngine = ql.DiscountingSwapEngine(discountYTS)
  swap.setPricingEngine(swapEngine)


npv = swap.NPV()
$\endgroup$
10
  • $\begingroup$ Hi. Can anyone reply on my post. That will really help. Thank you. $\endgroup$
    – robin
    Dec 9, 2021 at 15:52
  • $\begingroup$ Hi. Still waiting for anyone to reply. Thank you. $\endgroup$
    – robin
    Dec 14, 2021 at 16:40
  • $\begingroup$ Hi. I just tried to run your code and I got an error. Can you please provide a minimal working example? That would make it much easier to help you $\endgroup$
    – mmencke
    Dec 15, 2021 at 22:42
  • $\begingroup$ @mmencke thanks for your reply. As requested I have edited my post. If you find errors in rates or fixings, please add some hypothetical rates. The format of the rate data frame is defined in the code. Please text me if you need more information. $\endgroup$
    – robin
    Dec 16, 2021 at 0:49
  • $\begingroup$ Hi again. I have tried to run the adjusted code using a csv with EUHICP fixings and I still get an error: "2nd leg: all instruments expired". I'll have a look at it later today to figure out where the error comes from $\endgroup$
    – mmencke
    Dec 16, 2021 at 7:44

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.