第6节 蒙特卡罗模拟计算欧式期权价格
6.1 简介
- 蒙特卡罗模拟
蒙特卡罗模拟是一种通过简单的随机抽样来模拟一个随机实验或者随机过程的方法。它主要包括三个部分:- 基本的随机数产生器。一般情况下我们可以直接使用编程语言常用库的随机数产生器。比如Python 中
random
模块中的random.random()
,它可以产生一个在[0, 1]之间的均匀分布的浮点随机数,或者numpy
里的random
类中包括的均匀分布、正态分布等几种常用随机数产生器。 - 需要模拟的随机试验或者随机过程。比如掷骰子,掷飞镖,布朗运动,或者泊松过程。
- 如何使用基本的随机数产生器模拟目标实验或者过程。
- 基本的随机数产生器。一般情况下我们可以直接使用编程语言常用库的随机数产生器。比如Python 中
- 蒙特卡罗模拟股价变化过程
考虑股票价格 S S S的变化过程服从几何布朗运动,其连续形式为:
d S = S μ d t + σ d z . dS = S\mu dt+\sigma dz. dS=Sμdt+σdz.
μ \mu μ为收益率期望值, σ \sigma σ为股价波动率, z z z为维纳过程,设 μ \mu μ和 σ \sigma σ为常数。股价变化的离散化形式为:
S ( t + Δ t ) = S ( t ) ( 1 + μ Δ t + σ ε Δ t ) . S(t+\Delta t) = S(t)(1+\mu\Delta t+\sigma\varepsilon \sqrt{\Delta t}) . S(t+Δt)=S(t)(1+μΔt+σεΔt).
其中 ε \varepsilon ε为期望值为0,标准差为1的正态分布的一个随机抽样。如果我们将期权有效期0至 T T T之间的时间划分为等间隔的 N N N段, Δ t = T / N \Delta t=T/N Δt=T/N。则我们需要独立地抽取 N N N个正态分布随机数,以构成一条股票价格可能的变化路径。
- 蒙特卡罗模拟计算欧式期权价格
为了计算期权价格,我们需要在风险中性世界里模拟股票价格变化过程,即将 μ \mu μ取为无风险利率 r r r。按照上述方式我们可以对股票价格变化过程进行抽样。每完成一次对股票价格变化过程的抽样,我们都会得到一个执行时刻 T T T时的股票价格,它对应于一个期权价格。我们可以进行 M M M次股票变化过程的抽样,将每次最终得到的期权价格放在一起取平均值,即为蒙特卡罗模拟计算出的期权价格。
6.2 蒙卡模拟计算欧式期权价格算法
- 确定股票价格离散化变化过程, Δ t = T / N \Delta t = T/N Δt=T/N, ε \varepsilon ε为一个标准正态分布抽样,则
S ( t + Δ t ) = S ( t ) ( 1 + r Δ t + σ ε Δ t ) . S(t+\Delta t) = S(t)(1+r\Delta t+\sigma\varepsilon \sqrt{\Delta t}). S(t+Δt)=S(t)(1+rΔt+σεΔt). - 由初始股票价格 S ( t = 0 ) = S 0 S(t=0)=S_0 S(t=0)=S0开始,使用正态分布随机数产生器产生 ε \varepsilon ε,根据股票价格离散化变化过程计算得股票价格在 Δ t \Delta t Δt时间后的数值。连续抽样计算直到得到执行时刻的股票价格,完成一次股票价格变化过程的抽样。
- 由股票价格变化过程的抽样结果计算出相应欧式期权执行时刻的价格。
- 重复步骤2和3,共 M M M次,将 M M M个得到的期权价格取算术平均值,然后乘以贴现系数 e − r T e^{-rT} e−rT,即得到蒙卡模拟计算欧式期权价格结果。
6.3 算法Python代码实现
import numpy as np
import math
class Monte_Carlo_European_option:
def __init__(self, r, sigma, S_0, K, T, N, M):
self.r = r
self.sigma = sigma
self.S_0 = S_0
self.K = K
self.T = T
self.N = N
self.M = M
self.call_price = None
self.put_price = None
def MC_simulation(self):
self.call_price = 0
self.put_price = 0
dt = self.T/self.N
# 抽样 M 次股价变化过程。
for i in range(self.M):
S = self.S_0
# 股价变化过程由 N 次对正态分布抽样构成。
for j in range(self.N):
S = S*(1+self.r*dt+self.sigma*dt**0.5*np.random.normal())
# 另一种离散化表示:
# S = S*math.e**((self.r-0.5*self.sigma*self.sigma)*dt+self.sigma*dt**0.5*np.random.normal())
self.call_price += max(0, S-self.K)/self.M
self.put_price += max(0, self.K-S)/self.M
self.call_price *= math.e**(-self.r*self.T)
self.put_price *= math.e**(-self.r*self.T)
return
6.4 计算示例
考虑当无风险利率为0.05,股价波动率为0.2,初始股价为90,执行价格为100,执行时间为1年后的欧式期权。取 N = 400 , Δ t = 0.0025 N=400,\, \Delta t= 0.0025 N=400,Δt=0.0025, 进行 M = 40000 M=40000 M=40000次蒙卡模拟股价变化过程,并计算期权价格。
MC_obj = Monte_Carlo_European_option(0.05, 0.2, 90, 100, 1, 400, 40000)
MC_obj.MC_simulation()
print("欧式看涨期权价格:{0:.5f}".format(MC_obj.call_price))
print("欧式看跌期权价格:{0:.5f}".format(MC_obj.put_price))
# 解析解:“欧式看涨期权价格为:5.0912, 欧式看跌期权价格为:10.214” 。
欧式看涨期权价格:5.03626
欧式看跌期权价格:10.13694
6.5 相关说明
6.5.1 股价变化过程离散化
上面我们使用的股价变化的离散化表示为:
S ( t + Δ t ) = S ( t ) ( 1 + r Δ t + σ ε Δ t ) . S(t+\Delta t) = S(t)(1+r\Delta t+\sigma\varepsilon \sqrt{\Delta t}) . S(t+Δt)=S(t)(1+rΔt+σεΔt).
但如果我们认为股价变化的“真实”过程为连续的几何布朗运动,则由
d ln S ( t ) = ( r − 1 2 σ 2 ) d t + σ d z , ln S ( t + Δ t ) − ln S ( t ) = ( r − 1 2 σ 2 ) Δ t + σ ε Δ t . d\ln{S(t)} = (r-\frac{1}{2}\sigma^2)dt+\sigma dz, \\ \ln{S(t+\Delta t)}-\ln{S(t)} = (r-\frac{1}{2}\sigma^2)\Delta t +\sigma\varepsilon \sqrt{\Delta t} . dlnS(t)=(r−21σ2)dt+σdz,lnS(t+Δt)−lnS(t)=(r−21σ2)Δt+σεΔt.
股价变化过程应该为:
S ( t + Δ t ) =