%% Workflow for Plotting an Option Sensitivity Surface Using the Bates Model
% optSensByBatesNI uses numerical integration to compute option sensitivities and then to plot option sensitivity surfaces.
%% Define Option Variables and Bates Model Parameters

AssetPrice = 80;
Rate = 0.03;
DividendYield = 0.02;
OptSpec = 'call';

V0 = 0.04;
ThetaV = 0.05;
Kappa = 1.0;
SigmaV = 0.2;
RhoSV = -0.7;
MeanJ = 0.02;
JumpVol = 0.08;
JumpFreq = 2;

%
%% Compute the Option Sensitivity for a Single Strike

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, 6);
Strike = 80; 

Delta = optSensByBatesNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta")

%
%% Compute the Option Sensitivities for a Vector of Strikes
% The Strike input can be a vector.

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, 6);
Strike = (76:2:84)';

Delta = optSensByBatesNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta")

%
%% Compute the Option Sensitivities for a Vector of Strikes and a Vector of Dates of the Same Lengths
% Use the Strike input to specify the strikes. Also, the Maturity input can be a vector, but it must match the length of the Strike vector if the ExpandOutput name-value pair argument is not set to "true".

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, [12 18 24 30 36]); % Five maturities
Strike = [76 78 80 82 84]'; % Five strikes

Delta  = optSensByBatesNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta") % Five values in vector output

%
%% Expand the Output for a Surface
% Set the ExpandOutput name-value pair argument to "true" to expand the output into a NStrikes-by-NMaturities matrix. In this case, it is a square matrix.

Delta  = optSensByBatesNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta", ...
    'ExpandOutput', true) % (5 x 5) matrix output

%
%% Compute the Option Sensitivities for a Vector of Strikes and a Vector of Dates of Different Lengths
% When ExpandOutput is "true", NStrikes do not have to match NMaturities. That is, the output NStrikes -by- NMaturities matrix can be rectangular.

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, 12*(0.5:0.5:3)'); % Six maturities
Strike = (76:2:84)'; % Five strikes

Delta  = optSensByBatesNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta", ...
    'ExpandOutput', true)  % (5 x 6) matrix output

%
%% Compute the Option Sensitivities for a Vector of Strikes and a Vector of Asset Prices
% When ExpandOutput is "true", the output can also be a NStrikes-by-NAssetPrices rectangular matrix by accepting a vector of asset prices.

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, 12); % Single maturity
ManyAssetPrices = [70 75 80 85]; % Four asset prices
Strike = (76:2:84)'; % Five strikes

Delta  = optSensByBatesNI(Rate, ManyAssetPrices, Settle, Maturity, OptSpec, Strike, ...
    V0, ThetaV, Kappa, SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, ...
    'DividendYield', DividendYield, 'OutSpec', "delta", ...
    'ExpandOutput', true) % (5 x 4) matrix output

%
%% Plot Option Sensitivity Surfaces
% The Strike and Maturity inputs can be vectors. Set ExpandOutput to "true" to output the surfaces as NStrikes-by-NMaturities matrices.

Settle = datenum('29-Jun-2017');
Maturity = datemnth(Settle, 12*[1/12 0.25 (0.5:0.5:3)]');
Times = yearfrac(Settle, Maturity);
Strike = (2:2:200)';

[Delta, Gamma, Rho, Theta, Vega, VegaLT] = optSensByBatesNI(...
    Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, V0, ThetaV, Kappa, ...
    SigmaV, RhoSV, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield, ...
    'OutSpec', ["delta", "gamma", "rho", "theta", "vega", "vegalt"], ...
    'ExpandOutput', true);

[X,Y] = meshgrid(Times,Strike);

figure;
surf(X,Y,Delta);
title('Delta');
xlabel('Years to Option Expiry');
ylabel('Strike');
view(-112,34);
xlim([0 Times(end)]);

figure;
surf(X,Y,Gamma)
title('Gamma')
xlabel('Years to Option Expiry')
ylabel('Strike')
view(-112,34);
xlim([0 Times(end)]);

figure;
surf(X,Y,Rho)
title('Rho')
xlabel('Years to Option Expiry')
ylabel('Strike')
view(-112,34);
xlim([0 Times(end)]);

figure;
surf(X,Y,Theta)
title('Theta')
xlabel('Years to Option Expiry')
ylabel('Strike')
view(-112,34);
xlim([0 Times(end)]);

figure;
surf(X,Y,Vega)
title('Vega')
xlabel('Years to Option Expiry')
ylabel('Strike')
view(-112,34);
xlim([0 Times(end)]);

figure;
surf(X,Y,VegaLT)
title('VegaLT')
xlabel('Years to Option Expiry')
ylabel('Strike')
view(-112,34);
xlim([0 Times(end)]);

% Copyright 2012 The MathWorks, Inc.