Bohrium
robot
新建

空间站广场

论文
Notebooks
比赛
课程
Apps
我的主页
我的Notebooks
我的论文库
我的足迹

我的工作空间

任务
节点
文件
数据集
镜像
项目
数据库
公开
期权定价:布莱克-斯科尔斯模型
python
金融数学
notebook
python金融数学notebook
SharpLonde
发布于 2023-11-09
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
赞 4
2
期权定价:布莱克-斯科尔斯模型
引言
1. 从借钱开始
2. 来看看期权
3. 期权的定价
4. 股价怎么变?
5. 伊藤引理
6. 布莱克-斯科尔斯方程
7. 期权定价:数值解
8. 后记:回到开头

期权定价:布莱克-斯科尔斯模型

代码
文本

©️ Copyright 2023 @ Authors
作者: SharpLonde
日期:2023-10-28
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

代码
文本

引言

期权是一种重要的金融衍生品,在投资组合管理中起极其重要的作用,是一种重要的风险管理工具。

本文将从一个生活例子开始引入期权相关概念,随后基于例子对随机微积分中重要的的伊藤引理进行引入,最后导出用于期权定价的布莱克-斯科尔斯方程。得到布莱克-斯科尔斯方程后,我们分别用数值方法和解析方法求解并比较结果。

让我们开始吧!

代码
文本

1. 从借钱开始

假定在平常的一天,你的一个不太熟悉的朋友小明突然想找你借 元钱,说好了一年之后还。

你本来想爽快地借给他,但突然一想,这 元钱你放在银行里,一年里还是能吃不少利息的。所以,你和小明约定现在借给他的钱要经过折现,今天你给他 元,一年后他按照约定还 元。考虑到你和小明不是特别熟,这笔钱的现值你决定用连续复利的方式计算,则有: 其中 是你们约定好的利率。

代码
文本

正当你决定给出 元时,突然你又想到:小明一年后跑路了怎么办?虽然是朋友,但你还是决定找小明要一些抵押物。

小明表示:我没啥宝贝东西可以给你,但是我有现在价值 元的股票可以做抵押,一年后我买你手上的股票,你把股票卖我,咱就等于清了。

你想了想,觉得这个抵押物也还可以。于是你接受了他的股票,正准备给钱时,突然又想起来:这支股票价格是会变的,谁知道一年后这股票会不会碰上股灾跌得一文不值?到时候,小明肯定不要他抵押在这的股票了,你的 元还是拿不回来。

代码
文本

所以,你决定和小明签一个合同,合同赋予你下面的权利:

一年后 ( 时),无论股票价格 多少,你都可以要求小明以价格 购入你持有的这支股票。

这个合同我们记为

合同赋予你的是权利,你是可以不行使的。

但小明一看,这不行呀:要是股价涨了大翻天,你不要权利,也不要他的钱,转手把他的更值钱的股票卖给别人了怎么办?

于是他也要和你签类似的合同:

一年后 ( 时),无论股票价格 多少,小明都可以要求你以价格 出售你持有的这支股票。

这个合同我们记为

代码
文本

这下大家终于都满意了,你现在手上获得了小明的股票和一份合同: 小明获得了你借出的钱和另一份合同:

显然,你们满意的原因是这两个组合的价值是相等的:

最后,你和小明发现你们的合同 就是看跌期权(Put Option)和看涨期权(Call Option)。

而上面的等式就是期权的看跌-看涨平价关系式(Put-Call Pairty)。

我们接下来认为,在市场中看跌-看涨评价关系式总是成立。

平价关系的成立与市场有效性和无套利原则有关,其中无套利原则对包括期权在内的金融衍生品定价至关重要,感兴趣的读者可进一步阅读金融衍生品的相关书籍。

代码
文本

2. 来看看期权

现在我们来看看你和小明刚刚签订的两份期权合同。

对你而言,你持有的是股票的看跌期权 。为什么叫看跌期权?我们来看看这个期权的收益情况。

  • 如果未来标的股价 小于约定的行权价格

此时股价下跌,你为了维护自己的权益,会要求小明按行权价格 回购他抵押在你手上的现在只值 的股票。

此时,期权客观给你带来了收益,收益是 元。

  • 如果未来标的股价 大于约定的行权价格

此时股价上涨,你不必行使期权,小明则会按借钱约定的 元回购他更值钱的股票。

此时,期权本身没有给你带来收益。

总的来说,到期日 时看跌期权给持有者(也就是你)带来的收益是:

代码
文本

同样,我们对小明持有的看涨期权 分析:

  • 如果未来标的股价 小于约定的行权价格

