概述
导航
- 基本原理
- 对数正态分布的随机变量模拟
- 案例
- 欧式期权定价
- 案例
- 对冲参数计算
- 案例
- 参考资料
基本原理
在风险中性的世界里,首先随机产生标的资产价格的可能路径,并由此计算期权收益的期望值,然后再以无风险利率贴现计算价格.
考虑某个与标的变量
θ
theta
θ相关的衍生证券,该衍生证券在时刻
T
T
T产生收益,如果利率为常数,计算衍生证券价格步骤如下:
- 在风险中性世界对变量 θ theta θ进行路径模拟.
- 计算衍生证券的收益.
- 多次模拟,计算均值近似衍生证券的价格
- 贴现计算
设风险中性世界中标的变量
θ
theta
θ服从标准差为
s
s
s,预期收益率为
m
˘
breve{m}
m˘的几何布朗运动
d
θ
=
m
˘
θ
d
t
+
s
θ
ε
d
t
dtheta=breve{m}theta dt+sthetavarepsilonsqrt{dt}
dθ=m˘θdt+sθεdt
离散化方程得到
Δ
θ
=
m
˘
θ
Δ
t
+
s
θ
ε
Δ
t
Deltatheta=breve{m}thetaDelta t+sthetavarepsilonsqrt{Delta t}
Δθ=m˘θΔt+sθεΔt
如果存在多个标的变量,定义
s
i
s_i
si为标准差,
m
^
i
hat{m}_i
m^i是风险中性世界中的预期收益率
ρ
i
j
rho_{ij}
ρij是
θ
i
theta_i
θi和
θ
j
theta_j
θj的瞬间相关系数,
θ
i
theta_i
θi的离散过程形式为
Δ
θ
i
=
m
^
i
θ
i
Δ
t
+
s
i
θ
i
ε
i
Δ
t
Delta theta_i=hat{m}_itheta_iDelta t+s_itheta_ivarepsilon_isqrt{Delta t}
Δθi=m^iθiΔt+siθiεiΔt
每次模拟需要从多维标准正态分布中随机抽取
ε
i
(
1
≤
i
≤
n
)
varepsilon_i(1leq ileq n)
εi(1≤i≤n)的
N
N
N个样本.
对数正态分布的随机变量模拟
对标的变量
S
S
S的对数
ln
S
ln S
lnS的抽样一般比对
S
S
S的直接抽样更加精确,由伊藤引理得到
d
ln
S
=
(
r
−
σ
2
2
)
d
t
+
σ
ε
d
t
dln S=(r-frac{sigma^2}{2})dt+sigmavarepsilonsqrt{dt}
dlnS=(r−2σ2)dt+σεdt
离散形式为
ln
S
t
+
1
−
ln
S
t
=
(
r
−
σ
2
2
)
Δ
t
+
σ
ε
Δ
t
ln S_{t+1}-ln S_{t}=(r-frac{sigma^2}{2})Delta t+sigmavarepsilonsqrt{Delta t}
lnSt+1−lnSt=(r−2σ2)Δt+σεΔt
可以计算出
S
T
=
S
t
exp
[
(
r
−
σ
2
2
)
(
T
−
t
)
+
σ
ϵ
T
−
t
]
S_T=S_texp[(r-frac{sigma^2}{2})(T-t)+sigmaepsilonsqrt{T-t}]
ST=Stexp[(r−2σ2)(T−t)+σϵT−t]
案例
假设标的资产当前价格为10,无风险利率为
1
%
1%
1%,年波动率为
30
%
30%
30%,距离下一时刻6个月,计算下一时刻资产的价格.
解析:
由
S
t
=
10
,
r
=
0.01
,
σ
=
0.3
,
σ
=
0.3
,
Δ
t
=
0.5
S_t=10, r=0.01, sigma=0.3, sigma=0.3, Delta t=0.5
St=10,r=0.01,σ=0.3,σ=0.3,Δt=0.5计算得到
S
t
+
1
=
S
t
exp
[
(
r
−
σ
2
2
)
Δ
t
+
σ
ε
Δ
t
]
S_{t+1}=S_texp[(r-frac{sigma^2}{2})Delta t+sigmavarepsilonsqrt{Delta t}]
St+1=Stexp[(r−2σ2)Δt+σεΔt]
cpp
代码:
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<cassert>
#include<iomanip>
#include<random>
#include<map>
using namespace std;
const double pi=3.1415926;
default_random_engine dre; // 随机数引擎
const int N=10000;
double rv(){
normal_distribution<double> nd;
double ans=0.00;
for(int i=0; i<N; ++i) ans+=nd(dre)/N;
return ans;
}
double simulate_rv(const double &S, const double &r, const double &sigma, const double &tm){
double R=(r-0.5*pow(sigma, 2))*tm;
double SD=sigma*sqrt(tm);
return S*exp(R+SD*rv());
}
int main(){
double S=10;
double r=0.01;
double sigma=0.3;
double tm=0.5;
cout<<"下一时刻资产的价格:"<<simulate_rv(S, r, sigma, tm)<<endl;
}
python
代码
from scipy.stats import norm as N
from scipy.stats import multivariate_normal as mvn
from math import log, exp, pi
import numpy as np
def sample():
n=1000
return np.sum(np.random.normal(0, 1, size=n))/n
def sim_price(S, r, sigma, tm):
return S*exp((r-sigma**2/2)*tm+sigma*sqrt(tm)*sample())
print('下一时刻资产标的价格为 {}'.format(sim_price(10, 0.01, 0.3, 0.5)))
欧式期权定价
对于标的资产价格为
S
0
S_0
S0,行权价格为
K
K
K的欧式看涨期权,在期权到期日
T
T
T的价格为
c
T
=
max
{
0
,
S
T
−
K
}
c_T=max{0, S_T-K}
cT=max{0,ST−K}
在风险中性世界中,使用无风险利率
r
r
r进行贴现,得到期权在
t
t
t时刻的价格为
c
t
=
e
−
r
(
T
−
t
)
E
(
max
{
0
,
S
T
−
K
}
)
c_t=e^{-r(T-t)}mathbb{E}(max{0, S_T-K})
ct=e−r(T−t)E(max{0,ST−K})
使用模拟算法计算得到欧式看涨期权价格
c
^
t
=
e
−
r
(
T
−
t
)
n
∑
i
=
1
n
E
(
max
{
0
,
S
T
i
−
K
}
)
hat{c}_t=frac{e^{-r(T-t)}}{n}sum_{i=1}^nmathbb{E}(max{0, S_{T_i}-K})
c^t=ne−r(T−t)i=1∑nE(max{0,STi−K})
欧式看跌期权价格
p
^
t
=
e
−
r
(
T
−
t
)
n
∑
i
=
1
n
E
(
max
{
K
−
S
T
i
,
0
}
)
hat{p}_t=frac{e^{-r(T-t)}}{n}sum_{i=1}^nmathbb{E}(max{K-S_{T_i}, 0})
p^t=ne−r(T−t)i=1∑nE(max{K−STi,0})
案例
考虑不支付红利股票的欧式看涨期权和看跌期权,它们的标的资产价格是100,行权价格是100,无风险利率是10%,年波动率是25%,期权有效期为1年,使用BS公式和蒙特卡洛模拟计算价格
解析:
可得
S
=
100
,
K
=
100
,
r
=
10
%
,
σ
=
25
%
,
T
−
t
=
1
S=100, K=100, r=10%, sigma=25%, T-t=1
S=100,K=100,r=10%,σ=25%,T−t=1
模拟标的资产价格路径
S
T
i
=
S
t
exp
[
(
r
−
σ
2
2
)
(
T
−
t
)
+
σ
ε
T
−
t
]
S_{T_i}=S_texp[(r-frac{sigma^2}{2})(T-t)+sigmavarepsilonsqrt{T-t}]
STi=Stexp[(r−2σ2)(T−t)+σεT−t]
抽取样本
ε
varepsilon
ε,计算
S
T
i
S_{T_i}
STi,计算
max
{
0
,
S
T
i
−
K
}
max{0, S_{T_i}-K}
max{0,STi−K}或者
max
{
K
−
S
T
i
,
0
}
max{K-S_{T_i}, 0}
max{K−STi,0}, 多次模拟计算均值进行近似
cpp
计算代码
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<cassert>
#include<iomanip>
#include<random>
#include<map>
using namespace std;
const double pi=3.1415926;
default_random_engine dre; // 随机数引擎
normal_distribution<double> nd; // 标准正态分布
const int n=5000000; // 模拟次数
double N(const double &x){
if(x>6.0) return 1.0;
if(x<-6.0) return 0.0;
double b1=0.31938153;
double b2=-0.356563782;
double b3=1.781477937;
double b4=-1.821255978;
double b5=1.330274429;
double p=0.2316419;
double c=1.0/sqrt(2*pi);
double a=fabs(x);
double k=1.0/(1+a*p);
double b=c*exp(-pow(x, 2)/2.0);
double n=((((b5*k+b4)*k+b3)*k+b2)*k+b1)*k;
n=1.0-b*n;
if(x<0.0) n=1.0-n;
return n;
}
void BSprice(const double& S, const double& K, const double& r, const double& sigma, const double& tm){
double d1=(log(S/K)+(r+pow(sigma, 2)/2))/(sigma*sqrt(tm));
double d2=d1-sigma*sqrt(tm);
double c=S*N(d1)-K*exp(-r*tm)*N(d2);
double p=K*exp(-r*tm)*N(-d2)-S*N(-d1);
cout<<"BS公式计算欧式看涨期权:"<<c<<endl;
cout<<"BS公式计算欧式看跌期权:"<<p<<endl;
}
void simulate_rv(const double &S, const double &K, const double &r, const double &sigma, const double &tm){
double R=(r-0.5*pow(sigma, 2))*tm;
double SD=sigma*sqrt(tm);
double call_price=0.00;
double put_price=0.00;
for(int i=0; i<n; ++i){
double ST=S*exp(R+SD*nd(dre));
call_price+=max(ST-K, 0.00)/n;
put_price+=max(K-ST, 0.00)/n;
}
cout<<"模拟法计算看涨期权价格为:"<<call_price*exp(-r*tm)<<endl;
cout<<"模拟法计算看跌期权价格为:"<<put_price*exp(-r*tm)<<endl;
}
int main(){
double S=100, K=100, r=0.1, sigma=0.25, tm=1;
simulate_rv(S, K, r, sigma, tm);
BSprice(S, K, r, sigma, tm);
}
对冲参数计算
欧式看涨期权的
Δ
Delta
Δ是其他变量不变时,期权价格对标的资产价格的一阶偏导数
Δ
=
f
(
S
+
q
,
K
,
r
,
σ
,
T
−
t
)
−
f
(
S
,
K
,
r
,
σ
,
T
−
t
)
q
Delta=frac{f(S+q,K,r,sigma,T-t)-f(S,K,r,sigma,T-t)}{q}
Δ=qf(S+q,K,r,σ,T−t)−f(S,K,r,σ,T−t)
案例
分别使用BS公式和模拟法计算上例中的
Δ
Delta
Δ.
解析:
根据公式
S
T
=
S
t
exp
[
(
r
−
σ
2
2
)
(
T
−
t
)
+
σ
ε
T
−
t
]
S
T
′
=
(
S
t
+
q
)
exp
[
(
r
−
σ
2
2
)
(
T
−
t
)
+
σ
ε
T
−
t
]
S_T=S_texp[(r-frac{sigma^2}{2})(T-t)+sigmavarepsilonsqrt{T-t}]\ S_T'=(S_t+q)exp[(r-frac{sigma^2}{2})(T-t)+sigmavarepsilonsqrt{T-t}]
ST=Stexp[(r−2σ2)(T−t)+σεT−t]ST′=(St+q)exp[(r−2σ2)(T−t)+σεT−t]
取
q
=
0.01
S
t
q=0.01S_t
q=0.01St进行模拟.
c++
计算代码
#include<iostream>
#include<vector>
#include<cmath>
#include<cstring>
#include<cassert>
#include<iomanip>
#include<random>
#include<map>
using namespace std;
const double pi=3.1415926;
default_random_engine dre; // 随机数引擎
normal_distribution<double> nd; // 标准正态分布
const int n=50000; // 模拟次数
double N(const double &x){
if(x>6.0) return 1.0;
if(x<-6.0) return 0.0;
double b1=0.31938153;
double b2=-0.356563782;
double b3=1.781477937;
double b4=-1.821255978;
double b5=1.330274429;
double p=0.2316419;
double c=1.0/sqrt(2*pi);
double a=fabs(x);
double k=1.0/(1+a*p);
double b=c*exp(-pow(x, 2)/2.0);
double n=((((b5*k+b4)*k+b3)*k+b2)*k+b1)*k;
n=1.0-b*n;
if(x<0.0) n=1.0-n;
return n;
}
double BS_delta(const double& S, const double& K, const double& r, const double& sigma, const double& tm){
double d1=(log(S/K)+(r+pow(sigma, 2)/2))/(sigma*sqrt(tm));
return N(d1);
}
double simulate_delta(const double &S, const double &K, const double &r, const double &sigma, const double &tm){
double R=(r-0.5*pow(sigma, 2))*tm;
double SD=sigma*sqrt(tm);
double call=0.00;
double call_q=0.00;
double q=S*0.01;
for(int i=0; i<n; ++i){
double Z=nd(dre);
double ST=S*exp(R+SD*Z);
call+=max(ST-K, 0.00)/n;
double STq=(S+q)*exp(R+SD*Z);
call_q+=max(STq-K, 0.00)/n;
}
call=exp(-r*tm)*call;
call_q=exp(-r*tm)*call_q;
return (call_q-call)/q;
}
int main(){
double S=100, K=100, r=0.1, sigma=0.25, tm=1;
double bs_delta=BS_delta(S, K, r, sigma, tm);
double sim_delta=simulate_delta(S, K, r, sigma, tm);
cout<<"BS公式计算Delta:"<<bs_delta<<endl;
cout<<"模拟法计算Delta: "<<sim_delta<<endl;
}
参考资料
金融资产定价理论与数值计算 北京大学出版社 田文昭
最后
以上就是乐观帆布鞋为你收集整理的【FinE】蒙特卡洛模拟(1)基本原理对数正态分布的随机变量模拟欧式期权定价对冲参数计算参考资料的全部内容,希望文章能够帮你解决【FinE】蒙特卡洛模拟(1)基本原理对数正态分布的随机变量模拟欧式期权定价对冲参数计算参考资料所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复