from . import dbconn from quantlib.indexes.api import UsdLiborSwapIsdaFixAm from quantlib.quotes import SimpleQuote from quantlib.time.api import Date, Period, Years, pydate_from_qldate from quantlib.instruments.api import MakeSwaption from quantlib.instruments.swap import SwapType from quantlib.pricingengines.api import BlackSwaptionEngine from quantlib.settings import Settings from yieldcurve import YC class IRSwaption: """ adapter class for the QuantLib code""" def __init__( self, swap_index, option_tenor, strike, option_type="payer", direction="Long", notional=10_000_000, yc=None, ): self._qloption = ( MakeSwaption(swap_index, option_tenor, strike) .with_nominal(notional) .with_underlying_type(SwapType[option_type.title()])() ) if type(direction) is bool: self._direction = 2 * direction - 1 else: self.direction = direction self._yc = yc or swap_index.forwarding_term_structure self._sigma = SimpleQuote(0.218) self._qloption.set_pricing_engine(BlackSwaptionEngine(self._yc, self._sigma)) @property def direction(self): if self._direction == 1.0: return "Long" else: return "Short" @direction.setter def direction(self, d): if d == "Long": self._direction = 1.0 elif d == "Short": self._direction = -1.0 else: raise ValueError("Direction needs to be either 'Long' or 'Short'") @property def pv(self): return self._direction * self._qloption.npv @property def sigma(self): return self._sigma.value @sigma.setter def sigma(self, s): self._sigma.value = s def from_tradeid(trade_id): with dbconn("dawndb") as conn: with conn.cursor() as c: c.execute("SELECT * from swaptions " "WHERE id = %s", (trade_id,)) rec = c.fetchone() yc = YC(evaluation_date=rec["trade_date"], fixed=True) p = Period(int(rec["security_id"].replace("USISDA", "")), Years) swap_index = UsdLiborSwapIsdaFixAm(p, yc) instance = IRSwaption( swap_index, Date.from_datetime(rec["expiration_date"]), rec["strike"], rec["option_type"], rec["buysell"], rec["notional"], ) return instance @property def value_date(self): return pydate_from_qldate(self._qloption.valuation_date) @value_date.setter def value_date(self, d): self.yc.link_to(YC(evaluation_date=d, fixed=True))