Coverage for rivapy/pricing/analytics.py: 95%
19 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-05 14:27 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-05 14:27 +0000
1import math
2from scipy.optimize import brentq
3from scipy.stats import norm
4from scipy.special import ndtr
5import numpy as np
8def compute_european_price_Buehler(strike:float, maturity:float, volatility:float, is_call: bool=True)->float:
9 """Compute a call/put option price for the Buehler model (w.r.t. x-process), i.e. no dividends, rates etc.
10 Args:
11 strike (float): strike
12 maturity (float): maturity
13 volatility (float): volatility
14 is_call (bool): if option is call or put
15 Returns:
16 float: Black-Scholes call price
17 """
18 if maturity < 1E-12:
19 return np.maximum(1.0 - strike, 0)
20 sqrt_mat = math.sqrt(maturity)
21 d1 = ( math.log( 1.0 / strike ) + 0.5*volatility*volatility*maturity ) / ( volatility * sqrt_mat)
22 d2 = d1 - volatility * sqrt_mat
23 #print(d1,d2)
24 if is_call:
25 return ndtr(d1) - strike * ndtr(d2)
26 return -ndtr(-d1) + strike*ndtr(-d2)
28def compute_implied_vol_Buehler(strike: float, maturity:float, price:float,
29 min_vol = 0.05, max_vol = 2.0, is_call=True, **kwargs)->float:
30 """Computes the implied volatility for a given cal/putl price using brentq from scipy. It throws an exception if no implied vol can be determined.
32 Args:
33 strike (float): [description]
34 maturity (float): [description]
35 price (float): [description]
36 min_vol (float, optional): [description]. Defaults to 0.05.
37 max_vol (float, optional): [description]. Defaults to 2.0.
38 is_call (bool): if option is call or put
40 Returns:
41 float: [description]
42 """
43 def error(vol:float):
44 result = price - compute_european_price_Buehler(strike, maturity, vol, is_call= is_call)
45 return result
46 return brentq(error,a=min_vol, b=max_vol, **kwargs)