aboutsummaryrefslogtreecommitdiffstats
path: root/python/tests/test_cms_spread.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/tests/test_cms_spread.py')
-rw-r--r--python/tests/test_cms_spread.py48
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()