Sie sind auf Seite 1von 5

function [call,put,bdata,u] = blspricefdam(SO,X,r,T,sig,q,M,N)

%
%BLSPRICEFDAM Black-Scholes put and call pricing for American Options using
% the Crank-Nicholson finite difference solution of Black-Scholes
% Partial differential equation. Note that this function
% returns an approximate solution unlike the analytical solution (BLSPRICE
)
%
%
% [CALL,PUT] = BLSPRICEFDAM(SO,X,R,T,SIG,Q,M,N) returns the value of
% call and put options using the Black-Scholes pricing formula. SO is
% the current asset price, X is the exercise price, R is the risk-free
% interest rate, T is the time to maturity of the option in years, SIG
% is the standard deviation of the annualized continuously compounded
% rate of return of the asset (also known as volatility), and Q is the
% dividend rate of the asset. The default Q is 0. N denotes the number
% of discretization points in the stock price domain, and M denotes
% the number of discretization points in time domain used for the PDE solu
tion.
% Try increasing either of M or N to achieve greater efficiency.
%
% BDATA output denotes the exercise boundary data for american put. The co
mmand
% plot(bdata(:,1),bdata(:,2)) plots the american put exercise boundary.
% Also returned is the matrix u, which is the surface of american put
% over the discretized space of S and T.
% Use amcontour(bdata,u) to see the boundary with put prices.
%
% For example, the current price an asset is $100, the exercise price
% of the option is $95, the risk-free interest rate is 10%, the time
% to maturity of the option is .25 years, and the standard deviation of
% of the asset is 50%. Using this data,
%
% [call,put] = blspricefdam(100,95,.1,.25,.5,0)
%
% returns a call option price of $13.70 and put option value of $6.47
%
% Reference: John C Hull : Options, Futures and other derivatives, Chap 15
.
%
% See also BLSPRICEFD for European options

% Set up default parameters if not provided


if nargin < 6 q =[]; end
if nargin < 7 M =[]; end
if nargin < 8 N =[]; end
if isempty(q) q=0; end
if isempty(M) M=20; end
if isempty(N) N=20; end
outdimrow=max([size(SO,1),size(X,1),size(r,1),size(T,1),size(sig,1),size(q,1)]);
outdimcol=max([size(SO,2),size(X,2),size(r,2),size(T,2),size(sig,2),size(q,2)]);
pad1=ones(outdimrow,outdimcol);
%Initialise outputs
call=zeros(outdimrow,outdimcol);
if nargout > 1 put=call; end
if ~isequal(length(SO),1) & (~isequal(size(SO,1),outdimrow) | ~isequal(size(SO,2
),outdimcol))
error('Size of SO should be compatible with other arguments');
else
SO=SO.*pad1;
end

if ~(length(X)==1) & (~isequal(size(X,1),outdimrow) | ~isequal(size(X,2),outdimc


ol))
error('Size of X should be compatible with other arguments');
else
X=X.*pad1;
end
if ~(length(r)==1) & (~isequal(size(r,1),outdimrow) | ~isequal(size(r,2),outdimc
ol))
error('Size of r should be compatible with other arguments');
else
r=r.*pad1;
end
if ~(length(T)==1) & (~isequal(size(T,1),outdimrow) | ~isequal(size(T,2),outdimc
ol))
error('Size of T should be compatible with other arguments');
else
T=T.*pad1;
end
if ~(length(sig)==1) & (~isequal(size(sig,1),outdimrow) | ~isequal(size(sig,2),o
utdimcol))
error('Size of sig should be compatible with other arguments');
else
sig=sig.*pad1;
end
if ~(length(q)==1) & (~isequal(size(q,1),outdimrow) | ~isequal(size(q,2),outdimc
ol))
error('Size of q should be compatible with other arguments');
else
q=q.*pad1;
end

if ((min(min(X))~=max(max(X))) | (min(min(r))~=max(max(r))) | (min(min(sig))~=ma


x(max(sig))) |(min(min(q))~=max(max(q))))
for I = 1: outdimrow
for J = 1:outdimcol
% Set up the discretized stock price space 0:3*X, total of N points.
x1=0;
x2=max(3*X(I,J),max(max(SO)));
S=linspace(x1,x2,N); S=S(:);
pad = ones(N,1);
newsig=sig(I,J).*pad;

% Setup the finite-difference matrix for timestepping.


[A,c,a,A1,c1,a1]=compA(newsig,r(I,J),q(I,J),T(I,J),M,N);

% The time step


dt = T(I,J)/(M-1);

% COMPUTE the CALL value.


