我按照本文中的实现创建了下面的 Matlab 代码来实现欧式看跌期权的价值。我试图绘制 M 的值与欧洲看跌期权的值的关系图,其中 M 以 5 的时间步长从 20 增加到 250。
为了做到这一点,我创建了一个 for 循环来更改 M 的值,
for M = 20:5:250
Run Code Online (Sandbox Code Playgroud)
我认为我需要创建这个 for 循环才能更改 M 的值。单元测试表明我做错了。for 循环未按预期工作。代码生成的图表引用 M 的原始值(定义为 200),而不是 for 循环内 M 的变化值。我不知道为什么代码返回 M 的原始值而不是 for 循环内的值。
clear all;
close all;
% EURO9 Binomial method for a European put.
%
% Uses explicit solution based on binomial expansion.
% Vectorized, based on logs to avoid overflow,
% and avoids computing with zeros.
%%%%%%%%%% Problem and method parameters %%%%%%%%%%%%%
S = 9 ;E = 10 ;T = 3 ;r = 0.06 ;sigma = 0.3 ; M = 200;
dt = T/M ; A = 0.5*(exp(-r*dt)+exp((r+sigma^2)*dt)) ;
u= A + sqrt(A^2-1) ; d = 1/u ; p = (exp(r*dt)-d)/(u-d) ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cut-off index
for M = 20:5:250
z = max(1,min(M+1,floor( log((E*u)/(S*d^(M+1)))/(log(u/d)) )));
% Option values at time T
W=E-S*d.^([M:-1:M-z+1]').*u.^([0:z-1]');
% log/cumsum version using cut-off index z
tmp1 = cumsum(log([1;[M:-1:M-z+2]'])) - cumsum(log([1;[1:z-1]']));
tmp2 = tmp1 + log(p)*([0:z-1]') + log(1-p)*([M:-1:M-z+1]');
value = exp(-r*T)*sum(exp(tmp2).*W);
disp('M is'), disp(M)
disp('Option value is'), disp(value)
hold on;
xlabel('M') % x-axis label
ylabel('European Put') % y-axis label
plot(M,value,'r*')
end
Run Code Online (Sandbox Code Playgroud)
单元测试表明我的代码是错误的。当真实值为 1.5076 时,针对 M=20 进行测试会返回小于 1 的值。
我写的for循环完全错误吗?为什么它在每次迭代时引用 M=200 的值,而不是 for 循环中为 M = 20:5:250 指定的增量?
举个例子,运行
clear all;
close all;
% EURO9 Binomial method for a European put.
%
% Uses explicit solution based on binomial expansion.
% Vectorized, based on logs to avoid overflow,
% and avoids computing with zeros.
%%%%%%%%%% Problem and method parameters %%%%%%%%%%%%%
S = 9 ;E = 10 ;T = 3 ;r = 0.06 ;sigma = 0.3 ; M = 20;
dt = T/M ; A = 0.5*(exp(-r*dt)+exp((r+sigma^2)*dt)) ;
u= A + sqrt(A^2-1) ; d = 1/u ; p = (exp(r*dt)-d)/(u-d) ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cut-off index
z = max(1,min(M+1,floor( log((E*u)/(S*d^(M+1)))/(log(u/d)) )));
% Option values at time T
W=E-S*d.^([M:-1:M-z+1]').*u.^([0:z-1]');
% log/cumsum version using cut-off index z
tmp1 = cumsum(log([1;[M:-1:M-z+2]'])) - cumsum(log([1;[1:z-1]']));
tmp2 = tmp1 + log(p)*([0:z-1]') + log(1-p)*([M:-1:M-z+1]');
value = exp(-r*T)*sum(exp(tmp2).*W);
disp('M is'), disp(M)
disp('Option value is'), disp(value)
Run Code Online (Sandbox Code Playgroud)
回报
Option value is
1.5076
Run Code Online (Sandbox Code Playgroud)
和跑步
clear all;
close all;
% EURO9 Binomial method for a European put.
%
% Uses explicit solution based on binomial expansion.
% Vectorized, based on logs to avoid overflow,
% and avoids computing with zeros.
%%%%%%%%%% Problem and method parameters %%%%%%%%%%%%%
S = 9 ;E = 10 ;T = 3 ;r = 0.06 ;sigma = 0.3 ; M = 25;
dt = T/M ; A = 0.5*(exp(-r*dt)+exp((r+sigma^2)*dt)) ;
u= A + sqrt(A^2-1) ; d = 1/u ; p = (exp(r*dt)-d)/(u-d) ;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cut-off index
z = max(1,min(M+1,floor( log((E*u)/(S*d^(M+1)))/(log(u/d)) )));
% Option values at time T
W=E-S*d.^([M:-1:M-z+1]').*u.^([0:z-1]');
% log/cumsum version using cut-off index z
tmp1 = cumsum(log([1;[M:-1:M-z+2]'])) - cumsum(log([1;[1:z-1]']));
tmp2 = tmp1 + log(p)*([0:z-1]') + log(1-p)*([M:-1:M-z+1]');
value = exp(-r*T)*sum(exp(tmp2).*W);
disp('M is'), disp(M)
disp('Option value is'), disp(value)
Run Code Online (Sandbox Code Playgroud)
回报
Option value is
1.4666
Run Code Online (Sandbox Code Playgroud)
尽管如此,我没有在 M = 20:5:250 的 for 循环图中得到这些值。我一定是在 for 循环中犯了一个错误。
问题在于M. 您M=200在循环开始之前进行了初始化,这会影响您在循环之前进行的所有计算。而在您提供的两个单元测试中,您分别使用M=20和M=25进行所有计算。
M因此,解决方法是简单地移动受循环内部影响的计算。IE
S=9; E=10; T=3; r=0.06; sigma=0.3;
for M = 20:5:250
dt = T/M;
A = 0.5*(exp(-r*dt)+exp((r+sigma^2)*dt)) ;
u = A + sqrt(A^2-1);
d = 1/u;
p = (exp(r*dt)-d)/(u-d);
%And here goes what you already have in your loop
%....
%....
end
Run Code Online (Sandbox Code Playgroud)