蒙特卡洛期权定价方法Word文件下载.docx
《蒙特卡洛期权定价方法Word文件下载.docx》由会员分享,可在线阅读,更多相关《蒙特卡洛期权定价方法Word文件下载.docx(53页珍藏版)》请在冰豆网上搜索。
但是如果路径依赖型期权,我们就需要整条路径或者至少需要在给定时刻的一系列价值。
如果服从几何布朗运动,情况的处理就非常简单。
事实上,必须认识到在路径生成中有两个误差源:
样本误差、离散误差。
样本错误时因为蒙特卡洛方法的随机性,这个问题可以通过减小方差的办法得到缓解。
为了理解什么是离散错误,我们考虑一个典型的离散连续时间模型,例如:
伊藤随机微分方程:
根据最简单的离散的方法欧拉公式,得到以下离散时间模型:
是离散时间步,且
这种方法在概念上与有限差分类似,并且在确定性微分方程上的应用会产生一个截尾误差,在离散步长很小的时候这个误差可以忽略不计【1】。
当我们讨论随机过程收敛性时是一个非常重要的概念,但是我们可以猜想我们能够通过从标准正态分布中抽取随机变量
来模拟一个与连续时间方程的解密切相关的离散时间随机过程。
随着样本路径和复制次数的增加,我们也就能够减小样本误差。
虽然可以更正式地证明上述理由,但我们应该认识到离散误差至可能改变特征解的概率分布例如,几何布朗运动模型:
欧拉公式
这是非常容易掌握和执行的,但是每个
值的边缘分布比起对数正态分布更普通。
事实上,取很小的
就可以减小误差,但是很费时。
在一个特定的案例中,我们可以通过伊藤引理的一个简单应用来同时消除随机误差,但对大多数情况而言这种方法不可取。
对于复杂的随机微分方程,我们必须生成整条样本路径。
.1模拟几何布朗运动
利用伊藤引理,我们可以把()转换为下面这种形式:
我们还记得,利用对数正态分布性质【2】,令
有:
当完全合并时()非常有用,得到:
为了模拟在时间段(0,T)上的资产价格的路径,我们必须用一个间步长
把时间离散化。
从最后一个等式以及标准Wiener过程(见节),得到
而
是一个标准正态随机变量。
以等式()为基础,很容易生成资产价格的样本路径。
在图中给出了生成服从几何布朗运动的资产价格的样本路径的令。
函数AssetPaths产生一个样本路径矩阵,在这个矩阵里,模拟的资产价格按行存储且每一列类似于一个时间瞬间。
第一列包含了对所有路径来说相同的值和初始价格。
我们必须给这个函数赋值,始价格S0,漂移率mu,波动性sigma,时间范围T,时间步长的数量NSteps,模拟次数NRep1.值得注意的是该函数把参数
作为已知的然后计算参数
例如,生成并且绘制三条为期一年的样本路径,初始价格$50,均值为,标准差(以一年为基础),假定时间步长为一天【3】
绘制的结果如图所示。
如果用另一种状态为randn标准型生成随机数,将会得到不同的结果。
functionSPaths=AssetPaths(S0,mu,sigma,T,NSteps,NRepl)
SPaths=zeros(NRepl,1+NSteps);
SPaths(:
1)=S0;
dt=T/NSteps;
nudt=*sigma^2)*dt;
sidt=sigma*sqrt(dt);
fori=1:
NRepl
forj=1:
NSteps
SPaths(i,j+1)=SPaths(i,j)*exp(nudt+sidt*randn);
end
end
图用蒙特卡洛模拟生成资产价格路径的MATLAB命令
图用蒙特卡洛模拟生成的样本路径
functionSPaths=AssetPathsV(S0,mu,sigma,T,NSteps,NRepl)
Increments=nudt+sidt*randn(NRepl,NSteps);
LogPaths=cumsum([log(S0)*ones(NRepl,1),Increments],2);
SPaths=exp(LogPaths);
Spaths(:
图生成资产价格路径的矢量命令
图中的命令是基于两个循环嵌套。
有时在MATLAB中使用矢量命令会更有效。
为了使用矢量命令,可以便于把等式()重写为
为了对行进行加总(默认的是对列进行加总),我们可以生成资产价格对数的差分然后把可选参数设置为2利用cumsum函数。
函数AssetPathsV的结果如图所示。
值得注意的是在最后一行我们把初始价格写在第一列。
原因如下:
最好避免这个误差(在这里看是微不足道,但以后会发现并不是这样的。
)
我们可以比较这两组实现的速度:
在这种情况下我们不能看出矢量命令的优势。
我们应该注意到处理tic和toc的返回时间是受后台操作系统的许多变量控制的,但是在写这本书的第一版时,矢量命令是有明显的优势的。
并且,事实上,在很多情况下这种优势也是存在的。
问题是硬件和软件(在在这种情况下,MATLAB的解释程序已经有了改进,这个是可以论证的)的改进可能使得一些程序不再适用。
有时一个完全的矢量命令需要很多的矩阵,这不适合计算机的主存储器。
在这种情况下,利用虚拟内存磁盘空间可能会使得运行减缓。
所以我们必须知道所有可能的问题,但是最终是由这个问题的有效率的实证检验所决定的。
模拟套期保值策略
利用函数生成样本路径,我们可以首先为普通的欧式看涨期权比较套期保值策略。
从第二章我们了解到期权价格基本上是一个delta套期保值策略并且对看涨期权来说连续时间的套期保值策略需要持有标的资产的大量
。
一个简单的策略就是止损策略【4】。
这种方法是说当期权价格在执行价格以上时我们需要一个轧平头寸(即买入股票),并且当期权价格在执行价格以下时我们需要一个裸型头寸(即卖出股票)。
在实际操作中,当标的资产的价格高于执行价格K时就买入股票,反之当股票价格低于执行价格K时就卖出股票。
这个方法很直观但是它用在连续时间分析中并不是那么容易的【5】。
尽管如此,我们可以评判这种方法在离散时间中使用蒙特卡洛模拟时的作用。
在离散时间中存在一个执行的问题就是在执行价格我们并不能真正的买卖股票:
当我们发现价格高于临界值时我们买入得价格大大高于K,然而我们卖出股票的价格却是比临界值稍微低一点点。
所以即使不考虑同样会影响delta套期保值的交易费用,在使用止损策略时同样存在一个潜在的问题。
在图中给出了用来估计止损策略的平均成本的一个MATLAB程序。
该函数包括了可能由函数AssetPaths生成的样本路径矩阵。
值得注意的是在这种情况下,在模拟中必须使用的是真正意识上的漂移率mu而不是像期权价格那样。
为了检验这些命令,需要注意这里的步数(时间间隔)等于路径矩阵的列数减一。
如果我们要购买标的股票,就需要把借入的资金考虑在内。
但是一旦假定存在确定且连续的利率,就不需要把借入的资金考虑在内,因为我们能够很容易的记录交易中的现金流量并且把它们折现到t=0时刻,就已经预先把DiscountFactors这些折现因素考虑在内了。
使用一个状态变量Covered去判断执行价格上涨或下跌。
既然在购买股票股票时现金流对购买者来说是负的,而在出售股票时则是正的,那么期权“价格”就通过平均现金流的变动趋势来评价。
同样需要注意在到期日的状况:
如果到期日期权的价格高于执行价格,那么期权持有者就会行权,我们也会得到的是本应该包含在现金流中的执行价格
functionP=StopLoss(S0,K,mu,sigma,r,T,Paths)
[NRepl,NSteps]=size(Paths);
NSteps=NSteps-1;
%truenumberofsteps
Cost=zeros(NRepl,1);
DiscountFactors=exp(-r*(0:
1:
NSteps)*dt);
fork=1:
CashFlows=zeros(NSteps+1,1);
if(Paths(k,1)>
=K)
Covered=1;
CashFlows
(1)=-Paths(k,1);
else
Covered=0;
fort=2:
NSteps+1
if(Covered==1)&
(Paths(k,t)<
K)
%Sell
CashFlows(t)=Paths(k,t);
elseif(Covered==0)&
(Paths(k,t)>
%Buy
CashFlows(t)=-Paths(k,t);
ifPaths(k,NSteps+1)>
=K
%Optionisexercised
CashFlows(NSteps+1)=...
CashFlows(NSteps+1)+K;
Cost(k)=-dot(DiscountFactors,CashFlows);
P=mean(Cost);
图估计止损策略的平均成本的MATLAB程序
既然我们知道有时候用矢量命令更方便,那么在图中我们也用矢量命令表示出来了。
这里主要的不同之处是使用了变量OldPrice,它本质上是节点路径的转换复制,在节点处价格处于临界状态,上涨或者下跌。
价格上升的次数我们用UpTimes来记录,上升时现金流对持有者是不利得;
同理用DownTimes来记录下跌的次数。
functionP=StopLossV(S0,K,mu,sigma,r,T,Paths)
CashFlows=zeros(NRepl,NSteps+1);
OldPrice=[zeros(NRepl,1),Paths(:
1:
NSteps)];
UpTimes=find(OldPrice<
K&
Paths>
=K);
DownTimes=find(OldPrice>
=K&
Paths<
K);
CashFlows(UpTimes)=-Paths(UpTimes);
CashFlows(DownTimes)=Paths(DownTimes);
ExPaths=find(Paths(:
NSteps+1)>
CashFlows(ExPaths,NSteps+1)=CashFlows(ExPaths,NSteps+1)+K;
Cost=-CashFlows*DiscountFactors'
;
图止损套期保值策略的矢量命令
现在我们可以检验这两个程序是否是一致的,以及矢量是否存在优势。
不同于资产路径的生成在这里我们可以从矢量命令中看出优势。
使用矢量程序生成资产路径我们也可以在这里发现为什么正确分配初始资产价格很可能很重要,正如我们在图最后一行命令中所做的那样。
在这种情况下期权的价格正好符合这个价格,那么我们总是会购买初始股票;
但是如果初始股票价格使我们则不够买股票,并且一个在这个过程中一个明显的但被忽略的误差已经产生了很严重的后果。
functionP=DeltaHedging(S0,K,mu,sigma,r,T,Paths)
CashFlows=zeros(1,NSteps+1);
Path=Paths(i,:
);
Position=0;
Deltas=blsdelta(Path(1:
NSteps),K,r,T-(0:
NSteps-1)*dt,sigma);
NSteps;
CashFlows(j)=(Position-Deltas(j))*Path(j);
Position=Deltas(j);
ifPath(NSteps+1)>
K
CashFlows(NSteps+1)=K-(1-Position)*Path(NSteps+1);
CashFlows(NSteps+1)=Position*Path(NSteps+1);
Cost(i)=-CashFlows*DiscountFactors'
图估计delta套期保值策略
现在我们应该比较止损策略的成本、delta套期保值策略的成本以及理论的期权价格。
估计delta套期保值策略的平均成本的程序已经在图中给出了。
这个程序跟止损策略有点类似,但它不是向量。
在样本路径每一个点上为了获得期权
而调用函数blsdelta时使用的向量是我们所处理过的唯一的向量。
注意必须用趋于到期日的当前资产价格和当前时间来计算
;
我们使用金融工具blsdelta函数。
给
赋一个新的值就会更新股票的当前Position,也会产生没有被考虑在内的现金流。
图给出了比较两个套期保值策略作用的脚本。
运行这个脚本,我们可以得到以下的结果:
%
S0=50;
K=52;
mu=;
sigma=;
r=;
T=5/12;
NRepl=10000;
NSteps=10;
C=blsprice(S0,K,r,T,sigma);
fprintf(1,'
%s%f\n'
'
trueprice='
C);
%
randn('
state'
0);
Paths=AssetPaths(S0,mu,sigma,T,NSteps,NRepl);
SL=StopLossV(S0,K,mu,sigma,r,T,Paths);
costofstop/loss(S)=%f\n'
SL);
DC=DeltaHedging(S0,K,mu,sigma,r,T,Paths);
costofdelta-hedging=%f\n'
DC);
NSteps=100;
图比较套期保值策略的脚本
在第一组运行中我们使用十个套期保值步骤,在第二组中使用100个套期保值步骤。
我们发现止损策略不像delta套期保值成本那样收敛于真实的期权价格。
事实上,需要在不同的设置下进行这种比较,并且也应该包括该套期保值成本的可变性。
布朗桥
在前面几节中,我们依据收益与时间密切相关的自然过程生成了一个资产路径。
事实上,Wiener过程倾向于一些能够用不同的方法生成样本路径的特殊性质。
假如有一个左边和右边的终点分别为
和
的时间间隔且存在一个中间瞬时时间
,使得
在生成的标准路径中,我们能够很自然地生成Wiener过程:
以及最终的
利用所谓的布朗桥,我们可以在条件
及
处生成
可以看出在这两个值的条件下
是一个正常变量,其期望值为
方差为
这是由多元正态分布的条件分布的一些性质所决定的。
以上这些公式【6】都是很直观的,我们就不必要再去证明了。
的条件期望值是通过
线性插值求出的;
方差在两个端点
附近较小,在整个时间间隔中间确实最大值。
利用布朗桥,我们可以通过二分法生成样本路径。
假定
,抽取样本
再次抽取样本
,抽样
,等等。
实际上,我们可以用非均匀时间步骤生成我们想要的任何序列样本路径。
有人也许会问为什么如此复杂的结构却这么有用。
至少有以下两点原因:
它可以通过分层使得方差减小。
在多维中运用分层很困难,但是我们可以对资产价格终值进行分层,并且可以利用其中点对其进行分层。
然后利用布朗桥生成中间值。
在低差异序列结合中布朗桥构造也很有用。
在节中我们发现简单低差异序列在高纬定义域内运用很困难,因为不能完全包含一些维度。
利用布朗桥,我们可以通过以样本点作为基点用高效率序列去描述Wiener过程路径;
然后我们用其他序列甚至是蒙特卡洛抽样来填补路径。
在图中给出了用布朗桥的方法生成标准Wiener过程路径的一个MATLAB程,但是只有在二等分的时间间隔[0,T](例如,时间间隔的数量是2的幂)这种特殊例子中才适用;
在更多通常的设置中可能适用。
在这种情况之下,我们可以把上面的公式简化为样本
如果令
,则有
其中,Z服从标准正态分布。
在这个程序中假定时间间隔T的长度和把程序分隔开来次间隔的NSteps数量,并且这个程序运行出一个包含一条样本路径的向量。
假定时间间隔次数为8(必须是2的幂)。
那么我们就必须执行3次二等分。
给定初始条件
,必须先抽取样本
,即是跳过一个长度为T的时间间隔,在这个程序中即为TJump。
因为我们输入了9个要素矢量值(从index1开始,包括
),为了输入新的值,我们必须跳过矢量中的八个值。
跳过的值的数量是记为
然后我们开始第一个循环。
在第一阶段,只能抽取样本
,给定
给定状态
,我们必须生成一个新的值并且在状态
中保存起来,
在本例中即为4+1=5。
在这里我们只生成了一个值,并且把两个跳跃都除以2。
在第二次迭代中,我们必须抽取样本
将会执行两次嵌套循环,且指数left,right和i都会增加4。
在第三次和最后一次迭代中生成了剩余四个值。
我们要求读者通过这个程序逐步利用调试器来验证以上我们所说的模式。
在图我们也给出了验证所生成的随机过程的边缘分布式正确的的脚本。
期望值应该为0,标准差应该为时间的平方根:
我们发现出去样本误差,这个结果看起来是正确的。
给定一个生成标准Wiener过程的方法,很容易就可以模拟出几何布朗运动。
在图中给出了这个程序,并且使用了一种类似于矢量方法中的AssetPathsV.值得注意的一点是使用函数diff在对数资产价格中生成矢量Increments.事实上在标准蒙特卡洛中我们用连续递增生成基本Wiener过程;
利用布朗桥结构在不同的瞬时时间我们很直接的得出了这个过程的不同值,且必须使用函数diff去取得相对差异。
在一些情况之下,diff与cumsum起相反的作用,从以下这个例子中我们可以看出来:
NRepl=100000;
T=1;
NSteps=4;
WSamples=zeros(NRepl,1+NSteps);
WSamples(i,:
)=WienerBridge(T,NSteps);
m=mean(WSamples(:
2:
(1+NSteps)))
sdev=sqrt(var(WSamples(:
(1+NSteps))))
sqrt((1:
NSteps).*T/NSteps)
图检验利用布朗桥为标准Wiener过程生成的路径
functionSPaths=GBMHaltonBridge(S0,mu,sigma,T,NSteps,NRepl)
ifround(log2(NSteps))~=log2(NSteps)
fprintf('
ERRORinGBMBridge:
NStepsmustbeapowerof2\n'
return
SPaths=zeros(NRepl,NSteps+1);
W=WienerHaltonBridge(T,NSteps,NRepl);
Increments=nudt+sigma*diff(W);
LogPath=cumsum([log(S0),Increments]);
SPaths=exp