diff options
Diffstat (limited to 'python/analytics/cms_spread.py')
| -rw-r--r-- | python/analytics/cms_spread.py | 46 |
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) |
