aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/scenarios.py53
1 files changed, 35 insertions, 18 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py
index 1a99562d..0c132076 100644
--- a/python/analytics/scenarios.py
+++ b/python/analytics/scenarios.py
@@ -3,6 +3,10 @@ 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 multiprocessing import Pool
def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock,
vol_surface, params=["pv"]):
@@ -21,12 +25,13 @@ def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock,
swaption = deepcopy(swaption)
spreads = swaption.ref * (1 + spread_shock)
+ r = []
for date in date_range:
swaption.index.trade_date = date.date()
T = swaption.T
for s in spreads:
swaption.ref = s
- curr_vol = float(max(0, vol_surface(T, swaption.moneyness)))
+ curr_vol = max(0, float(vol_surface(T, swaption.moneyness)))
for vs in vol_shock:
swaption.sigma = curr_vol * (1 + vs)
r.append([date, s, vs] + [getattr(swaption, p) for p in params])
@@ -34,7 +39,7 @@ def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock,
return df.set_index('date')
-def run_index_scenarios(index, date_range, spread_shock):
+def run_index_scenarios(index, date_range, spread_shock, params=['pnl']):
index = deepcopy(index)
spreads = index.spread * (1 + spread_shock)
@@ -43,12 +48,21 @@ def run_index_scenarios(index, date_range, spread_shock):
index.trade_date = date.date()
for s in spreads:
index.spread = s
- r.append([date, s, index.pnl])
- df = pd.DataFrame.from_records(r, columns=['date', 'spread_shock', 'pnl'])
+ r.append([date, s] + [getattr(index, p) for p in params])
+ df = pd.DataFrame.from_records(r, columns=['date', 'spread_shock'] + params)
return df.set_index('date')
-def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
- vol_surface, params=["pnl"]):
+def _aux(portf, curr_vols, params, vs):
+ for swaption, curr_vol in zip(portf.swaptions, curr_vols):
+ swaption.sigma = curr_vol * (1 + vs)
+ return [vs] + [getattr(portf, p) for p in params]
+
+@contextmanager
+def MaybePool(nproc):
+ yield Pool(nproc) if nproc > 0 else None
+
+def run_portfolio_scenarios_multiproc(portf, date_range, spread_shock, vol_shock,
+ vol_surface, params=["pnl"], nproc=-1):
"""computes the pnl of a portfolio for a range of scenarios
Parameters
@@ -60,20 +74,23 @@ def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
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 = portf.index.spread * (1 + spread_shock)
+
r = []
- for date in date_range:
- portf.index.trade_date = date.date()
- t = [swaption.T for swaption in portf.swaptions]
- mon = [swaption.moneyness for swaption in portf.swaptions]
- curr_vols = np.maximum(vol_surface.ev(t, mon), 0)
- for s in spreads:
- portf.index.ref = s
- for vs in vol_shock:
- for swaption, curr_vol in zip(portf.swaptions, curr_vols):
- swaption.sigma = curr_vol * (1 + vs)
- r.append([date, s, vs] + [getattr(portf, p) for p in params])
- df = pd.DataFrame.from_records(r, columns=['date', 'spread_shock', 'vol_shock'] + params)
+ with MaybePool(nproc) as pool:
+ pmap = pool.map if pool else map
+ for date in date_range:
+ portf.index.trade_date = date.date()
+ t = [swaption.T for swaption in portf.swaptions]
+ for s in spreads:
+ portf.index.ref = 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_shock', 'vol_shock'] + params)
return df.set_index('date')