diff options
Diffstat (limited to 'python/analytics')
| -rw-r--r-- | python/analytics/option.py | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py index fe543dde..b2d04618 100644 --- a/python/analytics/option.py +++ b/python/analytics/option.py @@ -4,7 +4,6 @@ import logging import math import numpy as np import pandas as pd -import analytics from .black import black, Nx from .exceptions import MissingDataError @@ -12,7 +11,7 @@ from .sabr import sabr from .utils import GHquad, build_table, bus_day from .index import g, ForwardIndex, CreditIndex from . import serenitas_engine, dawn_engine -from .utils import memoize +from .utils import memoize, get_external_nav from pandas.tseries.offsets import BDay from pyisda.optim import init_context, update_context, expected_pv @@ -71,6 +70,7 @@ class BlackSwaption(ForwardIndex): "sigma", "_original_pv", "_direction", + "_trade_id", ) def __init__( @@ -85,6 +85,7 @@ class BlackSwaption(ForwardIndex): self._original_pv = None self.direction = direction self._orig_params = (strike, index.factor, index.cumloss) + self._trade_id = None self.index.observe(self) def __setstate__(self, state): @@ -113,14 +114,20 @@ class BlackSwaption(ForwardIndex): direction="Long" if rec.buysell else "Short", ) instance.notional = rec.notional - instance.pv = rec.price * 1e-2 * rec.notional * (2 * rec.buysell - 1) + instance.price = rec.price instance._original_pv = instance.pv instance._orig_params = (rec.strike, index.factor, index.cumloss) + instance._trade_id = trade_id return instance def mark(self, source_list=[], surface_id=None, **kwargs): ind = self.index ind.mark() + if kwargs.get("use_external", False): + self.pv = get_external_nav( + dawn_engine, self._trade_id, self.value_date, "swaptions" + ) + return # add None so that we always try everything source_list = source_list + [None] surface_date = kwargs.get("surface_date", ind.value_date) @@ -265,6 +272,14 @@ class BlackSwaption(ForwardIndex): ) @property + def price(self): + return abs(self.pv / (self.index.factor * self.notional)) * 100 + + @price.setter + def price(self, p): + self.pv = p * 1e-2 * self.notional * self.index.factor * self._direction + + @property def tail_prob(self): """compute exercise probability by pricing it as a binary option""" strike_tilde = ( @@ -282,12 +297,11 @@ class BlackSwaption(ForwardIndex): raise ValueError("val is nan") if self._direction * (val - self.intrinsic_value) < 0: raise ValueError( - "{}: is less than intrinsic value: {}".format(val, self.intrinsic_value) + f"{val}: is less than intrinsic value: {self.intrinsic_value}" ) elif val == self.intrinsic_value: self.sigma = 0 return - val = val * self.index.factor def handle(x): self.sigma = x |
