%function vol_test = vol_test(S_today,Vola,Rate,Dividend,Kmin,Kmax,Knum,Tmax,Tmin,Tnum,num_plots) function vol_test = vol_test() S_today = 100; Vola = 0.232; Rate = 0.03; Dividend = 0.01; Kmin = 80; Kmax = 130; Knum = 20; Tmin = 1/12; Tmax = 12/12; Tnum = 30; num_plots = 3; num_strikes = 10; % vol_test(S_today,Vola,Rate,Dividend,Kmin,Kmax,Knum,Tmax,Tmin,Tnum,num_plots) % This function plot the implied volatility and the local volatility (using DUPIRE) % for a set of call price generating from the Black Scholes models with a % constant volatility. % % DATA % Underlying_asset_price = S_today; % Data from the inputs % Volatility = Vola; % Volatility data; % Risk_free_interest_rate = Rate; %Risk_free_interest_rate = 0.025; % Dividend_rate = Dividend; % Dividend Rate % Exercise_price = [Kmin .......Kmax] with a number of colums = Knum % Maturity = [Tmin .......Tmax] with a number of colums = Tnum % Number_of_plots_T = num_plots % % Internal Data: % Newton Rapson method variables % Maximum_number_of_iterations = 1000; % Tolerance_of_convergence = 1e-6; % Theta method variables. % Theta_variable = 1; % 0 <= Theta <= 1 % DATA Underlying_asset_price = S_today; % Data from the inputs Volatility = Vola; % Volatility data; Risk_free_interest_rate = Rate; %Risk_free_interest_rate = 0.025; Dividend_rate = Dividend; % Dividend Rate % Internal Data % Newton Rapson method variables Maximum_number_of_iterations = 1000; Tolerance_of_convergence = 1e-6; % Theta method variables. Theta_variable = 0.5; % 0 <= Theta <= 1 % Define K, T and Call_price % Exercise_price = K delta_K=(Kmax-Kmin)/(Knum-1); for j=1:Knum Exercise_price(1,j) = Kmin+delta_K*(j-1); end % Maturity_in_years % months of the year, i.e. June = 6/12 Month_of_today = 0/12; % month of the year, i.e. January = 1/12 delta_T=(Tmax-Tmin)/(Tnum-1); for i=1:Tnum Maturity_in_years(1,i) = Tmin+delta_T*(i-1); end % Call_price for i=1:Tnum for j=1:Knum Call_price(i,j) = BLSPRICE(S_today,Exercise_price(1,j),Rate,Maturity_in_years(1,i),Vola,Dividend); end end % NOTES IMPORTANTS % % A)This function use Black-Scholes put and call pricing % [CALL,PUT] = BLSPRICE(SO,K,R,T,VOL,Q) returns the value of % call and put options using the Black-Scholes pricing formula. % Note: This function uses normcdf, the normal cumulative distribution function in the Statistics Toolbox. % SO is the current asset price, % K is the exercise price, % R is the risk-free interest rate, % T is the time to maturity of the option in years, % VOL is the standard deviation of the annualized continuously compounded rate of return of the asset (also known as volatility) % Q is the dividend rate of the asset. The default Q is 0. % % 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 the asset is 50. Using this data, % call = blsprice(100,95,.1,.25,.5,0) % returns a call option price of $13.70. % % B) Imply volatility % This function solves for the implied volatility, using Newton's method and Black-Schooles equation. % MAXITER is the maximum number of iterations used in solving for V. By % default, MAXITER = 50. % By TOL is the tolerance when the result of the Newton-Raphson method % is considered to have converged; default is 1e-6. % Note: This function uses normcdf and normpdf, the normal cumulative distribution % and normal probability density functions in the Statistics Toolbox. % % C) Local volatility % This function solves for the local volatility, using dupire equation. % For solving the PDE I use the theta method. % If Theta = 1 is called the explicit method. % If Theta = 0.5 is called the Crank Nicholson method. %VARIABLES IN OUR WORKSPACE % Define variable names in our workspace S0 = Underlying_asset_price; K = Exercise_price; C = Call_price; T0 = Month_of_today; T = Maturity_in_years; R = Risk_free_interest_rate; Q = Dividend_rate; NK = Knum; % = Num_of_strikes NT = Tnum; % = Num_of_maturities VOL = Volatility; % Volatility_from Data warning off; % Newton Rapson method variables in our workspace MAXITER = Maximum_number_of_iterations; TOL = Tolerance_of_convergence; % Theta method variables in our workspace Theta = Theta_variable; %CALCULATIONS % Calculate Implied volatility with MATLAB for i=1:NT for j=1:NK if C(i,j)==0 Imp_vol(i,j) = 0; else Imp_vol(i,j)=BLSIMPV(S0,K(1,j),R,T(i)-T0,C(i,j),MAXITER,Q,TOL); end end end Imp_vol; % Calculate de Local Volatility using dupire equation in terms of Strikes and Maturity % define delta for maturities for i=1:NT if i==NT delta_T(i)= 0; else delta_T(i)=T(i+1)-T(i); end end % define delta for strikes for j=1:NK if j==NK delta_K(j)= 0 ; else delta_K(j)=K(j+1)-K(j); end end % parcial derivative of Call / respect MATURITY for i=1:NT for j=1:NK if i==NT | i==1 dp_C_r_T(i,j)=0; else dp_C_r_T(i,j)=[C(i+1,j)-C(i-1,j)]/[2*delta_T(i)]; end end end % parcial derivative of Call / respect STRIKES for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK dp_C_r_K(i,j)=0; else dp_C_r_K(i,j)=[Theta*(-C(i,j-1)+C(i,j+1))+(1-Theta)*(-C(i+1,j-1)+C(i+1,j+1))]/[2*delta_K(j)]; end end end % second parcial derivative of Call / respect STRIKES for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK sec_dp_C_r_K(i,j)=0; else sec_dp_C_r_K(i,j)=[Theta*(C(i,j-1)-2*C(i,j)+C(i,j+1))+(1-Theta)*(C(i+1,j-1)-2*C(i+1,j)+C(i+1,j+1))]/[delta_K(j)*delta_K(j)]; end end end %Using Dupire Equation in terms of Strikes and Maturity % Loc_vol1 = dupire formula % Loc_vol2 = Using Dupire Equation in terms call derivatives; for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK Loc_vol1(i,j)=0; Loc_vol2(i,j)=0; else Loc_vol1(i,j)=sqrt([dp_C_r_T(i,j)]/[0.5*K(1,j)*K(1,j)*sec_dp_C_r_K(i,j)]); Loc_vol2(i,j)=sqrt([dp_C_r_T(i,j)+((R-Q)*K(1,j)*dp_C_r_K(i,j))+Q*C(i,j)]/[0.5*K(1,j)*K(1,j)*sec_dp_C_r_K(i,j)]); end end end delta_K; delta_T; dp_C_r_T; dp_C_r_K; sec_dp_C_r_K; Loc_vol1; Loc_vol2; % Calculate de Local Volatility using dupire equation in terms of imply volatility % parcial derivative of imply volatility / respect MATURITY for i=1:NT for j=1:NK if i==1 | i==NT dp_IV_r_T(i,j)=0; else dp_IV_r_T(i,j)=[Imp_vol(i+1,j)-Imp_vol(i-1,j)]/[2*delta_T(i)]; end end end % parcial derivative of imply volatility / respect STRIKES for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK dp_IV_r_K(i,j)=0; else dp_IV_r_K(i,j)=[Theta*(-Imp_vol(i,j-1)+Imp_vol(i,j+1))+(1-Theta)*(-Imp_vol(i+1,j-1)+Imp_vol(i+1,j+1))]/[2*delta_K(j)]; end end end % second parcial derivative of imply volatility / respect STRIKES for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK sec_dp_IV_r_K(i,j)=0; else sec_dp_IV_r_K(i,j)=[Theta*(Imp_vol(i,j-1)-2*Imp_vol(i,j)+Imp_vol(i,j+1))+(1-Theta)*(Imp_vol(i+1,j-1)-2*Imp_vol(i+1,j)+Imp_vol(i+1,j+1))]/[delta_K(j)*delta_K(j)]; end end end %Using Dupire Equation in terms of implied volatility % Loc_vol3 = using Dupire Equation in terms of implied volatility; for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK Loc_vol3(i,j)=0; else d1(i,j)=[log(S0/K(1,j))+(R-Q+0.5*Imp_vol(i,j)^2*(T(i)-T0))]/[Imp_vol(i,j)*(sqrt(T(i)-T0))]; d2(i,j)=[1+K(1,j)*d1(i,j)*dp_IV_r_K(i,j)*sqrt(T(i)-T0)]^2+[Imp_vol(i,j)^2*K(1,j)^2*(T(i)-T0)*(sec_dp_IV_r_K(i,j)-d1(i,j)*dp_IV_r_K(i,j)^2*(sqrt(T(i)-T0)))]; Loc_vol3(i,j)=sqrt([Imp_vol(i,j)^2+2*Imp_vol(i,j)*(T(i)-T0)*(dp_IV_r_T(i,j)+(R-Q)*K(1,j)*dp_IV_r_K(i,j))]/d2(i,j)); end end end dp_IV_r_T; dp_IV_r_K; sec_dp_IV_r_K; Loc_vol3; % Diference betwwen Local and Impled Volatilit for i=1:NT for j=1:NK if i==1 | i==NT | j==1 | j==NK Dif_imp(i,j)=0; Dif_vol1(i,j)=0; Dif_vol2(i,j)=0; Dif_vol3(i,j)=0; else Dif_imp(i,j)=VOL-Imp_vol(i,j); Dif_vol1(i,j)=VOL-Loc_vol1(i,j); Dif_vol2(i,j)=VOL-Loc_vol2(i,j); Dif_vol3(i,j)=VOL-Loc_vol3(i,j); end end end % Plots and worksapce results % Loc_vol1 = dupire formula % Loc_vol2 = Using Dupire Equation in terms call derivatives; % Loc_vol3 = Using Dupire Equation in terms of implied volatility; % Dif_vol1 = Difference between volatility given and volatility 1 % Dif_vol2 = Difference between volatility given and volatility 2 % Dif_vol3 = Difference between volatility given and volatility 3 if num_plots > NT-1 num_plots=NT-1; end for i=1:num_plots if num_plots == 1 deltaplot(1)=NT-1; elseif num_plots == 2 deltaplot = [NT/2,NT-1]; else if i==1 deltaplot(1)=round(NT/num_plots); elseif i==num_plots deltaplot(num_plots)=NT-1; else deltaplot(i)=round(deltaplot(i-1)+(NT-1)/(num_plots)); end end end if num_strikes > NK-1 num_strikes=NK-1; end for j=1:num_strikes if num_strikes == 1 deltastrike(1)=NK-1; elseif num_strikes == 2 deltastrike = [NK/2,NK-1]; else if j==1 deltastrike(1)=round(NK/num_strikes); elseif j==num_strikes deltastrike(num_strikes)=NK-1; else deltastrike(j)=round(deltastrike(j-1)+(NK-1)/(num_strikes)); end end end %define worksapce for i=1:num_plots for j=1:num_strikes Maturity_in_years(i) = T(deltaplot(i)); Exercise_price(j) = K(deltastrike(j)); Call_price(i,j) = C(deltaplot(i),deltastrike(j)); Imp_vol_X(i,j) = Imp_vol(deltaplot(i),deltastrike(j)); Loc_vol_formula(i,j) = Loc_vol1(deltaplot(i),deltastrike(j)); Loc_vol_in_call_terms(i,j) = Loc_vol2(deltaplot(i),deltastrike(j)); Loc_vol_in_imp_vol_terms(i,j) = Loc_vol3(deltaplot(i),deltastrike(j)); Dif_imp_X(i,j) = Dif_imp(deltaplot(i),deltastrike(j)); Dif_vol_formula(i,j) = Dif_vol1(deltaplot(i),deltastrike(j)); Dif_vol_in_call_terms(i,j) = Dif_vol2(deltaplot(i),deltastrike(j)); Dif_vol_in_imp_vol_terms(i,j) = Dif_vol3(deltaplot(i),deltastrike(j)); end end %worksapce display Exercise_price; Maturity_in_years; Call_price; Imp_vol; Loc_vol1; Loc_vol2; Loc_vol3; Dif_imp; Dif_vol1; Dif_vol2; Dif_vol3; deltaplot; deltastrike; Exercise_price; Maturity_in_years; Call_price; Imp_vol_X; Loc_vol_formula; Loc_vol_in_call_terms; Loc_vol_in_imp_vol_terms; Dif_imp_X Dif_vol_formula; Dif_vol_in_call_terms Dif_vol_in_imp_vol_terms close all warning off figure for i=1:num_plots subplot(num_plots,1,i) plot(K,Dif_vol2(deltaplot(i),:),K,Dif_vol3(deltaplot(i),:)); %axis([K(1,2),K(1,NK-1),-1/(NK*10),1/(NK*10)]); YLABEL(+ Maturity_in_years(deltaplot(i))); GRID ON if i==1 TITLE('Error = volatility given minus Local Volatility '); legend('Local Volatility in terms of calls','Local Volatility in terms of implied volatility'); end if i==num_plots XLABEL('Maturity vs Strikes'); end end figure for i=1:num_plots subplot(num_plots,1,i) plot(K,Imp_vol(deltaplot(i),:),K,Loc_vol1(deltaplot(i),:),K,Loc_vol2(deltaplot(i),:),K,Loc_vol3(deltaplot(i),:)); axis([K(1,2),K(1,NK-1),VOL-1/NK,VOL+1/NK]); YLABEL(+ Maturity_in_years(deltaplot(i))); GRID ON if i==1 TITLE('Implied volatility and Local Volatilities '); legend('Implied volatility','Local vol(dupire formula)','Local vol(call prices)','Local vol(implied volatility)'); end if i==num_plots XLABEL('Maturity vs Strikes'); end end % Plot 3D for i=2:NT-1 for j=2:NK-1 T_plot(i-1) = real(T(i)); K_plot(j-1) = real(K(j)); Call_price_plot(i-1,j-1) = real(C(i,j)); Imp_vol_plot(i-1,j-1) = real(Imp_vol(i,j)); Loc_vol1_plot(i-1,j-1) = real(Loc_vol1(i,j)); Loc_vol2_plot(i-1,j-1) = real(Loc_vol2(i,j)); Loc_vol3_plot(i-1,j-1) = real(Loc_vol3(i,j)); Dif_imp_plot(i-1,j-1) = real(Dif_imp(i,j)); Dif_vol1_plot(i-1,j-1) = real(Dif_vol1(i,j)); Dif_vol2_plot(i-1,j-1) = real(Dif_vol2(i,j)); Dif_vol3_plot(i-1,j-1) = real(Dif_vol3(i,j)); end end figure subplot(3,2,2); surf(K,T,Dif_imp); TITLE(' 0.232 - Imp vol'); ZLABEL(' Error '); colormap cool; axis([Kmin,Kmax,Tmin,Tmax,-2*10^-14,2*10^-14]); subplot(3,2,4); surf(K_plot,T_plot,Dif_vol1_plot); TITLE(' 0.232 - Loc vol (Call prices)'); ZLABEL(' Error ') colormap cool; axis([Kmin,Kmax,Tmin,Tmax,-0.2,0.2]); subplot(3,2,6); surf(K_plot,T_plot,Dif_vol3_plot); TITLE(' 0.232 - Loc vol (Imp)'); XLABEL('Strikes');YLABEL('Maturity');ZLABEL(' Error '); colormap cool; axis([Kmin,Kmax,Tmin,Tmax,-2*10^-13,2*10^-13]); subplot(3,2,1); surf(K,T,Imp_vol); TITLE('Implied volatility'); colormap cool; axis([Kmin,Kmax,Tmin,Tmax,VOL-0.001,VOL+0.001]); subplot(3,2,3); surf(K_plot,T_plot,Loc_vol1_plot); TITLE('Local volatility (Call prices)');ZLABEL('Volatility') colormap cool; axis([Kmin,Kmax,Tmin,Tmax,0.1,0.3]); subplot(3,2,5); surf(K_plot,T_plot,Loc_vol3_plot); TITLE('Local volatility (Implied volatility)'); XLABEL('Strikes');YLABEL('Maturity'); colormap cool;axis([Kmin,Kmax,Tmin,Tmax,VOL-0.001,VOL+0.001]); K; T; Call_price; Imp_vol; Loc_vol1; Loc_vol2; Loc_vol3; Dif_imp; Dif_vol1; Dif_vol2; Dif_vol3; T_plot; K_plot; Call_price_plot; Imp_vol_plot; Loc_vol1_plot; Loc_vol2_plot; Loc_vol3_plot; Dif_imp_plot; Dif_vol1_plot; Dif_vol2_plot; Dif_vol3_plot;