aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/swaption.py57
1 files changed, 27 insertions, 30 deletions
diff --git a/python/swaption.py b/python/swaption.py
index 5d00c9c8..c85a9b12 100644
--- a/python/swaption.py
+++ b/python/swaption.py
@@ -119,7 +119,7 @@ class Index():
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._clean_pv = self._pv + self._accrued * self.fixed_rate * 1e-4
self._price = 100 * (1 - self._clean_pv)
@spread.setter
@@ -148,7 +148,7 @@ class Index():
@property
def clean_pv(self):
- return self._clean_pv
+ return self.notional * self._clean_pv
@property
def price(self):
@@ -312,16 +312,20 @@ def year_frac(d1, d2, day_count_conv = "Actual/365"):
return (d2-d1).days/360
-def calib(S0, fp, exercise_date, exercise_date_settle, index, tilt, w):
+def calib(S0, fp, exercise_date, exercise_date_settle, index,
+ rolled_curve, tilt, w):
S = S0 * tilt * 1e-4
- a, b = strike_vec(S, index._yc, exercise_date, exercise_date_settle,
+ 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 g(index, spread, exercise_date):
+def g(index, spread, exercise_date, use_rolled_curve = True):
""" computes the strike clean price using the expected forward yield curve """
- rolled_curve = roll_yc(index._yc, exercise_date)
+ 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,
@@ -330,22 +334,7 @@ def g(index, spread, exercise_date):
index.recovery)
a = index._fee_leg.pv(exercise_date, step_in_date, exercise_date_settle,
rolled_curve, sc, True)
- return index.notional * (spread - index.fixed_rate) * a *1e-4
-
-def g2(index, spread, exercise_date):
- """ computes the strike price using the expected forward yield curve """
- 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,
- 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)
+ return (spread - index.fixed_rate) * a *1e-4
def ATMstrike(index, exercise_date):
exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date()
@@ -364,6 +353,7 @@ class Option:
def __init__(self, index, exercise_date, strike, option_type="payer"):
self.index = index
self._exercise_date = exercise_date
+ self._forward_yc = roll_yc(self.index._yc, self.exercise_date)
self.exercise_date_settle = (pd.Timestamp(self.exercise_date) + 3* BDay()).date()
self._T = None
self.strike = strike
@@ -374,18 +364,21 @@ class Option:
@property
def exercise_date(self):
return self._exercise_date
+
@exercise_date.setter
def exercise_date(self, d : datetime.date):
self._exercise_date = d
self.exercise_date_settle = (pd.Timestamp(d) + 3* BDay()).date()
+ self._forward_yc = roll_yc(self.index._yc, self.exercise_date)
@property
def pv(self):
- fp = self.index.forward_pv(self.exercise_date)/self.index.notional
+ fp = self.index.forward_pv(self.exercise_date) / self.index.notional
T = self.T
tilt = np.exp(-self.sigma**2/2 * T + self.sigma * self._Z * math.sqrt(T))
+ rolled_curve = roll_yc(self.index._yc, self.exercise_date)
args = (fp, self.exercise_date, self.exercise_date_settle,
- self.index, tilt, self._w)
+ self.index, self._forward_yc, tilt, self._w)
eta = 1.1
a = self.index.spread
b = self.index.spread * eta
@@ -406,13 +399,13 @@ class Option:
Zstar = (math.log(self.strike/S0) + self.sigma**2/2 * T) / \
(self.sigma * math.sqrt(T))
if self.option_type == "payer":
- Z = Zstar + np.logspace(0, 2, 300) - 1
+ Z = Zstar + np.logspace(0, 1.5, 300) - 1
elif self.option_type == "receiver":
- Z = Zstar - np.logspace(0, 2, 300) + 1
+ Z = Zstar - np.logspace(0, 1.5, 300) + 1
else:
raise ValueError("option_type needs to be either 'payer' or 'receiver'")
S = S0 * np.exp(-self.sigma**2/2 * T + self.sigma * Z * math.sqrt(T))
- a, b = strike_vec(S * 1e-4, self.index._yc, self.exercise_date,
+ a, b = strike_vec(S * 1e-4, rolled_curve, self.exercise_date,
self.exercise_date_settle,
self.index.start_date, self.index.end_date, self.index.recovery)
val = ((a - b * self.index.fixed_rate*1e-4) - G) * 1/math.sqrt(2*math.pi) * np.exp(-Z**2/2)
@@ -422,18 +415,22 @@ class Option:
@property
def pv2(self):
G = g(self.index, self.strike, self.exercise_date)
- fp = self.index.forward_pv(self.exercise_date)
+ fp = self.index.forward_pv(self.exercise_date) / self.index.notional
forward_annuity = self.index.forward_annuity(self.exercise_date)
DA_forward_spread = fp / forward_annuity + self.index.fixed_rate * 1e-4
strike_tilde = self.index.fixed_rate * 1e-4 + G / forward_annuity
- return forward_annuity * black(DA_forward_spread, strike_tilde, self.T, self.sigma, self.option_type)
+ return forward_annuity * black(DA_forward_spread,
+ strike_tilde,
+ self.T,
+ self.sigma,
+ self.option_type) * self.notional
@property
def delta(self):
old_index_pv = self.index.pv
old_pv = self.pv
self.index.spread += 0.1
- notional_ratio = self.index.notional/self.option.notional
+ notional_ratio = self.index.notional/self.notional
delta = (self.pv - old_pv)/(self.index.pv - old_index_pv) * notional_ratio
self.index.spread -= 0.1
return delta