此时股价下跌,小明不必行使期权,你会要求小明按约定的 元回购股票。

此时,期权本身没有给小明带来收益。

  • 如果未来标的股价 大于约定的行权价格

此时股价上涨,小明会要求你以 的价格出售现在值 的股票。

此时,期权给小明带来了 的收益。

总的来说,看涨期权持有者小明带来的收益是:

代码
文本

同时,我们也不难看出,你和小明持有的期权给合同双方带来的收益情况刚好是相反的:

当股价下跌,你行使权利的时候,小明不会行使,并且此时你获得收益,小明则损失对应的金额;当股价上涨,小明行使权利的时候,你不会行使,且此时小明获得收益,你则损失对应的金额。

代码
文本

不难画出看涨期权持有者在到期日的收益情况:

代码
文本
[1]
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
代码
文本
[2]
E = 100 # 设定行权金额 E,我们考虑你们约定的价格是每股 100 元

plt.plot(range(70,130), [np.maximum(S - E, 0) for S in range(70,130)], label="Call Option")
plt.xlabel("Stock Price")
plt.ylabel("Payoff")
plt.legend()
代码
文本

读者可自行修改代码查看看跌期权的收益情况。

代码
文本

3. 期权的定价

上面所描述的,是你和小明都愿意签订合同的情况。

但假如小明对签合同有一种莫名的厌恶,你尽力劝说后他同意和你签订了看跌期权合同,但他不想通过签订看涨期权合同来保护自己,转而只想从你这里获得金钱补偿。此时问题就变成了:你应该给他多少钱换取他在看涨期权中获得的利益呢?

事实上,看涨-看跌平价关系中就给出了两个期权的价格关系:

所以,只要我们对其中一个期权有了合理的定价,就可以通过关系得到对应的另一个期权的定价。

期权的定价在到期日 是明确的:此时的股价 确定,进而对应的收益已经确定,直接按照上一节中的方式交换收益的金额 就可以。这也可以从看涨-看跌评价关系中令某一期权的价值为 后立刻得出。

但在其他的 时刻,平价关系不能告诉我们期权的具体定价方式,我们接下来研究看涨期权 的定价问题。

代码
文本

对于研究未知量的问题,我们知道研究影响这个量对相关的输入变量的响应是一个常用的办法。

通过研究微分关系,我们就可以建立微分方程,进而求解出未知量。

所以,既然期权的价格和当前股价 和当前时间 有关,我们来尝试对 进行泰勒展开:

上式中,引入了股价的变化量 。我们接下来就需要研究股价的变化情况。

代码
文本

4. 股价怎么变?

股价的变动规律当然是所有人都想要得到的,但在我们进行期权定价的建模时,我们还是选择简单一些的模型。

Black-Scholes期权定价模型中,我们认为股价按照下面的规律变化: 其中,第一项 表示股票价格的漂移项(Drift Term)。不难看出,这其实就是股价对时间的一阶泰勒展开,也就是短时间内股价的变化与当前价格呈正比。系数 衡量了这种效应的大小。

但是,我们知道股票价格还会产生随机波动,因此第二项 就是波动项(Volatility Term)。其中的变化量 不是常量,而是一个服从正态分布的随机变量:;波动的均值为 ,而随机波动的方差与事件发生的时间长度 正相关。波动系数 反映了市场的活跃程度。

代码
文本

下面是一个有用的性质: 对于 , 随着方差 以概率 收敛到

说明:记 , 因为 , 所以

所以随着 收敛于均值 的概率逐渐增加。

代码
文本

我们可以看一下 的期望值: 也就是说,股价的期望增量变化与波动无关,是由漂移项决定的。 而对于方差: 这也就意味着波动的标准差为

代码
文本

5. 伊藤引理

回到我们对期权价格的泰勒展开。

我们认为,可以忽略比 更高阶的无穷小,第三节式子的最后两项变量分别是 ,我们可以直接把这两项拿掉:

展开的第一项直接可以将股价变化的关系 代入得到:

代码
文本

接下来我们重点需要观察 项,以确定这个随机变量的阶。

我们将它展开: 展开的后两项显然也是比 高阶的小量,我们也忽略。 但展开的第一项含有 ,根据我们上一节分析的有用的命题,这个量在 时以概率 收敛到 。因此,这一项与 是同阶的,我们保留这一项。

代码
文本

最后,我们的展开就写成:

代码
文本

上式就是随机微积分中著名的伊藤引理(Ito‘s Lemma)的一种表达形式。

对于 ,其中 有:

以上式为例子,伊藤引理告诉我们:自变量中随机项 的引入会在一阶泰勒展开中引入一个二阶导数项。

代码
文本

