diff options
Diffstat (limited to 'python/analytics/option.py')
| -rw-r--r-- | python/analytics/option.py | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/python/analytics/option.py b/python/analytics/option.py index 0dfecf17..9a829b15 100644 --- a/python/analytics/option.py +++ b/python/analytics/option.py @@ -22,7 +22,7 @@ from pyisda.flat_hazard import pv_vec import numpy as np from scipy.optimize import brentq from scipy.integrate import simps -from scipy.interpolate import SmoothBivariateSpline, interp2d, CubicSpline +from scipy.interpolate import SmoothBivariateSpline, interp2d, interp1d, CubicSpline from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt @@ -661,7 +661,12 @@ class ProbSurface(QuoteSurface): prob = np.clip(prob, 1e-10, None, out=prob) quotes['prob'] = prob quotes.dropna(subset=['prob'], inplace=True) - spline = lambda df: CubicSpline(df.strike, logit(df.prob), bc_type="natural") + def spline(df): + x = df.strike + y = logit(df.prob) + x = np.log(x[np.hstack([True, np.diff(y) < 0])]) + y = y[np.hstack([True, np.diff(y) < 0])] + return CubicSpline(x, y, bc_type='natural') h = quotes.sort_values('strike').groupby('time').apply(spline) self._surfaces[surface_id] = MyInterp(h.index.values, h.values) return self._surfaces[surface_id] @@ -670,23 +675,25 @@ class ProbSurface(QuoteSurface): def tail_prob(self, T, strike, surface_id): """computes the prob for a given moneyness and term.""" - return expit(self[surface_id](T, strike)) + return expit(self[surface_id](T, math.log(strike))) def quantile_spread(self, T, prob, surface_id): """computes the spread for a given probability and term.""" l_prob = logit(prob) def prob_calib(x, T, surface_id): - return l_prob- self[surface_id](T, x) + return l_prob - self[surface_id](T, math.log(x)) eta = 1.5 - a = .1 - b = 50 * eta + a = 1e-6 + b = 50. + while True: if prob_calib(b, T, surface_id) > 0: break b *= eta - prog = brentq(prob_calib, a, b, args=(T, surface_id), full_output=True) - if prog[1].converged is True: - return prog[0] + + val, r = brentq(prob_calib, a, b, args=(T, surface_id), full_output=True) + if r.converged: + return val else: return ValueError("unable to converge") @@ -699,6 +706,7 @@ class ProbSurface(QuoteSurface): x = np.arange(time[0], time[-1], 0.01) z = np.vstack([[self.quantile_spread(xx, yy, surface_id) for yy in y] for xx in x]) xx, yy = np.meshgrid(x, y) + surf = ax.plot_surface(xx, yy, z.T, cmap=cm.viridis) ax.set_xlabel("Year fraction") |
