Code covered by the BSD License  

Highlights from
Graphically explore the Black-Scholes-Merton Option Pricing Model

image thumbnail

Graphically explore the Black-Scholes-Merton Option Pricing Model

by

 

10 Sep 2012 (Updated )

Visualize option price & gradient surfaces

blsOptionPricer
classdef blsOptionPricer < handle
% BLSOPTIONPRICER is a utility to explore the Black-Scholes-Merton option
% pricing model
%
% BLSOPTIONPRICER provides a graphical user interface to price vanilla call
% & put options as well as straddle and butterfly option combination
% contracts. It enables you to price these conracts as well as visualize
% the price & delta surface as a function of the spot price and time to
% expiration

% Copyright 2012 MathWorks, Inc.

    properties % GUI Parameters
        SpotPrice = 98
        StrikePrice = 98
        RiskFreeRate = .07
        TimeExpiry = 2
        Volatility = .2 % Expressed as a fraction .2 means 20% annual volatility
        % Fraction of the spot price that spans the range of visualization.
        % .1 means SpotPrice*.9 to SpotPrice*1.1
        VisRange = .1 
        % Fraction of the strike price that spans the range of butterfly
        % contracts. .1 implies a butterfly spread with two short options
        % at StrikePrice and a short option at StrikePrice*.9 and a short
        % option at StrikePrice*1.1
        ButRange = .1 
    end
    
    properties % Handles to graphics objects
        hFig
        hEditSpot
        hEditStrike
        hEditRate
        hEditTime
        hEditVolatility
        hEditVisRange
        hEditButRange
        hRBGType
        hRBCall
        hRBPut
        hRBStraddle
        hRBButterfly
        hEditPrice
        hButPrice
        hButVisualize
    end
    
    methods % Constructor & Initialization methods
        
        function obj = blsOptionPricer
        % Constructor - called when the object representing the GUI is
        % created. The constructor's job is to create the UI components and
        % set their callbacks. 
        
            % Create UI Components
            obj.createUIComponents();
            
            % Set callbacks
            obj.setCallbacks();
        end
        
        function createUIComponents(obj)
            % Create all of the UI components of the graphical interface
            % and populate the properties of the object
            obj.hFig = figure(...
                'MenuBar','none',...
                'Color',[0.941176470588235 0.941176470588235 0.941176470588235],...
                'Name','Option Contract Pricing & Visualization Tool',...
                'NumberTitle','off',...
                'Position',[232 286 402 296],...
                'ToolBar','none',...
                'HandleVisibility','off',...
                'Tag','figure1');
            
            h2 = uipanel(...
                'Parent',obj.hFig,...
                'Title','Option Parameters',...
                'Tag','uipanel1',...
                'Position',[0.02 0.037 0.55 0.94]);
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.842496998799516 0.508474576271186 0.0937517864288573],...
                'String','Spot Price',...
                'Style','text',...
                'Tag','text1');
            
            obj.hEditSpot = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.849997141713828 0.317796610169492 0.0937517864288573],...
                'String','98',...
                'Style','edit',...
                'Tag','editSpot');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0787037037037037 0.710317460317459 0.509259259259259 0.095238095238095],...
                'String','Strike Price',...
                'Style','text',...
                'UserData',[],...
                'Tag','text2');
            
            obj.hEditStrike = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.718744640713428 0.317796610169492 0.0937517864288573],...
                'String','98',...
                'Style','edit',...
                'Tag','editStrike');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.579991996798719 0.508474576271186 0.0937517864288573],...
                'String','Risk Free Rate',...
                'Style','text',...
                'UserData',[],...
                'Tag','text3');
            
            obj.hEditRate = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.587492139713028 0.317796610169492 0.0937517864288573],...
                'String','0.07',...
                'Style','edit',...
                'Tag','editRate');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.448739495798319 0.508474576271186 0.0937517864288573],...
                'String','Months to Expiry',...
                'Style','text',...
                'UserData',[],...
                'Tag','text4');
            
            obj.hEditTime = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.456239638712628 0.317796610169492 0.0937517864288573],...
                'String','2',...
                'Style','edit',...
                'Tag','editTime');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.317486994797919 0.508474576271186 0.0937517864288573],...
                'String','Volatility',...
                'Style','text',...
                'UserData',[],...
                'Tag','text5');
            
            obj.hEditVolatility = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.324987137712228 0.317796610169492 0.0937517864288573],...
                'String','0.20',...
                'Style','edit',...
                'Tag','editVolatility');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.163734065054593 0.508474576271186 0.1312525010004],...
                'String','Visualization Range',...
                'Style','text',...
                'UserData',[],...
                'Tag','text6');
            
            obj.hEditVisRange = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.193734636711827 0.317796610169492 0.0937517864288573],...
                'String','0.10',...
                'Style','edit',...
                'Tag','editVisRange');
            
            uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'CData',[],...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0805084745762711 0.0212313496827303 0.508474576271186 0.1312525010004],...
                'String','Butterfly Range',...
                'Style','text',...
                'UserData',[],...
                'Tag','text7');
            
            obj.hEditButRange = uicontrol(...
                'Parent',h2,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.610169491525424 0.0624821357114274 0.317796610169492 0.0937517864288573],...
                'String','0.10',...
                'Style','edit',...
                'Tag','editButRange');
            
            h17 = uipanel(...
                'Parent',obj.hFig,...
                'Title','Price',...
                'Tag','uipanel4',...
                'UserData',[],...
                'Clipping','on',...
                'Position',[0.597014925373134 0.189189189189189 0.378109452736318 0.290540540540541]);
            
            uicontrol(...
                'Parent',h17,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.168918918918919 0.579710144927536 0.675675675675676 0.36231884057971],...
                'String','Option Value',...
                'Style','text',...
                'Tag','text8');
            
            obj.hEditPrice = uicontrol(...
                'Parent',h17,...
                'Units','normalized',...
                'BackgroundColor',[1 1 1],...
                'Position',[0.168918918918919 0.130434782608696 0.675675675675676 0.36231884057971],...
                'Style','edit',...
                'Tag','editPrice');
            
            obj.hRBGType = uibuttongroup(...
                'Parent',obj.hFig,...
                'Title','Option Type',...
                'Tag','uipanel5',...
                'Position',[0.597014925373134 0.510135135135135 0.378109452736318 0.466216216216216]);
            
            obj.hRBCall = uicontrol(...
                'Parent',obj.hRBGType,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0810810810810811 0.745614035087719 0.810810810810811 0.219298245614035],...
                'String','Call Option',...
                'Style','radiobutton',...
                'Value',1,...
                'Tag','rbCall');
            
            obj.hRBPut = uicontrol(...
                'Parent',obj.hRBGType,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0810810810810811 0.526315789473684 0.810810810810811 0.219298245614035],...
                'String','Put Option',...
                'Style','radiobutton',...
                'Tag','rbPut');
            
            obj.hRBStraddle = uicontrol(...
                'Parent',obj.hRBGType,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0810810810810811 0.307017543859649 0.810810810810811 0.219298245614035],...
                'String','Straddle',...
                'Style','radiobutton',...
                'Tag','rbStraddle');
            
            obj.hRBButterfly = uicontrol(...
                'Parent',obj.hRBGType,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.0810810810810811 0.087719298245614 0.810810810810811 0.219298245614035],...
                'String','Butterfly',...
                'Style','radiobutton',...
                'Tag','rbButterfly');
            
            obj.hButPrice = uicontrol(...
                'Parent',obj.hFig,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.597014925373134 0.0472972972972973 0.181592039800995 0.10472972972973],...
                'String','Price',...
                'Tag','butPrice');
            
            obj.hButVisualize = uicontrol(...
                'Parent',obj.hFig,...
                'Units','normalized',...
                'FontSize',10,...
                'FontWeight','bold',...
                'Position',[0.791044776119403 0.0472972972972973 0.181592039800995 0.10472972972973],...
                'String','Visualize',...
                'Tag','butVisualize');


        end
        
        function setCallbacks(obj)
            % Assign the callback functions for the "Price" and "Visualize"
            % buttons on the GUI
            set(obj.hButPrice, 'Callback', @obj.onPrice);
            set(obj.hButVisualize, 'Callback', @obj.onVisualize);
        end
        
    end
    
    methods % Callbacks
        
        function onPrice(obj, varargin)
            % This method is called when the "Price" button is pushed. It
            % collects the inputs from the GUI, prices the contract and
            % displays the result in the GUI
            
            [price, strike, rate, time, vol, visRange, butRange, optionType] = getGUIInputs(obj); %#ok<ASGLU>
            optionPrice = priceContract(optionType, price, strike, rate, time, vol, butRange);
            set(obj.hEditPrice, 'String', num2str(optionPrice));
        end
        
        function onVisualize(obj, varargin)
            % This method is called when the "Visualize" button is pushed. It
            % collects the inputs from the GUI, prices the contract for a 
            % range of values and creates a surface plot
            
            [price, strike, rate, time, vol, visRange, butRange, optionType] = getGUIInputs(obj);
            visualizeContract(optionType, price, strike, rate, time, vol, butRange, visRange);
        end
    
    end
    
    methods % Helper functions
        
        function [price, strike, rate, time, vol, visRange, butRange, optionType] = getGUIInputs(obj)
            % getUIInputs collects all of the inputs from the GUI and
            % converts them into the appropriate numeric type. This
            % function is called by onPrice & onVisualize
            
            price = str2double(get(obj.hEditSpot, 'String'));
            strike = str2double(get(obj.hEditStrike, 'String'));
            rate = str2double(get(obj.hEditRate, 'String'));
            time = str2double(get(obj.hEditTime, 'String')) / 12;
            vol = str2double(get(obj.hEditVolatility, 'String'));
            visRange = str2double(get(obj.hEditVisRange, 'String'));
            butRange = str2double(get(obj.hEditButRange, 'String'));
            optionType = get(get(obj.hRBGType, 'SelectedObject'), 'String');
        end
        
    end