6. 布莱克-斯科尔斯方程

有了伊藤引理,我们得到了期权随股价波动和到期日之前时间的变化关系。我们接下来想要计算的是对于价格为 的股票,看涨期权在到期日之前 时刻的价值

为了对期权进行定价,我们再次需要利用无套利条件。在借钱的例子中,你所持有的价格为 的股票是有风险的金融资产,而你选择使用签订期权的方式来对冲(Hedge)资产的风险。

更一般地,有风险的资产和期权可以组成一个投资组合 其中的 被称为对冲比率(Hedge Ratio)。我们可以通过调控对冲比率,将投资组合 的风险消除。

我们首先计算导数:

代码
文本

接着,我们将 代入伊藤引理:

观察发现,只要表示风险的波动变量 的系数为 ,那么投资组合和 相关的风险因素就可以被全部对冲。

这就要求:

第二节中,我们绘制过看涨期权 的收益曲线,曲线斜率大于等于 ,所以对冲比率 也大于等于 。这就告诉我们在一个由看涨期权和风险资产组成的投资组合中,风险资产 应当以 的方式做空,这样资产价格的上涨和下跌的效应就可以得到抵消。

代码
文本

所以,对于一个完全对冲风险后的投资组合,我们有其预期收益:

但我们知道,银行存款 的利息也是一种无风险的收益。银行存款的复利方式是: 其中 是利率。那么对于同样一个完全对冲风险的投资组合的金额 : 这个金额在银行实现的无风险预期收益与对冲风险的投资组合预期收益应当是一样的:

本质上,这个关系也是来自金融衍生品的无套利定价原则。

代码
文本

上面的形式是看涨期权的,但可以证明对于看跌期权 方程的形式不变,只是看涨期权与看跌期权求解布莱克-斯科尔斯方程时使用的边界条件不同。此外,看跌期权的价格可以通过看涨-看跌平价关系得到,因此我们还是只需要计算看涨期权价格即可。

代码
文本

7. 期权定价:数值解

布莱克-斯科尔斯方程是一个后向抛物型方程(Backward Parabolic Equation),我们可以直接使用有限差分法进行求解。

我们首先考虑方程的边界条件。我们在第2节已经推导过到期日期权的价格就是 。因此第一个边界条件为: 而当股票价格下跌到 ,期权显然也没有任何价值。因此: 当股票价格涨翻天也就是 时,我们可以认为期权价格由 主导:

代码
文本

下面,我们建立方程参数和网格参数:

代码
文本
[3]
E = 100 # 执行金额
r = 0.05 # 无风险利率
sigma = 0.01 # 波动率

S_max = 400 # 求解价格区间上限
T = 3 # 到期日距离现在的时间(年)

# 网格建立: idS x ndT
i_tot = 200 # 价格区间 200 个网格
n_tot = 30 # 时间区间 30 个网格

dS = S_max/i_tot # 价格网格步长
dT = T/n_tot # 时间网格步长
代码
文本

然后我们按照上面的约定,建立求解网格 和边界条件:

代码
文本
[4]
C = np.zeros((i_tot+1, n_tot+1)) # 求解的 (S,t) 价格网络

C[0, :] = 0.0 # 股价为 0 的边界条件
C[i_tot, :] = [i_tot*dS - E * np.exp(-r * (T-n*dT)) for n in range(n_tot+1)] # 价格上界的边界条件
C[:, n_tot] = [np.maximum(i*dS - E, 0) for i in range(i_tot+1)] # 到期日的边界条件
代码
文本

我们检查一下到期日的边界条件:

代码
文本
[5]
plt.plot([i*dS for i in range(i_tot+1)], C[:, n_tot])
plt.xlabel("Stock Price")
plt.ylabel("Payoff")
代码
文本

这是符合我们之前所建立的认知的:到期日股价越高,收益越高。

代码
文本

接下来我们计算布莱克-斯科尔斯方程的有限差分形式。

布莱克-斯科尔斯方程是从到期日往回计算的,因此时间导数我们选择向后差分近似: 而价格的导数则使用中心差分近似:

代码
文本

将差分代入布莱克-斯科尔斯方程,得到:

整理得到: 其中参数

代码
文本

不难看出,从 列向前一个时间步长到 列的转移矩阵是一个三对角矩阵,并且这个矩阵与时间 无关。

这是马尔可夫性的一个体现。

我们现在建立这个矩阵:

