aboutsummaryrefslogtreecommitdiffstats
path: root/python/pnl_explain.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/pnl_explain.py')
-rw-r--r--python/pnl_explain.py52
1 files changed, 36 insertions, 16 deletions
diff --git a/python/pnl_explain.py b/python/pnl_explain.py
index ba5657a1..9851ee76 100644
--- a/python/pnl_explain.py
+++ b/python/pnl_explain.py
@@ -1,9 +1,10 @@
+import numpy as np
import pandas as pd
+
from db import dbengine
from dates import bus_day, imm_dates, yearfrac
-import numpy as np
-
from psycopg2.extensions import register_adapter, AsIs
+
register_adapter(np.int64, lambda x: AsIs(x))
def get_daycount(identifier, engine = dbengine("dawndb")):
@@ -24,21 +25,28 @@ def pnl_explain(identifier, start_date = None, end_date = None,
engine = dbengine("dawndb")):
""" if start_date is None, pnl since inception"""
trades = pd.read_sql_query("SELECT * FROM bonds where identifier=%s", engine,
- params=(identifier,), parse_dates=['trade_date', 'settle_date'],
- index_col=['settle_date'])
+ params=(identifier,), parse_dates=['trade_date', 'settle_date'])
+ for key in ['faceamount', 'principal_payment', 'accrued_payment']:
+ trades.loc[~trades.buysell, key] = -trades[key][~trades.buysell]
+
+ ## take care of multiple trades settling on the same date
+ trades = (trades.
+ groupby('settle_date')[['faceamount', 'principal_payment', 'accrued_payment']].
+ sum())
+
marks = pd.read_sql_query("SELECT * FROM marks where identifier=%s", engine,
params=(identifier,), parse_dates = ['date'], index_col='date')
factors = pd.read_sql_query("SELECT * FROM factors_history where identifier=%s", engine,
params=(identifier,), parse_dates = ['last_pay_date', 'prev_cpn_date'])
factors = factors.set_index('prev_cpn_date', drop=False)
daycount, delay = get_daycount(identifier, engine)
- for key in ['faceamount', 'principal_payment', 'accrued_payment']:
- trades.loc[~trades.buysell, key] = -trades[key][~trades.buysell]
+
df = (marks[['price']].
join([factors, trades[['principal_payment', 'accrued_payment', 'faceamount']]],
how='outer'))
df.sort_index(inplace=True)
+
if start_date is None:
start_date = trades.trade_date.ix[trades.index.min()]
if end_date is None:
@@ -62,11 +70,16 @@ def pnl_explain(identifier, start_date = None, end_date = None,
daily['accrued'] = yearfrac(daily.prev_cpn_date, daily.index.to_series(), daycount) * \
daily.coupon/100*daily.factor * daily.faceamount
daily['unrealized_accrued'] = daily.accrued.diff() + daily.realized_accrued
- # for some reason .shift(0, bus_day) doesn't work (but would work on an index)
- daily['realized_accrued'] = (daily.loc[daily.realized_accrued>0, 'realized_accrued'].
- shift(delay, 'D').shift(-1, bus_day).shift(1, bus_day))
- daily['realized_pnl'] = (daily.loc[daily.realized_pnl>0, 'realized_pnl'].
- shift(delay, 'D').shift(-1, bus_day).shift(1, bus_day))
+ if delay >0:
+ ## we shift cashflows by delay 'D', and then move it to the next business day
+ ## for some reason .shift(0, bus_day) doesn't work (but would work on an index)
+ if not daily.loc[daily.realized_accrued>0, 'realized_accrued'].empty:
+ daily['realized_accrued'] = (daily.loc[daily.realized_accrued>0, 'realized_accrued'].
+ shift(delay, 'D').shift(-1, bus_day).shift(1, bus_day))
+ if not daily.loc[daily.realized_pnl>0, 'realized_pnl'].empty:
+ daily['realized_pnl'] = (daily.loc[daily.realized_pnl>0, 'realized_pnl'].
+ shift(delay, 'D').shift(-1, bus_day).shift(1, bus_day))
+
daily[['realized_pnl', 'realized_accrued']] = (daily[['realized_pnl', 'realized_accrued']].
fillna(value=0))
extra_pnl = daily.clean_nav.diff() - daily.principal_payment
@@ -191,14 +204,21 @@ def cds_explain_strat(strat, start_date, end_date, engine = dbengine("dawndb")):
return pd.concat(df)
if __name__=="__main__":
- workdate = pd.datetime.today()
engine = dbengine("dawndb")
- from position import get_list
- clo_list = get_list(engine, workdate, 'CLO')
- df = pnl_explain_list(clo_list.identifier.tolist(), None, '2015-11-30', engine)
+ from position import get_list_range
+ ## CLO
+ clo_list = get_list_range(engine, '2015-01-01', '2015-12-31', 'CLO')
+ df = pnl_explain_list(clo_list.identifier.tolist(), '2015-01-01', '2015-12-31', engine)
+ df = pd.concat(df)
+ df_agg = df.groupby(level=1).sum()
+ ## subprime
+ subprime_list = get_list_range(engine, '2015-01-01', '2015-12-31', 'Subprime')
+ df = pnl_explain_list(subprime_list.identifier.tolist(), '2015-01-01', '2015-12-31', engine)
df = pd.concat(df)
df_agg = df.groupby(level=1).sum()
- cds_df = cds_explain_strat(['SER_IGINX', 'SER_IGMEZ'], None, '2015-12-16', engine)
+ df_agg[['realized_accrued','unrealized_accrued',
+ 'realized_pnl', 'unrealized_pnl']].sum(axis=1).cumsum().plot(x_compat=True)
+ cds_df = cds_explain_strat(['SER_IGINX', 'SER_IGMEZ'], None, None, engine)
#cds_df = cds_explain_strat(['SER_HYMEZ'], None, '2015-03-10', engine)
#cds_df2 = cds_explain_strat('SER_IGCURVE', None, None, engine)
#cds_df = cds_explain('HY', 21, '5yr', 25, 35, '2014-07-18')