четверг, 12 августа 2021 г.

MatLab, Greeks, Example

%function [ output_args ] = calcGreeks( input_args )

%CALCGREEKS Summary of this function goes here

%   Detailed explanation goes here

% end


function [fairValue, greeks] = calcGreeks(spot, strike, rate, yield, volatility, maturity, putCallInd, annualFactor)

% calcGreeks - Calculate Greeks (Black/Scholes, Vanilla European Option, Closed Form)

%

% calcGreeks computes and reports the fair price value and numerous Greek values

% for vanilla European options, using the Black-Sholes-Merton model, optimized

% for performance. No toolbox is required - only basic Matlab.

%

% Any input parameter can be vectorized (examples below), but only one parameter

% can be vectorized.

%

% calcGreeks is used by the IQFeed-Matlab connector (IQML - https://undocumentedmatlab.com/IQML)

%

% Syntax:

%    [fairValue, greeks] = calcGreeks(spot, strike, rate, yield, volatility, maturity, putCallInd, annualFactor)

%

% Inputs:

%    spot         - (mandatory) Underlying asset's spot price

%    strike       - (mandatory) Derivative contract's strike price

%    rate         - (default: 0) Domestic risk-free interest rate (%)

%    yield        - (default: 0) Foreign interest rate (Forex) or dividend yield (stock)

%    volatility   - (default: 0.3) Historic volatility of the underlying asset's price

%    maturity     - (default: 1.0) Number of years until derivative contract expires

%    putCallInd   - (default: 'Call') Either 1 (Call), -1 (Put), or [1,-1] (both)

%                   or as strings: "Call", 'put', 'cp', {'Call',"put"} etc.

%    annualFactor - (default: 1) Used to de-annualize Theta, Charm, Veta, Color

%                   1: report annualized values; 365: report 1-day estimates

%                   Typical values: 1, 365, 252

%

% Usage examples:

%

%    % Example 1: vectorized call/put

%    >> [fairValue, greeks] = calcGreeks(56.8, 60, 5, 2.5, 35, 15/365, {'call','put'}, 365)

%    fairValue =

%         0.5348    3.6700

%    greeks = 

%       struct with fields:

%          delta: [0.2347  -0.7642]

%           vega: 3.5347

%          theta: [-0.0421 -0.0378]

%            rho: [0.5260  -1.9347]

%           crho: [0.5480  -1.7839]

%          omega: [24.9311 -11.8278]

%         lambda: [24.9311 -11.8278]

%          gamma: 0.0762

%          vanna: 0.6959

%          charm: [-0.0025 -0.0275]

%          vomma: 5.7897

%          volga: 5.7897

%           veta: 0.1876

%          speed: 0.0123

%          zomma: -0.0929

%          color: -0.0010

%         ultima: -40.2881

%

%    % Example 2: vectorized strike prices

%    >> [fairValue, greeks] = calcGreeks(56.8, 45:5:65, 5, 2.5, 35, 15/365, 'c', 365)

%    fairValue =

%        11.8345    6.8966    2.6769    0.5348    0.0493

%    greeks = 

%       struct with fields:

%          delta: [0.9985 0.9666 0.6921 0.2347 0.0321]

%           vega: [0.0178 0.8334 4.0419 3.5347 0.8280]

%          theta: [-0.0025 -0.0125 -0.0495 -0.0421 -0.0098]

%            rho: [1.8445 1.9730 1.5055 0.5260 0.0729]

%           crho: [2.3308 2.2564 1.6155 0.5480 0.0749]

%          omega: [4.7925 7.9612 14.6854 24.9311 36.9547]

%         lambda: [4.7925 7.9612 14.6854 24.9311 36.9547]

%          gamma: [3.8391e-04 0.0180 0.0871 0.0762 0.0178]

%          vanna: [-0.0144 -0.3673 -0.4341 0.6959 0.3948]

%          charm: [0.0251 0.0284 0.0220 -0.0025 -0.0039]

%          vomma: [0.5531 7.8117 2.5186 5.7897 8.4126]

%          volga: [0.5531 7.8117 2.5186 5.7897 8.4126]

%           veta: [0.0070 0.1174 0.1619 0.1876 0.1272]

%          speed: [-3.2418e-04 -0.0085 -0.0124 0.0123 0.0079]

%          zomma: [0.0108 0.1170 -0.1946 -0.0929 0.1303]

%          color: [1.2500e-04 0.0013 -0.0023 -0.0010 0.0016]

%         ultima: [12.4303 6.2331 -20.1849 -40.2881 13.3330]

%

% Bugs and suggestions:

%    Please send to Yair Altman (altmany at gmail dot com)

%

% Technical description:

%    https://en.wikipedia.org/wiki/Greeks_(finance)#Delta

%

% Release history:

%    1.0  2018-11-28: initial version

%    1.1  2018-11-28: retrying to upload as a toolbox...

% License to use and modify this code is granted freely to all interested, as long as the original author is

% referenced and attributed as such. The original author maintains the right to be solely associated with this work.

% Programmed and Copyright by Yair M. Altman: altmany(at)gmail.com

    %{

    See also:

     - http://option-price.com

     - https://en.wikipedia.org/wiki/Greeks_(finance)

     - http://www.walkingrandomly.com/?p=4416

     - https://www.nag.co.uk/numeric/MB/manual64_24_1/pdf/S/s30ab.pdf

     - https://www.nag.co.uk/numeric/MB/manual64_25_1/pdf/S/s30ab.pdf

     - https://www.nag.co.uk/content/using-nag-toolbox-matlab-part-5

     - https://www.maplesoft.com/support/help/Maple/view.aspx?path=Finance/BlackScholesGamma (etc.)

     - https://www.mathworks.com/matlabcentral/fileexchange/10428-plotmethegreeks

     - https://www.mathworks.com/matlabcentral/fileexchange/44258-vanilla-option-price-black-scholes-close-form

     - https://www.mathworks.com/matlabcentral/fileexchange/44289-vanilla-option-greeks-black-scholes-close-form

    %}

    % Assign default values to optional input args

    if nargin < 8, annualFactor = 1;  end  % compatibility with Matlab's Financial Toolbox, NAG, Maple

    if nargin < 7, putCallInd   = 1;  end  % default: Call

    if nargin < 6, maturity     = 1;  end  % default: 1 year

    if nargin < 5, volatility   = 30; end  % default: 30%

    if nargin < 4, yield        = 0;  end  % default: 0%

    if nargin < 3, rate         = 0;  end  % default: 0%

    if nargin < 2, error('At least one spot price and one strike price must be specified!'); end

    % Normalize % values to fractions:

    rate  = rate/100;

    yield = yield/100;

    volatility = volatility/100;

    % Normalize putCallInd that can be specified in many different formats

    try %#ok if isa(putCallInd,'string')

        putCallInd = controllib.internal.util.hString2Char(putCallInd);

    end

    if iscellstr(putCallInd)

        putCallInd = cellfun(@(c)c(1),putCallInd);

    end

    if ischar(putCallInd)

        putCallInd = unique(lower(regexprep(putCallInd,'[^PpCc]','')),'stable');

        pcVal = [];

        for idx = 1 : length(putCallInd)

            if putCallInd(idx)=='c'

                pcVal(end+1) = +1; %#ok<AGROW>

            elseif putCallInd(idx)=='p'

                pcVal(end+1) = -1; %#ok<AGROW>

            end

        end

        if isempty(pcVal), error('Either put or call or both must be specified!'); end

        putCallInd = pcVal;

    elseif iscell(putCallInd)

        putCallInd = [putCallInd{:}];

    end

    % Calculate basic mathematical values that are used below

    r = rate;

    q = yield;

    b = r-q;  % Carry rate: https://www.nag.co.uk/numeric/MB/manual64_25_1/pdf/S/s30ab.pdf

    sqrt_maturity = sqrt(maturity);

    f = volatility .* sqrt_maturity;

    sqr_sigma = volatility .* volatility;

    sqr_sigma_2 = 0.5 * sqr_sigma;

    d1 = (log(spot./strike) + (b + sqr_sigma_2) .* maturity) ./ f;

    d2 = d1 - f; %=(log(spot/strike) + (r-q-sqr_sigma_2) * maturity) / f;

    eqm = exp(-q .* maturity);

    erm = exp(-r .* maturity);

    npd1 = 1/sqrt(2*pi) * exp(-d1.^2/2); %=normpdf(d1);

    epd1 = eqm .* npd1;

    sepd1 = spot .* epd1;

    sqrt2 = sqrt(2);

    ncd1 = 0.5*erfc(-putCallInd.*d1/sqrt2); %=0.5*erf(putCallInd*d1/sqrt2)+0.5; %=normcdf(putCallInd*d1);

    ncd2 = 0.5*erfc(-putCallInd.*d2/sqrt2); %=0.5*erf(putCallInd*d2/sqrt2)+0.5; %=normcdf(putCallInd*d2);

    ecd1 = eqm .* ncd1;

    ecd2 = erm .* ncd2;

    secd1 = spot   .* ecd1;

    secd2 = strike .* ecd2;

    % Compute and report the fair value (bail-out immediately if greeks are not requested)

    fairValue = putCallInd .* (secd1 - secd2);

    if nargout < 2,  return,  end

    % 1st-order Greeks

    greeks.delta = putCallInd .* ecd1;

    greeks.vega  = sepd1 .* sqrt_maturity; %*0.01

    greeks.theta = (-sepd1 .* sqr_sigma_2 ./ f + putCallInd.*(q.*secd1 - r.*secd2)) / annualFactor;

    greeks.rho   = putCallInd .* maturity .* secd2; %*0.01

    greeks.crho  = greeks.rho .* secd1 ./ secd2;  %https://www.nag.co.uk/numeric/MB/manual64_25_1/pdf/S/s30ab.pdf

    greeks.omega = greeks.delta .* spot ./ fairValue;

    greeks.lambda = greeks.omega; %synonym

    % 2nd-order Greeks

    d12 = d1 .* d2;

    greeks.gamma = epd1 ./ spot ./ f;

    greeks.vanna = -epd1 .* d2 ./ volatility;  % =vega/spot*(1-d1/f);

    greeks.charm = q .* greeks.delta - epd1 .* (b./f - 0.5*d2./maturity) / annualFactor;

    greeks.vomma = sepd1 .* f .* d12 / sqr_sigma;  % AKA volga, vega convexity

    greeks.volga = greeks.vomma; %synonym

    greeks.veta  = -sepd1 .* sqrt_maturity .* (q + b.*d1./f - 0.5*(1+d12)./maturity) / annualFactor; %*0.01

    % 3rd-order Greeks

    greeks.speed  = -greeks.gamma ./ spot .* (d1./f + 1);

    greeks.zomma  =  greeks.gamma .* (d12-1) ./ volatility;

    greeks.color  = -greeks.gamma .* (q + 1./(2*maturity) + (b./f - d2./(2*maturity)).*d1) / annualFactor;

    greeks.ultima = -greeks.vega ./ sqr_sigma .* (d12.*(1-d12) + d1.*d1 + d2.*d2);

end




Комментариев нет:

Отправить комментарий