aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics')
-rw-r--r--python/analytics/scenarios.py39
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