Home Interest Rate Swap (IRS)
Post
Cancel

Interest Rate Swap (IRS)

This post is about interest rate swap. Though IRS is not familiar, IRS can offer interest rate risk mitigation or chance to seize from interest rate fluctuation.

What is Interest Rate Swap

Interest rate swap is method to mitigate interest rate risk. If you buy IRS, you can pay fixed swap rate until maturity, while you receive floating rate(such as LIBOR) to counterparty.

Since, size of this contract is huge, it is mainly field of institutional players. I strongly recommend you to study this material for your future goal, becomming rich enough to trade IRS with your own capital. IRS combined with FX market makes huge impacts. Big IRS contracts sometimes impacts FX market. Suppose you are foreign bond investors (at dollar perspective), you might want to secure fixed income at your currency, then you might go to Forward market. So interest rate (bond) and fixed income is inevitable.

Buyer of interest rate swap(IRS)

Suppose you are investor of floating bond investors, you might worry about fluctuating interest rate. To mitigate this, you buy IRS. So, you receive floating interest rate and pay fixed rate(swap rate). IRS

Seller of interest rate swap(IRS)

On contrary, If you think that interest rate will fall soon, you will sell IRS to counterparty. If rate falls as you expected, floating interest payment you need to pay to buyer will decrease.

How to understand IRS?

Of course, IRS might seems complicated to some of you. If you decompose IRS vertically, you can easily understand that IRS is simply sum of selling fixed interest rate bond and buying floating rate bond. So, you pay fixed and receive floating. This mitigates risk of interest rate rise. See picutre below.
IRS

In addition, IRS can be expressed in horizontally. Cashflow of IRS is sum of combined forward rate aggrements. If we sum value of forward rate aggrement with different maturity, you can calculate value of IRS. See picture below. IRS

Summary

See below picture, if you are facing trouble in memorizing the IRS structure. IRS

Prequisite

1
from quant_lib.swap_curve import get_quote, swap_curve

If you don’t want to make your own swap curve library, go to this link and download and place it appripriate directory. Swap_Curve_Code Swap_Curve_Notebook

for example, let’s price IRS for buyers

1
2
3
4
5
6
7
8
9
10
11
issueDate = 10/9/2022
pricingDate = 1/9/2021
maturityDate = 4/9/2021
tenor = quarterly
swap rate = 2.18%
face value = 1000000
settlement days = first date of month

price of IRS = 16.134813731714075
delta of IRS = 25.262571390637277
theta of IRS = -2.3642255974538102

Let’s code this idea

Full code can be found at below link. CODE

Full Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
import datetime
import numpy as np
import pandas as pd

import QuantLib as ql
from quant_lib.swap_curve import get_quote, swap_curve

class IRS():
    def __init__(self, today, pricing_date, maturity_date, irs_rate, notional, position, spread=0.0):
        
        # initial setup
        self.date = today
        self.curve = self.CURVE(self.date)

        self.pricing_date = ql.Date(pricing_date.day, pricing_date.month, pricing_date.year)
        self.maturity_date = ql.Date(maturity_date.day, maturity_date.month, maturity_date.year)

        self.calendar = ql.UnitedStates()
        self.convention = ql.ModifiedPreceding
        self.day_counter = ql.Actual360()

        self.fixed_tenor = ql.Period(1, ql.Years)
        self.float_tenor = ql.Period(3, ql.Months)

        self.irs_rate = irs_rate
        self.notional = notional
        if position == 'long':
            self.position = ql.VanillaSwap.Payer
        else:
            self.position = ql.VanillaSwap.Receiver

        self.spread = spread

        # pricing result
        self.npv = self.PRICING(self.curve)
        self.delta = self.DELTA()
        self.theta = self.THETA()
    
    def CURVE(self, date):
        return swap_curve(date, get_quote(date))
    

    def PRICING(self, curve):

        #yield term structure
        curve_handle = ql.YieldTermStructureHandle(curve)

        # USD 3M Libor
        float_index = ql.USDLibor(ql.Period(3, ql.Months), curve_handle)

        # Fixed Schedule
        fixedSchedule= ql.Schedule(self.pricing_date, # effectiveDate
                                    self.maturity_date, # terminationDate
                                    self.fixed_tenor, # tenor
                                    self.calendar, # calendar
                                    self.convention, # convention
                                    self.convention, # terminationDateConvention
                                    ql.DateGeneration.Backward, # rule
                                    False  # endOfMonth
                    )

        # Fixed Schedule
        floatingSchedule= ql.Schedule(self.pricing_date, # effectiveDate
                                    self.maturity_date, # terminationDate
                                    self.float_tenor, # tenor
                                    self.calendar, # calendar
                                    self.convention, # convention
                                    self.convention, # terminationDateConvention
                                    ql.DateGeneration.Backward, # rule
                                    False # endOfMonth
                    )


        # Interest Rate Swap
        irs = ql.VanillaSwap(self.position,
                            self.notional,
                            fixedSchedule,
                            self.irs_rate,
                            self.day_counter,
                            floatingSchedule,
                            float_index,
                            self.spread,
                            self.day_counter
                )

        # pricing engine
        swapEngine = ql.DiscountingSwapEngine(curve_handle)
        irs.setPricingEngine(swapEngine)

        # IRS pricing
        npv = irs.NPV()
        
        return npv

    
    def DELTA(self):
       # delta is change in values if 1bp of interest rate curve changes
       # in here we use KRD (Key Rate Delta) not DV01
       # KRD means how each tenor changes
        curve_handle = ql.YieldTermStructureHandle(self.curve)

        basis_point = 0.0001

        # irs price when 1bp up
        up_curve = ql.ZeroSpreadedTermStructure(
                                                curve_handle,
                                                ql.QuoteHandle(ql.SimpleQuote(basis_point))
                                                )
        up_irs = self.PRICING(up_curve)

        down_curve = ql.ZeroSpreadedTermStructure(
                                                curve_handle,
                                                ql.QuoteHandle(ql.SimpleQuote(-basis_point))
                                                )
        down_irs = self.PRICING(down_curve)

        #DV01 
        delta = (up_irs - down_irs)/2
        
        return delta

    def THETA(self):
        # theta is change in value if one unit time passes.
        # in here, unit time is 1 day
        # since derivative product have time value, time to maturity is major variable in pricing derivatives
        price_t0 = self.PRICING(self.CURVE(self.date))
        price_t1 = self.PRICING(self.CURVE(self.date + datetime.timedelta(days=1)))

        return price_t1 - price_t0

## set information
todays_date = datetime.date(2020, 10, 9)
pricing_date = datetime.date(2021, 1, 9)
maturity_date = datetime.date(2021, 4, 9)

position = 'long'
irs_rate = 0.00218
notional = 1000000

irs = IRS(
    today=todays_date,
    pricing_date=pricing_date,
    maturity_date=maturity_date,
    irs_rate=irs_rate,
    notional=notional,
    position=position,
    spread=0.0
    )

print("price of IRS = {}".format(irs.npv))
print("delta of IRS = {}".format(irs.delta))
print("theta of IRS = {}".format(irs.theta))
This post is licensed under CC BY 4.0 by the author.