from analytics.curve_trades import on_the_run from analytics.index_data import get_index_quotes, index_returns from db import dbengine import pandas as pd import math import datetime dawndb = dbengine('dawndb') serenitasdb = dbengine('serenitasdb') def hist_var(portf, index_type='IG', quantile=.05, years=5): df = index_returns(index=index_type, years=years, tenor=['3yr', '5yr', '7yr', '10yr']) df = (df.reset_index(['index'], drop=True). reorder_levels(['date', 'series', 'tenor'])) returns = df.spread_return.dropna().reset_index('series') returns['dist_on_the_run'] = (returns. groupby('date')['series']. transform(lambda x: x.max() - x)) del returns['series'] returns = returns.set_index('dist_on_the_run', append=True).unstack('tenor') returns.columns = returns.columns.droplevel(0) portf.reset_pv() otr = on_the_run(index_type) spreads = pd.DataFrame({'spread': portf.spread, 'tenor': [ind.tenor for ind in portf.indices], 'dist_on_the_run': [otr - ind.series for ind in portf.indices]}) spreads = spreads.set_index(['dist_on_the_run', 'tenor']) r = [] for k, g in returns.groupby(level='date', as_index=False): shocks = g.reset_index('date', drop=True).stack('tenor') shocks.name = 'shocks' portf.spread = spreads.spread * (1 + spreads.join(shocks).shocks) r.append((k, portf.pnl)) pnl = pd.DataFrame.from_records(r, columns=['date', 'pnl'], index=['date']) return pnl.quantile(quantile) * math.sqrt(12) def rel_spread_diff(report_date=datetime.date.today(), index='HY', rolling=10): otr = on_the_run(index) ## look at spreads df = get_index_quotes(index, list(range(otr - rolling, otr + 1)), tenor=['3yr', '5yr', '7yr', '10yr'], years=5) duration = df.duration.xs((report_date, '5yr', otr), level=['date', 'tenor', 'series'])[-1] df = df.xs('5yr', level='tenor')['closespread'].groupby(['date']).last() df = df.loc['2013-01-15':report_date] curr_spread = df.iloc[-1] df = df.pct_change(freq='22B').dropna() return df.groupby('date').last(), curr_spread, duration def get_pos(report_date, strategy=None): if strategy is None: return pd.read_sql_query("SELECT * from list_cds_marks(%s)", dawndb, params=(report_date,)) else: return pd.read_sql_query("SELECT * from list_cds_marks(%s, %s)", dawndb, params=(report_date, strategy)) def cleared_cds_margins(report_date=datetime.date.today()): df = get_pos(report_date) #Cap Allocation for Deltas percentile = .95 #monthly 90%tile case... shocks, widen, tighten, onTR_dur, onTR_spread = {}, {}, {}, {}, {} for ind in ['IG', 'HY', 'EU']: shocks[ind], onTR_spread[ind], onTR_dur[ind] = rel_spread_diff(report_date, index=ind) widen[ind] = shocks[ind].quantile(percentile) tighten[ind] = shocks[ind].quantile(1-percentile) df['onTR_notional'] = df.apply(lambda df: df.notional * df.factor * df.duration / onTR_dur[df.p_index], axis=1) df['widen'] = df.apply(lambda df: df.onTR_notional * onTR_spread[df.p_index] * onTR_dur[df.p_index] * widen[df.p_index]/10000, axis=1) df['tighten'] = df.apply(lambda df: df.onTR_notional * onTR_spread[df.p_index] * onTR_dur[df.p_index] * tighten[df.p_index]/10000, axis=1) delta_alloc = df.groupby('strategy').sum() delta_alloc['total'] = delta_alloc.apply(lambda df: max(abs(df.widen), abs(df.tighten)), axis=1) return delta_alloc