diff options
Diffstat (limited to 'python/tests')
| -rw-r--r-- | python/tests/test_cms_spread.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/python/tests/test_cms_spread.py b/python/tests/test_cms_spread.py new file mode 100644 index 00000000..457d8fbd --- /dev/null +++ b/python/tests/test_cms_spread.py @@ -0,0 +1,87 @@ +import datetime +import math +import numpy as np +import unittest +from analytics.cms_spread import ( + build_spread_index, VolatilityType, + get_swaption_vol_data, get_swaption_vol_matrix, get_cms_coupons, + get_params, h_call, h_put) +from quantlib.quotes import SimpleQuote +from quantlib.time.api import (Actual365Fixed, Days, Date, ModifiedFollowing, + Period, Years) +from yieldcurve import YC +from quantlib.cashflows.conundrum_pricer import ( + AnalyticHaganPricer, YieldCurveModel) +from quantlib.experimental.coupons.cms_spread_coupon import ( + CappedFlooredCmsSpreadCoupon) +from quantlib.experimental.coupons.lognormal_cmsspread_pricer import ( + LognormalCmsSpreadPricer) +from scipy.special import roots_hermitenorm + + +class TestCmsSpread(unittest.TestCase): + + def setUp(self): + self.trade_date = datetime.date(2018, 1, 19) + option_tenor = Period(2, Years) + maturity = Date.from_datetime(self.trade_date) + Period(2, Years) + spread_index, self.yc = build_spread_index(30, 2) + fixing_date = (spread_index. + fixing_calendar. + adjust(maturity, ModifiedFollowing)) + payment_date = (spread_index. + fixing_calendar. + advance(fixing_date, 2, Days)) + accrued_end_date = payment_date + accrued_start_date = accrued_end_date - Period(1, Years) + + self.cap = 0.0075835 + + self.notional = 100_000_000 + self.cms30y2y_cap = CappedFlooredCmsSpreadCoupon( + payment_date, + self.notional, + start_date=accrued_start_date, + end_date=accrued_end_date, + fixing_days=spread_index.fixing_days, + index=spread_index, + gearing=1., + spread=-self.cap, + floor=0., + day_counter=Actual365Fixed(), + is_in_arrears=True) + + self.cms2y, self.cms30y = get_cms_coupons(self.trade_date, + self.notional, + option_tenor, + spread_index) + + def test_black_model(self): + evaluation_date = datetime.date(2018, 8, 23) + self.yc.link_to(YC(evaluation_date=evaluation_date)) + self.yc.extrapolation = True + date, surf = get_swaption_vol_data(date=evaluation_date, + vol_type=VolatilityType.ShiftedLognormal) + atm_vol = get_swaption_vol_matrix(evaluation_date, surf) + μ = SimpleQuote(0.1) + ρ = SimpleQuote(0.8) + cms_pricer = AnalyticHaganPricer(atm_vol, YieldCurveModel.Standard, μ) + params = get_params(self.cms2y, self.cms30y, cms_pricer, atm_vol) + x, w = roots_hermitenorm(16) + val_call = 1 / math.sqrt(2 * math.pi) * np.dot(w, + h_call(x, self.cap, *params, ρ.value)) + val_put = 1 / math.sqrt(2 * math.pi) * np.dot(w, + h_put(x, self.cap, *params, ρ.value)) + cms_spread_pricer = LognormalCmsSpreadPricer( + cms_pricer, + ρ, + integration_points=20) + self.cms30y2y_cap.set_pricer(cms_spread_pricer) + self.assertAlmostEqual(self.cms30y2y_cap.rate, + val_call) + self.assertAlmostEqual(-self.cms30y2y_cap.underlying.rate, val_put - val_call) + self.assertAlmostEqual(self.cms30y.rate - self.cms2y.rate - self.cap, + self.cms30y2y_cap.underlying.rate) + +if __name__ == "__main__": + unittest.main() |
