aboutsummaryrefslogtreecommitdiffstats
path: root/python/tests/test_swaption.py
blob: b51e048b1709b48307db928132dd568d5ee09b4f (plain)
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
import unittest
import datetime

from serenitas.analytics.index import g
from serenitas.analytics.api import CreditIndex, Swaption, BlackSwaption


class TestPutCallParity(unittest.TestCase):
    index = CreditIndex("ig", 27, "5yr", value_date=datetime.date(2016, 10, 25))
    index.spread = 74
    exercise_date = datetime.date(2017, 3, 15)
    strike = 82.5

    def test_parity(self):
        payer = Swaption(self.index, self.exercise_date, self.strike)
        receiver = Swaption(self.index, self.exercise_date, self.strike, "receiver")
        payer.sigma = 0.416
        receiver.sigma = 0.416
        df = self.index._yc.discount_factor(payer.exercise_date_settle)
        self.assertAlmostEqual(
            payer.pv - receiver.pv,
            df * (payer.forward_pv - g(self.index, self.strike, self.exercise_date)),
        )

    def test_parity_black(self):
        payer = BlackSwaption(self.index, self.exercise_date, self.strike)
        receiver = BlackSwaption(
            self.index, self.exercise_date, self.strike, "receiver"
        )
        payer.sigma = 0.416
        receiver.sigma = 0.416
        df = self.index._yc.discount_factor(payer.exercise_date_settle)
        self.assertAlmostEqual(
            payer.pv - receiver.pv,
            df * (payer.forward_pv - g(self.index, self.strike, self.exercise_date)),
        )

    def test_calibration(self):
        payer = Swaption(self.index, self.exercise_date, self.strike)
        payer.sigma = 0.2
        pv = 30 * 1e-4
        payer.pv = pv
        self.assertAlmostEqual(payer.pv, pv)
        self.assertAlmostEqual(payer.sigma, 0.37648716)

    def test_hy(self):
        index = CreditIndex("hy", 27, "5yr", value_date=datetime.date(2016, 11, 8))
        index.price = 103.875
        exercise_date = datetime.date(2017, 3, 15)
        strike = 102.5
        payer = Swaption(index, exercise_date, strike)
        payer.pv = 1.948 * 1e-2
        self.assertAlmostEqual(payer.sigma, 0.4156000826)


class TestBreakeven(unittest.TestCase):

    exercise_date = datetime.date(2017, 3, 15)
    hyindex = CreditIndex("hy", 27, "5yr", value_date=datetime.date(2016, 11, 16))
    hyindex.price = 103.75
    hystrike = 102.5

    igindex = CreditIndex("ig", 27, "5yr", value_date=datetime.date(2016, 11, 18))
    igindex.spread = 76.5
    igstrike = 80

    def test_hypayer(self):
        payer = Swaption(self.hyindex, self.exercise_date, self.hystrike)
        payer.sigma = 0.4
        payer.notional = 100_000_000
        self.assertAlmostEqual(payer.breakeven, 100.67426187413359)

    def test_hyreceiver(self):
        receiver = Swaption(self.hyindex, self.exercise_date, self.hystrike, "receiver")
        receiver.sigma = 0.4
        receiver.notional = 100_000_000
        self.assertAlmostEqual(receiver.breakeven, 103.95644740397454)

    def test_igpayer(self):
        payer = Swaption(self.igindex, self.exercise_date, self.igstrike)
        payer.sigma = 0.4
        payer.notional = 1e7
        self.assertAlmostEqual(payer.breakeven, 88.366980851176223)

    def test_igreceiver(self):
        receiver = Swaption(self.igindex, self.exercise_date, self.igstrike, "receiver")
        receiver.sigma = 0.4
        receiver.notional = 1e7
        self.assertAlmostEqual(receiver.breakeven, 73.71594264020226)


class TestMoveForward(unittest.TestCase):
    trade = BlackSwaption.from_tradeid(7)

    def test_move_value_date(self):
        trade = BlackSwaption.from_tradeid(7)
        trade.value_date = datetime.date(2017, 6, 5)
        trade.mark()
        ig23 = CreditIndex("IG", 28, "5yr", value_date=datetime.date(2017, 6, 5))
        trade2 = BlackSwaption(ig23, datetime.date(2017, 6, 21), 65.0)
        trade2.notional = 150_000_000
        trade2.mark()
        self.assertAlmostEqual(trade.pv, trade2.pv)


class TestDifferentVersion(unittest.TestCase):
    trade = BlackSwaption.from_tradeid(342)

    def test_build_from_scratch(self):
        self.trade.value_date = datetime.date(2022, 10, 12)
        index = CreditIndex(
            redcode="2I65BRZG8",
            maturity=datetime.date(2027, 6, 20),
            notional=25_000_000,
            value_date=datetime.date(2022, 10, 12),
        )
        new_trade = BlackSwaption(
            index, datetime.date(2022, 11, 16), 94.0, "payer", "Short"
        )
        new_trade.notional = 25_000_000
        self.assertAlmostEqual(self.trade._G, new_trade._G)
        self.assertAlmostEqual(self.trade._strike, new_trade._strike)
        self.trade.mark()
        new_trade.mark()
        self.assertAlmostEqual(self.trade.pv, new_trade.pv)


if __name__ == "__main__":
    unittest.main()