diff options
| -rw-r--r-- | python/analytics/credit_default_swap.py | 9 | ||||
| -rw-r--r-- | python/analytics/portfolio.py | 4 | ||||
| -rw-r--r-- | python/analytics/utils.py | 20 |
3 files changed, 31 insertions, 2 deletions
diff --git a/python/analytics/credit_default_swap.py b/python/analytics/credit_default_swap.py index 4ad253d1..932e90ed 100644 --- a/python/analytics/credit_default_swap.py +++ b/python/analytics/credit_default_swap.py @@ -12,7 +12,7 @@ from pyisda.curve import SpreadCurve from pyisda.date import previous_twentieth from pyisda.legs import ContingentLeg, FeeLeg from termcolor import colored -from .utils import build_table +from .utils import build_table, get_fx from weakref import WeakSet from yieldcurve import get_curve, rate_helpers, YC, ql_to_jp @@ -211,6 +211,13 @@ class CreditDefaultSwap: self.price = 100 * (1 - self._clean_pv) @property + def local_pv(self): + if self.currency == "USD": + return self.pv + else: + return self.pv * get_fx(self.currency, self.value_date) + + @property def accrued(self): return -self.notional * self._factor * self._accrued * self.fixed_rate * 1e-4 diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py index 1d040627..b6bd35af 100644 --- a/python/analytics/portfolio.py +++ b/python/analytics/portfolio.py @@ -104,6 +104,10 @@ class Portfolio: return sum(t.pv for t in self.trades) @property + def local_pv(self): + return sum(t.local_pv for t in self.trades) + + @property def pv_list(self): return [t.pv for t in self.trades] diff --git a/python/analytics/utils.py b/python/analytics/utils.py index 09145b41..3d5c0da4 100644 --- a/python/analytics/utils.py +++ b/python/analytics/utils.py @@ -1,10 +1,11 @@ import datetime import numpy as np import pandas as pd +from . import dbconn from .exceptions import MissingDataError from scipy.special import h_roots from dateutil.relativedelta import relativedelta, WE -from functools import partial, wraps +from functools import partial, wraps, lru_cache from pyisda.date import pydate_to_TDate from pandas.api.types import CategoricalDtype from pandas.tseries.offsets import CustomBusinessDay @@ -187,3 +188,20 @@ def get_external_nav(engine, trade_id, value_date=None, trade_type="swaption"): return pd.read_sql_query( query, engine, params=(trade_id,), parse_dates=["date"], index_col=["date"] ) + + +@lru_cache(32) +def get_fx(currency: str, value_date: datetime.date): + if currency == "USD": + return 1.0 + conn = dbconn("dawndb") + with conn.cursor() as c: + c.execute("SELECT * FROM fx where date=%s", (value_date,)) + rec = c.fetchone() + r = getattr(rec, currency.lower() + "usd", None) + if r is None: + raise MissingDataError( + f"No {currency.upper()}USD fx rate available for {value_date}" + ) + conn.close() + return r |
