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.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
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 2.6804
See Also
Functions
Heston
|Bates
|Merton
|ratecurve
|AssetMonteCarlo
|Barrier
|lsqnonlin
|simulannealbnd
(Global Optimization Toolbox)