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.py46
1 files changed, 45 insertions, 1 deletions
diff --git a/python/analytics/cms_spread.py b/python/analytics/cms_spread.py
index 402d0413..c39bff6d 100644
--- a/python/analytics/cms_spread.py
+++ b/python/analytics/cms_spread.py
@@ -5,7 +5,9 @@ from .black import bachelier, cnd_erf
from numba import (cfunc, types, jit, float64, boolean,
optional, vectorize)
from quantlib.time.api import (
- Date, Period, Days, Months, Years, UnitedStates, Actual365Fixed, Following)
+ Date, Period, Days, Months, Years, UnitedStates, Actual365Fixed, Following,
+ ModifiedFollowing)
+from quantlib.cashflows.cms_coupon import CmsCoupon
from quantlib.termstructures.yields.api import YieldTermStructure
from quantlib.indexes.swap.usd_libor_swap import UsdLiborSwapIsdaFixAm
from quantlib.experimental.coupons.swap_spread_index import SwapSpreadIndex
@@ -203,3 +205,45 @@ def globeop_model(date, spread_index, yc, strike, rho, maturity,
# normal vol is not scale independent and is computed in percent terms, so we scale
# everything by 100.
return 0.01 * yc.discount(T) * bachelier(forward * 100, strike * 100, T, vol_spread)
+
+def get_cms_coupons(trade_date, notional, option_tenor, spread_index,
+ fixing_days=2):
+ maturity = Date.from_datetime(trade_date) + option_tenor
+ fixing_date = spread_index.fixing_calendar.adjust(maturity, ModifiedFollowing)
+ payment_date = spread_index.fixing_calendar.advance(fixing_date, fixing_days, Days)
+ accrued_end_date = payment_date
+ accrued_start_date = accrued_end_date - Period(1, Years)
+ cms_beta = CmsCoupon(payment_date,
+ notional,
+ start_date=accrued_start_date,
+ end_date=accrued_end_date,
+ fixing_days=fixing_days,
+ index=spread_index.swap_index2,
+ is_in_arrears=True)
+
+ cms_gamma = CmsCoupon(payment_date,
+ notional,
+ start_date=accrued_start_date,
+ end_date=accrued_end_date,
+ fixing_days=fixing_days,
+ index=spread_index.swap_index1,
+ is_in_arrears=True)
+ return cms_beta, cms_gamma
+
+def get_params(cms_beta, cms_gamma, cms_pricer, atm_vol):
+ cms_beta.set_pricer(cms_pricer)
+ cms_gamma.set_pricer(cms_pricer)
+ s_gamma = cms_gamma.index_fixing
+ s_beta = cms_beta.index_fixing
+ adjusted_gamma = cms_gamma.rate
+ adjusted_beta = cms_beta.rate
+ T_alpha = atm_vol.time_from_reference(cms_beta.fixing_date)
+ mu_beta = 1 / T_alpha * log(adjusted_beta / s_beta)
+ mu_gamma = 1 / T_alpha * log(adjusted_gamma / s_gamma)
+ vol_gamma = atm_vol.volatility(cms_gamma.fixing_date, cms_gamma.swap_index.tenor, s_gamma)
+ vol_beta = atm_vol.volatility(cms_beta.fixing_date, cms_beta.swap_index.tenor, s_beta)
+ mu_x = (mu_gamma - 0.5 * vol_gamma ** 2) * T_alpha
+ mu_y = (mu_beta - 0.5 * vol_beta ** 2) * T_alpha
+ sigma_x = vol_gamma * sqrt(T_alpha)
+ sigma_y = vol_beta * sqrt(T_alpha)
+ return (s_gamma, s_beta , mu_x, mu_y, sigma_x, sigma_y)