aboutsummaryrefslogtreecommitdiffstats
path: root/python/swaption_pnl.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/swaption_pnl.py')
-rw-r--r--python/swaption_pnl.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/python/swaption_pnl.py b/python/swaption_pnl.py
new file mode 100644
index 00000000..cf0cc653
--- /dev/null
+++ b/python/swaption_pnl.py
@@ -0,0 +1,99 @@
+import datetime
+import pandas as pd
+from psycopg2.extensions import connection
+from risk.swaptions import get_swaption_portfolio
+from risk.indices import get_index_portfolio
+from pandas.tseries.offsets import BDay
+from pyisda.date import previous_twentieth
+from typing import Tuple
+
+
+def get_index_pv(
+ start_date: datetime.date,
+ end_date: datetime.date,
+ strategies: Tuple[str],
+ conn: connection,
+):
+ dr = pd.bdate_range(start_date, end_date)
+ pvs = []
+ daily = []
+ dates = []
+
+ for d in dr:
+ prev_day = (d - BDay()).date()
+ if previous_twentieth(d, roll=True) == d.date():
+ accrued = 0.0
+ for t in portf.trades:
+ d, amount = t._fee_leg.cashflows[0]
+ accrued -= amount * t.notional * t.factor * t.fixed_rate * 1e-4
+ else:
+ accrued = 0.0
+ portf = get_index_portfolio(prev_day, strategies, conn)
+ nav = 0.0
+ with conn.cursor() as c:
+ c.execute(
+ "SELECT upfront FROM cds WHERE trade_date=%s " "AND folder in %s",
+ (prev_day, strategies),
+ )
+ for (fee,) in c:
+ nav += fee
+ daily.append(nav + accrued)
+ pvs.append(portf.pv)
+ dates.append(prev_day)
+ df = pd.DataFrame({"pv": pvs, "daily": daily}, index=pd.to_datetime(dates))
+ return df
+
+
+def get_swaption_pv(
+ start_date: datetime.date, end_date: datetime.date, conn: connection
+):
+ dr = pd.bdate_range(start_date, end_date)
+ pv = []
+ daily = []
+ dates = []
+ for d in dr:
+ print(d)
+ prev_day = (d - BDay()).date()
+ portf = get_swaption_portfolio(prev_day, conn, source_list=["GS"])
+ nav = 0.0
+ # add terminations
+ with conn.cursor() as c:
+ c.execute(
+ "SELECT termination_fee "
+ "FROM swaptions WHERE termination_date=%s AND folder != 'STEEP'",
+ (prev_day,),
+ )
+ for (fee,) in c:
+ nav += fee
+ # add new trades
+ with conn.cursor() as c:
+ c.execute(
+ "SELECT notional * price/100 * (CASE WHEN buysell THEN -1. ELSE 1. END) "
+ "FROM swaptions WHERE trade_date=%s AND folder != 'STEEP'",
+ (prev_day,),
+ )
+ for (fee,) in c:
+ nav += fee
+ dates.append(prev_day)
+ pv.append(portf.pv)
+ daily.append(nav)
+ df = pd.DataFrame({"pv": pv, "daily": daily}, index=pd.to_datetime(dates))
+ return df
+
+
+if __name__ == "__main__":
+ import argparse
+ from utils.db import dbconn
+
+ dawndb = dbconn("dawndb")
+ parser = argparse.ArgumentParser()
+ parser.add_argument("start_date", type=datetime.datetime.fromisoformat)
+ parser.add_argument("end_date", type=datetime.datetime.fromisoformat)
+ args = parser.parse_args()
+ df_index = get_index_pv(
+ args.start_date, args.end_date, ("IGOPTDEL", "HYOPTDEL"), dawndb
+ )
+ df_swaption = get_swaption_pv(args.start_date, args.end_date, dawndb)
+ pnl_index = df_index.pv.diff() + df_index.daily
+ pnl_swaption = df_swaption.pv.diff() + df_swaption.daily
+ pnl = pd.concat([pnl_index, pnl_swaption], keys=["index", "swaption"], axis=1)