Price European Vanilla Call Options Using Black-Scholes Model and Different Equity Pricers
This example shows how to compare European Vanilla
instrument call option prices using a BlackScholes
model and different pricing methods. The pricing methods for this comparison are the Cox-Ross-Rubinstein, Leisen-Reimer, finite difference, and the Black-Scholes analytical formula.
Create ratecurve
Object
Create a ratecurve
object using ratecurve
.
Settle = datetime(2019,01,01); Maturity = datetime(2022,01,01); Rate = 0.0111; Compounding = -1; ZeroCurve = ratecurve('zero',Settle,Maturity,Rate,'Compounding',Compounding);
Create BlackScholes
Model Object
Use finmodel
to create a BlackScholes
model object.
Volatility = .35; BSModel = finmodel("BlackScholes",'Volatility',Volatility);
Create Vanilla
Instrument Object
Use fininstrument
to create a Vanilla
instrument object.
ExerciseDates = datetime(2019,09,01); Strike = 30; OptionType = 'call'; EuropeanCallOption = fininstrument("Vanilla",'ExerciseDate',ExerciseDates,'Strike',Strike,... 'OptionType',OptionType,'Name',"vanilla_call_option");
Create Analytic
, AssetTree
, and FiniteDifference
Pricer Objects
Create two scenarios for the Vanilla option. In the first scenario, the option is out of the money (OTM). In the second scenario the option is at the money (ATM).
% Define the number of levels of the tree for AssetTree pricer
NumPeriods = 55;
Calculate Vanilla Option Price for OTM Option
Use finpricer
to create an BlackScholes
, AssetTree
, and FiniteDifference
pricer objects for the OTM option and use the ratecurve
object for the 'DiscountCurve'
name-value pair argument.
SpotPriceOTM = 25; % Analytic Pricer AnalyticPricerOTM = finpricer('Analytic', 'Model', BSModel, 'SpotPrice', SpotPriceOTM, 'DiscountCurve', ZeroCurve); PriceBLSOTM = price(AnalyticPricerOTM, EuropeanCallOption); % AssetTree Pricer CRRPricerOTM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceOTM, ... 'PricingMethod',"CoxRossRubinstein",'NumPeriods', NumPeriods, 'Maturity', ExerciseDates); PriceCRROTM = price(CRRPricerOTM, EuropeanCallOption); LRPricerOTM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceOTM, ... 'PricingMethod',"LeisenReimer",'NumPeriods', NumPeriods, 'Maturity', ExerciseDates, 'Strike', Strike); PriceLROTM = price(LRPricerOTM, EuropeanCallOption); % FiniteDifference Pricer FDPricerOTM = finpricer('FiniteDifference', 'Model', BSModel, 'SpotPrice', SpotPriceOTM, 'DiscountCurve', ZeroCurve); PriceFDOTM = price(FDPricerOTM, EuropeanCallOption);
Calculate Vanilla Option Price for ATM Option
Use finpricer
to create an BlackScholes
, AssetTree
, and FiniteDifference
pricer objects for the ATM option and use the ratecurve
object for the 'DiscountCurve'
name-value pair argument.
SpotPriceATM = 30; % Analytic Pricer AnalyticPricerATM = finpricer('Analytic', 'Model', BSModel, 'SpotPrice', SpotPriceATM, 'DiscountCurve', ZeroCurve); PriceBLSATM = price(AnalyticPricerATM, EuropeanCallOption); % AsetTree Pricer CRRPricerATM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceATM, ... 'PricingMethod',"CoxRossRubinstein",'NumPeriods', NumPeriods, 'Maturity', ExerciseDates); PriceCRRATM = price(CRRPricerATM, EuropeanCallOption); LRPricerATM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceATM, ... 'PricingMethod',"LeisenReimer",'NumPeriods', NumPeriods, 'Maturity', ExerciseDates, 'Strike', Strike); PriceLRATM = price(LRPricerATM, EuropeanCallOption); % FiniteDifference Pricer FDPricerATM = finpricer('FiniteDifference', 'Model', BSModel, 'SpotPrice', SpotPriceATM, 'DiscountCurve', ZeroCurve); PriceFDATM = price(FDPricerATM, EuropeanCallOption);
Vanilla Option Price Comparison When Option Is OTM
Use the displayPricesVanillaCallOption
in Local Functions to compare the Vanilla call prices for OTM.
displayPricesVanillaCallOption("OTM", PriceBLSOTM, PriceCRROTM, PriceLROTM, PriceFDOTM)
Comparison of Vanilla Call Option Prices OTM: Black-Scholes: 1.280591 Cox-Ross-Rubinstein: 1.278306 Leisen-Reimer: 1.280651 Finite-Difference: 1.280599
Vanilla Option Price Comparison When Option Is ATM
Use the displayPricesVanillaCallOption
in Local Functions to compare the Vanilla call prices for ATM.
displayPricesVanillaCallOption("ATM", PriceBLSATM, PriceCRRATM, PriceLRATM, PriceFDATM)
Comparison of Vanilla Call Option Prices ATM: Black-Scholes: 3.505323 Cox-Ross-Rubinstein: 3.520559 Leisen-Reimer: 3.505377 Finite-Difference: 3.505452
Analyze Effect of Number of Tree Levels on Price of Options When Using AssetTree
Pricer
Create graphs to visualize how convergence changes as the number of steps in the binomial calculation increases for the Cox-Ross-Rubinstein and Leisen-Reimer tree models, as well as the impact on convergence to changes to the asset price.
% Define the number of time steps of the tree NPoints = 240; % Cox-Ross-Rubinstein NumPeriodCRR = 5 : 1 : NPoints; NbStepCRR = length(NumPeriodCRR); PriceOTMCRR = nan(NbStepCRR, 1); PriceATMCRR = PriceOTMCRR; for i = 1 : NbStepCRR PricerCRROTM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceOTM, ... 'PricingMethod',"CoxRossRubinstein",'NumPeriods', NumPeriodCRR(i), 'Maturity', ExerciseDates); PriceOTMCRR(i) = price(PricerCRROTM, EuropeanCallOption); PricerCRRATM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceATM, ... 'PricingMethod',"CoxRossRubinstein",'NumPeriods', NumPeriodCRR(i), 'Maturity', ExerciseDates); PriceATMCRR(i) = price(PricerCRRATM, EuropeanCallOption); end % Leisen-Reimer NumPeriodLR = 5 : 2 : NPoints; NbStepLR = length(NumPeriodLR); PriceOTMLR = nan(NbStepLR, 1); PriceATMLR = PriceOTMLR; for i = 1 : NbStepLR PricerLROTM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceOTM, ... 'PricingMethod',"LeisenReimer",'NumPeriods', NumPeriodLR(i), 'Maturity', ExerciseDates, 'Strike', Strike); PriceOTMLR(i) = price(PricerLROTM, EuropeanCallOption); PricerLRATM = finpricer("AssetTree",'DiscountCurve',ZeroCurve,'Model',BSModel, 'SpotPrice',SpotPriceATM, ... 'PricingMethod',"LeisenReimer",'NumPeriods', NumPeriodLR(i), 'Maturity', ExerciseDates, 'Strike', Strike); PriceATMLR(i) = price(PricerLRATM, EuropeanCallOption); end
First Scenario: OTM Vanilla Call Option
Plot the convergence of CRR and LR models to a Black-Scholes solution for an OTM option.
% Cox-Ross-Rubinstein plot(NumPeriodCRR, PriceOTMCRR); hold on; plot(NumPeriodCRR, PriceBLSOTM*ones(NbStepCRR,1),'Color',[0 0.9 0], 'linewidth', 1.5); % Leisen-Reimer plot(NumPeriodLR, PriceOTMLR, 'Color',[0.9 0 0], 'linewidth', 1.5); % Concentrate the area of interest by clipping on the Y axis at five times the % LR price: YLimDelta = 5*abs(PriceOTMLR(1) - PriceBLSOTM); ax = gca; ax.YLim = [PriceBLSOTM - YLimDelta PriceBLSOTM + YLimDelta]; ax.XLim = [5 NPoints]; % Annotate plot titleString = sprintf('\nConvergence of CRR and LR Models to a BLS Solution (OTM)\nStrike = %d, Asset Price = %d', Strike , SpotPriceOTM); title(titleString) ylabel('Option Price') xlabel('Number of Steps') legend('CRR', 'BLS', 'LR', 'Location', 'NorthEast')
Observe that the Leisen-Reimer model removes the oscillation and produces estimates close to the Black-Scholes model using only a small number of steps.
Second Scenario: ATM Vanilla Call Option
Plot the convergence of CRR and LR models to a Black-Scholes solution for an ATM option.
% Cox-Ross-Rubinstein figure; plot(NumPeriodCRR, PriceATMCRR); hold on; plot(NumPeriodCRR, PriceBLSATM*ones(NbStepCRR,1),'Color',[0 0.9 0], 'linewidth', 1.5); % Leisen-Reimer plot(NumPeriodLR, PriceATMLR, 'Color',[0.9 0 0], 'linewidth', 1.5); % Concentrate the area of interest by clipping on the Y axis at five times the % LR price: YLimDelta = 5*abs(PriceATMLR(1) - PriceBLSATM); ax = gca; ax.YLim = [PriceBLSATM - YLimDelta PriceBLSATM + YLimDelta]; ax.XLim = [5 NPoints]; % Annotate plot titleString = sprintf('\nConvergence of CRR and LR Models to a BLS Solution (ATM)\nStrike = %d, Asset Price = %d', Strike , SpotPriceATM); title(titleString) ylabel('Option Price') xlabel('Number of Steps') legend('CRR', 'BLS', 'LR', 'Location', 'NorthEast')
While the CRR binomial model and the Black-Scholes model converge as the number of time steps increases, this convergence, except for the at-the-money options, is anything but smooth or uniform.
Local Functions
function displayPricesVanillaCallOption(type, PriceBLS, PriceCRR, PriceLR, PriceFD) fprintf('Comparison of Vanilla Call Option Prices %s:\n', type); fprintf('\n'); fprintf('Black-Scholes: %f\n', PriceBLS); fprintf('Cox-Ross-Rubinstein: %f\n', PriceCRR); fprintf('Leisen-Reimer: %f\n', PriceLR); fprintf('Finite-Difference: %f\n', PriceFD); fprintf('\n'); end
See Also
FiniteDifference
| AssetTree
| BlackScholes
| Vanilla
Related Examples
More About
- Get Started with Workflows Using Object-Based Framework for Pricing Financial Instruments
- Choose Instruments, Models, and Pricers
- Supported Exercise Styles