%% Workflow for Plotting an Option Price Surface Using the Merton76 Model
% optByMertonNI uses numerical integration to compute option prices and then plot an option price surface.
%% Define Option Variables and Merton76 Model Parameters

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

Sigma = 0.16;
MeanJ = 0.02;
JumpVol = 0.08;
JumpFreq = 2;

%
%% Compute the Option Price for a Single Strike

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

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield)

%
%% Compute the Option Prices 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)';

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield)

%
%% Compute the Option Prices 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

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield)
    % 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.

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield, ...
    'ExpandOutput', true) % (5 x 5) matrix output

%
%% Compute the Option Prices 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

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield, ...
    'ExpandOutput', true) % (5 x 6) matrix output

%
%% Compute the Option Prices 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

Call = optByMertonNI(Rate, ManyAssetPrices, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield, ...
    'ExpandOutput', true) % (5 x 4) matrix output

%
%% Plot an Option Price Surface
% The Strike and Maturity inputs can be vectors. Set ExpandOutput to "true" to output the surface as a NStrikes-by-NMaturities matrix.

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)';

Call = optByMertonNI(Rate, AssetPrice, Settle, Maturity, OptSpec, Strike, ...
    Sigma, MeanJ, JumpVol, JumpFreq, 'DividendYield', DividendYield, ...
    'ExpandOutput', true);

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

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

% Copyright 2012 The MathWorks, Inc.