from db 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.: 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'], 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))