我正在尝试使用 Matlab (2012b) 中的 Black-Scholes 公式计算隐含波动率,但在某些执行价格方面存在问题。例如 blsimpv(1558,1440,0.0024,(1/12),116.4) 将返回 NaN。我认为该函数可能存在问题,因此在互联网上搜索了一些其他 matlab 脚本并根据我的自定义需求对其进行了定制,但不幸的是我仍然无法返回有效的隐含波动率。
function sigma=impvol(C,S,K,r,T)
%F=S*exp((r).*T);
%G=C.*exp(r.*T);
%alpha=log(F./K)./sqrt(T);
%beta=0.5*sqrt(T);
%a=beta.*(F+K);
%b=sqrt(2*pi)*(0.5*(F-K)-G);
%c=alpha.*(F-K);
%disc=max(0,b.^2-4*a.*c);
%sigma0=(-b+sqrt(disc))./(2*a);
i=-1000;
while i<=5000
sigma0=i/1000;
sigma=NewtonMethod(sigma0);
if sigma<=10 && sigma>=-10
fprintf('This is sigma %f',sigma)
end
i=i+1;
end
end
function s1=NewtonMethod(s0)
s1=s0;
count=0;
f=@(x) call(S,K,r,x,T)-C;
fprime=@(x) call_vega(S,K,r,x,T);
max_count=1e4;
while max(abs(f(s1)))>1e-7 && count<max_count
count=count+1;
s0=s1;
s1=s0-f(s0)./fprime(s0);
end
end
end
function d=d1(S,K,r,sigma,T)
d=(log(S./K)+(r+sigma.^2*0.5).*(T))./(sigma.*sqrt(T));
end
function d=d2(S,K,r,sigma,T)
d=(log(S./K)+(r-sigma.^2*0.5).*(T))./(sigma.*sqrt(T));
end
function p=Phi(x)
p=0.5*(1.+erf(x/sqrt(2)));
end
function p=PhiPrime(x)
p=exp(-0.5*x.^2)/sqrt(2*pi);
end
function c=call(S,K,r,sigma,T)
c=S.*Phi(d1(S,K,r,sigma,T))-K.*exp(-r.*(T)).*Phi(d2(S,K,r,sigma,T));
end
function v=call_vega(S,K,r,sigma,T)
v=S.*PhiPrime(d1(S,K,r,sigma,T)).*sqrt(T);
end
不幸的是,运行 impvol(116.4,1558,1440,0.0024,(1/12)) 将返回值“Inf”。不知何故,牛顿-拉普森方法没有收敛,但我对如何解决这个问题一无所知。有谁知道如何解决这个问题或知道如何计算隐含波动率的其他方法?
预先感谢您的帮助!亲切的问候,
亨克