u=max(S-X(I,J),0);
for i = dt : dt : T(I,J)
u1=timestepcallam(u,A,c,A1,c1,S,X(I,J),exp(-q(I,J)*i));
u=u1;
end
% Find call value using linear interpolation.
ind1=find(SO(I,J) <= S); ind1=ind1(1);
if ind1 > 1 ind2=ind1-1; else ind2=1; end
call(I,J)=( u(ind2)*(S(ind1)-SO(I,J))+ u(ind1)*(SO(I,J)-S(ind2)))/(S(ind1)-S(ind
2));
% COMPUTE the PUT value.
if nargout > 1
u=max(X(I,J)-S,0);
for i = dt : dt : T(I,J)
u1=timestepputam(u,A,a,A1,a1,S,X(I,J));
u=u1;
end
% Find put value
ind1=find(SO(I,J) <= S); ind1=ind1(1);
if ind1 > 1 ind2=ind1-1; else ind2=1; end
put(I,J)=( u(ind2)*(S(ind1)-SO(I,J))+ u(ind1)*(SO(I,J)-S(ind2)))/(S(ind1)-S(ind2
));
end
end
end

else
% In the vector arguments only SO and T vary, so we can use only a single
% discretization solution to get the value at all points.

x1=0;
x2=max(3*X(1,1),max(max(SO)));
S=linspace(x1,x2,N); S=S(:);
pad = ones(N,1);
newsig=sig(1,1).*pad;

% Setup the finite-difference matrix for timestepping.


[A,c,a,A1,c1,a1]=compA(newsig,r(1,1),q(1,1),max(max(T)),M,N);
% The time step
dt = max(max(T))/(M-1);

% COMPUTE the CALL value.


u=max(S-X(1,1),0);
if max(max(T))==0 tvec=0; else tvec=0:dt:max(max(T)); end
count=0;
for i = dt : dt : max(max(T))
count=count+1;
u1=timestepcallam(u(:,count),A,c,A1,c1,S,X(1,1),exp(-q(1,1)*i));
u=[u u1];
end

for I=1:outdimrow
for J=1:outdimcol
% Find call value using linear interpolation.
ind1=find(SO(I,J) <= S); ind1=ind1(1);
indT1=find(T(I,J) <= tvec); indT1=indT1(1);
if (indT1 > 1) & (ind1 >1)
ind2=ind1-1;
indT2=indT1-1;
c11=(S(ind1)-SO(I,J))*(tvec(indT1)-T(I,J));
c22=(SO(I,J)-S(ind2))*(T(I,J)-tvec(indT2));
c12=(SO(I,J)-S(ind2))*(tvec(indT1)-T(I,J));
c21=(S(ind1)-SO(I,J))*(T(I,J)-tvec(indT2));
quot=(tvec(indT1)-tvec(indT2))*(S(ind1)-S(ind2));
call(I,J)=(u(ind2,indT2)*c11+ u(ind1,indT1)*c22 + u(ind1,indT2)*c12 + u(ind2,ind
T1)*c21)/quot;
elseif (ind1 > 1)
ind2=ind1-1;
call(I,J)=( u(ind2,1)*(S(ind1)-SO(I,J))+ u(ind1,1)*(SO(I,J)-S(ind2)))/(S(ind1)-S
(ind2));
elseif (indT1 > 1)
indT2=indT1-1;
call(I,J)=( u(1,indT2)*(tvec(indT1)-T(I,J))+ u(1,indT1)*(T(I,J)-tvec(indT2)))/(t
vec(indT1)-tvec(indT2));
else
call(I,J)=u(1,1);
end
end
end
% COMPUTE the PUT value.
if nargout > 1
u=max(X(1,1)-S,0);
count=0;
bdata(1)=X(1,1);
for i = dt : dt : max(max(T))
count=count+1;
[u1,ind]=timestepputam(u(:,count),A,a,A1,a1,S,X(1,1));
bdata(count+1)=S(ind);
u=[u u1];
end
bdata=[bdata' flipud(tvec')];
% Find put value
for I=1:outdimrow
for J=1:outdimcol
ind1=find(SO(I,J) <= S); ind1=ind1(1);
indT1=find(T(I,J) <= tvec); indT1=indT1(1);
if (indT1 > 1) & (ind1 > 1)
indT2=indT1-1;
ind2=ind1-1;
c11=(S(ind1)-SO(I,J))*(tvec(indT1)-T(I,J));
c22=(SO(I,J)-S(ind2))*(T(I,J)-tvec(indT2));
c12=(SO(I,J)-S(ind2))*(tvec(indT1)-T(I,J));
c21=(S(ind1)-SO(I,J))*(T(I,J)-tvec(indT2));
quot=(tvec(indT1)-tvec(indT2))*(S(ind1)-S(ind2));
put(I,J)=(u(ind2,indT2)*c11+ u(ind1,indT1)*c22 + u(ind1,indT2)*c12 + ...
u(ind2,indT1)*c21)/quot;
elseif (ind1 > 1)
ind2=ind1-1;
put(I,J)=( u(ind2,1)*(S(ind1)-SO(I,J))+ u(ind1,1)*(SO(I,J)-S(ind2)))/(S(ind1)-S(
ind2));
elseif (indT1 > 1)
indT2=indT1-1;
put(I,J)=( u(1,indT2)*(tvec(indT1)-T(I,J))+ u(1,indT1)*(T(I,J)-tvec(indT2)))/(tv
ec(indT1)-tvec(indT2));
else
put(I,J)=u(1,1);
end
end
end
end

end

Das könnte Ihnen auch gefallen