Main Content

Calibrate Option Pricing Model Using Heston Model

This example shows how to use the Calibrate Pricing Model Live Editor task to calibrate a Heston pricing model to call option prices from the market. After calibration, use the Financial Instruments Toolbox™ object-based workflow to price an American option for a Barrier instrument using the calibrated parameter values for the Heston model with an AssetMonteCarlo pricing method.

Define Pricing Data

Define the data.

Settle = datetime(2015,7,10);
SpotPrice = 123.28;
Rate = -0.001;
MaturityDates = datetime([2015,8,21; 2015,9,18; 2015,12,18; 2016,4,15; 2016,6,17; 2017,1,20]);

Strikes = [115 120 125 130 135 140 145]';

Prices = [9.95 10.63 12.84 15.10 15.95 20.00; ...
    6.30 7.20 9.90 12.30 13.57 17.50; ...
    3.60 4.55 7.30 9.70 11.15 15.20; ...
    1.82 2.68 5.30 7.70 9.00 13.20; ...
    0.82 1.45 3.70 5.85 7.20 11.27; ...
    0.36 0.77 2.50 4.48 5.76 9.65; ...
    0.15 0.38 1.70 3.44 4.54 8.10];

ZeroCurve = ratecurve("zero", Settle, MaturityDates(end), Rate)
ZeroCurve = 
  ratecurve with properties:

                 Type: "zero"
          Compounding: -1
                Basis: 0
                Dates: 20-Jan-2017
                Rates: -1.0000e-03
               Settle: 10-Jul-2015
         InterpMethod: "linear"
    ShortExtrapMethod: "next"
     LongExtrapMethod: "previous"

Use the Calibrate Pricing Model live task to interactively select the data, model, parameter constraints, and the optimization and solver options to generate a volatility surface plot.

% Create fininstrument objects
[MAT, STR] = meshgrid(MaturityDates', Strikes);
Inst = fininstrument('Vanilla', 'ExerciseDate', MAT(:), ...
	'Strike', STR(:), 'OptionType', 'Call');

% Construct objective function
objectiveFcn = @(Param) Prices(:) - price(finpricer('FFT', 'Model', ...
	finmodel('Heston', 'V0', Param(1), 'ThetaV', Param(2), ...
	'Kappa', Param(3), 'SigmaV', Param(4), 'RhoSV', Param(5)), ...
	'SpotPrice', 123.28, 'DiscountCurve', ZeroCurve), Inst);

% Estimate model parameters
options = optimoptions('lsqnonlin', 'FunctionTolerance', 0.0001, ...
	'Display', 'final', 'PlotFcn', 'optimplotresnorm');
Param = lsqnonlin(objectiveFcn, [0.1 0.4 0.2 0.6 -0.1], [0 0 0 0 -1], ...
	[1 1 10 2 1], options);

{"String":"Figure Optimization Plot Function contains an axes object. The axes object with title Norm of Residuals: 2.87832 contains an object of type line.","Tex":[],"LaTex":[]}

Local minimum possible.

lsqnonlin stopped because the final change in the sum of squares relative to 
its initial value is less than the value of the function tolerance.
HestonModel = finmodel('Heston', 'V0', Param(1), 'ThetaV', Param(2), ...
	'Kappa', Param(3), 'SigmaV', Param(4), 'RhoSV', Param(5))
HestonModel = 
  Heston with properties:

        V0: 0.0448
    ThetaV: 0.1625
     Kappa: 0.3317
    SigmaV: 0.0776
     RhoSV: -0.8401

% Calculate implied volatilities for market and model prices
TMAT = yearfrac(ZeroCurve.Settle, MAT);
MKTVOL = blsimpv(123.28, STR, ZeroCurve.Rates(1), TMAT, Prices);

ModelPrice = price(finpricer('FFT', 'Model', HestonModel, 'SpotPrice', 123.28, ...
	'DiscountCurve', ZeroCurve), Inst);
ModelVol = blsimpv(123.28, STR(:), ZeroCurve.Rates(1), TMAT(:), ModelPrice);

% Plot implied volatility surface
figure
surf(TMAT, STR, MKTVOL)
hold on
scatter3(TMAT(:), STR(:), ModelVol, 'ro')
xlabel('Time to Maturity (years)')
ylabel('Strike Price')
zlabel('Implied Volatility')
hold off
grid on

Figure contains an axes object. The axes object contains 2 objects of type surface, scatter.

clearvars TMAT MKTVOL ModelPrice ModelVol
clearvars STR MAT Inst Param options objectiveFcn

Continue with this workflow to price an American option for a Barrier instrument using the calibrated parameter values for a Heston model with an AssetMonteCarlo pricing method.

Create Barrier Instrument Object

Use fininstrument to create a Barrier instrument object.

ExerciseDate = datetime(2016,1,1);
BarrierOpt = fininstrument("Barrier",Strike=90,ExerciseDate=ExerciseDate,OptionType="call",ExerciseStyle="american",BarrierType="DO",BarrierValue=40,Name="barrier_option")
BarrierOpt = 
  Barrier with properties:

       OptionType: "call"
           Strike: 90
      BarrierType: "do"
     BarrierValue: 40
           Rebate: 0
    ExerciseStyle: "american"
     ExerciseDate: 01-Jan-2016
             Name: "barrier_option"

Create AssetMonteCarlo Pricer Object

Use finpricer to create an AssetMonteCarlo pricer object and use the ratecurve object ZeroCurve for the 'DiscountCurve' name-value pair argument.

outPricer = finpricer("AssetMonteCarlo",DiscountCurve=ZeroCurve,Model=HestonModel,SpotPrice=100,SimulationDates=Settle+days(1):days(5):ExerciseDate)
outPricer = 
  HestonMonteCarlo with properties:

      DiscountCurve: [1x1 ratecurve]
          SpotPrice: 100
    SimulationDates: [11-Jul-2015    16-Jul-2015    21-Jul-2015    ...    ]
          NumTrials: 1000
      RandomNumbers: []
              Model: [1x1 finmodel.Heston]
       DividendType: "continuous"
      DividendValue: 0

Price Barrier Instrument

Use price to compute the price and sensitivities for the Barrier instrument.

[Price,outPR] = price(outPricer,BarrierOpt,"all")
Price = 12.4688
outPR = 
  priceresult with properties:

       Results: [1x8 table]
    PricerData: [1x1 struct]

outPR.Results
ans=1×8 table
    Price      Delta      Gamma      Lambda     Rho       Theta      Vega     VegaLT
    ______    _______    ________    ______    ______    _______    ______    ______

    12.469    0.94837    -0.24723    7.6059    297.84    -46.736    17.591    2.6804

See Also

Functions

Related Topics