蒙特卡洛法与BS模型法分别实现欧式期权定价
并且可以通过逐渐增大蒙特卡洛法的路径数量以及每一条模拟路径的步数(缩小步长)来验证蒙特卡洛方法最终结果会收敛于BS模型计算结果。
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 13 16:57:43 2022
@author: liangshanliao
"""
import math
import numpy as np
from scipy.stats import norm
from numpy.random import standard_normal
import matplotlib.pyplot as plt
#from tqdm import tqdm
# 解决中文显示问题,在开头加入下面一句
plt.rcParams['font.sans-serif'] = ['STLiti'] # 用来正常显示中文标签,字体名称为win中中文字体对应的英文名
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
def MonteCarlo(S0,r,T,K,sigma,M,I):
'''
S0 : 标的资产初始价格
K : 期权执行价格
r : 无风险利率
sigma : 预期波动率
T:到期期限/剩余期限
M :模拟步数
I:模拟路径条数
'''
dt=T/M
S=np.zeros((M+1,I))
S[0]=S0
for t in range(1,M+1):
S[t]=S[t-1]*np.exp((r-0.5*sigma**2)*dt+sigma*np.sqrt(dt)*standard_normal(I))
outcome=sum(np.maximum(0,S[-1]-K))*(np.exp(-r*T))/I
return outcome,S
S_m,S=MonteCarlo(50,0.1,0.5,52,0.4,100,1000)
plt.figure(figsize=(10,8))
plt.hist(S[-1],bins=50)
plt.xlabel(u'到期日时几何布朗运动模拟的股票价格')
plt.ylabel(u'频率')
plt.figure(figsize=(10,8))
plt.plot(S[:100],lw=1.5)
plt.xlabel(u'时间')
plt.ylabel(u'股票价格')
plt.title(u'几何布朗运动下的股票价格路径')
def BS(St,K,sigma,T,r,t):
'''
BS模型计算期权的价格
St:标的资产的价格;
K:期权的执行价格;
sigma:基础资产价格百分比变化的年化波动率;
r:无风险收益率;
T:期权合约最长期限
t:现时期限;
'''
# 计算一些常量
d1=(np.log((St)/K)+(r+0.5*sigma**2)*(T-t))/(sigma*np.sqrt(T-t))
d2=d1-sigma*np.sqrt(T-t)
# if option=='call':
# value=St*norm.cdf(d1)-K*np.exp(-r*(T-t)*norm.cdf(d2))
# elif option=='put':
# value=K*np.exp(-r*(T-t))*norm.cdf(-d2)-(St)*norm.cdf(-d1)
value=St*norm.cdf(d1)-K*np.exp(-r*(T-t))*norm.cdf(d2)
return value
S_bs=BS(50,52,0.4,0.5,0.1,0)
print("蒙特卡洛法计算结果是:",S_m)
print("BS模型计算结果是:",S_bs)