我试图将此代码用于欧洲定价选项的Black-Scholes公式,但我收到以下错误:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-25-0e7b66f29cf6> in <module>
35
36 a = BsmModel('c', 42, 35, 0.1, 90.0/365, 0.2)
---> 37 a.bsm_price()
<ipython-input-25-0e7b66f29cf6> in bsm_price(self)
26
27 def bsm_price(self):
---> 28 d1 = self.d1()
29 d2 = d1 - self.sigma * sqrt(self.T)
30 if self.type == 'c':
<ipython-input-25-0e7b66f29cf6> in d1(self)
20
21 def d1(self):
---> 22 return (log(self.s / self.k) + (self.r - self.q + self.sigma ** 2 * 0.5) * self.T) / (self.sigma * sqrt(self.T))
23
24 def d2(self):
NameError: name 'log' is not defined
据我所知,我通过相应地修复数学函数使用了以下调整后的代码并且它有效。
import scipy.stats as sp
import numpy as np
class BsmModel:
def __init__(self, option_type, price, strike, interest_rate, expiry, volatility, dividend_yield=0):
self.s = price # Underlying asset price
self.k = strike # Option strike K
self.r = interest_rate # Continuous risk fee rate
self.q = dividend_yield # Dividend continuous rate
self.T = expiry # time to expiry (year)
self.sigma = volatility # Underlying volatility
self.type = option_type # option type "p" put option "c" call option
def n(self, d):
# cumulative probability distribution function of standard normal distribution
return sp.norm.cdf(d)
def dn(self, d):
# the first order derivative of n(d)
return sp.norm.pdf(d)
def d1(self):
return (math.log(self.s / self.k) + (self.r - self.q + self.sigma ** 2 * 0.5) * self.T) / (self.sigma * math.sqrt(self.T))
def d2(self):
return (math.log(self.s / self.k) + (self.r - self.q - self.sigma ** 2 * 0.5) * self.T) / (self.sigma * math.sqrt(self.T))
def bsm_price(self):
d1 = self.d1()
d2 = d1 - self.sigma * math.sqrt(self.T)
if self.type == 'c':
return math.exp(-self.r*self.T) * (self.s * math.exp((self.r - self.q)*self.T) * self.n(d1) - self.k * self.n(d2))
if self.type == 'p':
return math.exp(-self.r*self.T) * (self.k * self.n(-d2) - (self.s * math.exp((self.r - self.q)*self.T) * self.n(-d1)))
print ("option type can only be c or p")
a = BsmModel('c', 42, 35, 0.1, 90.0/365, 0.2)
a.bsm_price()
## 7.8778518797804225
我也仔细检查了数学,得到了 7.88 美元的相同解决方案。
\begin{align*}
\text{stock price}&=S\\
\text{strike price}&=K\\
\text{time to expiration}&=T-t\\
\text{interest rates}&=r\\
\text{future volatility of the underlying stock}&=\sigma\\
\end{align*}
To get our solution, we calculate
\begin{align*}
d_1&=\frac{\ln(S_0/K)+(r+\sigma^2/2)T}{\sigma\sqrt{T}}\\
&=\frac{\ln(42/35)+(0.1+0.2^2/2)\frac{90}{365}}{0.2\sqrt{\frac{90}{365}}}\\
&\approx2.13377\\
\\
d_2&=d_1-\sigma\sqrt{T}\\
&=2.00963-0.2\sqrt{\frac{90}{365}}\\
&\approx2.03445\\
\end{align*}
Now, looking up $\Phi(2.13377)$ and $\Phi(2.03445)$ on the z-score table, we find
\begin{align*}
\Phi(2.13377)&=0.9835692\\
\Phi(2.03445)&=0.9790469\\
\\
\Rightarrow C(S_0,t)=S_0\Phi(d_1)-Ke^{-r(T)}\Phi(d_2)\\
&=(42\times 0.9835692)-\left(35\times e^{(-0.1\times90/365)}\times 0.9790469\right)\\
&=41.3099064-33.43204\\
&=\boxed{7.87786}
\end{align*}