from db import dbconn from quantlib.indexes.api import UsdLiborSwapIsdaFixAm from quantlib.quotes import SimpleQuote from quantlib.time.api import Date, Period, Years 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.: return "Long" else: return "Short" @direction.setter def direction(self, d): if d == "Long": self._direction = 1. elif d == "Short": self._direction = -1. 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']) 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 Settings().evaluation_date