import unittest import datetime from serenitas.analytics.index import g from serenitas.analytics 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) if __name__ == "__main__": unittest.main()