end

% Sub functions 
function optionValue = priceContract(optionType, spotPrice, strikePrice, rfRate, timeExpiry, volatility, butterflyRange)
% PRICECONTRACT prices the option contract using the Black-Scholes-Model
% for scalar or matrix input values
%
% SYNTAX: optionValue = priceContract(optionType, spotPrice, strikePrice, rfRate, timeExpiry, volatility, butterflyRange)

% Price basic options
[call, put] = priceOption(spotPrice, strikePrice, rfRate, timeExpiry, volatility);

switch lower(optionType(1:3))
    case 'cal'
        optionValue = call;
    case 'put'
        optionValue = put;
    case 'str'
        optionValue = call + put;
    case 'but'
         lowCall = priceOption(spotPrice, strikePrice * (1 - butterflyRange), rfRate, timeExpiry, volatility);
        highCall = priceOption(spotPrice, strikePrice * (1 + butterflyRange), rfRate, timeExpiry, volatility);
        optionValue = lowCall + highCall - 2*call;
end
end

function visualizeContract(optionType, spotPrice, strikePrice, rfRate, timeExpiry, volatility, butterflyRange, vizRange)
% VISUALIZECONTRACT prices the option contract using the Black-Scholes-Model
% & then creates a surface plot of the option value (and gradient shown as
% color) for different values of the spot price and time to expiration
%
% SYNTAX: visualizeContract(optionType, spotPrice, strikePrice, rfRate, timeExpiry, volatility, butterflyRange, vizRange)