代码
文本
[6]
# input C vector : i_tot+1 x 1
def bs_backward():
back_mat = np.zeros((i_tot-1, i_tot+1))
for i in range(i_tot-1):
a = sigma**2 * (dT/dS**2) * ((i+1)*dS)**2
b = r * dT/(2*dS) * (i+1)*dS
band = np.array([0.5*a - b, 1 - r*dT - a, 0.5*a + b])
back_mat[i, i:i+3] = band
return back_mat
代码
文本

通过不断的向前迭代,我们就可以得到 之间的期权价格曲线:

代码
文本
[7]
n = n_tot
Cout = np.copy(C)
backward = bs_backward()

while n >= 1:
C_in = Cout[:, n]
C_out = backward @ C_in
Cout[1:i_tot, n-1] = C_out
n-=1
代码
文本

我们画出对应的期权价格曲线图:

代码
文本
[8]
S_axis = np.array([i*dS for i in range(i_tot+1)])
for k in range(0, n_tot, 5):
plt.plot(S_axis, Cout[:, k], label=f"Call Option Before Expiration at t = {T-k*dT} yrs")
plt.plot(S_axis, Cout[:, n_tot], label=f"Call Option At Expiration")

plt.xlim((70, 130))
plt.ylim((-2, 50))
plt.xlabel("Stock Price")
plt.ylabel("Price")
plt.legend()
代码
文本

注意到,随着到期日的临近,同一价格下期权的价值下降。这是期权的时间价值(Time Value)的体现。随着到期日的临近,期权价格逐渐收敛到预期到期日的收益上。

有了上面的定价公式,我们就可以愉快地在不同时刻,根据当前股票的价格 对看涨期权 进行交易了!

代码
文本

8. 后记:回到开头

事实上,布莱克-斯科尔斯方程可以通过变量替换的方式转换为数学物理中常见的热传导方程 热传导方程的通解即是热核(Heat Kernel):

通过变量替换,看涨期权 价格的解析解为: 其中 为正态分布的累积分布函数(CDF)。参数 分别为:

代码
文本

我们接下来求解文章最开始的问题: 年后到期的看涨期权 价格应该是多少?

解析解我们可以直接通过公式得到:

代码
文本
[9]
from scipy.stats import norm

d1 = (np.log(S_axis/E) + (r + sigma**2/2)) / sigma
d2 = (np.log(S_axis/E) + (r - sigma**2/2)) / sigma
Nd1 = norm.cdf(d1)
Nd2 = norm.cdf(d2)
Cexact = S_axis * Nd1 - E * np.exp(-r) * Nd2
/tmp/ipykernel_104/2626593189.py:3: RuntimeWarning: divide by zero encountered in log
  d1 = (np.log(S_axis/E) + (r + sigma**2/2)) / sigma
/tmp/ipykernel_104/2626593189.py:4: RuntimeWarning: divide by zero encountered in log
  d2 = (np.log(S_axis/E) + (r - sigma**2/2)) / sigma
代码
文本

我们可以对比之前的数值结果和解析解结果:

代码
文本
[10]
plt.plot(S_axis, Cexact, label="Exact Solution 1 yr Before Expiration")
plt.plot(S_axis, Cout[:, 20], label="Numerical Solution 1 yr Before Expiration")
plt.xlim((70, 130))
plt.ylim((-5, 40))
plt.xlabel("Stock Price")
plt.ylabel("Price")
plt.legend()
代码
文本

可以看出,两个解法给出的结果的吻合程度还是很好的。通过解的曲线,我们可以得到文章开头中,你和小明签订的看涨期权合同 价值约为 元。看涨-看跌期权平价关系给出了你持有的看跌期权合同 的价值,实际上价值不到 分钱。此时,期权对小明的保护作用更大。

总而言之,通过布莱克-斯科尔斯模型,我们不仅可以给期权定价,还可以分析引起期权价格变化的因素,例如波动率的大小对期权价格的影响等。读者不妨以上面的代码为基础,直接修改代码运行进行实践观察。

注:此处求解布莱克-斯科尔斯方程使用的是有限差分数值解的显形式,在遇到求解出现数值问题(如数值爆炸、振荡)的时候,可以考虑减小时间步长(即增加i_total)克服数值误差问题。

代码
文本

Ref:

[1] Mathematics of Finance: An intuitive Introduction, Donald G. Saari

[2] A Study on Numerical Solution of Black-Scholes Model, Md. Nurul Anwar, Laek Sazzad Andallah

代码
文本
python
金融数学
notebook
python金融数学notebook
已赞4
推荐阅读
公开
自由能计算
notebook
notebook
pignoi
发布于 2024-03-01
4 赞3 转存文件
公开
TBPLaS并行计算
TBPLaS并行计算任务提交
TBPLaS并行计算任务提交
李云海
发布于 2023-07-27
1 赞1 转存文件