Is there library support for pricing options using the Heston stochastic volatilty model? Also, can you calibrate the Heston model from market quoted volatilities?
Good question. I know that @jesper has extensive knowledge about that.
Thanks for the question. Yes, we can do all of that.
We can offer very accurate functions, based on state-of-the-art numerical techniques, to price options in the Heston model using Black volatilities as input. In addition to this, we also have a very accurate function to calculate the implied black volatility directly from from the Heston model as well.
The functions are very straightforward to use and have signatures
number heston_option_price(number initial_variance, number long_term_variance, number correlation, number mean_reversion, number vol_vol,
number strike, number forward_value, number T, number df, logical is_call)
and
number heston_implied_black_volatility(number initial_variance, number long_term_variance, number correlation, number mean_reversion, number vol_vol, number strike, number forward_value, number time_to_maturity)
respectively.
The input here, except for the standard option parameters, like strike and forward_value, refers to the parameters of the Heston model, which is given by the two correlated processes
where \mu is the risk free rate with the continuous dividend subtracted and dW_t^S and dW_t^{\nu} are two Brownian motions with correlation \rho.
In the function input \theta is called long term variance, \kappa is the mean reversion, \sigma is called vol_vol, \rho is called rho and the starting value of the variance process, v_t is called initial variance.
We can also calibrate the Heston model from market data in a customizable way where we can choose a proper weighting scheme to put different weight on different option prices depending on their importance in the calibration procedure
In the simplest form we just create an instance of the Heston calibration class, add our black option data we have available for all maturities and then simple call calibrate:
heston_calibration my_calib = heston_calibration();
// Give a forward value and time to maturity.
number F1 = 100;
number T1 = 1;
// Create a vector of strikes for the first maturity
vector(number) strikes1 = [95, 100, 105, 110];
// Create a vector of black volatilities corresponding to options for the given strikes.
// The input should be in decimal form (for example 0.45 represents 45% volatility)
vector(number) black_vol1 = [0.55, 0.50, 0.47, 0.45];
// Add the data to the calibration class
my_calib.add_data_for_maturity(T1, F1, strikes1, black_vol1);
// Do the same thing for options of another maturity
number F2 = 100;
number T2 = 2;
vector(number) strikes2 = [90, 100, 115];
vector(number) black_vol2 = [0.50, 0.45, 0.42];
// Add this to the calibration object as we..
my_calib.add_data_for_maturity(T2, F2, strikes2, black_vol2);
// Then finally tell the class to calibrate the heston model.
heston_params result = my_calib.calibrate();
// The object result now contains the Heston parameters if the calibration was successful.
// You can ask for the Heston paramters by calling its accessor functions.
vector(number) my_heston_params = [result.v0(), result.theta(), result.rho(), result.kappa(), result.sigma()];
As mentioned, the calibration procedure is very customizable so there are a lot of settings to play around with.
Even though the calibration procedure is stable, it can fail. Since the Heston model has parameters concerning the time development of the process, the model is unsuitable to calibrate against options of one maturity only. A decent supply of options is also preferable to fewer ones.
I hope this helps!
Hi,
There could be a typo in the last active line.
my_calib.calibrate() returns an object “heston_params”, from which you can extract the individual parameters.
// ***
heston_params result_obj = my_calib.calibrate();
vector(number) my_heston_params = [result_obj.kappa(),
result_obj.rho(),
result_obj.sigma(),
result_obj.theta(),
result_obj.v0()];
You might also want to divide the input black vols by 100 to get them in decimal form?
Hi, thanks for the correction, you are correct. I have updated my post.
Thanks for taking the time and effort. /R.