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);

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.1624
     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

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    26-Jul-2015    31-Jul-2015    05-Aug-2015    10-Aug-2015    15-Aug-2015    20-Aug-2015    25-Aug-2015    30-Aug-2015    04-Sep-2015    09-Sep-2015    ...    ] (1x35 datetime)
               NumTrials: 1000
           RandomNumbers: []
                   Model: [1x1 finmodel.Heston]
            DividendType: "continuous"
           DividendValue: 0
        MonteCarloMethod: "standard"
    BrownianMotionMethod: "standard"

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    285.94

See Also

Functions

Related Topics