aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/option.py3
-rw-r--r--python/analytics/portfolio.py57
2 files changed, 56 insertions, 4 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py
index e7c87fbb..14e64d54 100644
--- a/python/analytics/option.py
+++ b/python/analytics/option.py
@@ -424,6 +424,8 @@ class VolatilitySurface(ForwardIndex):
engine,
parse_dates = ['quotedate', 'expiry'],
params=(trade_date, index_type.upper(), series))
+ if self._quotes.empty:
+ raise ValueError("No quotes for that day")
self._quotes['quotedate'] = (self._quotes['quotedate'].
dt.tz_convert('America/New_York').
dt.tz_localize(None))
@@ -479,6 +481,7 @@ class VolatilitySurface(ForwardIndex):
quotes = quotes.assign(mid = quotes[['pay_bid','pay_offer']].mean(1) * 1e-4)
else:
quotes = quotes.assign(mid = quotes[['rec_bid','rec_offer']].mean(1) * 1e-4)
+ quotes = quotes.dropna(subset=['mid'])
with Pool(4) as p:
for expiry, df in quotes.groupby(['expiry']):
atm_strike = ATMstrike(self._index, expiry.date())
diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py
index e7abf0a2..0688c868 100644
--- a/python/analytics/portfolio.py
+++ b/python/analytics/portfolio.py
@@ -1,11 +1,35 @@
from .index import Index
-from .option import BlackSwaption
+from .option import BlackSwaption, VolatilitySurface
+from db import dbengine
+from warnings import warn
+
+serenitasdb = dbengine('serenitasdb')
+
+def _key_from_index(index):
+ _, index_type, _, series, tenor = index.name.split()
+ series = int(series[1:])
+ tenor = tenor.lower() + 'r'
+ return index_type, series, tenor
class Portfolio:
def __init__(self, trades):
self.trades = trades
self.indices = [t for t in trades if isinstance(t, Index)]
self.swaptions = [t for t in trades if isinstance(t, BlackSwaption)]
+ self._keys = []
+ for index in self.indices:
+ self._keys.append(_key_from_index(index))
+ #pick the first available trade_date
+ trade_dates = set()
+ for index in self.indices:
+ trade_dates.add(index.trade_date)
+ for swaption in self.swaptions:
+ trade_dates.add(swaption.index.trade_date)
+ self._trade_date = trade_dates.pop()
+ if len(trade_dates) >= 1:
+ warn("not all instruments have the same trade date, picking {}".
+ format(self._trade_date))
+ self._vs = {}
@property
def pnl(self):
@@ -29,15 +53,40 @@ class Portfolio:
@property
def trade_date(self):
- return self.index.trade_date
+ return self._trade_date
@trade_date.setter
def trade_date(self, d):
+ #we try to keep everybody in sync
for index in self.indices:
index.trade_date = d
+ if len(self.indices) == 0:
+ for swaption in self.swaptions:
+ self.swaption.trade_date = d
+ self._trade_date = d
- def mark(self):
- pass
+ def mark(self, source=None, option_type=None, model=None, surface_id=None):
+ vs_dict = {}
+ for index, (index_type, series, tenor) in zip(self.indices, self._keys):
+ run = serenitasdb.execute("""SELECT * FROM index_quotes
+ WHERE index=%s AND series=%s AND tenor=%s AND date=%s""",
+ (index_type, series, tenor, self.trade_date))
+ rec = run.fetchone()
+ index.spread = rec.closespread
+ k = (self.trade_date, index_type, series, tenor)
+ if k not in self._vs:
+ vs = VolatilitySurface(index_type, series, tenor, self.trade_date)
+ if surface_id is None and len(vs.list(source, option_type, model)) >=1:
+ surface_id = vs.list(source, option_type, model)[-1]
+ else:
+ raise ValueError("No market data available for this day")
+ self._vs[k] = vs[surface_id]
+ for swaption in self.swaptions:
+ vol_surface = self._vs[(swaption.index.trade_date, ) + \
+ _key_from_index(swaption.index)]
+ swaption.sigma = float(self._vs[(swaption.index.trade_date, ) \
+ + _key_from_index(swaption.index)].
+ ev(swaption.T, swaption.moneyness))
@property
def ref(self):