# 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```