diff options
Diffstat (limited to 'python/analytics')
| -rw-r--r-- | python/analytics/scenarios.py | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py index cdbcf4f0..16a7921a 100644 --- a/python/analytics/scenarios.py +++ b/python/analytics/scenarios.py @@ -10,6 +10,7 @@ from multiprocessing import Pool from .index_data import _get_singlenames_curves from .curve_trades import curve_shape from scipy.interpolate import RectBivariateSpline +from functools import reduce def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock, vol_surface, params=["pv"], vol_time_roll=True): @@ -26,21 +27,23 @@ def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock, list of attributes to call on the swaption object. """ swaption = deepcopy(swaption) - spreads = swaption.ref * (1 + spread_shock) + spreads = swaption.index.spread * (1 + spread_shock) T = swaption.T r = [] for date in date_range: - swaption.index.value_date = date.date() + swaption.index.value_date = min(swaption.exercise_date, date.date()) if vol_time_roll: T = swaption.T for s in spreads: - swaption.ref = s + swaption.index.spread = s curr_vol = max(0, float(vol_surface(T, swaption.moneyness))) + if date.date() > swaption.exercise_date: curr_vol = 0 for vs in vol_shock: swaption.sigma = curr_vol * (1 + vs) - r.append([date, s, vs] + [getattr(swaption, p) for p in params]) + r.append([date, s, round(vs,2)] + [getattr(swaption, p) for p in params]) df = pd.DataFrame.from_records(r, columns=['date', 'spread', 'vol_shock'] + params) - return df.set_index('date') + df.loc[df.date > pd.to_datetime(swaption.exercise_date), 'delta'] = 0 + return df.set_index(['date', 'spread', 'vol_shock']) def run_index_scenarios(index, date_range, spread_shock, params=['pnl']): @@ -54,7 +57,7 @@ def run_index_scenarios(index, date_range, spread_shock, params=['pnl']): index.spread = s r.append([date, s] + [getattr(index, p) for p in params]) df = pd.DataFrame.from_records(r, columns=['date', 'spread'] + params) - return df.set_index('date') + return df.set_index(['date', 'spread']) def _aux(portf, curr_vols, params, vs): for swaption, curr_vol in zip(portf.swaptions, curr_vols): @@ -65,6 +68,30 @@ def _aux(portf, curr_vols, params, vs): def MaybePool(nproc): yield Pool(nproc) if nproc > 0 else None +def run_portfolio_scenarios_module(portf, date_range, spread_shock, vol_shock, + vol_surface, nproc=-1, vol_time_roll=True): + """computes the pnl of a portfolio for a range of scenarios, + but running each component individually + """ + + temp_results = [] + for inst in portf.swaptions: + temp = run_swaption_scenarios(inst, date_range, spread_shock, vol_shock, + vol_surface, params=["pnl", 'delta'], vol_time_roll=True) + temp.delta *= inst.notional + temp_results.append(temp) + results = reduce(lambda x, y: x.add(y, fill_value=0), temp_results) + temp_results = [] + for inst in portf.indices: + temp_results.append(run_index_scenarios(inst, date_range, + spread_shock, params=['pnl'])) + temp_results = reduce(lambda x, y: x.add(y, fill_value=0), temp_results) + results = results.reset_index(['vol_shock']).join(temp_results, rsuffix='_idx') + results.set_index('vol_shock', append=True) + + return results.drop(['pnl_idx'], axis=1) + + def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl"], nproc=-1, vol_time_roll=True): """computes the pnl of a portfolio for a range of scenarios |
