diff options
Diffstat (limited to 'python/analytics/option.py')
| -rw-r--r-- | python/analytics/option.py | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py index 32f4f947..fe60d2d5 100644 --- a/python/analytics/option.py +++ b/python/analytics/option.py @@ -1,10 +1,57 @@ +import array +import datetime +import math +import numpy as np +import pandas as pd + from .black import black from .utils import GHquad from yieldcurve import roll_yc from pandas.tseries.offsets import BDay +from pyisda.curve import SpreadCurve +from pyisda.flat_hazard import strike_vec +from scipy.optimize import brentq +from scipy.integrate import simps + +def g(index, spread : float, exercise_date : datetime.date, use_rolled_curve = True): + """ computes the strike clean price using the expected forward yield curve """ + if use_rolled_curve: + rolled_curve = roll_yc(index._yc, exercise_date) + else: + rolled_curve = index._yc + step_in_date = exercise_date + datetime.timedelta(days=1) + exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date() + sc = SpreadCurve(exercise_date, rolled_curve, index.start_date, + step_in_date, exercise_date_settle, + [index.end_date], array.array('d', [spread * 1e-4]), + index.recovery) + a = index._fee_leg.pv(exercise_date, step_in_date, exercise_date_settle, + rolled_curve, sc, True) + return (spread - index.fixed_rate) * a *1e-4 + +def calib(S0, fp, exercise_date : datetime.date, exercise_date_settle :datetime.date, + index, rolled_curve, tilt, w): + S = S0 * tilt * 1e-4 + a, b = strike_vec(S, rolled_curve, exercise_date, exercise_date_settle, + index.start_date, index.end_date, index.recovery) + vec = a - index.fixed_rate * b * 1e-4 + return np.inner(vec, w) - fp + +def ATMstrike(index, exercise_date : datetime.date): + exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date() + fp = index.forward_pv(exercise_date) + closure = lambda S: g(index, S, exercise_date) - fp + eta = 1.1 + a = index.spread + b = index.spread * eta + while True: + if closure(b) > 0: + break + b *= eta + return brentq(closure, a, b) -class Option: - def __init__(self, index, exercise_date, strike, option_type="payer"): +class Swaption: + def __init__(self, index, exercise_date : datetime.date, strike : float, option_type="payer"): self.index = index self._exercise_date = exercise_date self._forward_yc = roll_yc(self.index._yc, self.exercise_date) @@ -97,7 +144,7 @@ class Option: if self._T: return self._T else: - return year_frac(self.index.trade_date, self.exercise_date) + 1/365 + return ((self.exercise_date - self.index.trade_date).days + 1)/365 @property def gamma(self): |
