aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics')
-rw-r--r--python/analytics/index.py32
-rw-r--r--python/analytics/option.py18
2 files changed, 27 insertions, 23 deletions
diff --git a/python/analytics/index.py b/python/analytics/index.py
index d085b140..56ab4704 100644
--- a/python/analytics/index.py
+++ b/python/analytics/index.py
@@ -59,6 +59,7 @@ class Index():
self._sc = None
self._risky_annuity = None
self._spread = None
+ self._price = None
self.name = None
@property
@@ -168,19 +169,20 @@ class Index():
@price.setter
def price(self, val):
- def handle(x, self, val):
- self._spread = x
+ if self._price is None or math.fabs(val, self._price) > 1e-6:
+ def handle(x, self, val):
+ self._spread = x
+ self._update()
+ return val - self.price
+ eta = 1.2
+ a = self.fixed_rate*1e-4 * 0.5
+ b = a * eta
+ while True:
+ if handle(b, self, val) > 0:
+ break
+ b *= eta
+ self._spread = brentq(handle, a, b, args = (self, val))
self._update()
- return val - self.price
- eta = 1.2
- a = self.fixed_rate*1e-4 * 0.5
- b = a * eta
- while True:
- if handle(b, self, val) > 0:
- break
- b *= eta
- self._spread = brentq(handle, a, b, args = (self, val))
- self._update()
@property
def DV01(self):
@@ -366,10 +368,12 @@ class ForwardIndex():
@ref.setter
def ref(self, val : float):
if self._ref_is_price:
- if math.abs(self.index.price - val) > 1e-6:
+ if self.index.price is None or \
+ math.fabs(self.index.price - val) > 1e-6:
self.index.price = val
+ self._update()
else:
- if val != self.index.spread:
+ if self.index.spread is None or val != self.index.spread:
self.index.spread = val
self._update()
diff --git a/python/analytics/option.py b/python/analytics/option.py
index 89b6e244..1f250bb3 100644
--- a/python/analytics/option.py
+++ b/python/analytics/option.py
@@ -10,17 +10,17 @@ from .index import g, ForwardIndex
from yieldcurve import roll_yc
from pandas.tseries.offsets import BDay
from pyisda.curve import SpreadCurve
-from pyisda.flat_hazard import strike_vec
+from pyisda.flat_hazard import pv_vec
from scipy.optimize import brentq
from scipy.integrate import simps
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
+ pv = pv_vec(S, rolled_curve, exercise_date, exercise_date_settle,
+ index.start_date, index.end_date, index.recovery,
+ index.fixed_rate * 1e-4)
+ return np.inner(pv, w) - fp
def ATMstrike(index, exercise_date : datetime.date):
exercise_date_settle = (pd.Timestamp(exercise_date) + 3* BDay()).date()
@@ -120,10 +120,10 @@ class Swaption(ForwardIndex):
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._forward_yc, 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) - self._G) * 1/math.sqrt(2*math.pi) * np.exp(-Z**2/2)
+ r = pv_vec(S * 1e-4, self._forward_yc, self.exercise_date,
+ self.exercise_date_settle, self.index.start_date,
+ self.index.end_date, self.index.recovery, self.index.fixed_rate * 1e-4)
+ val = (r - self._G) * 1/math.sqrt(2*math.pi) * np.exp(-Z**2/2)
return self.notional * simps(val, Z) * self.df
@pv.setter