aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics/cms_spread.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics/cms_spread.py')
-rw-r--r--python/analytics/cms_spread.py58
1 files changed, 38 insertions, 20 deletions
diff --git a/python/analytics/cms_spread.py b/python/analytics/cms_spread.py
index ff222268..49a59c71 100644
--- a/python/analytics/cms_spread.py
+++ b/python/analytics/cms_spread.py
@@ -7,9 +7,14 @@ from math import exp, sqrt, log
from .black import bachelier
from bbg_helpers import BBG_IP, retrieve_data, init_bbg_session
from quantlib.time.api import (
- Date, Period, Days, Years, UnitedStates, Actual365Fixed, today)
-from quantlib.time.calendars.united_states import GOVERNMENTBOND
+ Date, Period, Days, Months, Years, UnitedStates, Actual365Fixed, today,
+ Following)
+from quantlib.time.calendars.united_states import GovernmentBond
from quantlib.indexes.swap.usd_libor_swap import UsdLiborSwapIsdaFixAm
+from quantlib.experimental.coupons.swap_spread_index import SwapSpreadIndex
+from quantlib.termstructures.volatility.api import (
+ VolatilityType, SwaptionVolatilityMatrix)
+from quantlib.math.matrix import Matrix
from scipy.interpolate import RectBivariateSpline
from yieldcurve import YC
from db import dbconn
@@ -58,36 +63,49 @@ def get_forward_spread(tenor1, tenor2, maturity):
yc.extrapolation = True
conn = dbconn('serenitasdb')
fixing_date, fixing1, fixing2 = get_fixings(conn, tenor1, tenor2)
- USISDA1 = UsdLiborSwapIsdaFixAm(Period(tenor1, Years),
- forwarding=yc, discounting=yc)
+ USISDA1 = UsdLiborSwapIsdaFixAm(Period(tenor1, Years), yc, yc)
USISDA1.add_fixing(fixing_date, fixing1)
- USISDA2 = UsdLiborSwapIsdaFixAm(Period(tenor2, Years),
- forwarding=yc, discounting=yc)
+ USISDA2 = UsdLiborSwapIsdaFixAm(Period(tenor2, Years), yc, yc)
USISDA2.add_fixing(fixing_date, fixing2)
- expiration = UnitedStates(GOVERNMENTBOND).advance(
+ spread_index = SwapSpreadIndex(f"{tenor1}-{tenor2}", USISDA1, USISDA2)
+ expiration = UnitedStates(GovernmentBond).advance(
Date.from_datetime(maturity),
0, Days)
+ return spread_index.fixing(expiration)
- USFS1 = USISDA1.underlying_swap(expiration)
- USFS2 = USISDA2.underlying_swap(expiration)
- return USFS2.fair_rate - USFS1.fair_rate
-
-def get_swaption_vol_surface(source="ICPL", vol_type="N"):
- if vol_type == "N":
+def get_swaption_vol_data(source="ICPL", vol_type=VolatilityType.ShiftedLognormal):
+ if vol_type == VolatilityType.Normal:
table_name = "swaption_normal_vol"
else:
table_name = "swaption_lognormal_vol"
- sql_str = "SELECT * FROM {table_name} WHERE source = %s ORDER BY date DESC LIMIT 1"
+ sql_str = f"SELECT * FROM {table_name} WHERE source = %s ORDER BY date DESC LIMIT 1"
conn = dbconn('serenitasdb')
with conn.cursor() as c:
c.execute(sql_str, (source,))
surf_data = next(c)
- date, surf = surf_data[0], np.array(surf_data[1:-1])
- if source == "ICPL":
- tenors = [1/12, 0.25, 0.5] + list(range(1, 11)) + [15., 20., 25., 30.]
- else:
- tenors = [1/12, 0.25, 0.5, 0.75] + list(range(1, 11)) + [15., 20., 25., 30.]
- return RectBivariateSpline(tenors, tenors[-14:], surf.T)
+ return surf_data[0], np.array(surf_data[1:-1], order='F').T, vol_type
+
+def get_swaption_vol_surface(date, data, vol_type):
+ tenors = [1/12, 0.25, 0.5, 0.75] + list(range(1, 11)) + [15., 20., 25., 30.]
+ return RectBivariateSpline(tenors, tenors[-14:], data.T)
+
+def get_swaption_vol_matrix(date, data, vol_type):
+ # figure out what to do with nan
+ calendar = UnitedStates()
+ m = Matrix.from_ndarray(data)
+ option_tenors = [Period(i, Months) for i in [1, 3, 6, 9]] + \
+ [Period(i, Years) for i in range(1, 11)] + \
+ [Period(i, Years) for i in [15, 20, 25, 30]]
+ swap_tenors = option_tenors[-14:]
+ return (SwaptionVolatilityMatrix.
+ from_reference_date(Date.from_datetime(date),
+ calendar,
+ Following,
+ option_tenors,
+ swap_tenors,
+ m,
+ Actual365Fixed(),
+ vol_type=vol_type))
def plot_surf(surf, tenors):
xx, yy = np.meshgrid(tenors, tenors[-14:])