aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/swaption.py62
1 files changed, 33 insertions, 29 deletions
diff --git a/python/swaption.py b/python/swaption.py
index 0323eb5f..20cd2d03 100644
--- a/python/swaption.py
+++ b/python/swaption.py
@@ -24,7 +24,8 @@ serenitasdb = dbconn('serenitasdb')
class Index():
""" minimal class to represent a credit index """
- def __init__(self, start_date, end_date, recovery, fixed_rate):
+ def __init__(self, start_date, end_date, recovery, fixed_rate,
+ notional = 10e6):
"""
start_date : :class:`datetime.date`
index start_date (Could be issue date, or last imm date)
@@ -36,7 +37,7 @@ class Index():
fixed coupon (in bps)
"""
self.fixed_rate = fixed_rate
- self.notional = 1
+ self.notional = notional
self._start_date = start_date
self._end_date = end_date
self.recovery = recovery
@@ -86,13 +87,12 @@ class Index():
"""This is default adjusted forward price at time exercise_date"""
step_in_date = exercise_date + datetime.timedelta(days=1)
value_date = (pd.Timestamp(exercise_date) + 3* BDay()).date()
-
- a = self._fee_leg.pv(self.trade_date, step_in_date, value_date,
+ a = self._fee_leg.pv(self.trade_date, step_in_date, self._value_date,
self._yc, self._sc, False)
Delta = self._fee_leg.accrued(step_in_date)
df = self._yc.discount_factor(value_date)
if exercise_date > self.trade_date:
- q = math.exp(-self.flat_hazard * (year_frac(self.trade_date, exercise_date)-0.5/365))
+ q = math.exp(-self.flat_hazard * (year_frac(self.trade_date, exercise_date)))
else:
q = 1
clean_forward_annuity = a - Delta * df * q
@@ -107,12 +107,6 @@ class Index():
def spread(self):
return self._spread * 1e4
- @spread.setter
- def spread(self, s: float):
- """ s: spread in bps """
- self._spread = s * 1e-4
- self._update()
-
def _update(self):
self._sc = SpreadCurve(self.trade_date, self._yc, self.start_date,
self._step_in_date, self._value_date,
@@ -124,6 +118,15 @@ class Index():
self._dl_pv = self._default_leg.pv(
self.trade_date, self._step_in_date, self._value_date,
self._yc, self._sc, self.recovery)
+ self._pv = self._dl_pv - self._risky_annuity * self.fixed_rate * 1e-4
+ self._clean_pv = self._pv - self._accrued * self.fixed_rate * 1e-4
+ self._price = 100 * (1 - self._clean_pv)
+
+ @spread.setter
+ def spread(self, s: float):
+ """ s: spread in bps """
+ self._spread = s * 1e-4
+ self._update()
@property
def flat_hazard(self):
@@ -133,7 +136,7 @@ class Index():
@property
def pv(self):
- return self.notional * (self._dl_pv - self._risky_annuity * self.fixed_rate * 1e-4)
+ return self.notional * self._pv
@property
def accrued(self):
@@ -145,16 +148,20 @@ class Index():
@property
def clean_pv(self):
- return self.pv - self.accrued
+ return self._clean_pv
@property
def price(self):
- return 100*(1-self.clean_pv/self.notional)
+ return self._price
+
+ @price.setter
+ def price(self, val):
+ pass
@property
def DV01(self):
old_pv = self.pv
- self.spread +=1
+ self.spread += 1
dv01 = self.pv - old_pv
self.spread -= 1
return dv01
@@ -166,7 +173,7 @@ class Index():
for rh in self._helpers:
rh.quote += 1e-4
self._yc = ql_to_jp(self._ql_yc)
- self._update()
+ self._update() ## to force recomputation
new_pv = self.pv
for r in self._helpers:
r.quote -= 1e-4
@@ -191,6 +198,7 @@ class Index():
@property
def jump_to_default(self):
return self.notional * (1 - self.recovery) - self.clean_pv
+
@property
def risky_annuity(self):
return self._risky_annuity - self._accrued
@@ -309,31 +317,27 @@ def calib(S0, fp, exercise_date, exercise_date_settle, index, tilt, w):
a, b = strike_vec(S, index._yc, exercise_date, exercise_date_settle,
index.start_date, index.end_date, index.recovery)
vec = a - index.fixed_rate * b * 1e-4
- df = index._yc.discount_factor(exercise_date_settle) / \
- index._yc.discount_factor(index._value_date)
- return np.inner(vec * df - fp, w)
+ return np.inner(vec, w) - fp
def g(index, spread, exercise_date):
""" computes the strike price using the expected forward yield curve """
+ rolled_curve = roll_yc(index._yc, exercise_date)
step_in_date = exercise_date + datetime.timedelta(days=1)
exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date()
- sc = SpreadCurve(exercise_date, index._yc, index.start_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,
- index._yc, sc, True)
- dl_pv = index._default_leg.pv(
- exercise_date, step_in_date, exercise_date_settle, index._yc,
- sc, index.recovery)
- return index.notional * (dl_pv - a * index.fixed_rate * 1e-4)
+ rolled_curve, sc, True)
+ return index.notional * (spread - index.fixed_rate) * a *1e-4
def ATMstrike(index, exercise_date):
exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date()
- df = index._yc.discount_factor(exercise_date_settle) / \
- index._yc.discount_factor(index._value_date)
+ # df = index._yc.discount_factor(exercise_date_settle) / \
+ # index._yc.discount_factor(index._value_date)
fp = index.forward_pv(exercise_date)
- closure = lambda S: g(index, S, exercise_date) * df - fp
+ closure = lambda S: g(index, S, exercise_date) - fp
eta = 1.1
a = index.spread
b = index.spread * eta
@@ -467,7 +471,7 @@ def option(index, exercise_date, sigma, K, option_type="payer"):
if __name__ == "__main__":
import datetime
from swaption import Index, Option
- ig27_5yr = Index.from_name('ig', 27, '5yr', datetime.date(2016, 10, 21))
+ ig27_5yr = Index.from_name('ig', 27, '5yr', datetime.date(2016, 10, 24))
ig27_5yr.spread = 74
payer = Option(ig27_5yr, datetime.date(2017, 3, 15), 75)
payer.sigma = 0.4847