aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/analytics/credit_default_swap.py9
-rw-r--r--python/analytics/portfolio.py4
-rw-r--r--python/analytics/utils.py20
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