奇异期权

奇异期权

Monte-Carlo 定价

Python

import scipy
import math
import numpy as np

# Initial
S0=100;K=100;R=0.03;T=1;N=100;M=10000;sigma=0.3
# N:路径的长度
# M:路径/模拟的条数
np.random.seed(1)

# 构建模拟路径
paths=np.zeros((M,N),dtype=float,order='c')
for j in range(M):
paths[j,0]=np.random.normal(loc=0,scale=1,size=1)*np.sqrt(T/N)*sigma*S0 + T/N *R*S0 +S0
for i in range(1,N):
for j in range(M):
paths[j,i]=np.random.normal(loc=0,scale=1,size=1)*np.sqrt(T/N)*sigma*paths[j,i-1] + T/N *R*paths[j,i-1] +paths[j,i-1]

# Asian Call Option
def asian_call_option(S0,K,R,T,N,M,sigma):
c_asian_call = math.exp(-R * T) * np.sum(np.maximum(np.sum(paths,axis=1)/N - K, 0))/M
print("c_asian_call=",c_asian_call)
return
asian_call_option(S0=100,K=100,R=0.03,T=1,N=100,M=10000,sigma=0.3) # 7.591412137835365

# Fixed Lookback Call Option
def fixed_lookback_call_option(S0,K,R,T,N,M,sigma):
c_fixed_lookback_call = math.exp(-R * T) * np.sum(np.maximum(np.max(paths,axis=1) - K, 0))/M
print("c_fixed_lookback_call=",c_fixed_lookback_call)
return
fixed_lookback_call_option(S0=100,K=100,R=0.03,T=1,N=100,M=10000,sigma=0.3) # 25.463098827823984

# Knock-Out Call Option
def knock_out_call_option(S0,K,R,T,N,M,sigma,knock_price):
paths_barrier=np.zeros((M,N),dtype=float,order='c')
paths_barrier[:,0]=paths[:,0]
for j in range(M):
for i in range(1,N):
if paths[j,i]>knock_price:
paths_barrier[j,i]=paths[j,i]
else:
break
c_barrier_call = math.exp(-R * T) * np.sum(np.maximum(paths_barrier[:,-1] - K, 0))/M
print("c_barrier_call=",c_barrier_call)
return
knock_out_call_option(S0=100,K=100,R=0.03,T=1,N=100,M=10000,sigma=0.3,knock_price=80) # 12.51125308933265

R

# Initial
S0 = 100
K = 100
R = 0.03
T = 1
N = 100
M = 10000
SIGMA = 0.3
set.seed(865)

# 构建模拟路径
PATHS = data.frame(matrix(NA, nrow = M, ncol= N))
for (J in 1:M)
{
PATHS[J,1] = rnorm(1)*sqrt(T/N)*SIGMA*S0 + T/N*R*S0 + S0
}
for (I in 2:N)
{
for (J in 1:M)
{
PATHS[J,I] = rnorm(1)*sqrt(T/N)*SIGMA*PATHS[J,I-1] + T/N*R*PATHS[J,I-1] + PATHS[J,I-1]
}
}

# European Call Option: Shown as an Example
payoff_euro_call = PATHS[,N]-K
for (J in 1:M)
{
payoff_euro_call[J] = max(payoff_euro_call[J],0)
}
c_euro_call = exp(-R*T)*mean(payoff_euro_call)
c_euro_call

# Asian Call Option
payoff_asian_call=(rowSums(PATHS[,1:N])/N)-K
for (J in 1:M)
{
payoff_asian_call[J] = max(payoff_asian_call[J],0)
}
c_asian_call=exp(-R*T)*mean(payoff_asian_call)
c_asian_call

# Fixed Lookback Call Option
PATHS_max=matrix()
payoff_lookback_call=matrix()
for (i in 1:nrow(PATHS)) {
PATHS_max[i]=max(PATHS[i,1:N])
payoff_lookback_call[i] = PATHS_max[i]-K
}
for (J in 1:M)
{
payoff_lookback_call[J] = max(payoff_lookback_call[J],0)
}
c_lookback_call = exp(-R*T)*mean(payoff_lookback_call)
c_lookback_call

# Knock-out Call Option
knock_price=80
PATHS_Barrier=data.frame(matrix(0, nrow = M, ncol= N))
for (J in 1:M)
{
PATHS_Barrier[J,1] = PATHS[J,1]
}

for (J in 1:M)
{
for (I in 2:N)
{
if(PATHS[J,I]>80){PATHS_Barrier[J,I] = PATHS[J,I]}
else break
}
}
payoff_knockout_call = PATHS_Barrier[,N]-K
for (J in 1:M)
{
payoff_knockout_call[J] = max(payoff_knockout_call[J],0)
}
c_knockout_call = exp(-R*T)*mean(payoff_knockout_call)
c_knockout_call