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