Skip to content

Commit 364109a

Browse files
authored
Update black_scholes.py
Fix bug in black76 delta, add a function to compute strike from delta
1 parent c7364c1 commit 364109a

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

fypy/pricing/analytical/black_scholes.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,53 @@ def black76_delta(F: float,
8282
K: Union[float, np.ndarray],
8383
is_call: bool,
8484
vol: Union[float, np.ndarray],
85-
disc: float,
86-
T: float) -> Union[float, np.ndarray]:
85+
T: float,
86+
div_disc: Optional[float] = 1.0,
87+
is_fwd_delta: bool = False) -> Union[float, np.ndarray]:
8788
"""
8889
Delta for strikes of a common parity (ie only call or put).
8990
:param F: float, forward price
9091
:param K: float or array, the Strike(s)
9192
:param is_call: bool, determines if ALL strikes are call or all are put
9293
:param vol: float or array, the Volatility(ies) ... if float, all strikes get same vol, else a vol smile
93-
:param disc: float, the discount factor, e.g. 0.99
9494
:param T: float, time to maturity of option
95+
:param div_disc: float, the dividend discount factor, e.g. 0.99 = exp(-q*T)
96+
:param is_fwd_delta: bool, if true its a delta w.r.t. forward, else it's w.r.t. spot
9597
:return: float or np.ndarray, same shape as strikes
9698
"""
9799
vol_st = vol * np.sqrt(T)
100+
phi = 1 if is_call else 0
98101
d_1 = (np.log(F / K) + 0.5 * vol_st ** 2) / vol_st
99-
delta = norm.cdf(d_1)
100-
if not is_call:
101-
delta -= 1.0
102-
103-
return disc * delta
102+
delta = phi * norm.cdf(phi * d_1)
103+
if is_fwd_delta:
104+
delta *= div_disc
105+
return delta
106+
107+
108+
def black76_strike_from_delta(F: float,
109+
delta: Union[float, np.ndarray],
110+
is_call: bool,
111+
vol: Union[float, np.ndarray],
112+
T: float,
113+
div_disc: Optional[float] = 1.0,
114+
is_fwd_delta: bool = False
115+
) -> Union[float, np.ndarray]:
116+
"""
117+
Strike(s) corresponding to delta(s) of a common parity (ie only call or put).
118+
:param F: float, forward price
119+
:param delta: float or array, the deltas(s)
120+
:param is_call: bool, determines if ALL strikes are call or all are put
121+
:param vol: float or array, the Volatility(ies) ... if float, all strikes get same vol, else a vol smile
122+
:param T: float, time to maturity of option
123+
:param div_disc: float, the dividend discount factor, e.g. 0.99 = exp(-q*T)
124+
:param is_fwd_delta: bool, if true its a delta w.r.t. forward, else it's w.r.t. spot
125+
:return: float or np.ndarray, same shape as strikes
126+
"""
127+
phi = 1 if is_call else -1
128+
vol_st = vol * np.sqrt(T)
129+
if is_fwd_delta:
130+
delta /= div_disc
131+
return F * np.exp(-(vol_st * phi * norm.ppf(phi * delta) - 0.5 * vol * vol * T))
104132

105133

106134
def black_scholes_price(S: float,

0 commit comments

Comments
 (0)