aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics')
-rw-r--r--python/analytics/option.py59
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)