aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/option.py22
-rw-r--r--python/calibrate_swaption.py10
2 files changed, 10 insertions, 22 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py
index ef931701..1669803a 100644
--- a/python/analytics/option.py
+++ b/python/analytics/option.py
@@ -319,6 +319,9 @@ class BlackSwaption(ForwardIndex):
def pv(self, val):
if np.isnan(val):
raise ValueError("val is nan")
+ # early exit
+ if self.sigma is not None and abs(self.pv - val) < 1e-12:
+ return
if self._direction * (val - self.intrinsic_value) < 0:
raise ValueError(
f"{val}: is less than intrinsic value: {self.intrinsic_value}"
@@ -571,7 +574,7 @@ class Swaption(BlackSwaption):
@pv.setter
def pv(self, val):
# use sigma_black as a starting point
- self.pv_black = val
+ BlackSwaption.pv.fset(self, val)
if self.sigma == 0.0:
self.sigma = 1e-6
@@ -592,23 +595,6 @@ class Swaption(BlackSwaption):
b *= eta
self.sigma = brentq(handle, a, b)
- def __setpv_black(self, val):
- black_self = BlackSwaption.__new__(BlackSwaption)
- for k in chain.from_iterable(
- c.__slots__ for c in type(black_self).__mro__[:-1]
- ):
- if k != "__weakref__":
- setattr(black_self, k, getattr(self, k))
- black_self.pv = val
- self.sigma = black_self.sigma
-
- pv_black = property(None, __setpv_black)
-
- def __setprice_black(self, p):
- self.pv_black = p * 1e-2 * self.notional * self.index.factor * self._direction
-
- price_black = property(None, __setprice_black)
-
def _get_keys(df, models=["black", "precise"]):
for quotedate, source in (
diff --git a/python/calibrate_swaption.py b/python/calibrate_swaption.py
index 703b6429..7d67d654 100644
--- a/python/calibrate_swaption.py
+++ b/python/calibrate_swaption.py
@@ -1,7 +1,6 @@
import pandas as pd
-from analytics import CreditIndex, Swaption
+from analytics import CreditIndex, Swaption, BlackSwaption
import datetime
-import sys
from utils.db import dbengine
from contextlib import contextmanager
@@ -52,7 +51,7 @@ def calib(option, ref, strike, pay_bid, pay_offer, rec_bid, rec_offer):
option.ref = ref
option.strike = strike
r = []
- for price_type in ["price", "price_black"]:
+ for price_type in ["price_black", "price"]:
for option_type in ["pay", "rec"]:
if option_type == "pay":
mid = (pay_bid + pay_offer) / 2 * 1e-2
@@ -65,7 +64,10 @@ def calib(option, ref, strike, pay_bid, pay_offer, rec_bid, rec_offer):
r.append(0.0)
continue
try:
- setattr(option, price_type, mid)
+ if price_type == "price_black":
+ BlackSwaption.price.fset(option, mid)
+ else:
+ setattr(option, price_type, mid)
except (ValueError, SystemError) as e:
if "Failed" in str(e):
logger.error(e)