diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/analytics/tranche_basket.py | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index 4b6491ea..6681b53f 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -3,8 +3,10 @@ from .tranche_functions import ( credit_schedule, adjust_attachments, GHquad, BCloss_recov_dist, BCloss_recov_trunc, tranche_cl, tranche_pl) from .index_data import get_tranche_quotes +from cityhash import CityHash64 from collections import namedtuple from copy import deepcopy +from lru import LRU from pyisda.date import cds_accrued from scipy.optimize import brentq from scipy.interpolate import CubicSpline, PchipInterpolator @@ -13,6 +15,23 @@ import datetime import pandas as pd import numpy as np +_cache = LRU(64) +def BCloss_recov_dist_cached(default_prob, + weights, + recovery_rates, + rho, + Z, w, Ngrid): + h = CityHash64(default_prob.T) ^ CityHash64(weights) ^ \ + CityHash64(recovery_rates) ^ hash(rho) + if h in _cache: + return _cache[h] + else: + _cache[h] = BCloss_recov_dist(default_prob, + weights, + recovery_rates, + rho, + Z, w, Ngrid) + return _cache[h] class DualCorrTranche(BasketIndex): def __init__(self, index_type: str, series: int, tenor: str, *, @@ -57,11 +76,11 @@ class DualCorrTranche(BasketIndex): elif np.isnan(rho): raise ValueError("rho needs to be a real number between 0. and 1.") else: - L, R = BCloss_recov_dist(self.default_prob.values, - self.weights, - self.recovery_rates, - rho, - self._Z, self._w, self._Ngrid) + L, R = BCloss_recov_dist_cached(self.default_prob, + self.weights, + self.recovery_rates, + rho, + self._Z, self._w, self._Ngrid) Legs = namedtuple('TrancheLegs', 'coupon_leg, protection_leg') return Legs(tranche_cl(L, R, self.cs, 0., K), tranche_pl(L, self.cs, 0., K)) |
