aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/swaption.py42
1 files changed, 24 insertions, 18 deletions
diff --git a/python/swaption.py b/python/swaption.py
index 305e7e51..88ae5543 100644
--- a/python/swaption.py
+++ b/python/swaption.py
@@ -85,7 +85,8 @@ 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, self._value_date,
+
+ a = self._fee_leg.pv(self.trade_date, step_in_date, value_date,
self._yc, self._sc, False)
Delta = self._fee_leg.accrued(step_in_date)
df = self._yc.discount_factor(value_date)
@@ -109,6 +110,9 @@ class Index():
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,
[self.end_date], array.array('d', [self._spread]),
@@ -161,25 +165,26 @@ class Index():
for rh in self._helpers:
rh.quote += 1e-4
self._yc = ql_to_jp(self._ql_yc)
- self.spread = self.spread ## to force recomputation
+ self._update()
new_pv = self.pv
for r in self._helpers:
r.quote -= 1e-4
self._yc = old_yc
- self.spread = self.spread
+ self._update()
return new_pv - old_pv
@property
def rec_risk(self):
old_pv = self.pv
- self.recovery -= 0.01
- self.spread = self.spread
+ old_recovery = self.recovery
+ self.recovery = old_recovery - 0.01
+ self._update()
pv_minus = self.pv
- self.recovery += 0.02
- self.spread = self.spread
+ self.recovery = old_recovery + 0.01
+ self._update()
pv_plus = self.pv
- self.recovery -= 0.01
- self.spread = self.spread
+ self.recovery = old_recovery
+ self._update()
return (pv_plus - pv_minus)/2
@property
@@ -206,7 +211,7 @@ class Index():
self._accrued = self._fee_leg.accrued(self._step_in_date)
self._value_date = (pd.Timestamp(self._trade_date) + 3* BDay()).date()
if self._spread is not None:
- self.spread = self.spread
+ self._update()
@classmethod
def from_name(cls, index, series, tenor, trade_date = datetime.date.today(),
@@ -244,10 +249,11 @@ class Index():
"{:<20}\t{:>15}".format("Valuation Date", '{:%m/%d/%y}'.format(self.trade_date)),
"{:<20}\t{:>15}".format("Cash Settled On", '{:%m/%d/%y}'.format(self._value_date)),
"",
- "{:<20}\t{:>15.8f}\t\t{:<20}\t{:>8,.2f}".format("Price", self.price, "Spread DV01", self.DV01),
- "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>8,.2f}".format("Principal", self.clean_pv, "IR DV01", self.IRDV01),
- "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>8,.2f}".format(accrued_str, self.accrued, "Rec Risk (1%)", self.rec_risk),
- "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>8,.2f}".format("Cash Amount", self.pv, "Def Exposure", self.rec_risk)]
+ "{:<20}\t{:>15.8f}\t\t{:<20}\t{:>10,.2f}".format("Price", self.price, "Spread DV01", self.DV01),
+ "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>10,.2f}".format("Principal", self.clean_pv, "IR DV01", self.IRDV01),
+ "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>10,.2f}".format(accrued_str, self.accrued, "Rec Risk (1%)", self.rec_risk),
+ "{:<20}\t{:>15,.0f}\t\t{:<20}\t{:>10,.0f}".format("Cash Amount", self.pv, "Def Exposure",
+ self.notional*(1-self.recovery)-self.clean_pv)]
return "\n".join(s)
def year_frac(d1, d2, day_count_conv = "Actual/365"):
@@ -421,8 +427,8 @@ def option(index, exercise_date, sigma, K, option_type="payer"):
if __name__ == "__main__":
import datetime
from swaption import Index, Option
- ig26_5yr = Index.from_name('ig', 26, '5yr', datetime.date(2016, 8, 19))
- ig26_5yr.spread = 70
- payer = Option(ig26_5yr, datetime.date(2016, 9, 21), 70)
+ ig27_5yr = Index.from_name('ig', 27, '5yr', datetime.date(2016, 10, 21))
+ ig27_5yr.spread = 74
+ payer = Option(ig27_5yr, datetime.date(2017, 3, 15), 75)
payer.sigma = 0.4847
- payer.notional = 100e6
+ payer.notional = 10e6