修复期权定价模型中的数学库函数

问题描述 投票:0回答:0

我试图将此代码用于欧洲定价选项的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*}
python numpy math scipy quantitative-finance
© www.soinside.com 2019 - 2024. All rights reserved.