diff options
Diffstat (limited to 'python/tests')
| -rw-r--r-- | python/tests/test_cms_spread.py | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/python/tests/test_cms_spread.py b/python/tests/test_cms_spread.py index 3a88badb..b45acce6 100644 --- a/python/tests/test_cms_spread.py +++ b/python/tests/test_cms_spread.py @@ -5,7 +5,7 @@ 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) + get_params, h1, h_call, h_put) from quantlib.quotes import SimpleQuote from quantlib.time.api import (Actual365Fixed, Days, Date, ModifiedFollowing, Period, Years) @@ -16,8 +16,10 @@ from quantlib.experimental.coupons.cms_spread_coupon import ( CappedFlooredCmsSpreadCoupon) from quantlib.experimental.coupons.lognormal_cmsspread_pricer import ( LognormalCmsSpreadPricer) +from scipy import LowLevelCallable from scipy.special import roots_hermitenorm - +from scipy.integrate import quad +import ctypes class TestCmsSpread(unittest.TestCase): @@ -55,8 +57,6 @@ class TestCmsSpread(unittest.TestCase): 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 @@ -64,19 +64,22 @@ class TestCmsSpread(unittest.TestCase): 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, μ) - self.cms2y.set_pricer(cms_pricer) - self.cms30y.set_pricer(cms_pricer) - params = get_params(self.cms2y, self.cms30y, atm_vol) + self.ρ = SimpleQuote(0.8) + self.cms_pricer = AnalyticHaganPricer(atm_vol, YieldCurveModel.Standard, μ) + self.cms2y.set_pricer(self.cms_pricer) + self.cms30y.set_pricer(self.cms_pricer) + self.params = get_params(self.cms2y, self.cms30y, atm_vol) + + def test_black_model(self): + x, w = roots_hermitenorm(16) val_call = 1 / math.sqrt(2 * math.pi) * np.dot(w, - h_call(x, self.cap, *params, ρ.value)) + h_call(x, self.cap, *self.params, self.ρ.value)) val_put = 1 / math.sqrt(2 * math.pi) * np.dot(w, - h_put(x, self.cap, *params, ρ.value)) + h_put(x, self.cap, *self.params, self.ρ.value)) cms_spread_pricer = LognormalCmsSpreadPricer( - cms_pricer, - ρ, + self.cms_pricer, + self.ρ, integration_points=20) self.cms30y2y_cap.set_pricer(cms_spread_pricer) self.assertAlmostEqual(self.cms30y2y_cap.rate, @@ -85,5 +88,24 @@ class TestCmsSpread(unittest.TestCase): self.assertAlmostEqual(self.cms30y.rate - self.cms2y.rate - self.cap, self.cms30y2y_cap.underlying.rate) + def test_h1_hcall(self): + args = (self.cap, *self.params, self.ρ.value) + h1_fun = LowLevelCallable(h1.ctypes).function + + for x in np.linspace(-5, 5, 11): + full_args = np.array((x, *args)) + a = h1_fun(9, full_args.ctypes.data_as(ctypes.POINTER(ctypes.c_double))) + b = h_call(x, *args) * math.exp(-0.5 * x * x) + self.assertAlmostEqual(a, b) + + def test_scipy_integrate(self): + x, w = roots_hermitenorm(20) + val_call = np.dot(w, h_call(x, self.cap, *self.params, self.ρ.value)) + integrand = LowLevelCallable(h1.ctypes) + args = (self.cap, *self.params, self.ρ.value) + val, _ = quad(integrand, -np.inf, np.inf, args=(self.cap, *self.params, self.ρ.value)) + self.assertAlmostEqual(val, val_call) + + if __name__ == "__main__": unittest.main() |
