functionvol=newtoniv(S,K,r,T,price,callput) % S is stock price, % K is strike price, % r is free interest rate, % T is time to maturity, % price is market option price, % callput is 1 if call 0 if put
vol = 1.0; % initial value of implied volatility sigma = vol+0.1; % sigma is volatility in BS model maxiter = 20; tol = 1e-4; iter = 0;
% newton-raphson method whileabs(sigma-vol)>tol || iter < maxiter % precision of result sigma = vol; d1 = (log(S/K)+(r+sigma^2/2)*T)/(sigma*sqrt(T)); d2 = d1-sigma*sqrt(T); if callput == 1 cp = S*normcdf(d1)-K*exp(-r*T)*normcdf(d2); %European call option price under BS model else cp = K*exp(-r*T)*normcdf(-d2) - S*normcdf(-d1); %European put option price under BS model end vega = S*sqrt(T)*normpdf(d1);% call/put vega fsigma = cp-price; vol = sigma-fsigma/vega;% 期权对 sigma 的偏导即 vega iter = iter + 1; end
This MATLAB function using a Black-Scholes model computes the implied volatilityof an underlying asset from the market value of European call and put options.
S=260.05;% stock price r=0.02; % interest rate T=[4/365,11/365,18/365,25/365,32/365]; % time maturity K=[250,252.5,255,257.5,260,262.5,265,267.5,270];%strike price C=[ 10.47.735.83.82.31.190.550.250.12; 10.248.696.64.853.32.21.290.810.46; 10.98.236.44.653.422.451.721.110.75; 129.897.956.44.93.842.521.81.4; 11.5710.838.027.265.74.13.552.541.97;];%prices for different maturities in rows volatility=zeros(5,9); % plot implied volatility surface [x,y]=meshgrid(K,T); fori=1:5 forj=1:9 volatility(i,j)=blsimpv(S,K(j),r,T(i),C(i,j)); end end surf(x,y,volatility)
1 2 3 4 5 6
fori=1:5 forj=1:9 volatility(i,j)=newtoniv(S,K(j),r,T(i),C(i,j),1); end end surf(x,y,volatility)
我们可以发现结果是很相似的
Week 3: Delta-hedging in the Black-Scholes model
此部分主要计算采用 Delta 对冲后的策略价值。首先我们引入股票价格的增长公式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
functionST=BSpath(S0,mu,sigma,T,n,N) % S0 is the initial stock price, % K is strike price, % r is free interest rate, % T is time to maturity, % n is the number of time discretisation steps, % N is the sample size % mu is the asset's rate of return % sigma is the asset's volatility
function[X,PNL]=deltahedge(S0,K,r,mu,sigma,T,n,N) % S0 is the initial stock price, % K is strike price, % r is free interest rate, % T is time to maturity, % n is the number of time discretisation steps, % N is the sample size % mu is the asset's rate of return % sigma is the asset's volatility
strike = K; nstep = power(2,n); % number of time steps delt = T/nstep;% time step size tstep = linspace(0,T,nstep+1); const = ones(N,nstep+1)*(mu - 0.5*sigma*sigma)*delt; BMval = normrnd(0,1,[N,nstep+1]); % Brownian motion increments BMval(1:N,1) = 0; const(1:N,1) = 0; incr = const + sigma*sqrt(delt)*BMval; ST = S0*cumprod(exp(incr),2); % Compute delta at each readjustment time tt = T-tstep(1:nstep); % 剩余时间 X = zeros(N,length(K)); % final value of the self-financing portfolio PNL = zeros(N,length(K)); % Profit and loss over Monte Carlo sample paths
S0 = 100; %Starting price r = 0.05; %interest rate T = 1; %call option maturity n = 5; %exponent in the number of time steps N = 1000; %number of Monte Carlo sample paths mu = 0.02; %asset return sigma = 0.2; %volatility parameter K = 80; %option strike
Week 4: Pricing European options in Heston‘s model using inverse Fourier transform
此部分对应于笔记中的 Unit 2.9 。普通定价模型中将风险定义为一个常量,而Heston’s Stochastic Volatility Model 则将其定义为一个随时间变换的值。并且 sigma 的值是 mean-reversion 的。如果它偏离了 mean 会有一种力量把它纠正回原点的方向。
% initialization of parameters for Heston model s0=100;% stock price r=0.02; % interest rate kappa=5; % speed of mean reversion theta=0.04;% long term mean sigma=0.5; % volatility of volatility rho=-0.7; v0=0.5;% initial variance T=[0.2,0.4,0.6,0.8,1]; % time maturity K=[80,90,100,110,120]; % strike price
C=zeros(5,5); fori=1:5 forj=1:5 C(i,j)=HestonCallQuad(kappa,theta,sigma,rho,v0,r,T(i),s0,K(j)); % European call option price under Heston model end end
volatility=zeros(5,5); % plot implied volatility surface [x,y]=meshgrid(T,K); fori=1:5 forj=1:5 volatility(i,j)=blsimpv(s0,K(j),r,T(i),C(i,j)); end end surf(x,y,volatility)
Week 5: Calibration of Heston’s model to market data
但实际上 Heston’s model 的准确度非常依赖它的系数与波动率初始值 ($\kappa,\theta,\sigma,\rho,v_0$)。因此,在运用模型之前还需要运用 lsqnonlin 对模型的系数进行训练。如果令 $\Theta = (\kappa,\theta,\sigma,\rho,v_0)$,优化函数则是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
functionret = HestonDifferences(input) global NoOfOptions; global OptionData; global NoOfIterations; global PriceDifference; NoOfIterations = NoOfIterations + 1; %counts the no of iterations run to calibrate model fori = 1:NoOfOptions PriceDifference(i) = (OptionData(i,5)-HestonCallQuad( ... (input(1)+input(3)^2)/(2*input(2)),input(2),input(3),input(4),input(5), ... OptionData(i,1),OptionData(i,2),OptionData(i,3),OptionData(i,4)))... /sqrt((abs(OptionData(i,6)- OptionData(i,7)))); %Option Value-Estimated Value(4个系数,4个已知) %kappa=(?+sigma^2)/2theta,theta,sigma,rho,v0,r,T,s0,K %sqrt((abs(OptionData(i,6)-OptionData(i,7))))-> w_ij (weight) end ret = PriceDifference';
clear; global OptionData; global NoOfOptions; global NoOfIterations; global PriceDifference; NoOfIterations = 0; load OptionData.m ; %OptionData = [r,T,S0,K,Option Value,bid,offer] Size = size(OptionData); NoOfOptions = Size(1); %input sequence in initial vectors [2*kappa*theta - sigma^2,theta,sigma,rho,v0] %x0 = [0.05 0.05 0.5 -0.5 0.15]; x0 = [0.50.11.3-0.750.2]; % 系数训练初始值 lb = [000-10]; % 系数训练最小值 ub = [201501]; % 系数训练最大值 options = optimset('MaxFunEvals',20000); %sets the max no. of iteration to 20000 so that termination doesn't take place early. tic; Calibration = lsqnonlin(@HestonDifferences,x0,lb,ub); toc; Solution = [(Calibration(1)+Calibration(3)^2)/(2*Calibration(2)), Calibration(2:5)]; %output sequence in Solution = [kappa,theta,sigma,rho,v0]
Week 6: Pricing of European option in Heston’s model using the Monte Carlo method
此部分对应于笔记中的 Unit 3.1 。蒙特卡洛部分要使用 Euler-Maruyama 和 Milstein schemes 两种方法来运算,并且对比。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
% European call option under Heston model with Euler-Maruyama-Method and Milstein method clear all; M = 50000; % number of paths N = 100;% number of time steps T = 1;% maturity h = T/N;%delta t S0 = 100; sigma20 = 0.0625; %variance at t=0 K=100; % strike kappa = 2; theta = 0.4; nu = 0.2; rho = -0.7; r=0.02;
% Initialisation of stock price and volatility for Euler Maruyama method S = S0*ones(M,N+1); sigma2 = sigma20*ones(M,N+1);
% Solution of the SDE-System with Euler-Maruyama-Method % NOTE: we don't need to store the entire simulation path to compute the %European option payoff! fori = 1:N sigma2(:,i+1) = sigma2(:,i) + kappa*(theta-sigma2(:,i))*h ... + nu*sqrt(abs(sigma2(:,i))).*dW2(:,i); S(:,i+1) = S(:,i).*(1 + r*h + sqrt(abs(sigma2(:,i))).*dW1(:,i)); end
payoff = exp(-r*T)*max(0,S(:,end)-K); stdpayoff = std(payoff); V = mean(payoff) Vleft = V - 1.96*stdpayoff/sqrt(M) Vright = V + 1.96*stdpayoff/sqrt(M)
Milstein Scheme 的主要公式是
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
% Initialisation of stock price and volatility for Milstein method S1 = S0*ones(M,N+1); sigma3 = sigma20*ones(M,N+1); % Solution of the Milstein method
fori = 1:N sigma3(:,i+1) = sigma3(:,i) + kappa*(theta-sigma3(:,i))*h ... + nu*sqrt(abs(sigma3(:,i))).*dW2(:,i)+1/4*nu.*(dW2(:,i).^2-h); S1(:,i+1) = S1(:,i).*(1 + r*h + sqrt(abs(sigma3(:,i))).*dW1(:,i))+1/2*sigma3(:,i).*S1(:,i).*(dW1(:,i).^2-h); end
Week 7: Variance reduction method in the Black-Scholes model for Asian option pricing
此部分对应笔记中的 Unit 3.2.1。我们想要预测 Arithmetic average Asian call option 的价格,同时将 Geometric average Asian option 作为 control variate 来降低预测值的 VAR。在代码中使用的 Geometric Asian option 的定价方程参考于 Nielsen 的论文《Pricing Asian Options》^[1]^。
functionUn=hestonPDEprice(kappa,theta,delta,rho,T,dt,K,Y,I,J) %hestonPDEprice(1.15,0.10,0.2,-0.4,4/52,4/(52*4000),40,1.0,80,40) nt=ceil(T/dt); xmin = log(1e-2); xmax = log(2.0*K); ymin = 0; ymax = Y*1.2; dx = (xmax-xmin)/I; %step length of x dx2 = dx*dx; dy = Y/J; %step length of y dy2 = dy*dy; xvalue = xmin:dx:xmax; %grid of x values yvalue = ymin:dy:ymax; %grid of y values nx = length(xvalue)-1; %number of entries in x axis - 1 ny = length(yvalue)-1; %number of entries in y axis - 1 temp = max(exp(xvalue)-K,0); %European call payoff: terminal condition uinitial = temp'*ones(1,ny+1); %x in row i, vol in col j U = uinitial; % u in dimension of (nx+1)*(ny+1) for n=1:nt %interior elements in cross derivative Upp = U(3:nx+1,3:ny+1); %+1 in x, +1 in y Umm = U(1:nx-1,1:ny-1); %-1 in x, -1 in y Ump = U(1:nx-1,3:ny+1); %-1 in x, +1 in y Upm = U(3:nx+1,1:ny-1); %+1 in x, -1 in y Uxy = Upp+Umm-Ump-Upm; G0t = (rho*delta*dt/(4*dx*dy))*ones(1,nx+1)'*yvalue; G0 = G0t(2:nx,2:ny); U1t = G0.*Uxy; U1 = [zeros(1,ny+1);zeros(nx-1,1) U1t zeros(nx-1,1);zeros(1,ny+1)];% pad with zeros at the edge of domain % dsdv 项以及其前面的系数
% elements in X direction C1 = ones(1,nx-1)*(0.5/dx2 + 0.25/dx); C1 = [C1';0;0]; A1 = -ones(1,nx-1)/dx2; A1 = [0;A1';0]; E1 = ones(1,nx-1)*(0.5/dx2 - 0.25/dx); E1 = [0;0;E1']; %sparse matrix with A1 on the diagonal, C1 one below & D1 one above B = spdiags([C1 A1 E1],[-101],nx+1,nx+1); forj=2:ny A = U(:,j); G1 = dt*yvalue(j)*B; U2t = G1*A; % the interior elements along the j-th sub-vector. U2t(nx+1) = 0; U2t(1) = 0; ifj==2 U2 = U2t; else U2 = [U2 U2t]; % arrange in columns % ds,(ds)^2项以及前面的系数 end end U2 = [zeros(nx+1,1) U2 zeros(nx+1,1)]; %pad with zeros in the first and last columns % % elements in Y direction E1 = 0.5*delta^2*yvalue(2:ny)/dy2 - 0.5*kappa*(theta-yvalue(2:ny))/dy; E1 = [E1';0;0]; A1 = -delta^2*yvalue(2:ny)/dy2; A1 = [0;A1';0]; F1 = 0.5*delta^2*yvalue(2:ny)/dy2 + 0.5*kappa*(theta-yvalue(2:ny))/dy; F1 = [0;0;F1']; D = spdiags([E1 A1 F1],[-101],ny+1,ny+1); fori = 2:nx A = U(i,:)'; U3t = dt*D*A; U3t(1) = 0; U3t(ny+1) = 0; ifi==2 U3 = U3t'; else U3 = [U3; U3t']; end end U3 = [zeros(1,ny+1);U3;zeros(1,ny+1)]; % dv,(dv)^2项以及前面的系数 Uy = U(:,1); % the first column of the previous U U = U + U1 + U2 + U3 ; % 代入边界条件 U(1,:) = zeros(1, ny+1); %when x = xmin U(:,ny+1) = exp(xvalue)'; %when y = ymax % elements where y=0 fori=2:nx U(i,1)=(Uy(i)+kappa*theta*dt*U(i,2)/dy)/(1+kappa*theta*dt/dy); end U(nx+1,2:ny) = exp(xvalue(nx+1))- K;%when x = xmax %U(nx+1,2:ny) = (2*dx*exp(xvalue(nx+1))+4*U(nx,2:ny)-U(nx-1,2:ny))/3; end Un = U(1:I+1,1:J+1);
% p0 = zeros(nx+1,ny+1); % for i=1:nx+1 % for j=1:ny+1 % p0(i,j) = HestonCallQuad(kappa,theta,delta,rho,yvalue(j),0,T,exp(xvalue(i)),K); % end % end % p = p0(1:I+1,1:J+1); end
以上代码是以 log(S) 为纵轴方向指标变换的,因此与文章中的代码有些不同。
其中矩阵 B 的样式为
矩阵 D 的样式为
[2] Lin, S. (2008). Finite Difference Schemes for Heston Model. Master of Mathematical and Computational Finance Dissertation, University of Oxford
Week 10: Calibration of Dupire’s model to market data
此部分对应笔记中的 Unit 2 。主要运用两种方法来预测local volatility。 第一种是Dupire’s model 的原始公式,公式中参考的是 $q=0$ 的格式
%In the data provided, there are non-zero call option prices for 0 maturity. %In order to do the calculations, drop the values corresponding to 0 maturity. T = 0.9; n = 8; num_step = 2^n; S0 = 100; r = 0.0; dt = T/num_step; dK = 0.1; MaxCounter = 100; %number of maximum iterations for implied vol inversion MaxVolLevel = 6.0; N = 1000; %number of Monte Carlo sample paths
strk = load('strikes.txt'); %strike vector length 401 mat = load('maturities.txt'); %maturity vector length 257 mat = mat(2:end); %remove the maturity 0 entry pr = load('optionprices.txt'); %price is STRK * MAT pr = pr(:,2:end);%remove the prices corresponding to maturity 0 % pr_T = zeros(size(pr)); pr_T(1:end,2:end-1) = (pr(1:end,3:end)-pr(1:end,1:end-2))/(2*dt); pr_T(1:end,1) = (pr(1:end,2)-pr(1:end,1))/dt; pr_T(1:end,end) = (pr(1:end,end)-pr(1:end,end-1))/dt; % pr_K = zeros(size(pr)); pr_K(2:end-1,1:end) = (pr(3:end,1:end)-pr(1:end-2,1:end))/(2*dK); pr_K(1,1:end) = (pr(2,1:end)-pr(1,1:end))/dK; pr_K(end,1:end) = (pr(end,1:end)-pr(end-1,1:end))/dK;