[spotMat, timeMat] = calcrange(spotPrice, timeExpiry, vizRange);

optionValue = priceContract(optionType, spotMat, strikePrice, rfRate, timeMat, volatility, butterflyRange);

hqr = surf(spotMat, timeMat, optionValue, gradient(optionValue, diff(spotMat(1,1:2)), diff(timeMat(1:2))));
xlabel('Spot Price');
ylabel('Time to Expiry');
zlabel('Option Value');
title(optionType);

set(hqr,'FaceAlpha',.6)
set(hqr,'EdgeAlpha',.2)
set(hqr,'FaceLighting','phong')
set(hqr,'FaceColor','interp')
end

function [SpotMat, TimeMat] = calcrange(SpotPrice, TimeExpiry, VizRange)
%CALCRANGE Compute spot price and time to expiry range based on visualization
%range

%Compute a step for the spot price range which scales based on the magnitude
%of the spot price and the visualization range
SpotStep = (SpotPrice - SpotPrice * (1 - VizRange / 2)) / 10;

%Compute the range of spot prices based on the visualization range
SpotRange = SpotPrice * (1 - VizRange / 2) : ...
     SpotStep : SpotPrice * ((1 + VizRange / 2));

%Compute a step for the time to expiry range which scales based on the
%magnitude of the time to expiry and the visualization range
TimeStep = (TimeExpiry) / 30;

%Compute the range of times to expiry
TimeRange = 0 : TimeStep : TimeExpiry;

%Generate matrix spot prices and times to expiry based on the size of the
%spot price and time to expiry ranges
[SpotMat, TimeMat] = meshgrid(SpotRange, TimeRange);
end

Contact us