aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics')
-rw-r--r--python/analytics/__init__.py1
-rw-r--r--python/analytics/index.py2
-rw-r--r--python/analytics/option.py53
3 files changed, 52 insertions, 4 deletions
diff --git a/python/analytics/__init__.py b/python/analytics/__init__.py
index 90d1b1fe..1d5c0c0f 100644
--- a/python/analytics/__init__.py
+++ b/python/analytics/__init__.py
@@ -1 +1,2 @@
from .index import Index
+from .option import Swaption
diff --git a/python/analytics/index.py b/python/analytics/index.py
index 85ba3474..78b52fae 100644
--- a/python/analytics/index.py
+++ b/python/analytics/index.py
@@ -92,7 +92,7 @@ class Index():
if d > self.trade_date:
return 1
else:
- return math.exp( - self.flat_hazard * (d - self.trade_date)/365)
+ return math.exp( - self.flat_hazard * (d - self.trade_date).days/365)
def forward_pv(self, exercise_date):
"""This is default adjusted forward price at time exercise_date"""
diff --git a/python/analytics/option.py b/python/analytics/option.py
index 32f4f947..fe60d2d5 100644
--- a/python/analytics/option.py
+++ b/python/analytics/option.py
@@ -1,10 +1,57 @@
+import array
+import datetime
+import math
+import numpy as np
+import pandas as pd
+
from .black import black
from .utils import GHquad
from yieldcurve import roll_yc
from pandas.tseries.offsets import BDay
+from pyisda.curve import SpreadCurve
+from pyisda.flat_hazard import strike_vec
+from scipy.optimize import brentq
+from scipy.integrate import simps
+
+def g(index, spread : float, exercise_date : datetime.date, use_rolled_curve = True):
+ """ computes the strike clean price using the expected forward yield curve """
+ 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,
+ 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,
+ rolled_curve, sc, True)
+ return (spread - index.fixed_rate) * a *1e-4
+
+def calib(S0, fp, exercise_date : datetime.date, exercise_date_settle :datetime.date,
+ index, rolled_curve, tilt, w):
+ S = S0 * tilt * 1e-4
+ 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 ATMstrike(index, exercise_date : datetime.date):
+ exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date()
+ fp = index.forward_pv(exercise_date)
+ closure = lambda S: g(index, S, exercise_date) - fp
+ eta = 1.1
+ a = index.spread
+ b = index.spread * eta
+ while True:
+ if closure(b) > 0:
+ break
+ b *= eta
+ return brentq(closure, a, b)
-class Option:
- def __init__(self, index, exercise_date, strike, option_type="payer"):
+class Swaption:
+ def __init__(self, index, exercise_date : datetime.date, strike : float, option_type="payer"):
self.index = index
self._exercise_date = exercise_date
self._forward_yc = roll_yc(self.index._yc, self.exercise_date)
@@ -97,7 +144,7 @@ class Option:
if self._T:
return self._T
else:
- return year_frac(self.index.trade_date, self.exercise_date) + 1/365
+ return ((self.exercise_date - self.index.trade_date).days + 1)/365
@property
def gamma(self):