diff options
| -rw-r--r-- | python/analytics/option.py | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py index b6a4cf35..89b6e244 100644 --- a/python/analytics/option.py +++ b/python/analytics/option.py @@ -38,16 +38,16 @@ def ATMstrike(index, exercise_date : datetime.date): class Swaption(ForwardIndex): """Swaption class""" def __init__(self, index, exercise_date : datetime.date, strike : float, - option_type="payer"): - ForwardIndex.__init__(self, index, exercise_date) + option_type="payer", strike_is_price = False): + ForwardIndex.__init__(self, index, exercise_date, strike_is_price) self._exercise_date = exercise_date self._forward_yc = roll_yc(index._yc, exercise_date) self._T = None - self._strike = strike + self._strike_is_price = strike_is_price + self.strike = strike self.option_type = option_type.lower() self._Z, self._w = GHquad(50) self.notional = 1 - self._G = g(index, strike, exercise_date, self._forward_yc) @property def exercise_date(self): @@ -62,12 +62,30 @@ class Swaption(ForwardIndex): @property def strike(self): - return self._strike + if self._strike_is_price: + return 100 * (1 - self._G) + else: + return self._strike @strike.setter def strike(self, K : float): - self._strike = K - self._G = g(self.index, K, self.exercise_date, self._forward_yc) + if self._strike_is_price: + self._G = (100 - K) / 100 + # we compute the corresponding spread to the strike price + def handle(S, index, forward_date, forward_yc): + return g(index, S, forward_date, forward_yc) - self._G + eta = 1.2 + a = 250 + b = eta * a + while True: + if handle(b, self.index, self.exercise_date, self._forward_yc) > 0: + break + b *= eta + self._strike = brentq(handle, a, b, + args = (self.index, self.exercise_date, self._forward_yc)) + else: + self._G = g(self.index, K, self.exercise_date, self._forward_yc) + self._strike = K @property def intrinsic_value(self): @@ -89,11 +107,10 @@ class Swaption(ForwardIndex): b *= eta S0 = brentq(calib, a, b, args) - if T == 0: return self.notional * self.intrinsic - - Zstar = (math.log(self.strike/S0) + self.sigma**2/2 * T) / \ + ## Zstar solves S_0 exp(-\sigma^2/2 * T + sigma * Z^\star\sqrt{T}) = strike + Zstar = (math.log(self._strike/S0) + self.sigma**2/2 * T) / \ (self.sigma * math.sqrt(T)) if self.option_type == "payer": @@ -206,14 +223,16 @@ class Swaption(ForwardIndex): @property def breakeven(self): pv = self.pv / self.notional - G = g(self.index, self.strike, self.exercise_date) - aux = lambda S: g(self.index, S, self.exercise_date) - G - pv - eta = 1.1 - a = self.strike - b = a * eta - while True: - if aux(b) > 0: - break - b *= eta + if self._strike_is_price: + return self._G + pv + else: + aux = lambda S: g(self.index, S, self.exercise_date) - self._G - pv + eta = 1.1 + a = self._strike + b = a * eta + while True: + if aux(b) > 0: + break + b *= eta - return brentq(aux, a, b) + return brentq(aux, a, b) |
