蒙特卡洛法的基本思想为:在风险中性的世界里,随机产生标的资产价格的可能路径,由此获得期权收益的期望值,然后再对其以无风险利率进行贴现,得到期权的价格。
详细推导可查看:
参考文章:https://mp.weixin.qq.com/s/qTBuCSAmCc39G2nDfUDgmQ
首先我们需要通过蒙特卡洛模拟法模拟股价走势。
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import pandas as pd
import math
'''
s:股票现价
t:期限(年)
r:无风险利率(年)
sigma:股票年化波动率
N:每年的期数
M:模拟次数
'''
def generate_simulated_stock_returns(t,r,sigma,N):
a1=[]
dt=1/N
term = int(t*N)
for i in range (1, term+1):
z=np.random.normal()
simulated_return = (r-(sigma**2/2))*dt + z*sigma*(dt**(1/2))
a1.append(simulated_return)
array_return=np.array(a1)
return array_return
def generate_simulated_stock_values(s,t,r,sigma,N):
rate=generate_simulated_stock_returns(t,r,sigma,N)
stock_price = [s]
term = int(t*N)
for i in range(1, term+1):
values = stock_price[i-1]*math.e**(rate[i-1])
stock_price.append(values)
array_price = np.array(stock_price)
return array_price
欧式看涨期权的定价:
C = M a x ( S t − X , 0 ) e − r t C = Max(S_t-X,0)e^{-rt} C=Max(St−X,0)e−rt
def MCEuroCallOptionValue(s,x,t,r,sigma,N,M):
call_prices = []
for i in range(M):
stock_price = generate_simulated_stock_values(s,t,r,sigma,N)[-1]
call_price = max(stock_price-x,0)*np.exp(-r*t)
call_prices.append(call_price)
price_mean = np.mean(call_prices)
return price_mean
def BSEuroCallOptionValue(s,x,t,r,sigma):
d1 = (math.log(s/x)+(r+sigma**2/2)*t)/(sigma*math.sqrt(t))
d2 = d1-sigma*math.sqrt(t)
c = s*stats.norm.cdf(d1)-x*math.exp(-r*t)*stats.norm.cdf(d2)
return c
mc_price = MCEuroCallOptionValue(90, 100, 1, 0.1, 0.3, 100, 1000)
print(mc_price)
bs_price = BSEuroCallOptionValue(90, 100, 1, 0.1, 0.3)
print(bs_price)
9.84671058110504
10.51985812604488
欧式看跌期权的定价:
P = M a x ( X − S t , 0 ) e − r t P = Max(X-S_t,0)e^{-rt} P=Max(X−St,0)e−rt
def MCEuroPutOptionValue(s,x,t,r,sigma,N,M):
put_prices = []
for i in range(M):
stock_price = generate_simulated_stock_values(s,t,r,sigma,N)[-1]
put_price = max(x-stock_price,0)*np.exp(-r*t)
put_prices.append(put_price)
price_mean = np.mean(put_prices)
return price_mean
def BSEuroPutOptionValue(s,x,t,r,sigma):
d1 = (math.log(s/x)+(r+sigma**2/2)*t)/(sigma*math.sqrt(t))
d2 = d1-sigma*math.sqrt(t)
p = x*math.exp(-r*t)*stats.norm.cdf(-d2)-s*stats.norm.cdf(-d1)
return p
mc_price = MCEuroPutOptionValue(100, 100, 1.0, 0.1, 0.3, 100, 10000)
print(mc_price)
bs_price = BSEuroPutOptionValue(100, 100, 1.0, 0.1, 0.3)
print(bs_price)
7.217875385982609
亚式期权的收益依附于标准的资产有效期至少一段时间内的平均价格,亚式期权可分为平均价期权和平均执行价格期权。
亚式期权应用于股票期权报酬有两个作用:
1、避免人为炒作股票价格。
2、减少公司员工进行内幕交易、损害公司利益的行为。
亚式看涨期权的定价:
C = M a x ( A v e r a g e ( S ) − X , 0 ) e − r t C = Max(Average(S)-X,0)e^{-rt} C=Max(Average(S)−X,0)e−rt
def MCAsianCallOptionValue(s,x,t,r,sigma,N,M):
call_prices = []
for i in range(M):
stock_price = np.mean(generate_simulated_stock_values(s,t,r,sigma,N))
call_price = max(stock_price-x,0)*np.exp(-r*t)
call_prices.append(call_price)
price_mean = np.mean(call_prices)
return price_mean
acall_price = MCAsianCallOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(acall_price)
9.494626161093787
亚式看跌期权的定价:
P = m a x ( X − A v e r a g e ( S ) , 0 ) e − r t P = max(X-Average(S),0)e^{-rt} P=max(X−Average(S),0)e−rt
def MCAsianPutOptionValue(s,x,t,r,sigma,N,M):
put_prices = []
for i in range(M):
stock_price = np.mean(generate_simulated_stock_values(s,t,r,sigma,N))
put_price = max(x-stock_price,0)*np.exp(-r*t)
put_prices.append(put_price)
price_mean = np.mean(put_prices)
return price_mean
aput_price = MCAsianPutOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(aput_price)
4.462073414456472
回望期权(Lookback Options),是指回报不仅取决于标的资产的执行价格,同时还取决于期权续存期内标的资产的最高价或者最低价的期权。回望期权在到期时要回望过去标的资产的表现,其收益支付结构与合约期间标的资产价格所达到的最大值或者最小值相关,和很多奇异期权一样,回望期权也是路径依赖的一种期权。
**回望期权可以根据执行价格是固定还是浮动的分成以下几种:**分别是固定执行价格的回望看涨期权、固定执行价格的回望看跌期权、浮动执行价格的回望看涨期权和浮动执行价格的回望看跌期权。
固定执行价格的看涨期权和看跌期权在合约到期时的执行价格是固定的,和普通的期权无异,以期权持有期内标的资产所达到的最高价格和最低价格作为到期日价格;
而浮动执行价格的回望看涨期权和看跌期权则选取的是合约期间标的资产的最低价格和最高价格作为期权的执行价格,标的资产的价格用的仍旧是到期日的价格。
回望看涨期权的定价:
C = M a x ( M a x ( S ) − X , 0 ) e − r t C = Max(Max(S)-X,0)e^{-rt} C=Max(Max(S)−X,0)e−rt
def MCLookbackCallOptionValue(s,x,t,r,sigma,N,M):
call_prices = []
for i in range(M):
stock_price = max(generate_simulated_stock_values(s,t,r,sigma,N))
call_price = max(stock_price-x,0)*np.exp(-r*t)
call_prices.append(call_price)
price_mean = np.mean(call_prices)
return price_mean
lcall_price = MCLookbackCallOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(lcall_price)
29.63502178494703
回望看跌期权的定价:
P = M a x ( X − M i n ( S ) , 0 ) e − r t P = Max(X-Min(S),0)e^{-rt} P=Max(X−Min(S),0)e−rt
def MCLookbackPutOptionValue(s,x,t,r,sigma,N,M):
put_prices = []
for i in range(M):
stock_price = min(generate_simulated_stock_values(s,t,r,sigma,N))
put_price = max(x-stock_price,0)*np.exp(-r*t)
put_prices.append(put_price)
price_mean = np.mean(put_prices)
return price_mean
lput_price = MCLookbackPutOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(lput_price)
15.536862634356844