aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/scenarios.py92
1 files changed, 64 insertions, 28 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py
index 16a7921a..9996d405 100644
--- a/python/analytics/scenarios.py
+++ b/python/analytics/scenarios.py
@@ -1,16 +1,13 @@
-from analytics import ATMstrike
-from joblib import delayed, Parallel
import pandas as pd
from copy import deepcopy
import numpy as np
from contextlib import contextmanager
-from itertools import chain
-from functools import partial
+from itertools import chain, groupby
+from functools import partial, reduce
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):
@@ -68,8 +65,9 @@ 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):
+ vol_surface, nproc=-1, vol_time_roll=True):
"""computes the pnl of a portfolio for a range of scenarios,
but running each component individually
"""
@@ -77,7 +75,7 @@ def run_portfolio_scenarios_module(portf, date_range, spread_shock, vol_shock,
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)
+ 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)
@@ -90,10 +88,24 @@ def run_portfolio_scenarios_module(portf, date_range, spread_shock, vol_shock,
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):
+def join_dfs(l_df):
+ d = {}
+ # first we concat together dataframes with the same indices
+ for k, v in groupby(l_df.items(), lambda x: tuple(x[1].index.names)):
+ keys, dfs = zip(*v)
+ d[k] = pd.concat(dfs, axis=1, keys=keys).reset_index()
+ # then we merge them one by one on the common column
+ # (which should be spread_shock)
+ dfs = reduce(lambda df1, df2: pd.merge(df1, df2), d.values())
+ # then we set back the index
+ index_names = set()
+ for k in d.keys():
+ index_names |= set(k)
+ return dfs.set_index(list(index_names))
+
+
+def run_portfolio_scenarios(portf, date_range, params=["pnl"], **kwargs):
"""computes the pnl of a portfolio for a range of scenarios
Parameters
@@ -108,25 +120,49 @@ def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
nproc : int
if nproc > 0 run with nproc processes.
"""
- portf = deepcopy(portf)
- spreads = np.hstack([index.spread * (1 + spread_shock) for index in portf.indices])
+ d = {}
+ for date in date_range:
+ portf.value_date = date.date()
+ d[date] = join_dfs(portf.shock(params, **kwargs))
+ return pd.concat(d, names=['date'] + d[date].index.names)
- t = [swaption.T for swaption in portf.swaptions]
- r = []
- with MaybePool(nproc) as pool:
- pmap = pool.map if pool else map
- for date in date_range:
- portf.value_date = date.date()
- if vol_time_roll:
- t = [swaption.T for swaption in portf.swaptions]
- for s in spreads:
- portf.spread = s
- mon = [swaption.moneyness for swaption in portf.swaptions]
- curr_vols = np.maximum(vol_surface.ev(t, mon), 0)
- temp = pmap(partial(_aux, portf, curr_vols, params), vol_shock)
- r.append([[date, s] + rec for rec in temp])
- df = pd.DataFrame.from_records(chain(*r), columns=['date', 'spread', 'vol_shock'] + params)
- return df.set_index('date')
+# 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
+
+# Parameters
+# ----------
+# swaption : Swaption
+# date_range : `pandas.Datetime.Index`
+# spread_shock : `np.array`
+# vol_shock : `np.array`
+# vol_surface : VolSurface
+# params : list of strings
+# list of attributes to call on the Portfolio object.
+# nproc : int
+# if nproc > 0 run with nproc processes.
+# """
+# portf = deepcopy(portf)
+# spreads = np.hstack([index.spread * (1 + spread_shock) for index in portf.indices])
+
+# t = [swaption.T for swaption in portf.swaptions]
+# r = []
+# with MaybePool(nproc) as pool:
+# pmap = pool.map if pool else map
+# for date in date_range:
+# portf.value_date = date.date()
+# for t in portf.trades:
+# d[type(t)]
+# if vol_time_roll:
+# t = [swaption.T for swaption in portf.swaptions]
+# for s in spreads:
+# portf.spread = s
+# mon = [swaption.moneyness for swaption in portf.swaptions]
+# curr_vols = np.maximum(vol_surface.ev(t, mon), 0)
+# temp = pmap(partial(_aux, portf, curr_vols, params), vol_shock)
+# r.append([[date, s] + rec for rec in temp])
+# df = pd.DataFrame.from_records(chain(*r), columns=['date', 'spread', 'vol_shock'] + params)
+# return df.set_index('date')
def run_tranche_scenarios(tranche, spread_range, date_range, corr_map=False):
"""computes the pnl of a tranche for a range of spread scenarios